Some mods may be broken due to the recent Alloyed Collective update.
ItemStringParser
A library for parsing Item Strings. Does nothing on its own.
| Last updated | an hour ago |
| Total downloads | 1 |
| Total rating | 0 |
| Categories | Libraries |
| Dependency string | Def-ItemStringParser-1.0.0 |
| Dependants | 0 other packages depend on this package |
README
ItemStringParser
This mod is a library for parsing ItemStrings. See bottom on the developer manual.
User Manual
ItemStrings are a way to describe a droptable using plain text. They let you describe what items should appear and how many in a simple, readable line. ItemStrings can include instructions for repeating items, choosing items randomly, or excluding certain items.
ItemString Operators
ItemString operators are symbols that help you decide which items to give, repeat, or exclude in a list. They make it easy to write rules like "give this item", "skip that one", or "choose one randomly" using short codes. Each entry in the ItemString roughly follows the format: <repeat>x<itemkey>!<itemname>*<multiplier>: <weight>. Entries can be separated by & or |. Entries can be grouped with { and }.
! (Not-Operator)
- Purpose: Blacklist items from tiers or droptables.
- Placement: Directly after the name of the droptable or tier.
- Example:
Tier1!Hoof- White item but not a HoofdtChest1!Bear!Crowbar- Content of a Small Chest but neither Tougher Times nor Crowbar.
& (And-Operator)
- Purpose: Every item separated by
&will be selected. - Example:
Hoof & Boss- The player receives both a Hoof and a random Boss item.
| (Or-Operator)
- Purpose: Only one of the items separated by
|will be chosen at random. - Weights: You can specify selection weights using a colon
:after the item (e.g.,Tier1: 0.5 | Tier2: 0.5). - Example:
Tier1 | Tier2- The player gets either a Tier1 or a Tier2 item (equal chance unless weighted).
: (Weight Separator)
- Purpose: Assigns probability weights to options with the Or-Operator (
|). - Default: If omitted, the default weight 1 is used.
- Example:
Tier1: 0.6 | Tier2: 0.4- Tier1 has a 60% chance, Tier2 a 40% chance.Tier1: 3.0 | Tier2- Tier1 has a 75% chance, Tier2 a 25% chance.
x (Repeat-Operator)
- Purpose: Repeats the immediately following item or group a fixed number of times.
- Placement: Directly before a group or item.
- Example:
5xHoof- The player gets 5 Hoof items.3x{ Tier1 | Tier2 }- The player gets 3 times a randomly selected item from Tier1 or Tier2.
* (Multiplier-Operator)
- Purpose: Multiplies the amount of items of a group.
- Placement: Directly after a group or item.
- Example:
Hoof*5- The player gets 5 Hoof items.{ Tier1 | Tier2 }*3- The player gets 3 copies of a single type of item from either Tier1 or Tier2.
{ and } (Grouping Symbols)
- Purpose: Group items and operators together. Can use
&and|within a group, but they cannot be mixed. - Operator precedence: Use
{ }to explicitly control grouping and order of operations, especially when combining repeat, and, or multiply. - Nested groups: You can nest
{ }for more complex item generation logic. - Example:
{ 2xdtChest1 | dtChest2 }- Represents a choice between "2x small chest" and "1 large chest" as a single entity; useful with other operators.
Summary Table
| Operator | Symbol | Description | Example |
|---|---|---|---|
| Not | ! |
Blacklists the item from the group | A!B |
| And | & |
All items, together | A & B |
| Or | | |
Only one item, random (optional weight via :) |
A | B:0.7 | C:0.3 |
| Weight | : |
Specifies probability weight for options when using | |
A: 0.6 | B: 0.4 |
| Repeat | x |
Repeats the following item/group N times | 5xA or 3x{A | B} |
| Multiply | * |
Multiplies the amount of items in the group by N | {A & B}*4 |
| Grouping | {} |
Groups items/expressions | {A & 2xB} |
Examples
A random lunar item, except for Light Flux Pauldron and Stone Flux Pauldron:
ItemList = Lunar!HalfSpeedDoubleHealth!HalfAttackSpeedHalfCooldowns
5 Hooves:
ItemList = 5xHoof
Also 5 Hooves:
ItemList = Hoof*5
5 random whites:
ItemList = 5xTier1
5 copies of the same white:
ItemList = Tier1*5
5 Hooves and 2 Armor Plates:
ItemList = 5xHoof & 2xArmorPlate
Either 5 Hooves or 2 Armor Plates:
ItemList = 5xHoof | 2xArmorPlate
Either 5 Hooves with 30% chance or 2 Armor Plates with 70% chance:
ItemList = 5xHoof: 0.3 | 2xArmorPlate: 0.7
Infusion and either 5 Hooves with 30% chance or 2 Armor Plates with 70% chance:
ItemList = Infusion & { 5xHoof: 0.3 | 2xArmorPlate: 0.7 }
Either Infusion or Feather and either 5 Hooves with 30% chance or 2 Armor Plates with 70% chance:
ItemList = { Infusion | Feather } & { 5xHoof: 0.3 | 2xArmorPlate: 0.7 }
75% chance: Infusion and feather, 25% chance: 5 hoves and 5 Armor Plates
ItemList = { Infusion & Feather }: 0.75 | { Hoof & ArmorPlate }*5: 0.25
Either 5 whites or 3 greens or 1 red:
ItemList = 5xTier1 | 3xTier2 | Tier3
Between 1 and 5 whites.
ItemList = 1xTier1 | 2xTier1 | 3xTier1 | 4xTier1 | 5xTier1
10 random items which consist of around 50% whites, around 35% greens and around 15% red:
ItemList = 10x{ Tier1: 0.5 | Tier2: 0.35 | Tier3: 0.15 }
5 times one of the following: Either the contents of 2 small chests (except for Tougher Times) or the content of 1 large chest
ItemList = 5x{ 2xdtChest1!Bear | dtChest2 }
Preon Accumulator and 10 Gesture of the Drowned or Ifrit's Distinction and 1 Ignition Tank
{ BFG & 10xAutoCastEquipment } | { EliteFireEquipment & StrengthenBurn }
Item Keywords
You can use:
- Internal item names (see R2Wiki - Items-and-Equipments-Data).
- Item Tier names:
Tier1,Tier2,Tier3,Lunar,Boss,VoidTier1,VoidTier2,VoidTier3,VoidBoss,FoodTier - Droptable names: e.g.
dtChest1,dtLunarChest,dtVoidChest. See below.
Droptable Names
Here is a list of supported droptables:
| Drop Table Name | tier1 | tier2 | tier3 | boss | lunarEquipment | lunarItem | lunarCombined | equipment | voidTier1 | voidTier2 | voidTier3 | voidBoss | foodTier | powerShapes | canDropBeReplaced | requiredItemTags | bannedItemTags |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| dtCasinoChest | 0.7 | 0.3 | 0.01 | 0 | 0 | 0 | 0 | 0.1 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtSmallChestDamage | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | Damage | |
| dtSmallChestHealing | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | Healing | |
| dtSmallChestUtility | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | Utility | |
| dtChest1 | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtChest2 | 0 | 0.8 | 0.2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtAISafeTier1Item | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | AIBlacklist, SprintRelated | |
| dtAISafeTier2Item | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | AIBlacklist, SprintRelated | |
| dtAISafeTier3Item | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | AIBlacklist, SprintRelated | |
| dtEquipment | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtTier1Item | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtTier2Item | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtTier3Item | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtVoidChest | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | 3 | 1 | 0 | 0 | 0 | True | ||
| dtDuplicatorTier1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | CannotDuplicate | |
| dtDuplicatorTier2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | CannotDuplicate | |
| dtDuplicatorTier3 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | CannotDuplicate | |
| dtDuplicatorWild | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | WorldUnique | |
| dtGoldChest | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtLunarChest | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtMonsterTeamTier1Item | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | AIBlacklist, OnKillEffect, EquipmentRelated, SprintRelated | |
| dtMonsterTeamTier2Item | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | AIBlacklist, OnKillEffect, EquipmentRelated, SprintRelated | |
| dtMonsterTeamTier3Item | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | AIBlacklist, OnKillEffect, EquipmentRelated, SprintRelated | |
| dtSacrificeArtifact | 0.7 | 0.3 | 0.01 | 0 | 0 | 0 | 0 | 0.1 | 0 | 0 | 0 | 0 | 0 | 0 | True | SacrificeBlacklist | |
| dtShrineChance | 8 | 2 | 0.2 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtLockbox | 0 | 4 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtCommandChest | 0.2 | 0.2 | 0.05 | 0.05 | 0 | 0 | 0 | 0.2 | 0.1 | 0.1 | 0.05 | 0.05 | 0 | 0 | True | Any, Any, Any, Any, Any | |
| dtCategoryChest2Damage | 0 | 0.8 | 0.2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | Damage | |
| dtCategoryChest2Healing | 0 | 0.8 | 0.2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | Healing | |
| dtCategoryChest2Utility | 0 | 0.8 | 0.2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | Utility | |
| dtITBossWave | 0 | 80 | 7.5 | 7.5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtITDefaultWave | 80 | 10 | 0.25 | 0.25 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtITLunar | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtITSpecialBossWave | 0 | 0 | 80 | 20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtITVoid | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 80 | 20 | 1 | 0 | 0 | 0 | True | ||
| dtVoidLockbox | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | 5 | 2 | 0 | 0 | 0 | True | ||
| dtVoidCamp | 40 | 40 | 10 | 3 | 0 | 0 | 0 | 0 | 5.714286 | 5.714286 | 1.25 | 0 | 0 | 0 | True | ||
| dtVoidTriple | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| AurelioniteHeartPickupDropTable | 0 | 0 | 0.4 | 0.6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtShrineHalcyoniteTier1 | 0.65 | 0.3 | 0.05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtShrineHalcyoniteTier2 | 0.65 | 0.3 | 0.05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | HalcyoniteShrine | |
| dtShrineHalcyoniteTier3 | 0.65 | 0.3 | 0.05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| GeodeRewardDropTable | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtChanceDoll | 0 | 0.79 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtSonorousEcho | 0.9 | 0.1 | 0.001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtSalvage | 0.75 | 0.25 | 0.05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | False | CanBeTemporary | |
| dtDrifterBagChest | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | ||
| dtJunkDrone | 0.7 | 0.25 | 0.05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | False | CanBeTemporary | |
| dtSolusHeart | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | True | Technology | WorldUnique, CannotCopy, FoodRelated, ObjectiveRelated |
| dtTemporaryItemsDistributor | 0.8 | 0.2 | 0.01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | False | CanBeTemporary |
EBNF
You can use this EBNF to validate your item string for example at PaulKlineLabs' BNF Playground.
<ItemList> ::= <AND_LIST> | <OR_LIST>
<AND_LIST> ::= <ENTRY> (" & " <ENTRY>)*
<OR_LIST> ::= <WEIGHTED_ENTRY> (" | " <WEIGHTED_ENTRY>)*
<ENTRY> ::= (<rep> "x")? <ITEM_KEY> ("*" <mult>)?
<WEIGHTED_ENTRY> ::= <ENTRY> (": " <weight>)?
<ITEM_KEY> ::= <itemname> | <tier> ("!" <itemname>)* | <droptable> ("!" <itemname>)* | "{ " <AND_LIST> " }" | "{ " <OR_LIST> " }"
<itemname> ::= "AACannon" | "AdaptiveArmor" | "AlienHead" | "ArmorPlate" | "ArmorReductionOnHit" | "AttackSpeedAndMoveSpeed" | "AttackSpeedOnCrit" | "AttackSpeedPerNearbyAllyOrEnemy" | "AutoCastEquipment" | "Bandolier" | "BarrageOnBoss" | "BarrierOnCooldown" | "BarrierOnKill" | "BarrierOnOverHeal" | "Bear" | "BearVoid" | "BeetleGland" | "Behemoth" | "BleedOnHit" | "BleedOnHitAndExplode" | "BleedOnHitVoid" | "BonusGoldPackOnKill" | "BonusHealthBoost" | "BoostAllStats" | "BoostAttackSpeed" | "BoostDamage" | "BoostEquipmentRecharge" | "BoostHp" | "BossDamageBonus" | "BounceNearby" | "BurnNearby" | "ChainLightning" | "ChainLightningVoid" | "Clover" | "CloverVoid" | "ConvertCritChanceToCritDamage" | "CooldownOnCrit" | "CrippleWardOnLevel" | "CritAtLowerElevation" | "CritDamage" | "CritGlasses" | "CritGlassesVoid" | "CritHeal" | "Crowbar" | "CutHp" | "Dagger" | "DeathMark" | "DelayedDamage" | "DestructibleSpawner" | "DrizzlePlayerHelper" | "DroneDynamiteDisplay" | "DroneUpgradeHidden" | "DroneWeapons" | "DroneWeaponsBoost" | "DroneWeaponsDisplay1" | "DroneWeaponsDisplay2" | "DronesDropDynamite" | "Duplicator" | "ElementalRingVoid" | "EmpowerAlways" | "EnergizedOnEquipmentUse" | "EquipmentMagazine" | "EquipmentMagazineVoid" | "ExecuteLowHealthElite" | "ExplodeOnDeath" | "ExplodeOnDeathVoid" | "ExtraEquipment" | "ExtraLife" | "ExtraLifeConsumed" | "ExtraLifeVoid" | "ExtraLifeVoidConsumed" | "ExtraShrineItem" | "ExtraStatsOnLevelUp" | "FallBoots" | "Feather" | "FireRing" | "FireballsOnHit" | "Firework" | "FlatHealth" | "FocusConvergence" | "FragileDamageBonus" | "FragileDamageBonusConsumed" | "FreeChest" | "Ghost" | "GhostOnKill" | "GoldOnHit" | "GoldOnHurt" | "GummyCloneIdentifier" | "HalfAttackSpeedHalfCooldowns" | "HalfSpeedDoubleHealth" | "HeadHunter" | "HealOnCrit" | "HealWhileSafe" | "HealingPotion" | "HealingPotionConsumed" | "HealthDecay" | "Hoof" | "IceRing" | "Icicle" | "IgniteOnKill" | "ImmuneToDebuff" | "IncreaseDamageOnMultiKill" | "IncreaseHealing" | "IncreasePrimaryDamage" | "Incubator" | "Infusion" | "InvadingDoppelganger" | "ItemDropChanceOnKill" | "JumpBoost" | "JumpDamageStrike" | "Junk" | "KillEliteFrenzy" | "KnockBackHitEnemies" | "Knurl" | "LaserTurbine" | "LemurianHarness" | "LevelBonus" | "LightningStrikeOnHit" | "LowerPricedChests" | "LowerPricedChestsConsumed" | "LunarBadLuck" | "LunarDagger" | "LunarPrimaryReplacement" | "LunarSecondaryReplacement" | "LunarSpecialReplacement" | "LunarSun" | "LunarTrinket" | "LunarUtilityReplacement" | "LunarWings" | "MageAttunement" | "Medkit" | "MeteorAttackOnHighDamage" | "MinHealthPercentage" | "MinionLeash" | "MinorConstructOnKill" | "Missile" | "MissileVoid" | "MoneyLoan" | "MonsoonPlayerHelper" | "MonstersOnShrineUse" | "MoreMissile" | "MoveSpeedOnKill" | "Mushroom" | "MushroomVoid" | "NearbyDamageBonus" | "NovaOnHeal" | "NovaOnLowHealth" | "OnLevelUpFreeUnlock" | "OutOfCombatArmor" | "ParentEgg" | "PermanentDebuffOnHit" | "PersonalShield" | "Phasing" | "PhysicsProjectile" | "Plant" | "PlantOnHit" | "PlasmaCore" | "PrimarySkillShuriken" | "RandomDamageZone" | "RandomEquipmentTrigger" | "RandomlyLunar" | "RegeneratingScrap" | "RegeneratingScrapConsumed" | "RepeatHeal" | "RoboBallBuddy" | "SecondarySkillMagazine" | "Seed" | "SharedSuffering" | "ShieldBooster" | "ShieldOnly" | "ShockDamageAura" | "ShockNearby" | "SiphonOnLowHealth" | "SkullCounter" | "SlowOnHit" | "SlowOnHitVoid" | "SpeedBoostPickup" | "SpeedOnPickup" | "SprintArmor" | "SprintBonus" | "SprintOutOfCombat" | "SprintWisp" | "Squid" | "StatsFromScrap" | "StickyBomb" | "StrengthenBurn" | "StunAndPierce" | "StunChanceOnHit" | "Syringe" | "TPHealingNova" | "Talisman" | "TeamSizeDamageBonus" | "TeleportOnLowHealth" | "TeleportOnLowHealthConsumed" | "TeleportWhenOob" | "TempestOnKill" | "Thorns" | "TonicAffliction" | "Tooth" | "TransferDebuffOnHit" | "TreasureCache" | "TreasureCacheVoid" | "TriggerEnemyDebuffs" | "UseAmbientLevel" | "UtilitySkillMagazine" | "VoidMegaCrabItem" | "VoidmanPassiveItem" | "WarCryOnCombat" | "WarCryOnMultiKill" | "WardOnLevel" | "BFG" | "Blackhole" | "BossHunter" | "BurnNearby" | "Cleanse" | "CommandMissile" | "CrippleWard" | "CritOnUse" | "DeathProjectile" | "DroneBackup" | "FireBallDash" | "Fruit" | "GainArmor" | "Gateway" | "GoldGat" | "GummyClone" | "HealAndRevive" | "Jetpack" | "LifestealOnHit" | "Lightning" | "Meteor" | "Molotov" | "MultiShopCard" | "Parry" | "PassiveHealing" | "Recycle" | "Saw" | "Scanner" | "TeamWarCry" | "Tonic" | "VendingMachine"
<droptable> ::= "dtCasinoChest" | "dtSmallChestDamage" | "dtSmallChestHealing" | "dtSmallChestUtility" | "dtChest1" | "dtChest2" | "dtAISafeTier1Item" | "dtAISafeTier2Item" | "dtAISafeTier3Item" | "dtEquipment" | "dtTier1Item" | "dtTier2Item" | "dtTier3Item" | "dtVoidChest" | "dtDuplicatorTier1" | "dtDuplicatorTier2" | "dtDuplicatorTier3" | "dtDuplicatorWild" | "dtGoldChest" | "dtLunarChest" | "dtMonsterTeamTier1Item" | "dtMonsterTeamTier2Item" | "dtMonsterTeamTier3Item" | "dtSacrificeArtifact" | "dtShrineChance" | "dtLockbox" | "dtCommandChest" | "dtCategoryChest2Damage" | "dtCategoryChest2Healing" | "dtCategoryChest2Utility" | "dtITBossWave" | "dtITDefaultWave" | "dtITLunar" | "dtITSpecialBossWave" | "dtITVoid" | "dtVoidLockbox" | "dtVoidCamp" | "dtVoidTriple" | "AurelioniteHeartPickupDropTable" | "dtShrineHalcyoniteTier1" | "dtShrineHalcyoniteTier2" | "dtShrineHalcyoniteTier3" | "GeodeRewardDropTable" | "dtChanceDoll" | "dtSonorousEcho" | "dtSalvage" | "dtDrifterBagChest" | "dtJunkDrone" | "dtSolusHeart" | "dtTemporaryItemsDistributor"
<tier> ::= "Tier1" | "Tier2" | "Tier3" | "Lunar" | "Boss" | "VoidTier1" | "VoidTier2" | "VoidTier3" | "VoidBoss"
<rep> ::= <int>
<mult> ::= <int>
<weight> ::= <float>
<int> ::= [1-9] [0-9]*
<float> ::= ("0" | <int>) ("." [0-9]+ )?
Or use this one if you have modded items:
<ItemList> ::= <AND_LIST> | <OR_LIST>
<AND_LIST> ::= <ENTRY> (" & " <ENTRY>)*
<OR_LIST> ::= <WEIGHTED_ENTRY> (" | " <WEIGHTED_ENTRY>)*
<ENTRY> ::= (<rep> "x")? <ITEM_KEY> ("*" <mult>)?
<WEIGHTED_ENTRY> ::= <ENTRY> (": " <weight>)?
<ITEM_KEY> ::= <itemname> | <tier> ("!" <itemname>)* | <droptable> ("!" <itemname>)* | "{ " <AND_LIST> " }" | "{ " <OR_LIST> " }"
<itemname> ::= [a-z]+
<droptable> ::= "dtCasinoChest" | "dtSmallChestDamage" | "dtSmallChestHealing" | "dtSmallChestUtility" | "dtChest1" | "dtChest2" | "dtAISafeTier1Item" | "dtAISafeTier2Item" | "dtAISafeTier3Item" | "dtEquipment" | "dtTier1Item" | "dtTier2Item" | "dtTier3Item" | "dtVoidChest" | "dtDuplicatorTier1" | "dtDuplicatorTier2" | "dtDuplicatorTier3" | "dtDuplicatorWild" | "dtGoldChest" | "dtLunarChest" | "dtMonsterTeamTier1Item" | "dtMonsterTeamTier2Item" | "dtMonsterTeamTier3Item" | "dtSacrificeArtifact" | "dtShrineChance" | "dtLockbox" | "dtCommandChest" | "dtCategoryChest2Damage" | "dtCategoryChest2Healing" | "dtCategoryChest2Utility" | "dtITBossWave" | "dtITDefaultWave" | "dtITLunar" | "dtITSpecialBossWave" | "dtITVoid" | "dtVoidLockbox" | "dtVoidCamp" | "dtVoidTriple" | "AurelioniteHeartPickupDropTable" | "dtShrineHalcyoniteTier1" | "dtShrineHalcyoniteTier2" | "dtShrineHalcyoniteTier3" | "GeodeRewardDropTable" | "dtChanceDoll" | "dtSonorousEcho" | "dtSalvage" | "dtDrifterBagChest" | "dtJunkDrone" | "dtSolusHeart" | "dtTemporaryItemsDistributor"
<tier> ::= "Tier1" | "Tier2" | "Tier3" | "Lunar" | "Boss" | "VoidTier1" | "VoidTier2" | "VoidTier3" | "VoidBoss"
<rep> ::= <int>
<mult> ::= <int>
<weight> ::= <float>
<int> ::= [1-9] [0-9]*
<float> ::= ("0" | <int>) ("." [0-9]+ )?
Developer Manual
As a developer if you want to use the ItemStringParser in your mod, here is what you need to do.
- Add the
ItemStringParser.dllas dependency to your Visual Studio project. Set Copy Local to No so that the dll does not get copied to your build output. Example:
<Reference Include="ItemStringParser">
<HintPath>libs\ItemStringParser.dll</HintPath>
<Private>false</Private>
</Reference>
- Add
[BepInDependency(ItemStringParser.ItemStringParser.PluginGUID)]to yourUnityBasePluginclass - Add dependency string
Def-ItemStringParser-1.0.0to the dependencies list in yourmanifest.json
It provides two public methods: (1) ParseItemString and (2) ResolveItemKey
Attention: The methods rely on the Run.instance.available*DropList to be populated. As such, only run the ItemStringParser after Run.BuildDropTable() was executed.
ParseItemString
This is the main method you will want to use. This method interprets an item string, applying repetitions and other formatting rules, to build a collection of items/equipments with their amounts.
Signature
bool ItemStringParser.ItemStringParser.ParseItemString(string itemString, Dictionary<PickupIndex, int> resolvedItems, ManualLogSource log, int index = -1)
itemString (string): The input string containing item definitions to parse. It includes items, operators, and formatting syntax.
resolvedItems (Dictionary<PickupIndex, int>): A dictionary to which parsed item entries and their amounts will be added or updated.
log (ManualLogSource): For logging in case the provided itemString contains syntax errors.
index (int, optional): Specifies if a certain entry of the top-level or-group shall be taken or if it should be picked at random. -1 is default and means random.
Return Value: Whether it was successful
Usage Example
var resolvedItems = new Dictionary<PickupIndex, int>();
bool success = ItemStringParser.ItemStringParser.ParseItemString("5xHoof & {Tier1 | Tier2}*3", resolvedItems, Logger);
if (success) {
foreach (var (pickupIndex, itemAmount) in resolvedItems) {
if (itemIndex != ItemIndex.None && itemAmount > 0)
{
inventory.GiveItemPermanent(itemIndex, itemAmount);
}
}
}
Equipments are also supported. Example:
var inventory = master.inventory;
Dictionary<PickupIndex, int> itemsToGive = new Dictionary<PickupIndex, int>();
ItemStringParser.ItemStringParser.ParseItemString(itemString, itemsToGive, Logger);
uint equipIndex = 0;
foreach (var (pickupIndex, itemAmount) in itemsToGive)
{
var pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
// handle items
var itemIndex = pickupDef.itemIndex;
if (itemIndex != ItemIndex.None && itemAmount > 0)
{
inventory.GiveItemPermanent(itemIndex, itemAmount);
}
// handle equipments
int maxEquipmentSlots = master.bodyPrefab.name == "ToolbotBody" ? 2 : 1;
int maxEquipmentSets = master.inventory.GetItemCountEffective(DLC3Content.Items.ExtraEquipment.itemIndex) + 1;
int maxEquipmentCount = maxEquipmentSlots * maxEquipmentSets;
var equipmentCount = itemAmount;
var equipmentIndex = pickupDef.equipmentIndex;
while (equipmentIndex != EquipmentIndex.None && equipmentCount > 0 && equipIndex < maxEquipmentCount)
{
uint slot = (uint)(equipIndex % maxEquipmentSlots);
uint set = (uint)(equipIndex / maxEquipmentSlots);
inventory.SetEquipmentIndexForSlot(equipmentIndex, slot, set);
equipmentCount--;
equipIndex++;
}
}
Index can be used to retrieve the n-th entry of the root or-group. Example:
ItemStringParser.ItemStringParser.ParseItemString("Hoof | AlienHead", resolvedItems, Logger, 0); // results in "Hoof"
ItemStringParser.ItemStringParser.ParseItemString("Hoof | AlienHead", resolvedItems, Logger, 1); // results in "AlienHead"
ItemStringParser.ItemStringParser.ParseItemString("Hoof | AlienHead", resolvedItems, Logger, -1); // results in either "Hoof" or "AlienHead"
ResolveItemKey
This method resolves a single item key string into actual items and adds them to the resolvedItems dictionary. It supports parsing item keys that represent item tiers, drop tables, concrete items, or concrete equipment. It also supports blacklisting certain items from selection. As such this method only supports the !-operator, but no other operator.
Signature
bool ItemStringParser.ItemStringParser.ResolveItemKey(string itemkey, int repeat, Dictionary<PickupIndex, int> resolvedItems, ManualLogSource log)
itemkey (string): The identifier string for the item or group of items to resolve. May exclude items from droptables or tiers with with !.
repeat (int): How many times to add the resolved items.
resolvedItems (Dictionary<PickupIndex, int>): Dictionary where resolved items and their counts will be added or updated.
log (ManualLogSource): For logging in case of errors in the item string.
Return Value: Whether it was successful.
Usage Example
var resolvedItems = new Dictionary<PickupIndex, int>();
ManualLogSource log = new ManualLogSource();
bool success = ItemStringParser.ResolveItemKey(
"Tier1!Crowbar", // Tier1 items excluding Crowbar
3, // Add 3 items from this tier
resolvedItems,
Logger
);
if (success)
{
// Use resolvedItems as needed
}