Difference between revisions of "Talk:Loot Filtration"
(→Filtering Substitutions) |
|||
(17 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
You can find loot filters made by other players and download instructions at [[List of Loot Filters]]. | You can find loot filters made by other players and download instructions at [[List of Loot Filters]]. | ||
+ | |||
+ | == Overview == | ||
+ | PoD’s loot filter is based off of the same item filtering style originally introduced by BH. It has however grown substantially from the featureset provided by BH. | ||
+ | |||
+ | If you have a request for changes or additions, want to report bugs or merely get help building a filter, please join the [https://discord.com/invite/path-of-diablo-111158239135064064 Path of Diablo Discord], and ask in the #lootfilter channel. | ||
+ | |||
+ | NOTE: Anything marked as <span style="color:red">[Deprecated]</span> will be removed in future versions. | ||
+ | |||
+ | == Definitions and File Structure == | ||
+ | All PoD item filters are utf-8 encoded text files with the .filter file extension, found in the filter directory of your Path of Diablo installation. | ||
+ | |||
+ | Filters are processed from top to bottom, this has an important role when it comes to precedence of filter matching and accruing of transforms to the item name, notifications, notes and styles. | ||
+ | |||
+ | Ordering does not affect filter level names, macros, item code or skill lists. | ||
+ | |||
+ | File comments are made by starting a line with // causing anything else on the line to not be processed. One may also use blank/empty lines without any effect on the filter. | ||
+ | |||
+ | Filter files can contain the following top level definitions: | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name/Syntax | ||
+ | ! Description | ||
+ | |- | ||
+ | | ItemDisplay[expr]: text | ||
+ | | Defines a filtering expression and the item name it’ll produce when matched. | ||
+ | |- | ||
+ | | FilterLevel[id]: name | ||
+ | | Names a filter level. | ||
+ | |- | ||
+ | | SkillList[name]: skill id’s | ||
+ | | Defines a group of skill id’s that can be used to reduce duplication in filter expressions. | ||
+ | |- | ||
+ | | ItemList[name]: item codes | ||
+ | | Defines a group of item codes that can be used to reduce duplication in filter expressions. | ||
+ | |- | ||
+ | | Option[name]: value | ||
+ | | Defines an option. | ||
+ | |- | ||
+ | | Attribute[name]: value | ||
+ | | Defines a preset filter attribute. | ||
+ | |- | ||
+ | | ItemDescription[name]: text | ||
+ | | Defines a reusable item note. | ||
+ | |- | ||
+ | | ItemStyle[name]: styling | ||
+ | | Defines an item display and notification style. | ||
+ | |- | ||
+ | | TextMacro[name]: text | ||
+ | | Defines a reusable text macro to simplify commonly used idioms. | ||
+ | |- | ||
+ | | <nowiki> Sound[name]: path|id </nowiki> | ||
+ | | Defines a custom sound for use in the filter. | ||
+ | |- | ||
+ | | EnableIf[expr] | ||
+ | | Starts a block-level filter. | ||
+ | |- | ||
+ | | EndIf[] | ||
+ | | Ends a block-level filter. | ||
+ | |} | ||
+ | During parsing, all invalid or incorrectly formatted lines will be ignored to prevent potential crashes. Issues detected by the parser will be logged out to the Diablo II log file, additionally they can be logged to the in-game message console. Any invalid expressions will be ignored and always return true to prevent accidentally hiding items that shouldn’t be hidden. | ||
+ | |||
+ | == Item Display Filtering == | ||
+ | Items can be filtered on the ground, inventory and NPC trade windows. In each scenario the <code>[ItemDisplay]</code> entries will be evaluated from the top of the file to bottom, until a terminating match is found. Matches that do not terminate will accrue their changes for filters below them. This allows setting a general filter at the top for common styling and then making specific changes to the style further down. This does mean that you will want to have your most general matching filters at first and your most specific filters last. | ||
+ | |||
+ | If no terminating filter is found, any accrued style changes will still be applied. | ||
+ | |||
+ | Building an item filter is done using a combination of conditions and filtering variables that evaluate to true or false (Boolean logic). For a filter to match an item, the entire expression needs to evaluate to true. See Optimizing Your Filters for performance recommendations. | ||
+ | |||
+ | Filters can optionally include: | ||
+ | * An item note, shown in the full item description. The note can be inlined or use a globally defined note, see Item Descriptions. | ||
+ | * Styling, which can be done via the old (deprecated) specifiers, an inline style or a globally defined style, see Item Styles. | ||
+ | |||
+ | == Filtering Syntax == | ||
+ | Item filters have two core parts: | ||
+ | * The expression which is used to evaluate if a filter applies to an item. | ||
+ | *The text replacements used when an item matches the filter. | ||
+ | The expression is composed of one or more boolean expressions. These sub-expressions are built up using Filtering Variables. The sub-expressions can be joined together using logical OR (also aliased as ||) and AND (also aliased as &&). A space between two sub-expressions creates an implicit AND. | ||
+ | |||
+ | Parentheses can be used to group sub-expressions to better control the boolean evaluation of the expression. | ||
+ | |||
+ | N.B. Certain expression functions have optional parameters, to avoid parsing errors, ALWAYS use a space between a parameterless function and opening parenthesis. | ||
+ | |||
+ | A sub-expression or sub-expressions group with parentheses can be inverted using the ! (NOT) operator. | ||
+ | |||
+ | Integer comparisons can be performed using the following operators: | ||
+ | * < (less than) | ||
+ | * > (greater than) | ||
+ | * = (equal to) | ||
+ | * <= (less than or equal to) | ||
+ | * >= (greater than or equal to) | ||
+ | * != (not equal to) | ||
+ | Functions that produce integer values when not used with a comparison operator are implicitly converted to a boolean, where a value of 0 is false and any other value is true. | ||
+ | |||
+ | Names are always enclosed in quotation marks (eg: “Super Healing Potion”), however certain functions allow the usage of named-constants, which must not be enclosed, see Filtering Variables for more information. | ||
+ | |||
+ | == Options == | ||
+ | Filter options define default settings for the filter when it is first loaded. They can be defined anywhere in the filter file. Any or all of the options can be omitted. | ||
+ | |||
+ | Options are defined using the following syntax: <code>Option[name]: value</code> | ||
+ | |||
+ | Where name can be one of the following: | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | DefaultFilterLevel | ||
+ | | Sets a default FilterLevel | ||
+ | |- | ||
+ | | DefaultNotifyLevel | ||
+ | | Sets a default NotifyLevel | ||
+ | |- | ||
+ | | IgnoreMissingSounds | ||
+ | | Allows filter to not throw errors if sound files cannot be found | ||
+ | |} | ||
+ | |||
+ | == Attributes == | ||
+ | Filter attributes define various miscellaneous information about the filter; some of this information is displayed whenever the filter is loaded. They can be defined anywhere in the filter file. Attributes are always string values, any or all of the attributes can be omitted. | ||
+ | |||
+ | Options are defined using the following syntax: <code>Attribute[name]: value</code> | ||
+ | |||
+ | Where name can be one of the following: | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | Name | ||
+ | | What is the name of this filter | ||
+ | |- | ||
+ | | Version | ||
+ | | What is the current version of this filter | ||
+ | |- | ||
+ | | Author | ||
+ | | Who wrote this filter | ||
+ | |- | ||
+ | | Date | ||
+ | | When was the filter last updated | ||
+ | |} | ||
+ | |||
+ | These attributes are what define what filter information is displayed when a filter is loaded in game: | ||
+ | |||
+ | [[File:Wiki-loot-filter-attribution.png]] | ||
+ | |||
+ | == Filter And Notification Levels == | ||
+ | Filters can be set to varying degrees of strictness using filterlevels. To only show minor hp pots in the lowest filter level you could use: | ||
+ | |||
+ | <code>ItemDisplay[hp1 FILTERLVL=1]: %RED%!%WHITE%minor hp</code> | ||
+ | |||
+ | Filter levels can be given names that can be seen in game using the H menu: | ||
+ | |||
+ | <pre> | ||
+ | FilterLevel[1]: Ladder start | ||
+ | FilterLevel[2]: Maps | ||
+ | FilterLevel[3]: No low runes | ||
+ | FilterLevel[4]: No hp/mp pots | ||
+ | </pre> | ||
+ | |||
+ | [[File:Wiki-loot-filter-level1.png]] | ||
+ | |||
+ | Notifications can come in the form of chat messages or audio cues letting you know an item dropped. Notifications can be enabled by defining NotificationColor or NotificationSound. | ||
+ | |||
+ | Adding notification options to a style definition: | ||
+ | |||
+ | <code>ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "folderwithsounds\soundfile", NotificationSoundPriority = HIGH</code> | ||
+ | |||
+ | This would give a red notification in chat when the item drops and play the sound named “soundfile” that’s located in the “folderwithsounds” folder. | ||
+ | |||
+ | Alternatively you can use game sounds by referencing the sound location in game files: | ||
+ | |||
+ | <code>ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "@global\sfx\item\rune”, NotificationSoundPriority = HIGH</code> | ||
+ | |||
+ | This would give us a red notification in chat when the item drops and play the rune drop sound from the game files. | ||
+ | |||
+ | Items can be given notification and sound notification priority values of high, medium, or low. In game you can choose high medium and low values. Setting the values to low in game will cue all notifications, setting medium in game will allow medium and high notifications, and setting high in game will allow only notifications that are set to high. | ||
+ | |||
+ | |||
+ | == Macros == | ||
+ | <code>[TextMacro]</code> defines a textual substitution that can be reused through-out the filter in <code>[ItemDisplay]</code>, <code>[ItemDescription]</code> or inline item notes. They all for all the same substitutions are item names and notes. They however may not include other macros. | ||
+ | |||
+ | To reference a <code>[TextMacro]</code>, use the following syntax: | ||
+ | |||
+ | <code>%!name!% </code> | ||
+ | |||
+ | where name is a case-sensitive match to any defined <code>[TextMacro]</code>. If no match is found the text is left unchanged. | ||
+ | |||
+ | For example if you wanted to have red, green, and blue @ signs to be displayed when a super healing potion drops you would define the macros: | ||
+ | |||
+ | <pre> | ||
+ | TextMacro[RGB]: %RED%@%GREEN%@%BLUE%@ | ||
+ | TextMacro[BGR]: %BLUE%@%RED%@%GREEN%@ | ||
+ | </pre> | ||
+ | |||
+ | Then call it the items display line: | ||
+ | |||
+ | <code>ItemDisplay["Super Healing Potion"]: %!RGB!% %RED%%NAME% %!BGR!%</code> | ||
+ | |||
+ | Resulting in: | ||
+ | |||
+ | [[File:Wiki-loot-filter-macro1.png]] | ||
+ | |||
+ | == Skill & Item Lists == | ||
+ | |||
+ | == Sounds == | ||
+ | Loot filters support playback of custom sounds and default game sounds. These sounds can be set using the NotificationSound (see Item Styles) or by using <code>%NOTIFYSOUND()%</code>. | ||
+ | |||
+ | There are two methods to play a custom sound, each with their own pros and cons: | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Method | ||
+ | ! Pros | ||
+ | ! Cons | ||
+ | |- | ||
+ | | By Sounds.txt Id | ||
+ | | | ||
+ | * No need to include sound files with your filter. | ||
+ | | | ||
+ | * Plays through the game's shared sound channels. | ||
+ | * Requires looking up an ID from sounds.txt. | ||
+ | |- | ||
+ | | By File Path | ||
+ | | | ||
+ | * Can play custom sounds. | ||
+ | * Custom sounds play on their own channels separate from game sounds. | ||
+ | * Can still load sounds packaged with the base game. | ||
+ | | | ||
+ | * You will need to encode sounds correctly and package them with your filter. | ||
+ | |} | ||
+ | |||
+ | Any custom sounds need to be in the following format: | ||
+ | * Channels: 1 (Mono) | ||
+ | * BitRate: 22050Hz | ||
+ | * Format: Wav | ||
+ | File paths to custom sounds are relative to the filter folder in your Path of Diablo directory. If you want to use a sound that exists in one of the Diablo II archives, you need only append an “@” to the front of the path (eg. "@global\sfx\monster\beetle\attack1") and remove the top-level “data” portion from the path. Paths must always be enclosed in quotation marks. | ||
+ | |||
+ | Defining a reusable sound through-out your filter can be done with Sound[name]. They can be defined at any point in your filter file. To use it, first define your new sound, in this example it will be called “myFilterSound”: | ||
+ | |||
+ | <code>Sound[myFilterSound]: "path\to\file"</code> | ||
+ | |||
+ | Then you can use “myFilterSound” whenever you need a sound path or id. | ||
+ | |||
+ | == Filtering Variables == | ||
+ | Filtering variables form the basis of any filter boolean expression. They are divided into 5 main types: | ||
+ | * Item codes – these are 3 or 4 letter codes used to match the item's base. A list of item codes can be found on the [[Loot_Filtration_Codes | Loot filtration codes page]]. | ||
+ | * Item names – these are the in-game name of the item base, enclosed in quotations, eg: "Super Healing Potion". | ||
+ | * Booleans – these are true or false conditions based on properties of the item, the player or other global information. | ||
+ | * Complex – these are numerical values used in conjunction with the comparison operators. | ||
+ | * Functions – these take a set of 1 or more inputs and produce either a boolean or integer value. | ||
+ | |||
+ | === Variables === | ||
+ | Named Variables: | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | ALLSK | ||
+ | | Returns the value of the +x to all skills stat | ||
+ | |- | ||
+ | | ALVL | ||
+ | | Returns the affix level of the item | ||
+ | |- | ||
+ | | AR | ||
+ | | Returns the value of the + to attack rating stat | ||
+ | |- | ||
+ | | AREALVL | ||
+ | | Returns the area level (monster level) of the area you are currently in. | ||
+ | |- | ||
+ | | ARMOR | ||
+ | | Boolean indicating if the item is classed as armor | ||
+ | |- | ||
+ | | ARPER | ||
+ | | Returns the value of the attack rating per level stat | ||
+ | |- | ||
+ | | AXE, BOW, DAGGER, JAVELIN, MACE, POLEARM, SCEPTER, SPEAR, STAFF, SWORD, THROWING, WAND, XBOW | ||
+ | | Boolean indicating if the item falls into one of these weapon categories. | ||
+ | |- | ||
+ | | BAR, DIN, DRU, NEC, SIN, SOR, ZON | ||
+ | | Boolean indicating if the item falls into one of these class specific item categories. | ||
+ | |- | ||
+ | | BELT, BOOTS, CHEST, CIRC, GLOVES, HELM, SHIELD | ||
+ | | Boolean indicating if the item falls into one of these armor categories. | ||
+ | |- | ||
+ | | CHSKx | ||
+ | | Returns the level of the charged skill for skill id x | ||
+ | |- | ||
+ | | CLx | ||
+ | | Boolean indicating if the item is part of the given class-specific item group, where x is: | ||
+ | * 1 = Druid Pelt | ||
+ | * 2 = Barbarian Helm | ||
+ | * 3 = Paladin Shield | ||
+ | * 4 = Necromancer Shield | ||
+ | * 5 = Assassin Katar | ||
+ | * 6 = Sorceress Orb | ||
+ | * 7 = Amazon Weapon | ||
+ | |- | ||
+ | | CLSKx | ||
+ | | Returns the value of the + class skills stat, where x is: | ||
+ | * 0 = Amazon | ||
+ | * 1 = Sorceress | ||
+ | * 2 = Necromancer | ||
+ | * 3 = Paladin | ||
+ | * 4 = Barbarian | ||
+ | * 5 = Druid | ||
+ | * 6 = Assassin | ||
+ | |- | ||
+ | | CLVL | ||
+ | | Returns the level of your character | ||
+ | |- | ||
+ | | CORRUPTED | ||
+ | | Boolean indicating if the item is corrupted | ||
+ | |- | ||
+ | | CRAFT, CRAFTED, INF, INFERIOR, MAG, MAGIC, NMAG, NONMAGIC, RARE, SET, SUP, SUPERIOR, UNI, UNIQUE | ||
+ | | Boolean indicating if the item is of the specified quality | ||
+ | |- | ||
+ | | CRAFTALVL | ||
+ | | Returns the affix level of the item if used for crafting | ||
+ | |- | ||
+ | | CRES | ||
+ | | Returns the value of the +% cold resistance stat | ||
+ | |- | ||
+ | | DEF | ||
+ | | Returns the value of the + defense stat | ||
+ | |- | ||
+ | | DEX | ||
+ | | Returns the value of the + dexterity stat | ||
+ | |- | ||
+ | | DIFF, DIFFICULTY | ||
+ | | Returns the current difficulty: | ||
+ | * 0 = Normal | ||
+ | * 1 = Nightmare | ||
+ | * 2 = Hell | ||
+ | |- | ||
+ | | DTM | ||
+ | | Returns the value of the damage to mana stat | ||
+ | |- | ||
+ | | ED | ||
+ | | Returns the value of the +% enhanced damage for weapons or +% enhanced defense for armors | ||
+ | |- | ||
+ | | ELITE, ELT, EXCEPTIONAL, EXC, NORMAL, NORM | ||
+ | | Boolean indicating if the item is of the specified grade | ||
+ | |- | ||
+ | | ENR | ||
+ | | Returns the value of the + energy stat | ||
+ | |- | ||
+ | | EQx | ||
+ | | Boolean indicating if the item is part of the given armor item group, where x is: | ||
+ | * 1 = Helm | ||
+ | * 2 = Chest | ||
+ | * 3 = Shield | ||
+ | * 4 = Gloves | ||
+ | * 5 = Boots | ||
+ | * 6 = Belt | ||
+ | * 7 = Circlet | ||
+ | |- | ||
+ | | ETHEREAL, ETH | ||
+ | | Boolean indicating if the item is Ethereal | ||
+ | |- | ||
+ | | FBR | ||
+ | | Returns the value of the faster block recovery stat | ||
+ | |- | ||
+ | | FCR | ||
+ | | Returns the value of the faster cast rate stat | ||
+ | |- | ||
+ | | FHR | ||
+ | | Returns the value of the faster hit recovery stat | ||
+ | |- | ||
+ | | FILTERLVL | ||
+ | | Returns the current filter level | ||
+ | |- | ||
+ | | FOOLS | ||
+ | | Boolean indicating if the item has the “Fools” affix | ||
+ | |- | ||
+ | | FRES | ||
+ | | Returns the value of the +% fire resistance stat | ||
+ | |- | ||
+ | | FRW | ||
+ | | Returns the value of the faster run/walk speed stat | ||
+ | |- | ||
+ | | GEM | ||
+ | | Boolean indicating if the item is a gem | ||
+ | |- | ||
+ | | GEMGRADE | ||
+ | | Returns the gem's grade: | ||
+ | * 1 = Amethyst | ||
+ | * 2 = Diamond | ||
+ | * 3 = Emerald | ||
+ | * 4 = Ruby | ||
+ | * 5 = Sapphire | ||
+ | * 6= Topaz | ||
+ | * 7 = Skull | ||
+ | |- | ||
+ | | GEMMED | ||
+ | | Boolean indicating if the item is socketed with gems/runes/jewels | ||
+ | |- | ||
+ | | GEMTIER | ||
+ | | Returns the gem tier: | ||
+ | * 1 = Chipped | ||
+ | * 2 = Flawed | ||
+ | * 3 = Normal | ||
+ | * 4 = Flawless | ||
+ | * 5 = Perfect | ||
+ | |- | ||
+ | | GFIND | ||
+ | | Returns the value of the +% gold find stat | ||
+ | |- | ||
+ | | GOLD | ||
+ | | Returns the amount of gold if the item is a gold pile | ||
+ | |- | ||
+ | | GRAIL | ||
+ | | [On Hold] | ||
+ | |- | ||
+ | | HARDCORE | ||
+ | | Boolean indicating if the player is in Hardcore | ||
+ | |- | ||
+ | | IAS | ||
+ | | Returns the value of the increased attack speed stat | ||
+ | |- | ||
+ | | IDENTIFIED, ID | ||
+ | | Boolean indicating if the item is identified | ||
+ | |- | ||
+ | | IDSCROLLS | ||
+ | | Returns the number of identify scrolls in your inventory | ||
+ | |- | ||
+ | | ILVL | ||
+ | | Returns the item level | ||
+ | |- | ||
+ | | LEVEL | ||
+ | | Returns the id of the current level | ||
+ | |- | ||
+ | | LIFE | ||
+ | | Returns the value of the + life stat | ||
+ | |- | ||
+ | | LRES | ||
+ | | Returns the value of the +% lightning resistance stat | ||
+ | |- | ||
+ | | MAEK | ||
+ | | Returns the value of the mana after kill stat | ||
+ | |- | ||
+ | | MANA | ||
+ | | Returns the value of the + mana stat | ||
+ | |- | ||
+ | | MAP | ||
+ | | Boolean indicating if the item is a map | ||
+ | |- | ||
+ | | MAPTIER | ||
+ | | Returns the map tier: | ||
+ | * 1 = White | ||
+ | * 2 = Yellow | ||
+ | * 3 = Red | ||
+ | |- | ||
+ | | MAXDMG | ||
+ | | Returns the value of the + maximum damage stat | ||
+ | |- | ||
+ | | MAXDUR | ||
+ | | Returns the value of the + durability stat | ||
+ | |- | ||
+ | | MFIND | ||
+ | | Returns the value of the +% magic find stat | ||
+ | |- | ||
+ | | MINDMG | ||
+ | | Returns the value of the + minimum damage stat | ||
+ | |- | ||
+ | | NOTIFYLVL | ||
+ | | Returns the current notification level | ||
+ | |- | ||
+ | | OSx | ||
+ | | Returns the value of the + level x skill stat | ||
+ | |- | ||
+ | | PERCENTILE | ||
+ | | Returns the percentile (between 0 and 99) of the base armor roll of the item | ||
+ | |- | ||
+ | | PLRCLASS | ||
+ | | Returns the current class of the player: | ||
+ | * 0 = Amazon | ||
+ | * 1 = Sorceress | ||
+ | * 2 = Necromancer | ||
+ | * 3 = Paladin | ||
+ | * 4 = Barbarian | ||
+ | * 5 = Druid | ||
+ | * 6 = Assassin | ||
+ | |- | ||
+ | | PRES | ||
+ | | Returns the value of the +% poison resistance stat | ||
+ | |- | ||
+ | | POTION | ||
+ | | Boolean indicating if the item is a potion | ||
+ | |- | ||
+ | | POTIONTIER | ||
+ | | Returns the tier of the potion: | ||
+ | * 1 = Minor or rejuvenating | ||
+ | * 2 = Light or full rejuvenating | ||
+ | * 3 = Normal | ||
+ | * 4 = Greater | ||
+ | * 5 = Super | ||
+ | |- | ||
+ | | PRICE | ||
+ | | Returns the vendor sell price for the item in the current difficulty | ||
+ | |- | ||
+ | | QLVL | ||
+ | | Returns the quality level of the item | ||
+ | |- | ||
+ | | QTY | ||
+ | | Returns the quantity of the item stack | ||
+ | |- | ||
+ | | QUEST | ||
+ | | Boolean indicating if the item is a quest item | ||
+ | |- | ||
+ | | REPAIR | ||
+ | | Returns the value of the repairs durability stat | ||
+ | |- | ||
+ | | REPLIFE | ||
+ | | Returns the value of the + life replenish stat | ||
+ | |- | ||
+ | | REPQUANT | ||
+ | | Returns the value of the replenish quantity stat | ||
+ | |- | ||
+ | | REQLEVEL | ||
+ | | Returns the required level of the item | ||
+ | |- | ||
+ | | RES | ||
+ | | Returns the minimum value between all fire/lightning/cold/poison resistance stats on the item | ||
+ | |- | ||
+ | | RUNE | ||
+ | | Boolean indicating if the item is a rune | ||
+ | |- | ||
+ | | RUNETIER | ||
+ | | Returns a value between 1 to 33 indicating the rune's tier | ||
+ | |- | ||
+ | | RUNEWORD, RW | ||
+ | | Boolean indicating if the item is a runeword | ||
+ | |- | ||
+ | | SKx | ||
+ | | Returns the value of the + level x skill (class specific) stat | ||
+ | |- | ||
+ | | SOCKETS, SOCK | ||
+ | | Returns the number of sockets for the item | ||
+ | |- | ||
+ | | SPECIAL | ||
+ | | Boolean indicating if the item is a special item. Current special items are: | ||
+ | * Quest Items | ||
+ | * Synthesized Items | ||
+ | |- | ||
+ | | STR | ||
+ | | Returns the value of the + strength stat | ||
+ | |- | ||
+ | | SYNTH | ||
+ | | Boolean indicating if the item is synthesized | ||
+ | |- | ||
+ | | TABSKx | ||
+ | | Returns the value of the + to {tab} skills stat where x is the id of the tab. | ||
+ | |- | ||
+ | | TPSCROLLS | ||
+ | | Returns the number of townportal scrolls in your inventory (including books) | ||
+ | |- | ||
+ | | VIT | ||
+ | | Returns the value of the + vitality stat | ||
+ | |- | ||
+ | | WEAPON | ||
+ | | Boolean indicating if the item is classed as a weapon | ||
+ | |- | ||
+ | | WPx | ||
+ | | Boolean indicating if the item is part of the given weapon item group, where x is: | ||
+ | * 1 = Axe | ||
+ | * 2 = Mace | ||
+ | * 3 = Sword | ||
+ | * 4 = Dagger | ||
+ | * 5 = Throwing | ||
+ | * 6 = Javelin | ||
+ | * 7 = Spear | ||
+ | * 8 = Polearm | ||
+ | * 9 = Bow | ||
+ | * 10 = Crossbow | ||
+ | * 11 = Staff | ||
+ | * 12 = Wand | ||
+ | * 13 = Scepter | ||
+ | * 14 = One Handed | ||
+ | * 15 = Two Handed | ||
+ | * 16 = Ambihanded | ||
+ | |} | ||
+ | |||
+ | === Functions === | ||
+ | Functions: | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | CHARSTAT() | ||
+ | | | ||
+ | |- | ||
+ | | COUNT() [DISABLED] | ||
+ | | Counts the number of matching expressions. | ||
+ | |- | ||
+ | | CSKILLS() | ||
+ | | | ||
+ | |- | ||
+ | | CHARGES() | ||
+ | | | ||
+ | |- | ||
+ | | CTCSKILL() | ||
+ | | | ||
+ | |- | ||
+ | | ITEMLIST() | ||
+ | | | ||
+ | |- | ||
+ | | ITYPE() | ||
+ | | | ||
+ | |- | ||
+ | | OSKILL() | ||
+ | | | ||
+ | |- | ||
+ | | OSKILLS() | ||
+ | | | ||
+ | |- | ||
+ | | MAXSKILLS() | ||
+ | | | ||
+ | |- | ||
+ | | MAXOSKILLS() | ||
+ | | | ||
+ | |- | ||
+ | | PREFIX() | ||
+ | | | ||
+ | |- | ||
+ | | PLRCLASS() | ||
+ | | | ||
+ | |- | ||
+ | | REQCLASS() | ||
+ | | | ||
+ | |- | ||
+ | | SET() | ||
+ | | | ||
+ | |- | ||
+ | | SKILL() | ||
+ | | | ||
+ | |- | ||
+ | | SKILLS() | ||
+ | | | ||
+ | |- | ||
+ | | STAT() | ||
+ | | | ||
+ | |- | ||
+ | | STORAGE() | ||
+ | | | ||
+ | |- | ||
+ | | SUFFIX() | ||
+ | | | ||
+ | |- | ||
+ | | UNIQUE() | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | == Block-Level Filters == | ||
+ | Block-level filters provide a mechanism for skipping multiple filter lines (ItemDisplay[expr]: text entries) at once based on a set of common conditions. They can also be used to enable/disable groups of filter lines based on your filter level. | ||
+ | |||
+ | Block-level filters are required to have a start entry (with a filtering expression), and an end entry. Block-level filters can be nested, matching start entries to the next end entry in the file. | ||
+ | |||
+ | A start entry is defined as: <code>EnableIf[expr]</code> | ||
+ | An end entry is defined as: <code>EndIf[]</code> | ||
+ | expr uses the exact same filtering syntax and variables as ItemDisplay[expr]. An example of a basic block level filter is the following: | ||
+ | <pre> | ||
+ | EnableIf[RUNE] | ||
+ | ItemDisplay[]: %ORANGE%%RUNENAME% %TAN%[%RUNETIER%]%CONTINUE% | ||
+ | ItemDisplay[RUNETIER>16]: %NAME%%GOLD%!!HR!! | ||
+ | ItemDisplay[]: %NAME% | ||
+ | EndIf[] | ||
+ | </pre> | ||
+ | In this example, we can collate all filter lines that apply to runes, and then apply progressive styling based on the rune’s tier. | ||
+ | |||
+ | Block-level filters are a very powerful mechanism for both grouping and performance, and their usage is encouraged. | ||
+ | |||
+ | == Item Names == | ||
+ | |||
+ | Item names can be built using one or more item filter lines. They are defined in the text portion of the ItemDisplay[expr]: text declaration, before any Item Styles or Item Descriptions. | ||
+ | |||
+ | The filters lines’ actions and substitutions are only run if the expr of the ItemDisplay[expr] is true. With the appropriate usage of Filtering Substitutions and the <code>%CONTINUE%</code> action, you can easily create complex names using multiple filtering lines. | ||
+ | |||
+ | When an item name is empty once all filters lines have run, that item will be hidden (when shown on the ground), grayed out (when shown in a vendor screen) or marked as “(Filtered)” (when shown in your inventory). | ||
+ | |||
+ | == Item Descriptions == | ||
+ | |||
+ | Filters can also attach a “note” to an item's description in a player's or NPC’s inventory. Notes are useful for many things, such as recipes or trade values. Just like with item names, notes can be accrued, and use the same Filtering Substitutions. | ||
+ | |||
+ | Item descriptions are defined by any text appearing in the text portion of an <code>ItemDisplay[expr]</code> that is enclosed in curly braces. | ||
+ | |||
+ | Similar to Text Macro’s, you can also define globally reusable notes with the following syntax: <code>ItemDescription[name]: text</code> | ||
+ | |||
+ | To then use that note in a description, you would use the name enclosed by double curly braces. An example would be the following: | ||
+ | <pre> | ||
+ | ItemDescription[AnImportantNote]: %RED%This is important, don’t lose it! | ||
+ | ItemDisplay[QUEST]: %FULLNAME%{{AnImportantNote}} | ||
+ | </pre> | ||
+ | |||
+ | == Filtering Substitutions == | ||
+ | Name substitutions allow for rewriting of text based on item information, static strings and other constants. | ||
+ | |||
+ | Constants: | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name | ||
+ | ! Substitution | ||
+ | |- | ||
+ | | | ||
+ | %WHITE% <br> | ||
+ | %RED%<br> | ||
+ | %GREEN%<br> | ||
+ | %BLUE% <br> | ||
+ | %GOLD% <br> | ||
+ | %GRAY% <br> | ||
+ | %BLACK% <br> | ||
+ | %TAN% <br> | ||
+ | %ORANGE% <br> | ||
+ | %YELLOW% <br> | ||
+ | %PURPLE% <br> | ||
+ | %DGREEN% <br> | ||
+ | %DARK_GREEN% <br> | ||
+ | %BOLD% <br> | ||
+ | %CORAL% <br> | ||
+ | %SAGE% <br> | ||
+ | %TEAL% <br> | ||
+ | %LGRAY% <br> | ||
+ | %LIGHT_GRAY%<br> | ||
+ | %NAVY%<br> | ||
+ | %DBLUE%<br> | ||
+ | %DARK_BLUE%<br> | ||
+ | %COBALT%<br> | ||
+ | %DARK_PURPLE%<br> | ||
+ | %DPURPLE%<br> | ||
+ | %BROWN%<br> | ||
+ | | Sets any text after the color constant to this color. | ||
+ | |||
+ | Note that %CORAL%, %SAGE% and %TEAL% are only available in D2GL or Glide Wrapper. | ||
+ | |||
+ | Note that %NAVY%, %DBLUE%, %DARK_BLUE%, %COBALT%, %DARK_PURPLE%, %DPURPLE%, <br> | ||
+ | %BROWN%, %PINK% are only available in D2GL. | ||
+ | |||
+ | Colors will fall-back to an appropriate color if they are used in a mode where they are unavailable. | ||
+ | |- | ||
+ | | | ||
+ | %NEWLINE% <br> | ||
+ | %NL% | ||
+ | | Inserts a new line | ||
+ | |- | ||
+ | | %LBRACE% | ||
+ | | Inserts a left brace: { | ||
+ | |- | ||
+ | | %RBRACE% | ||
+ | | Inserts a right brace: } | ||
+ | |- | ||
+ | | %LANGLE% | ||
+ | | Inserts a left angle bracket: < | ||
+ | |- | ||
+ | | %RANGLE% | ||
+ | | Inserts a right angle bracket: > | ||
+ | |- | ||
+ | | %SPACE% | ||
+ | | Inserts a single space | ||
+ | |- | ||
+ | | %EMPTY% | ||
+ | | Inserts nothing, used to prevent white-space trimming. | ||
+ | |- | ||
+ | | %HIDE% | ||
+ | | Inserts nothing, purely a convenience to explicitly show this row is meant to hide an item | ||
+ | |} | ||
+ | |||
+ | Values: | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name | ||
+ | ! Substitution | ||
+ | |- | ||
+ | | %PREVIOUS% | ||
+ | | | ||
+ | |- | ||
+ | | %NAME% | ||
+ | | | ||
+ | |- | ||
+ | | %NOTE% | ||
+ | | | ||
+ | |- | ||
+ | | %ITEMNAME% | ||
+ | | | ||
+ | |- | ||
+ | | %FULLNAME% | ||
+ | | | ||
+ | |- | ||
+ | | %BASENAME% | ||
+ | | | ||
+ | |- | ||
+ | | %RWNAME% | ||
+ | | | ||
+ | |- | ||
+ | | %SOCKETS% | ||
+ | | | ||
+ | |- | ||
+ | | %TIER% | ||
+ | | | ||
+ | |- | ||
+ | | %RUNETIER% | ||
+ | | | ||
+ | |- | ||
+ | | %RUNENAME% | ||
+ | | | ||
+ | |- | ||
+ | | %GEMTIER% | ||
+ | | | ||
+ | |- | ||
+ | | %GEMTYPE% | ||
+ | | | ||
+ | |- | ||
+ | | %MAPTIER% | ||
+ | | | ||
+ | |- | ||
+ | | %POTIONTIER% | ||
+ | | | ||
+ | |- | ||
+ | | %ILVL% | ||
+ | | | ||
+ | |- | ||
+ | | %ALVL% | ||
+ | | | ||
+ | |- | ||
+ | | %QLVL% | ||
+ | | | ||
+ | |- | ||
+ | | %CRAFTALVL% | ||
+ | | | ||
+ | |- | ||
+ | | %LVLREQ% / %REQLEVEL% | ||
+ | | | ||
+ | |- | ||
+ | | %WPNSPD% | ||
+ | | | ||
+ | |- | ||
+ | | %RANGE% | ||
+ | | | ||
+ | |- | ||
+ | | %CODE% | ||
+ | | | ||
+ | |- | ||
+ | | %PRICE% | ||
+ | | | ||
+ | |- | ||
+ | | %PERCENTILE% | ||
+ | | | ||
+ | |- | ||
+ | | %DEF% | ||
+ | | | ||
+ | |- | ||
+ | | %EDAMAGE% | ||
+ | | | ||
+ | |- | ||
+ | | %EDEFENSE% | ||
+ | | | ||
+ | |- | ||
+ | | %RES% | ||
+ | | | ||
+ | |- | ||
+ | | %TOTALRES% | ||
+ | | | ||
+ | |- | ||
+ | | %QTY% | ||
+ | | | ||
+ | |- | ||
+ | | %CLASS% | ||
+ | | | ||
+ | |- | ||
+ | | %CL% | ||
+ | | | ||
+ | |- | ||
+ | | %QUAL% / %QUALITY% | ||
+ | | | ||
+ | |- | ||
+ | | %QT% / %GRADE% | ||
+ | | | ||
+ | |- | ||
+ | | %STAT()% | ||
+ | | | ||
+ | |- | ||
+ | | %SKILL()% | ||
+ | | | ||
+ | |- | ||
+ | | %OSKILL()% | ||
+ | | | ||
+ | |- | ||
+ | | %SKILLNAME()% | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | |||
+ | Item names can also be formed iteratively by using <code>%NAME%</code> to get the name set previously by any matching non-terminating filters. If no match to a substitution or function is found, the text is left unchanged. | ||
+ | |||
+ | == Item Styles == | ||
+ | Item styles allow one to set various nameplate styling options, and allow for playing sounds or showing map icons. Item styles can be declared at any point in the filter file. You can also declare inline | ||
+ | styles, or override specific attributes of a global style. | ||
+ | |||
+ | A global style is defined with the following syntax: <code>ItemStyle[name]: stylename</code> | ||
+ | |||
+ | stylename Must contain one or more of the following attributes, delimited with a comma. Values for the attributes are declared using the following syntax: attribute = value | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | MapIcon | ||
+ | | | ||
+ | |- | ||
+ | | MapIconColor | ||
+ | | | ||
+ | |- | ||
+ | | BorderColor | ||
+ | | | ||
+ | |- | ||
+ | | BorderSize | ||
+ | | | ||
+ | |- | ||
+ | | BackgroundColor | ||
+ | | | ||
+ | |- | ||
+ | | NotificationColor | ||
+ | | | ||
+ | |- | ||
+ | | NotificationPriority | ||
+ | | | ||
+ | |- | ||
+ | | NotificationSound | ||
+ | | | ||
+ | |- | ||
+ | | NotificationSoundPriority | ||
+ | | | ||
+ | |} | ||
+ | This global style can then be referenced by its name enclosed in double angle brackets. An example of a global style is the following: | ||
+ | |||
+ | <pre>ItemStyle[Fancy]: MapIcon = 4, MapIconColor = 5, BorderColor = RGB(0/255/63), BorderSize = 1, BackgroundColor = RGB(255/0/63), NotificationColor = ITEM, NotificationPriority = HIGH, NotificationSound = "@global\sfx\monster\beetle\attack1", NotificationSoundPriority = HIGH</pre> | ||
+ | |||
+ | <code>ItemDisplay[SKILL("Freezing Pulse") > 1]: %PURPLE%%NAME% <<Fancy>></code> | ||
+ | |||
+ | Styles can also be used and edited in-line and on the fly. To use the above style but change the border size: | ||
+ | |||
+ | <code>ItemDisplay[SKILL("Freezing Pulse") > 1]: %PURPLE%%NAME% <:Fancy: BorderSize = 3></code> | ||
+ | |||
+ | Style elements border color and background color can also utilize RGB values, for example <code>BackgroundColor = RGB(245/2/19)</code>. | ||
+ | |||
+ | == Filtering Actions == | ||
+ | <span style="color:red">NOTE:</span> With the exception of %CONTINUE% all items actions are deprecated and will be removed in a future version. All your actions should be moved over to item styles. | ||
+ | |||
+ | Item filters can also have “actions” attached to them, these perform certain functions when a terminating filter condition is met within a specific context. Just like names, actions will accrue until a terminating condition is met. If no terminating condition is found, the accrued actions will be applied. | ||
+ | |||
+ | The following table lists all available filtering actions, parameters in [] are optional, and when omitted will use their default value. | ||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | ! Name/Syntax | ||
+ | ! Defaults | ||
+ | ! Description | ||
+ | |- | ||
+ | | %CONTINUE% | ||
+ | | N/A | ||
+ | | | ||
+ | |- | ||
+ | | %NOTIFY()% | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | %MAPICON()% | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | %BORDER()% | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | %NOTIFYSOUND()% | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | %BGCOLOR()% | ||
+ | | | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | == Optimizing Your Filters == | ||
+ | |||
+ | Although PoD does its best to make sure loaded item filters are performant, it is still up to the user to make sure their filters and filtering expressions are well structured to prevent potential slow-downs. | ||
+ | |||
+ | Filtering ex | ||
+ | pressions are evaluated with short-circuiting. | ||
+ | |||
+ | Keeping this in mind, one can optimize filtering expressions to start with the most specific checks first, then becoming more broad. Certain conditionals are far more expensive (computationally) to evaluate. | ||
+ | |||
+ | Delaying the evaluation of these expensive conditions is preferable. | ||
+ | |||
+ | In many cases it is preferable to match to multiple expressions to build up styling for item groups. In this case it is recommended to keep all filter expression lines one-after-the-other, from most generic to most specific. To aid in fast evaluation it is recommended to start these “style blocks” with an item base type check, and then get more specific. | ||
+ | |||
+ | It is recommended to ensure that all filters have a suitable terminating filter line, doing so prevents unneeded evaluation of filtering expressions. By grouping non-terminating expressions as close as possible to their terminating filter will also reduce unnecessary evaluations. | ||
+ | |||
+ | == Debugging Your Filters == | ||
+ | Debugging of loot filters will be an evolving process that will improve over time. | ||
+ | |||
+ | When a filter is loaded, and the message appears in game, its color will notify you if any errors or warnings were found with the currently loaded filter. <span style="color:#00ff00">Light green</span> means no errors or warnings were found, <span style="color:#FFAC1C">Orange</span> means errors and/or warnings were found. | ||
+ | |||
+ | Currently all item codes, stat ids, skill ids, SkillList names and ItemList names are validated when the filter is loaded. Any errors will be logged out to the Diablo II log. | ||
+ | |||
+ | If you set the following setting: | ||
+ | |||
+ | <insert pic> | ||
+ | |||
+ | Then the errors and warnings will also be logged out to the game’s message log, helpful for on-the-fly filter adjustments and debugging. | ||
+ | |||
+ | == Appendix A: Map Icons == | ||
+ | |||
+ | These are the default icons and their associated numbers: | ||
+ | |||
+ | [[File:Mapicon1-15.png]] | ||
+ | |||
+ | [[File:Mapicon15-30.png]] | ||
+ | |||
+ | [[File:Mapicon30-45.png]] | ||
+ | |||
+ | [[File:Mapicon45-60.png]] | ||
+ | |||
+ | [[File:Mapicon60-75.png]] | ||
+ | |||
+ | [[File:Mapicon75-90.png]] | ||
+ | |||
+ | [[File:Mapicon90-98.png]] | ||
+ | |||
+ | == Appendix B: Palette Colors == | ||
+ | The default Diablo 2 color palette: | ||
+ | |||
+ | [[File:Pod-filter-color-palette.png|750px]] | ||
+ | |||
+ | Aside from the numeric color codes, BorderColor and BackgroundColor support RGB values. EG, a style using:<br> | ||
+ | <code>BackgroundColor = RGB(128/0/128)</code><br> | ||
+ | Would redult in a purple background | ||
+ | |||
+ | = Below to be replaced = | ||
Line 128: | Line 1,165: | ||
− | == | + | == Text Decoration and sounds == |
− | ===Filter levels | + | |
+ | You can alter the appearance of item drops by adding filter code to the items display line. | ||
+ | To make a super healing potion look like this: | ||
+ | |||
+ | [[File:Wiki-loot-filter-text-decorating1.png]] | ||
+ | |||
+ | You would format the potions display line as follows: | ||
+ | |||
+ | <code>ItemDisplay["Super Healing Potion"]: %RED%%NAME% %MAPICON(4,5)% %BORDER(1,33)% %BGCOLOR(4)% </code> | ||
+ | |||
+ | Drop decoration and sound modifiers: | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Code | ||
+ | ! Input | ||
+ | ! Description<br /> | ||
+ | ! | ||
+ | |- | ||
+ | | %MAPICON(x or x,x)% | ||
+ | | One (1-96) or two (1-8) numbers. The first number sets the icon, 2nd shifts the color | ||
+ | | Sets an icon that's visible on the minimap | ||
+ | | | ||
+ | |- | ||
+ | | %BORDER(x or x,x)% | ||
+ | | One (1-253) or two (1-4) numbers. The first number sets a border color, 2nd number sets border thickness | ||
+ | | Creates a border around the item name display | ||
+ | | | ||
+ | |- | ||
+ | | %BGCOLOR(x)% | ||
+ | | One number (1-253) | ||
+ | | Adds a background color to the item name display | ||
+ | | | ||
+ | |- | ||
+ | | %NOTIFY(x)% | ||
+ | | A Color, choosing "ITEM" uses the default item color (blue for magic, yellow for rare, etc.)<br /> | ||
+ | | Creates a chat notification when the item drops | ||
+ | | | ||
+ | |- | ||
+ | | %NOTIFYSOUND(x)% | ||
+ | | Number corresponding with an in game sound index | ||
+ | | Forces a special sound when an item drops | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | ==Filter levels== | ||
Filters can be set to varying degrees of strictness using filterlevels. To only show minor hp pots in the lowest filter level you could use: | Filters can be set to varying degrees of strictness using filterlevels. To only show minor hp pots in the lowest filter level you could use: | ||
Line 143: | Line 1,225: | ||
</pre> | </pre> | ||
+ | [[File:Wiki-loot-filter-level1.png]] | ||
+ | |||
+ | == Modern Filtering Techniques == | ||
+ | |||
+ | Patch [[Patch_Notes#Patch_.2321:_Shungite|#21 Shungite]] brought us new filtering options, including macros, styles, support for if statements, and better ways to manage custom sounds. | ||
===Text Macros=== | ===Text Macros=== | ||
Line 186: | Line 1,273: | ||
[[file:Wiki-loot-filter-style2.png]] | [[file:Wiki-loot-filter-style2.png]] | ||
− | Style elements border color and background color can also utilize RGB values, for example BackgroundColor = RGB(245/2/19). | + | Style elements border color and background color can also utilize RGB values, for example <code>BackgroundColor = RGB(245/2/19)</code>. |
Line 200: | Line 1,287: | ||
===Notifications and Sounds=== | ===Notifications and Sounds=== | ||
− | Notifications can come in the form of chat messages or audio cues letting you know an item dropped. You can enable notifications by defining NotificationColor or NotificationSound. | + | Notifications can come in the form of chat messages or audio cues letting you know an item dropped. You can enable notifications by defining NotificationColor or NotificationSound. Adding notification options to a style definition: |
− | <code>ItemStyle[Fancy]: | + | <code>ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "folderwithsounds\soundfile", NotificationSoundPriority = HIGH</code> |
− | This would give us a red notification in chat when the item drops | + | This would give us a red notification in chat when the item drops and play the sound named “soundfile” that’s located in the “folderwithsounds” folder. |
− | |||
− | |||
Alternatively you can use game sounds by referencing the sound location in game files: | Alternatively you can use game sounds by referencing the sound location in game files: | ||
− | <code>ItemStyle[Fancy]: | + | <code>ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "@global\sfx\item\rune”, NotificationSoundPriority = HIGH</code> |
− | |||
− | |||
− | |||
− | |||
− | + | This would give us a red notification in chat when the item drops and play the rune drop sound from the game files. | |
+ | Items can be given notification and sound notification priority values of high, medium, or low. In game you can choose high medium and low values. Setting the values to low in game will cue all notifications, setting medium in game will allow medium and high notifications, and setting high in game will allow only notifications that are set to high. | ||
===If Statements=== | ===If Statements=== | ||
Line 249: | Line 1,331: | ||
[[File:Wiki-loot-filter-if1.png]] | [[File:Wiki-loot-filter-if1.png]] | ||
− | These are small examples but this concept can be scaled up to apply to all + skill granting items, runeword bases, and even potions, potentially allowing many items to skip filter lines which wouldn’t apply to them. | + | These are small examples but this concept can be scaled up to apply to all + skill granting items, runeword bases, and even potions, potentially allowing many items to skip filter lines which wouldn’t apply to them. |
+ | |||
+ | ===ALT Text=== | ||
+ | Holding the ALT key when hovering over an item shows additional information not seen by default referred to as advanced item descriptions. You can add to these advanced item descriptions by enclosing "ALT text" in brackets {}. | ||
+ | |||
+ | Using: | ||
+ | <pre>ItemDisplay[tsc]: %NAME% {This is a TP scroll}</pre> | ||
+ | Adds the text "This is a TP scroll" to TP scrolls that's only visible when holding the ALT key on the keyboard. | ||
+ | |||
+ | [[File:Wiki-loot-filter-alt-text.png]] | ||
+ | |||
+ | A more useful implementation for this could be to add cube recipes or possible corruption mods to an item. Presenting this larger amount of text as an advanced item description allows the convenience of having the information there but with the convenience of not having it visible all the time. | ||
+ | |||
+ | |||
+ | ===Attribution=== | ||
+ | Attribute codes notify users of general filter info when it's loaded. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Code | ||
+ | ! Purpose | ||
+ | |- | ||
+ | | Attribute[Author]: | ||
+ | | Filter authors name | ||
+ | |- | ||
+ | | Attribute[Name]: | ||
+ | | Name of the filter | ||
+ | |- | ||
+ | | Attribute[Version]: | ||
+ | | Version number | ||
+ | |- | ||
+ | | Attribute[Date]: | ||
+ | | Last edit date | ||
+ | |} | ||
+ | |||
+ | How filter attributes are displayed in game: | ||
+ | |||
+ | |||
+ | [[File:Wiki-loot-filter-attribution.png]] | ||
== Credits == | == Credits == | ||
Loot filtration implemented in PoD by Dav92 based on code from McGoD, underbent and Deadlock39. Later rebuilt from the ground up by Necrolis. | Loot filtration implemented in PoD by Dav92 based on code from McGoD, underbent and Deadlock39. Later rebuilt from the ground up by Necrolis. |
Latest revision as of 12:18, 21 November 2024
"By editing the "item filter" file, which can be found in your "filter" folder within your Path of Diablo installation folder. You may create a set of rules which will change the way loot is displayed.
You can find loot filters made by other players and download instructions at List of Loot Filters.
Contents
- 1 Overview
- 2 Definitions and File Structure
- 3 Item Display Filtering
- 4 Filtering Syntax
- 5 Options
- 6 Attributes
- 7 Filter And Notification Levels
- 8 Macros
- 9 Skill & Item Lists
- 10 Sounds
- 11 Filtering Variables
- 12 Block-Level Filters
- 13 Item Names
- 14 Item Descriptions
- 15 Filtering Substitutions
- 16 Item Styles
- 17 Filtering Actions
- 18 Optimizing Your Filters
- 19 Debugging Your Filters
- 20 Appendix A: Map Icons
- 21 Appendix B: Palette Colors
- 22 Below to be replaced
Overview
PoD’s loot filter is based off of the same item filtering style originally introduced by BH. It has however grown substantially from the featureset provided by BH.
If you have a request for changes or additions, want to report bugs or merely get help building a filter, please join the Path of Diablo Discord, and ask in the #lootfilter channel.
NOTE: Anything marked as [Deprecated] will be removed in future versions.
Definitions and File Structure
All PoD item filters are utf-8 encoded text files with the .filter file extension, found in the filter directory of your Path of Diablo installation.
Filters are processed from top to bottom, this has an important role when it comes to precedence of filter matching and accruing of transforms to the item name, notifications, notes and styles.
Ordering does not affect filter level names, macros, item code or skill lists.
File comments are made by starting a line with // causing anything else on the line to not be processed. One may also use blank/empty lines without any effect on the filter.
Filter files can contain the following top level definitions:
Name/Syntax | Description |
---|---|
ItemDisplay[expr]: text | Defines a filtering expression and the item name it’ll produce when matched. |
FilterLevel[id]: name | Names a filter level. |
SkillList[name]: skill id’s | Defines a group of skill id’s that can be used to reduce duplication in filter expressions. |
ItemList[name]: item codes | Defines a group of item codes that can be used to reduce duplication in filter expressions. |
Option[name]: value | Defines an option. |
Attribute[name]: value | Defines a preset filter attribute. |
ItemDescription[name]: text | Defines a reusable item note. |
ItemStyle[name]: styling | Defines an item display and notification style. |
TextMacro[name]: text | Defines a reusable text macro to simplify commonly used idioms. |
Sound[name]: path|id | Defines a custom sound for use in the filter. |
EnableIf[expr] | Starts a block-level filter. |
EndIf[] | Ends a block-level filter. |
During parsing, all invalid or incorrectly formatted lines will be ignored to prevent potential crashes. Issues detected by the parser will be logged out to the Diablo II log file, additionally they can be logged to the in-game message console. Any invalid expressions will be ignored and always return true to prevent accidentally hiding items that shouldn’t be hidden.
Item Display Filtering
Items can be filtered on the ground, inventory and NPC trade windows. In each scenario the [ItemDisplay]
entries will be evaluated from the top of the file to bottom, until a terminating match is found. Matches that do not terminate will accrue their changes for filters below them. This allows setting a general filter at the top for common styling and then making specific changes to the style further down. This does mean that you will want to have your most general matching filters at first and your most specific filters last.
If no terminating filter is found, any accrued style changes will still be applied.
Building an item filter is done using a combination of conditions and filtering variables that evaluate to true or false (Boolean logic). For a filter to match an item, the entire expression needs to evaluate to true. See Optimizing Your Filters for performance recommendations.
Filters can optionally include:
- An item note, shown in the full item description. The note can be inlined or use a globally defined note, see Item Descriptions.
- Styling, which can be done via the old (deprecated) specifiers, an inline style or a globally defined style, see Item Styles.
Filtering Syntax
Item filters have two core parts:
- The expression which is used to evaluate if a filter applies to an item.
- The text replacements used when an item matches the filter.
The expression is composed of one or more boolean expressions. These sub-expressions are built up using Filtering Variables. The sub-expressions can be joined together using logical OR (also aliased as ||) and AND (also aliased as &&). A space between two sub-expressions creates an implicit AND.
Parentheses can be used to group sub-expressions to better control the boolean evaluation of the expression.
N.B. Certain expression functions have optional parameters, to avoid parsing errors, ALWAYS use a space between a parameterless function and opening parenthesis.
A sub-expression or sub-expressions group with parentheses can be inverted using the ! (NOT) operator.
Integer comparisons can be performed using the following operators:
- < (less than)
- > (greater than)
- = (equal to)
- <= (less than or equal to)
- >= (greater than or equal to)
- != (not equal to)
Functions that produce integer values when not used with a comparison operator are implicitly converted to a boolean, where a value of 0 is false and any other value is true.
Names are always enclosed in quotation marks (eg: “Super Healing Potion”), however certain functions allow the usage of named-constants, which must not be enclosed, see Filtering Variables for more information.
Options
Filter options define default settings for the filter when it is first loaded. They can be defined anywhere in the filter file. Any or all of the options can be omitted.
Options are defined using the following syntax: Option[name]: value
Where name can be one of the following:
Name | Description |
---|---|
DefaultFilterLevel | Sets a default FilterLevel |
DefaultNotifyLevel | Sets a default NotifyLevel |
IgnoreMissingSounds | Allows filter to not throw errors if sound files cannot be found |
Attributes
Filter attributes define various miscellaneous information about the filter; some of this information is displayed whenever the filter is loaded. They can be defined anywhere in the filter file. Attributes are always string values, any or all of the attributes can be omitted.
Options are defined using the following syntax: Attribute[name]: value
Where name can be one of the following:
Name | Description |
---|---|
Name | What is the name of this filter |
Version | What is the current version of this filter |
Author | Who wrote this filter |
Date | When was the filter last updated |
These attributes are what define what filter information is displayed when a filter is loaded in game:
Filter And Notification Levels
Filters can be set to varying degrees of strictness using filterlevels. To only show minor hp pots in the lowest filter level you could use:
ItemDisplay[hp1 FILTERLVL=1]: %RED%!%WHITE%minor hp
Filter levels can be given names that can be seen in game using the H menu:
FilterLevel[1]: Ladder start FilterLevel[2]: Maps FilterLevel[3]: No low runes FilterLevel[4]: No hp/mp pots
Notifications can come in the form of chat messages or audio cues letting you know an item dropped. Notifications can be enabled by defining NotificationColor or NotificationSound.
Adding notification options to a style definition:
ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "folderwithsounds\soundfile", NotificationSoundPriority = HIGH
This would give a red notification in chat when the item drops and play the sound named “soundfile” that’s located in the “folderwithsounds” folder.
Alternatively you can use game sounds by referencing the sound location in game files:
ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "@global\sfx\item\rune”, NotificationSoundPriority = HIGH
This would give us a red notification in chat when the item drops and play the rune drop sound from the game files.
Items can be given notification and sound notification priority values of high, medium, or low. In game you can choose high medium and low values. Setting the values to low in game will cue all notifications, setting medium in game will allow medium and high notifications, and setting high in game will allow only notifications that are set to high.
Macros
[TextMacro]
defines a textual substitution that can be reused through-out the filter in [ItemDisplay]
, [ItemDescription]
or inline item notes. They all for all the same substitutions are item names and notes. They however may not include other macros.
To reference a [TextMacro]
, use the following syntax:
%!name!%
where name is a case-sensitive match to any defined [TextMacro]
. If no match is found the text is left unchanged.
For example if you wanted to have red, green, and blue @ signs to be displayed when a super healing potion drops you would define the macros:
TextMacro[RGB]: %RED%@%GREEN%@%BLUE%@ TextMacro[BGR]: %BLUE%@%RED%@%GREEN%@
Then call it the items display line:
ItemDisplay["Super Healing Potion"]: %!RGB!% %RED%%NAME% %!BGR!%
Resulting in:
Skill & Item Lists
Sounds
Loot filters support playback of custom sounds and default game sounds. These sounds can be set using the NotificationSound (see Item Styles) or by using %NOTIFYSOUND()%
.
There are two methods to play a custom sound, each with their own pros and cons:
Method | Pros | Cons |
---|---|---|
By Sounds.txt Id |
|
|
By File Path |
|
|
Any custom sounds need to be in the following format:
- Channels: 1 (Mono)
- BitRate: 22050Hz
- Format: Wav
File paths to custom sounds are relative to the filter folder in your Path of Diablo directory. If you want to use a sound that exists in one of the Diablo II archives, you need only append an “@” to the front of the path (eg. "@global\sfx\monster\beetle\attack1") and remove the top-level “data” portion from the path. Paths must always be enclosed in quotation marks.
Defining a reusable sound through-out your filter can be done with Sound[name]. They can be defined at any point in your filter file. To use it, first define your new sound, in this example it will be called “myFilterSound”:
Sound[myFilterSound]: "path\to\file"
Then you can use “myFilterSound” whenever you need a sound path or id.
Filtering Variables
Filtering variables form the basis of any filter boolean expression. They are divided into 5 main types:
- Item codes – these are 3 or 4 letter codes used to match the item's base. A list of item codes can be found on the Loot filtration codes page.
- Item names – these are the in-game name of the item base, enclosed in quotations, eg: "Super Healing Potion".
- Booleans – these are true or false conditions based on properties of the item, the player or other global information.
- Complex – these are numerical values used in conjunction with the comparison operators.
- Functions – these take a set of 1 or more inputs and produce either a boolean or integer value.
Variables
Named Variables:
Name | Description |
---|---|
ALLSK | Returns the value of the +x to all skills stat |
ALVL | Returns the affix level of the item |
AR | Returns the value of the + to attack rating stat |
AREALVL | Returns the area level (monster level) of the area you are currently in. |
ARMOR | Boolean indicating if the item is classed as armor |
ARPER | Returns the value of the attack rating per level stat |
AXE, BOW, DAGGER, JAVELIN, MACE, POLEARM, SCEPTER, SPEAR, STAFF, SWORD, THROWING, WAND, XBOW | Boolean indicating if the item falls into one of these weapon categories. |
BAR, DIN, DRU, NEC, SIN, SOR, ZON | Boolean indicating if the item falls into one of these class specific item categories. |
BELT, BOOTS, CHEST, CIRC, GLOVES, HELM, SHIELD | Boolean indicating if the item falls into one of these armor categories. |
CHSKx | Returns the level of the charged skill for skill id x |
CLx | Boolean indicating if the item is part of the given class-specific item group, where x is:
|
CLSKx | Returns the value of the + class skills stat, where x is:
|
CLVL | Returns the level of your character |
CORRUPTED | Boolean indicating if the item is corrupted |
CRAFT, CRAFTED, INF, INFERIOR, MAG, MAGIC, NMAG, NONMAGIC, RARE, SET, SUP, SUPERIOR, UNI, UNIQUE | Boolean indicating if the item is of the specified quality |
CRAFTALVL | Returns the affix level of the item if used for crafting |
CRES | Returns the value of the +% cold resistance stat |
DEF | Returns the value of the + defense stat |
DEX | Returns the value of the + dexterity stat |
DIFF, DIFFICULTY | Returns the current difficulty:
|
DTM | Returns the value of the damage to mana stat |
ED | Returns the value of the +% enhanced damage for weapons or +% enhanced defense for armors |
ELITE, ELT, EXCEPTIONAL, EXC, NORMAL, NORM | Boolean indicating if the item is of the specified grade |
ENR | Returns the value of the + energy stat |
EQx | Boolean indicating if the item is part of the given armor item group, where x is:
|
ETHEREAL, ETH | Boolean indicating if the item is Ethereal |
FBR | Returns the value of the faster block recovery stat |
FCR | Returns the value of the faster cast rate stat |
FHR | Returns the value of the faster hit recovery stat |
FILTERLVL | Returns the current filter level |
FOOLS | Boolean indicating if the item has the “Fools” affix |
FRES | Returns the value of the +% fire resistance stat |
FRW | Returns the value of the faster run/walk speed stat |
GEM | Boolean indicating if the item is a gem |
GEMGRADE | Returns the gem's grade:
|
GEMMED | Boolean indicating if the item is socketed with gems/runes/jewels |
GEMTIER | Returns the gem tier:
|
GFIND | Returns the value of the +% gold find stat |
GOLD | Returns the amount of gold if the item is a gold pile |
GRAIL | [On Hold] |
HARDCORE | Boolean indicating if the player is in Hardcore |
IAS | Returns the value of the increased attack speed stat |
IDENTIFIED, ID | Boolean indicating if the item is identified |
IDSCROLLS | Returns the number of identify scrolls in your inventory |
ILVL | Returns the item level |
LEVEL | Returns the id of the current level |
LIFE | Returns the value of the + life stat |
LRES | Returns the value of the +% lightning resistance stat |
MAEK | Returns the value of the mana after kill stat |
MANA | Returns the value of the + mana stat |
MAP | Boolean indicating if the item is a map |
MAPTIER | Returns the map tier:
|
MAXDMG | Returns the value of the + maximum damage stat |
MAXDUR | Returns the value of the + durability stat |
MFIND | Returns the value of the +% magic find stat |
MINDMG | Returns the value of the + minimum damage stat |
NOTIFYLVL | Returns the current notification level |
OSx | Returns the value of the + level x skill stat |
PERCENTILE | Returns the percentile (between 0 and 99) of the base armor roll of the item |
PLRCLASS | Returns the current class of the player:
|
PRES | Returns the value of the +% poison resistance stat |
POTION | Boolean indicating if the item is a potion |
POTIONTIER | Returns the tier of the potion:
|
PRICE | Returns the vendor sell price for the item in the current difficulty |
QLVL | Returns the quality level of the item |
QTY | Returns the quantity of the item stack |
QUEST | Boolean indicating if the item is a quest item |
REPAIR | Returns the value of the repairs durability stat |
REPLIFE | Returns the value of the + life replenish stat |
REPQUANT | Returns the value of the replenish quantity stat |
REQLEVEL | Returns the required level of the item |
RES | Returns the minimum value between all fire/lightning/cold/poison resistance stats on the item |
RUNE | Boolean indicating if the item is a rune |
RUNETIER | Returns a value between 1 to 33 indicating the rune's tier |
RUNEWORD, RW | Boolean indicating if the item is a runeword |
SKx | Returns the value of the + level x skill (class specific) stat |
SOCKETS, SOCK | Returns the number of sockets for the item |
SPECIAL | Boolean indicating if the item is a special item. Current special items are:
|
STR | Returns the value of the + strength stat |
SYNTH | Boolean indicating if the item is synthesized |
TABSKx | Returns the value of the + to {tab} skills stat where x is the id of the tab. |
TPSCROLLS | Returns the number of townportal scrolls in your inventory (including books) |
VIT | Returns the value of the + vitality stat |
WEAPON | Boolean indicating if the item is classed as a weapon |
WPx | Boolean indicating if the item is part of the given weapon item group, where x is:
|
Functions
Functions:
Name | Description |
---|---|
CHARSTAT() | |
COUNT() [DISABLED] | Counts the number of matching expressions. |
CSKILLS() | |
CHARGES() | |
CTCSKILL() | |
ITEMLIST() | |
ITYPE() | |
OSKILL() | |
OSKILLS() | |
MAXSKILLS() | |
MAXOSKILLS() | |
PREFIX() | |
PLRCLASS() | |
REQCLASS() | |
SET() | |
SKILL() | |
SKILLS() | |
STAT() | |
STORAGE() | |
SUFFIX() | |
UNIQUE() |
Block-Level Filters
Block-level filters provide a mechanism for skipping multiple filter lines (ItemDisplay[expr]: text entries) at once based on a set of common conditions. They can also be used to enable/disable groups of filter lines based on your filter level.
Block-level filters are required to have a start entry (with a filtering expression), and an end entry. Block-level filters can be nested, matching start entries to the next end entry in the file.
A start entry is defined as: EnableIf[expr]
An end entry is defined as: EndIf[]
expr uses the exact same filtering syntax and variables as ItemDisplay[expr]. An example of a basic block level filter is the following:
EnableIf[RUNE] ItemDisplay[]: %ORANGE%%RUNENAME% %TAN%[%RUNETIER%]%CONTINUE% ItemDisplay[RUNETIER>16]: %NAME%%GOLD%!!HR!! ItemDisplay[]: %NAME% EndIf[]
In this example, we can collate all filter lines that apply to runes, and then apply progressive styling based on the rune’s tier.
Block-level filters are a very powerful mechanism for both grouping and performance, and their usage is encouraged.
Item Names
Item names can be built using one or more item filter lines. They are defined in the text portion of the ItemDisplay[expr]: text declaration, before any Item Styles or Item Descriptions.
The filters lines’ actions and substitutions are only run if the expr of the ItemDisplay[expr] is true. With the appropriate usage of Filtering Substitutions and the %CONTINUE%
action, you can easily create complex names using multiple filtering lines.
When an item name is empty once all filters lines have run, that item will be hidden (when shown on the ground), grayed out (when shown in a vendor screen) or marked as “(Filtered)” (when shown in your inventory).
Item Descriptions
Filters can also attach a “note” to an item's description in a player's or NPC’s inventory. Notes are useful for many things, such as recipes or trade values. Just like with item names, notes can be accrued, and use the same Filtering Substitutions.
Item descriptions are defined by any text appearing in the text portion of an ItemDisplay[expr]
that is enclosed in curly braces.
Similar to Text Macro’s, you can also define globally reusable notes with the following syntax: ItemDescription[name]: text
To then use that note in a description, you would use the name enclosed by double curly braces. An example would be the following:
ItemDescription[AnImportantNote]: %RED%This is important, don’t lose it! ItemDisplay[QUEST]: %FULLNAME%{{AnImportantNote}}
Filtering Substitutions
Name substitutions allow for rewriting of text based on item information, static strings and other constants.
Constants:
Name | Substitution |
---|---|
%WHITE% |
Sets any text after the color constant to this color.
Note that %CORAL%, %SAGE% and %TEAL% are only available in D2GL or Glide Wrapper. Note that %NAVY%, %DBLUE%, %DARK_BLUE%, %COBALT%, %DARK_PURPLE%, %DPURPLE%, Colors will fall-back to an appropriate color if they are used in a mode where they are unavailable. |
%NEWLINE% |
Inserts a new line |
%LBRACE% | Inserts a left brace: { |
%RBRACE% | Inserts a right brace: } |
%LANGLE% | Inserts a left angle bracket: < |
%RANGLE% | Inserts a right angle bracket: > |
%SPACE% | Inserts a single space |
%EMPTY% | Inserts nothing, used to prevent white-space trimming. |
%HIDE% | Inserts nothing, purely a convenience to explicitly show this row is meant to hide an item |
Values:
Name | Substitution |
---|---|
%PREVIOUS% | |
%NAME% | |
%NOTE% | |
%ITEMNAME% | |
%FULLNAME% | |
%BASENAME% | |
%RWNAME% | |
%SOCKETS% | |
%TIER% | |
%RUNETIER% | |
%RUNENAME% | |
%GEMTIER% | |
%GEMTYPE% | |
%MAPTIER% | |
%POTIONTIER% | |
%ILVL% | |
%ALVL% | |
%QLVL% | |
%CRAFTALVL% | |
%LVLREQ% / %REQLEVEL% | |
%WPNSPD% | |
%RANGE% | |
%CODE% | |
%PRICE% | |
%PERCENTILE% | |
%DEF% | |
%EDAMAGE% | |
%EDEFENSE% | |
%RES% | |
%TOTALRES% | |
%QTY% | |
%CLASS% | |
%CL% | |
%QUAL% / %QUALITY% | |
%QT% / %GRADE% | |
%STAT()% | |
%SKILL()% | |
%OSKILL()% | |
%SKILLNAME()% |
Item names can also be formed iteratively by using %NAME%
to get the name set previously by any matching non-terminating filters. If no match to a substitution or function is found, the text is left unchanged.
Item Styles
Item styles allow one to set various nameplate styling options, and allow for playing sounds or showing map icons. Item styles can be declared at any point in the filter file. You can also declare inline styles, or override specific attributes of a global style.
A global style is defined with the following syntax: ItemStyle[name]: stylename
stylename Must contain one or more of the following attributes, delimited with a comma. Values for the attributes are declared using the following syntax: attribute = value
Name | Description |
---|---|
MapIcon | |
MapIconColor | |
BorderColor | |
BorderSize | |
BackgroundColor | |
NotificationColor | |
NotificationPriority | |
NotificationSound | |
NotificationSoundPriority |
This global style can then be referenced by its name enclosed in double angle brackets. An example of a global style is the following:
ItemStyle[Fancy]: MapIcon = 4, MapIconColor = 5, BorderColor = RGB(0/255/63), BorderSize = 1, BackgroundColor = RGB(255/0/63), NotificationColor = ITEM, NotificationPriority = HIGH, NotificationSound = "@global\sfx\monster\beetle\attack1", NotificationSoundPriority = HIGH
ItemDisplay[SKILL("Freezing Pulse") > 1]: %PURPLE%%NAME% <<Fancy>>
Styles can also be used and edited in-line and on the fly. To use the above style but change the border size:
ItemDisplay[SKILL("Freezing Pulse") > 1]: %PURPLE%%NAME% <:Fancy: BorderSize = 3>
Style elements border color and background color can also utilize RGB values, for example BackgroundColor = RGB(245/2/19)
.
Filtering Actions
NOTE: With the exception of %CONTINUE% all items actions are deprecated and will be removed in a future version. All your actions should be moved over to item styles.
Item filters can also have “actions” attached to them, these perform certain functions when a terminating filter condition is met within a specific context. Just like names, actions will accrue until a terminating condition is met. If no terminating condition is found, the accrued actions will be applied.
The following table lists all available filtering actions, parameters in [] are optional, and when omitted will use their default value.
Name/Syntax | Defaults | Description |
---|---|---|
%CONTINUE% | N/A | |
%NOTIFY()% | ||
%MAPICON()% | ||
%BORDER()% | ||
%NOTIFYSOUND()% | ||
%BGCOLOR()% |
Optimizing Your Filters
Although PoD does its best to make sure loaded item filters are performant, it is still up to the user to make sure their filters and filtering expressions are well structured to prevent potential slow-downs.
Filtering ex pressions are evaluated with short-circuiting.
Keeping this in mind, one can optimize filtering expressions to start with the most specific checks first, then becoming more broad. Certain conditionals are far more expensive (computationally) to evaluate.
Delaying the evaluation of these expensive conditions is preferable.
In many cases it is preferable to match to multiple expressions to build up styling for item groups. In this case it is recommended to keep all filter expression lines one-after-the-other, from most generic to most specific. To aid in fast evaluation it is recommended to start these “style blocks” with an item base type check, and then get more specific.
It is recommended to ensure that all filters have a suitable terminating filter line, doing so prevents unneeded evaluation of filtering expressions. By grouping non-terminating expressions as close as possible to their terminating filter will also reduce unnecessary evaluations.
Debugging Your Filters
Debugging of loot filters will be an evolving process that will improve over time.
When a filter is loaded, and the message appears in game, its color will notify you if any errors or warnings were found with the currently loaded filter. Light green means no errors or warnings were found, Orange means errors and/or warnings were found.
Currently all item codes, stat ids, skill ids, SkillList names and ItemList names are validated when the filter is loaded. Any errors will be logged out to the Diablo II log.
If you set the following setting:
<insert pic>
Then the errors and warnings will also be logged out to the game’s message log, helpful for on-the-fly filter adjustments and debugging.
Appendix A: Map Icons
These are the default icons and their associated numbers:
Appendix B: Palette Colors
The default Diablo 2 color palette:
Aside from the numeric color codes, BorderColor and BackgroundColor support RGB values. EG, a style using:
BackgroundColor = RGB(128/0/128)
Would redult in a purple background
Below to be replaced
Basics
Item Codes
All items in the game have an id code. Below are a few examples:
Code | Item |
---|---|
tsc | Scroll of Town Portal |
rvs | Rejuvenation Potion |
pk1 | Key of Terror |
cx5 | Orb of Corruption |
See more codes at Loot Filtration Codes
If you would like to rename "Scroll of Town Portal" to a much shorter "TP" then you would type: ItemDisplay[tsc]: TP
You can also add more text to an item. If you want to remember which boss drops which uber key then you would type: ItemDisplay[pk1]: Key of Terror (Countess)
Color Codes
You can also change the color of the item name using color codes. Below are a few example colors:
Code | Color |
---|---|
%GREEN% | |
%DGREEN% | |
%GOLD% | |
%TAN% |
See more codes at Loot Filtration Codes
If you would like to change the color of the Horadric Cube to purple then you would type: ItemDisplay[box]: %PURPLE%Horadric Cube
You can also use multiple colors within a single item. For example if you want the word "Horadric" to be yellow and "Cube" to be purple you would type: ItemDisplay[box]: %YELLOW%Horadric %PURPLE%Cube
Value References
Sometimes you want to call upon a value in the game to show the player. Below are a few examples:
Code | Output |
---|---|
%PRICE% | Selling price of the item |
%ILVL% | Item level |
%SOCKETS% | Show the item's socket count |
See more codes at Loot Filtration Codes
If you want to show the selling price of an item using a dollar sign ($100) as a prefix you would type: ItemDisplay[gpm]: ($%PRICE%) Choking Gas Potion
The same thing can be done to show the item level {L99} as a suffix: ItemDisplay[cm3]: %NAME% {L%ILVL%}
Hiding Items
When you want to hide an item, you simply leave the space behind the colon (:) empty.
So for example if you want to hide Antidote potions (yps) you would type: ItemDisplay[yps]:
This tells the game to display Antidote potions as nothing, which hides the item.
Rule Priority
The higher the rule in your filter file, the higher priority it will have.
This means if on the first line of your item filter you choose to hide all Spears but then on Line 2 you choose to show Spears with 6 sockets then the result is no spear will ever show.
In this example, you would change their location within the file. So show 6 socket spears on Line 1 and hide all spears on Line 2. This will hide all Spears except those with 6 sockets.
Conditions
- >
- <
- =
- <=
- >=
- !=
Using Greater than >, Less than <, Equal to =, Less than or equal to <=, Greater than or equal to >=, and Not equal to != will help add conditions to rules.
You may want to hide gold stacks that are not worth your time (stacks below 1000g) by typing: ItemDisplay[GOLD<1000]:
Logical Operators
You can use logical operators whenever you want to show an item only if a certain condition is met. Below are all the options:
- AND
- OR
- ! (logic negation)
If you want to show all polearms (WP8) with 4 or 5 sockets then you would type: ItemDisplay[WP8 (SOCK>3 AND SOCK<6)]: %NAME%
This same rule can be written in a different way: ItemDisplay[WP8 !SOCK=0 !SOCK=1 !SOCK=2 !SOCK=3 !SOCK=6]: %NAME%
The first one says "Show me all polearms with more than 3 but less than 6 sockets" whereas the second says "Show me all polearms but not ones with 0, 1, 2, 3 or 6 sockets".
It is important to keep AND & OR within their own bracket set. For example: (SOCK>3 OR SOCK=1). This is not required for logic negation (!)
Text Decoration and sounds
You can alter the appearance of item drops by adding filter code to the items display line. To make a super healing potion look like this:
You would format the potions display line as follows:
ItemDisplay["Super Healing Potion"]: %RED%%NAME% %MAPICON(4,5)% %BORDER(1,33)% %BGCOLOR(4)%
Drop decoration and sound modifiers:
Code | Input | Description |
|
---|---|---|---|
%MAPICON(x or x,x)% | One (1-96) or two (1-8) numbers. The first number sets the icon, 2nd shifts the color | Sets an icon that's visible on the minimap | |
%BORDER(x or x,x)% | One (1-253) or two (1-4) numbers. The first number sets a border color, 2nd number sets border thickness | Creates a border around the item name display | |
%BGCOLOR(x)% | One number (1-253) | Adds a background color to the item name display | |
%NOTIFY(x)% | A Color, choosing "ITEM" uses the default item color (blue for magic, yellow for rare, etc.) |
Creates a chat notification when the item drops | |
%NOTIFYSOUND(x)% | Number corresponding with an in game sound index | Forces a special sound when an item drops |
Filter levels
Filters can be set to varying degrees of strictness using filterlevels. To only show minor hp pots in the lowest filter level you could use:
ItemDisplay[hp1 FILTERLVL=1]: %RED%!%WHITE%minor hp
You can give filter levels names that can be seen in game using the H menu:
FilterLevel[1]: Ladder start FilterLevel[2]: Maps FilterLevel[3]: No low runes FilterLevel[4]: No hp/mp pots
Modern Filtering Techniques
Patch #21 Shungite brought us new filtering options, including macros, styles, support for if statements, and better ways to manage custom sounds.
Text Macros
Text macros are lines of text that can be preset and used repeatedly without the need to retype the entirety of the text. This is useful if the same test will be reused in a filter, as well as making some filtering lines easier to read to and change. If, for example you wanted to have red, green, and blue @ signs to be displayed when a super healing potion drops you would display it as:
ItemDisplay["Super Healing Potion"]: %RED%@%GREEN%@%BLUE%@ %RED%%NAME% %BLUE%@%RED%@%GREEN%@
Assuming this text would be used multiple times in a filter, instead of having to reuse that you could assign it to a text macro. At the top of the filter:
TextMacro[RGB]: %RED%@%GREEN%@%BLUE%@ TextMacro[BGR]: %BLUE%@%RED%@%GREEN%@
Then to use a text macro you call it by wrapping the name of it %! !%, like this:
ItemDisplay["Super Healing Potion"]: %!RGB!% %RED%%NAME% %!BGR!%
Styling
Styles can be used to set display options like border and background color of an item drop. Styles are defined at the top of the filter just like text macros and can be used by wrapping the name in << and >> like <<Style>>. To achieve this display:
Define the style at the top of the filter:
ItemStyle[Fancy]: MapIcon = 4, MapIconColor = 5, BorderColor = 33, BorderSize = 1, BackgroundColor = 4
Then apply it using:
ItemDisplay["Super Healing Potion"]: %RED%%NAME% <<Fancy>>
Inline styles
Styles can also be used and edited in-line. Using the above example, if you wanted a different background color you would use:
ItemDisplay["Super Healing Potion"]: %RED%%NAME% <:Fancy: BackgroundColor = 155>
This would apply all parts of the Fancy style except for the background color, background color will use the newly defined color instead.
Style elements border color and background color can also utilize RGB values, for example BackgroundColor = RGB(245/2/19)
.
Applying Styles and Macros together
Text macros and styles can be used together
ItemDisplay["Super Healing Potion"]: %!RGB!% %RED%%NAME% %!BGR!% <:Fancy: BorderColor = 99, BorderSize = 4> ItemDisplay[POTION]: %!RGB!% %PURPLE%%NAME% %!BGR!% <<Fancy>>
Notifications and Sounds
Notifications can come in the form of chat messages or audio cues letting you know an item dropped. You can enable notifications by defining NotificationColor or NotificationSound. Adding notification options to a style definition:
ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "folderwithsounds\soundfile", NotificationSoundPriority = HIGH
This would give us a red notification in chat when the item drops and play the sound named “soundfile” that’s located in the “folderwithsounds” folder.
Alternatively you can use game sounds by referencing the sound location in game files:
ItemStyle[Fancy]: NotificationColor = RED, NotificationPriority = MEDIUM, NotificationSound = "@global\sfx\item\rune”, NotificationSoundPriority = HIGH
This would give us a red notification in chat when the item drops and play the rune drop sound from the game files.
Items can be given notification and sound notification priority values of high, medium, or low. In game you can choose high medium and low values. Setting the values to low in game will cue all notifications, setting medium in game will allow medium and high notifications, and setting high in game will allow only notifications that are set to high.
If Statements
If statements can be useful when you want to evaluate only certain items on some criteria. Since every drop is evaluated line-by-line in a filter until a match is found, if blocks can provide efficiency by forcing item checks to ignore multiple lines. As an example, if you wanted look for pre-buff assassin claws, and add the skill name to the display, you could use the lines:
ItemDisplay[CL5 NMAG SKILL("Blade Shield")>2]: %NAME% %LIGHT_GRAY%+3 Blade Shield ItemDisplay[CL5 NMAG SKILL("Venom")>2]: %NAME% %LIGHT_GRAY%+3 Venom
This would add “+3 skill name” to these claws, but every item dropped would be evaluated to see if they match. An if statement addressing this could be:
EnableIf[CL5 NMAG] ItemDisplay[SKILL("Venom")>2]: %NAME% %LIGHT_GRAY%+3 Venom %CONTINUE% ItemDisplay[SKILL("Blade Shield")>2]: %NAME% %LIGHT_GRAY%+3 Blade Shield %CONTINUE% ItemDisplay[CL5 NMAG]: %NAME% EndIf[]
This would cause any item that’s not a white or grey assassin claw to ignore those lines.
Another example could be to add Hemorrhage or life tap charges to the items display
EnableIf[(MAG OR NMAG) (WP12)] ItemDisplay[(MAG OR NMAG) SKILL("Hemorrhage")=3]:%NAME% %RED% +3 Hemo ItemDisplay[(MAG OR NMAG) SKILL("Hemorrhage")=2]:%NAME% %RED% +2 Hemo ItemDisplay[(MAG) CHARGES("Life Tap")>0]:%NAME% %LIGHT_GRAY%+Life Tap Charges %CONTINUE% ItemDisplay: %NAME% EndIf[]
These are small examples but this concept can be scaled up to apply to all + skill granting items, runeword bases, and even potions, potentially allowing many items to skip filter lines which wouldn’t apply to them.
ALT Text
Holding the ALT key when hovering over an item shows additional information not seen by default referred to as advanced item descriptions. You can add to these advanced item descriptions by enclosing "ALT text" in brackets {}.
Using:
ItemDisplay[tsc]: %NAME% {This is a TP scroll}
Adds the text "This is a TP scroll" to TP scrolls that's only visible when holding the ALT key on the keyboard.
A more useful implementation for this could be to add cube recipes or possible corruption mods to an item. Presenting this larger amount of text as an advanced item description allows the convenience of having the information there but with the convenience of not having it visible all the time.
Attribution
Attribute codes notify users of general filter info when it's loaded.
Code | Purpose |
---|---|
Attribute[Author]: | Filter authors name |
Attribute[Name]: | Name of the filter |
Attribute[Version]: | Version number |
Attribute[Date]: | Last edit date |
How filter attributes are displayed in game:
Credits
Loot filtration implemented in PoD by Dav92 based on code from McGoD, underbent and Deadlock39. Later rebuilt from the ground up by Necrolis.