diff --git a/CMake/Assets.cmake b/CMake/Assets.cmake index 9d6532b66..34f8d86af 100644 --- a/CMake/Assets.cmake +++ b/CMake/Assets.cmake @@ -155,6 +155,10 @@ set(devilutionx_assets txtdata/classes/rogue/attributes.tsv txtdata/classes/sorcerer/attributes.tsv txtdata/classes/warrior/attributes.tsv + txtdata/items/item_prefixes.tsv + txtdata/items/item_suffixes.tsv + txtdata/items/itemdat.tsv + txtdata/items/unique_itemdat.tsv txtdata/monsters/monstdat.tsv txtdata/monsters/unique_monstdat.tsv ui_art/diablo.pal diff --git a/Packaging/resources/assets/txtdata/items/item_prefixes.tsv b/Packaging/resources/assets/txtdata/items/item_prefixes.tsv new file mode 100644 index 000000000..ff47a50a8 --- /dev/null +++ b/Packaging/resources/assets/txtdata/items/item_prefixes.tsv @@ -0,0 +1,87 @@ +name power.type power.param1 power.param2 minLevel itemTypes alignment doubleChance useful minVal maxVal multVal +Tin TOHIT_CURSE 6 10 3 Weapon,Bow,Misc Any true false 0 0 -3 +Brass TOHIT_CURSE 1 5 1 Weapon,Bow,Misc Any true false 0 0 -2 +Bronze TOHIT 1 5 1 Weapon,Bow,Misc Any true true 100 500 2 +Iron TOHIT 6 10 4 Weapon,Bow,Misc Any true true 600 1000 3 +Steel TOHIT 11 15 6 Weapon,Bow,Misc Any true true 1100 1500 5 +Silver TOHIT 16 20 9 Weapon,Bow,Misc Good true true 1600 2000 7 +Gold TOHIT 21 30 12 Weapon,Bow,Misc Good true true 2100 3000 9 +Platinum TOHIT 31 40 16 Weapon,Bow Good true true 3100 4000 11 +Mithril TOHIT 41 60 20 Weapon,Bow Good true true 4100 6000 13 +Meteoric TOHIT 61 80 23 Weapon,Bow Any true true 6100 10000 15 +Weird TOHIT 81 100 35 Weapon,Bow Any true true 10100 14000 17 +Strange TOHIT 101 150 60 Weapon,Bow Any true true 14100 20000 20 +Useless DAMP_CURSE 100 100 5 Weapon,Staff,Bow Any true false 0 0 -8 +Bent DAMP_CURSE 50 75 3 Weapon,Staff,Bow Any true false 0 0 -4 +Weak DAMP_CURSE 25 45 1 Weapon,Staff,Bow Any true false 0 0 -3 +Jagged DAMP 20 35 4 Weapon,Staff,Bow Any true true 250 450 3 +Deadly DAMP 36 50 6 Weapon,Staff,Bow Any true true 500 700 4 +Heavy DAMP 51 65 9 Weapon,Staff,Bow Any true true 750 950 5 +Vicious DAMP 66 80 12 Weapon,Staff,Bow Evil true true 1000 1450 8 +Brutal DAMP 81 95 16 Weapon,Staff,Bow Any true true 1500 1950 10 +Massive DAMP 96 110 20 Weapon,Staff,Bow Any true true 2000 2450 13 +Savage DAMP 111 125 23 Weapon,Bow Any true true 2500 3000 15 +Ruthless DAMP 126 150 35 Weapon,Bow Any true true 10100 15000 17 +Merciless DAMP 151 175 60 Weapon,Bow Any true true 15000 20000 20 +Clumsy TOHIT_DAMP_CURSE 50 75 5 Weapon,Staff,Bow Any true false 0 0 -7 +Dull TOHIT_DAMP_CURSE 25 45 1 Weapon,Staff,Bow Any true false 0 0 -5 +Sharp TOHIT_DAMP 20 35 1 Weapon,Staff,Bow Any true false 350 950 5 +Fine TOHIT_DAMP 36 50 6 Weapon,Staff,Bow Any true true 1100 1700 7 +Warrior's TOHIT_DAMP 51 65 10 Weapon,Staff,Bow Any true true 1850 2450 13 +Soldier's TOHIT_DAMP 66 80 15 Weapon,Staff Any true true 2600 3950 17 +Lord's TOHIT_DAMP 81 95 19 Weapon,Staff Any true true 4100 5950 21 +Knight's TOHIT_DAMP 96 110 23 Weapon,Staff Any true true 6100 8450 26 +Master's TOHIT_DAMP 111 125 28 Weapon,Staff Any true true 8600 13000 30 +Champion's TOHIT_DAMP 126 150 40 Weapon,Staff Any true true 15200 24000 33 +King's TOHIT_DAMP 151 175 28 Weapon,Staff Any true true 24100 35000 38 +Vulnerable ACP_CURSE 51 100 3 Armor,Shield Any true false 0 0 -3 +Rusted ACP_CURSE 25 50 1 Armor,Shield Any true false 0 0 -2 +Fine ACP 20 30 1 Armor,Shield Any true true 20 100 2 +Strong ACP 31 40 3 Armor,Shield Any true true 120 200 3 +Grand ACP 41 55 6 Armor,Shield Any true true 220 300 5 +Valiant ACP 56 70 10 Armor,Shield Any true true 320 400 7 +Glorious ACP 71 90 14 Armor,Shield Good true true 420 600 9 +Blessed ACP 91 110 19 Armor,Shield Good true true 620 800 11 +Saintly ACP 111 130 24 Armor,Shield Good true true 820 1200 13 +Awesome ACP 131 150 28 Armor,Shield Good true true 1220 2000 15 +Holy ACP 151 170 35 Armor,Shield Good true true 5200 6000 17 +Godly ACP 171 200 60 Armor,Shield Good true true 6200 7000 20 +Red FIRERES 10 20 4 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 500 1500 2 +Crimson FIRERES 21 30 10 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 2100 3000 2 +Crimson FIRERES 31 40 16 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 3100 4000 2 +Garnet FIRERES 41 50 20 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 8200 12000 3 +Ruby FIRERES 51 60 26 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 17100 20000 5 +Blue LIGHTRES 10 20 4 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 500 1500 2 +Azure LIGHTRES 21 30 10 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 2100 3000 2 +Lapis LIGHTRES 31 40 16 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 3100 4000 2 +Cobalt LIGHTRES 41 50 20 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 8200 12000 3 +Sapphire LIGHTRES 51 60 26 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 17100 20000 5 +White MAGICRES 10 20 4 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 500 1500 2 +Pearl MAGICRES 21 30 10 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 2100 3000 2 +Ivory MAGICRES 31 40 16 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 3100 4000 2 +Crystal MAGICRES 41 50 20 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 8200 12000 3 +Diamond MAGICRES 51 60 26 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 17100 20000 5 +Topaz ALLRES 10 15 8 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 2000 5000 3 +Amber ALLRES 16 20 12 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 7400 10000 3 +Jade ALLRES 21 30 18 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 11000 15000 3 +Obsidian ALLRES 31 40 24 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 24000 40000 4 +Emerald ALLRES 41 50 31 Shield,Weapon,Staff,Bow Any false true 61000 75000 7 +Hyena's MANA_CURSE 11 25 4 Staff,Misc Any false false 100 1000 -2 +Frog's MANA_CURSE 1 10 1 Staff,Misc Evil false false 0 0 -2 +Spider's MANA 10 15 1 Staff,Misc Evil false true 500 1000 2 +Raven's MANA 15 20 5 Staff,Misc Any false true 1100 2000 3 +Snake's MANA 21 30 9 Staff,Misc Any false true 2100 4000 5 +Serpent's MANA 30 40 15 Staff,Misc Any false true 4100 6000 7 +Drake's MANA 41 50 21 Staff,Misc Any false true 6100 10000 9 +Dragon's MANA 51 60 27 Staff,Misc Any false true 10100 15000 11 +Wyrm's MANA 61 80 35 Staff Any false true 15100 19000 12 +Hydra's MANA 81 100 60 Staff Any false true 19100 30000 13 +Angel's SPLLVLADD 1 1 15 Staff Good false true 25000 25000 2 +Arch-Angel's SPLLVLADD 2 2 25 Staff Good false true 50000 50000 3 +Plentiful CHARGES 2 2 4 Staff Any false true 2000 2000 2 +Bountiful CHARGES 3 3 9 Staff Any false true 3000 3000 3 +Flaming FIREDAM 1 10 7 Weapon,Staff Any false true 5000 5000 2 +Lightning LIGHTDAM 2 20 18 Weapon,Staff Any false true 10000 10000 2 +Jester's JESTERS 1 1 7 Weapon Any false true 1200 1200 3 +Crystalline CRYSTALLINE 30 70 5 Weapon Any false true 1000 3000 3 +Doppelganger's DOPPELGANGER 81 95 11 Weapon,Staff Any false true 2000 2400 10 diff --git a/Packaging/resources/assets/txtdata/items/item_suffixes.tsv b/Packaging/resources/assets/txtdata/items/item_suffixes.tsv new file mode 100644 index 000000000..00d2540c2 --- /dev/null +++ b/Packaging/resources/assets/txtdata/items/item_suffixes.tsv @@ -0,0 +1,99 @@ +name power.type power.param1 power.param2 minLevel itemTypes alignment doubleChance useful minVal maxVal multVal +quality DAMMOD 1 2 2 Weapon,Staff,Bow Any false true 100 200 2 +maiming DAMMOD 3 5 7 Weapon,Staff,Bow Any false true 1300 1500 3 +slaying DAMMOD 6 8 15 Weapon Any false true 2600 3000 5 +gore DAMMOD 9 12 25 Weapon Any false true 4100 5000 8 +carnage DAMMOD 13 16 35 Weapon Any false true 5100 10000 10 +slaughter DAMMOD 17 20 60 Weapon Any false true 10100 15000 13 +pain GETHIT_CURSE 2 4 4 Armor,Shield,Misc Evil false false 0 0 -4 +tears GETHIT_CURSE 1 1 2 Armor,Shield,Misc Evil false false 0 0 -2 +health GETHIT 1 1 2 Armor,Shield,Misc Good false true 200 200 2 +protection GETHIT 2 2 6 Armor,Shield Good false true 400 800 4 +absorption GETHIT 3 3 12 Armor,Shield Good false true 1001 2500 10 +deflection GETHIT 4 4 20 Armor Good false true 2500 6500 15 +osmosis GETHIT 5 6 50 Armor Good false true 7500 10000 20 +frailty STR_CURSE 6 10 3 Armor,Shield,Weapon,Bow,Misc Evil false false 0 0 -3 +weakness STR_CURSE 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -2 +strength STR 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 200 1000 2 +might STR 6 10 5 Armor,Shield,Weapon,Bow,Misc Any false true 1200 2000 3 +power STR 11 15 11 Armor,Shield,Weapon,Bow,Misc Any false true 2200 3000 4 +giants STR 16 20 17 Armor,Weapon,Bow,Misc Any false true 3200 5000 7 +titans STR 21 30 23 Weapon,Misc Any false true 5200 10000 10 +paralysis DEX_CURSE 6 10 3 Armor,Shield,Weapon,Bow,Misc Evil false false 0 0 -3 +atrophy DEX_CURSE 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -2 +dexterity DEX 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 200 1000 2 +skill DEX 6 10 5 Armor,Shield,Weapon,Bow,Misc Any false true 1200 2000 3 +accuracy DEX 11 15 11 Armor,Shield,Weapon,Bow,Misc Any false true 2200 3000 4 +precision DEX 16 20 17 Armor,Weapon,Bow,Misc Any false true 3200 5000 7 +perfection DEX 21 30 23 Bow,Misc Any false true 5200 10000 10 +the fool MAG_CURSE 6 10 3 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -3 +dyslexia MAG_CURSE 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -2 +magic MAG 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 200 1000 2 +the mind MAG 6 10 5 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 1200 2000 3 +brilliance MAG 11 15 11 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 2200 3000 4 +sorcery MAG 16 20 17 Armor,Weapon,Staff,Bow,Misc Any false true 3200 5000 7 +wizardry MAG 21 30 23 Staff,Misc Any false true 5200 10000 10 +illness VIT_CURSE 6 10 3 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -3 +disease VIT_CURSE 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -2 +vitality VIT 1 5 1 Armor,Shield,Weapon,Staff,Bow,Misc Good false true 200 1000 2 +zest VIT 6 10 5 Armor,Shield,Weapon,Bow,Misc Good false true 1200 2000 3 +vim VIT 11 15 11 Armor,Shield,Weapon,Bow,Misc Good false true 2200 3000 4 +vigor VIT 16 20 17 Armor,Weapon,Bow,Misc Good false true 3200 5000 7 +life VIT 21 30 23 Misc Good false true 5200 10000 10 +trouble ATTRIBS_CURSE 6 10 12 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -10 +the pit ATTRIBS_CURSE 1 5 5 Armor,Shield,Weapon,Staff,Bow,Misc Evil false false 0 0 -5 +the sky ATTRIBS 1 3 5 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 800 4000 5 +the moon ATTRIBS 4 7 11 Armor,Shield,Weapon,Staff,Bow,Misc Any false true 4800 8000 10 +the stars ATTRIBS 8 11 17 Armor,Weapon,Bow,Misc Any false true 8800 12000 15 +the heavens ATTRIBS 12 15 25 Weapon,Bow,Misc Any false true 12800 20000 20 +the zodiac ATTRIBS 16 20 30 Misc Any false true 20800 40000 30 +the vulture LIFE_CURSE 11 25 4 Armor,Shield,Misc Evil false false 0 0 -4 +the jackal LIFE_CURSE 1 10 1 Armor,Shield,Misc Evil false false 0 0 -2 +the fox LIFE 10 15 1 Armor,Shield,Misc Any false true 100 1000 2 +the jaguar LIFE 16 20 5 Armor,Shield,Misc Any false true 1100 2000 3 +the eagle LIFE 21 30 9 Armor,Shield,Misc Any false true 2100 4000 5 +the wolf LIFE 30 40 15 Armor,Shield,Misc Any false true 4100 6000 7 +the tiger LIFE 41 50 21 Armor,Shield,Misc Any false true 6100 10000 9 +the lion LIFE 51 60 27 Armor,Misc Any false true 10100 15000 11 +the mammoth LIFE 61 80 35 Armor Any false true 15100 19000 12 +the whale LIFE 81 100 60 Armor Any false true 19100 30000 13 +fragility DUR_CURSE 100 100 3 Armor,Shield,Weapon Evil false false 0 0 -4 +brittleness DUR_CURSE 26 75 1 Armor,Shield,Weapon Evil false false 0 0 -2 +sturdiness DUR 26 75 1 Armor,Shield,Weapon,Staff Any false true 100 100 2 +craftsmanship DUR 51 100 6 Armor,Shield,Weapon,Staff Any false true 200 200 2 +structure DUR 101 200 12 Armor,Shield,Weapon,Staff Any false true 300 300 2 +the ages INDESTRUCTIBLE 25 Armor,Shield,Weapon,Staff Any false true 600 600 5 +the dark LIGHT_CURSE 4 4 6 Armor,Weapon,Misc Evil false false 0 0 -3 +the night LIGHT_CURSE 2 2 3 Armor,Weapon,Misc Evil false false 0 0 -2 +light LIGHT 2 2 4 Armor,Weapon,Misc Good false true 750 750 2 +radiance LIGHT 4 4 8 Armor,Weapon,Misc Good false true 1500 1500 3 +flame FIRE_ARROWS 1 3 1 Bow Any false true 2000 2000 2 +fire FIRE_ARROWS 1 6 11 Bow Any false true 4000 4000 4 +burning FIRE_ARROWS 1 16 35 Bow Any false true 6000 6000 6 +shock LIGHT_ARROWS 1 6 13 Bow Any false true 6000 6000 2 +lightning LIGHT_ARROWS 1 10 21 Bow Any false true 8000 8000 4 +thunder LIGHT_ARROWS 1 20 60 Bow Any false true 12000 12000 6 +many DUR 100 100 3 Bow Any false true 750 750 2 +plenty DUR 200 200 7 Bow Any false true 1500 1500 3 +thorns THORNS 1 3 1 Armor,Shield Any false true 500 500 2 +corruption NOMANA 5 Armor,Shield,Weapon Evil false false -1000 -1000 2 +thieves ABSHALFTRAP 11 Armor,Shield,Misc Any false true 1500 1500 2 +the bear KNOCKBACK 5 Weapon,Staff,Bow Evil false true 750 750 2 +the bat STEALMANA 3 3 8 Weapon Any false true 7500 7500 3 +vampires STEALMANA 5 5 19 Weapon Any false true 15000 15000 3 +the leech STEALLIFE 3 3 8 Weapon Any false true 7500 7500 3 +blood STEALLIFE 5 5 19 Weapon Any false true 15000 15000 3 +piercing TARGAC 1 1 1 Weapon,Bow Any false true 1000 1000 3 +puncturing TARGAC 2 2 9 Weapon,Bow Any false true 2000 2000 6 +bashing TARGAC 3 3 17 Weapon Any false true 4000 4000 12 +readiness FASTATTACK 1 1 1 Weapon,Staff,Bow Any false true 2000 2000 2 +swiftness FASTATTACK 2 2 10 Weapon,Staff,Bow Any false true 4000 4000 4 +speed FASTATTACK 3 3 19 Weapon,Staff Any false true 8000 8000 8 +haste FASTATTACK 4 4 27 Weapon,Staff Any false true 16000 16000 16 +balance FASTRECOVER 1 1 1 Armor,Misc Any false true 2000 2000 2 +stability FASTRECOVER 2 2 10 Armor,Misc Any false true 4000 4000 4 +harmony FASTRECOVER 3 3 20 Armor,Misc Any false true 8000 8000 8 +blocking FASTBLOCK 1 1 5 Shield Any false true 4000 4000 4 +devastation DEVASTATION 1 1 1 Weapon,Staff,Bow Any false true 1200 1200 3 +decay DECAY 150 250 1 Weapon,Staff,Bow Any false true 200 200 2 +peril PERIL 1 1 5 Weapon,Staff,Bow Any false true 500 500 1 diff --git a/Packaging/resources/assets/txtdata/items/itemdat.tsv b/Packaging/resources/assets/txtdata/items/itemdat.tsv new file mode 100644 index 000000000..549686937 --- /dev/null +++ b/Packaging/resources/assets/txtdata/items/itemdat.tsv @@ -0,0 +1,169 @@ +id dropRate class equipType cursorGraphic itemType uniqueBaseItem name shortName minMonsterLevel durability minDamage maxDamage minArmor maxArmor minStrength minMagic minDexterity specialEffects miscId spell usable value +IDI_GOLD Regular Gold Unequippable GOLD Gold NONE Gold 1 0 0 0 0 0 0 0 0 NONE Null true 0 +IDI_WARRIOR Never Weapon One-handed SHORT_SWORD Sword NONE Short Sword 2 20 2 6 0 0 18 0 0 NONE Null false 50 +IDI_WARRSHLD Never Armor One-handed BUCKLER Shield NONE Buckler 2 10 0 0 3 3 0 0 0 NONE Null false 50 +IDI_WARRCLUB Never Weapon One-handed CLUB Mace SPIKCLUB Club 1 20 1 6 0 0 0 0 0 NONE Null false 20 +IDI_ROGUE Never Weapon Two-handed SHORT_BOW Bow NONE Short Bow 1 30 1 4 0 0 0 0 0 NONE Null false 100 +IDI_SORCERER Never Weapon Two-handed SHORT_STAFF Staff NONE Short Staff of Mana 1 25 2 4 0 0 0 20 0 STAFF Mana false 520 +IDI_CLEAVER Never Weapon Two-handed CLEAVER Axe CLEAVER Cleaver 10 10 4 24 0 0 0 0 0 UNIQUE Null false 2000 +IDI_SKCROWN Never Armor Helm THE_UNDEAD_CROWN Helm SKCROWN The Undead Crown 0 50 0 0 15 15 0 0 0 RandomStealLife UNIQUE Null false 10000 +IDI_INFRARING Never Misc Ring EMPYREAN_BAND Ring INFRARING Empyrean Band 0 0 0 0 0 0 0 0 0 UNIQUE Null false 8000 +IDI_ROCK Never Quest Unequippable MAGIC_ROCK Misc NONE Magic Rock 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_OPTAMULET Never Misc Amulet OPTIC_AMULET Amulet OPTAMULET Optic Amulet 0 0 0 0 0 0 0 0 0 UNIQUE Null false 5000 +IDI_TRING Never Misc Ring RING_OF_TRUTH Ring TRING Ring of Truth 0 0 0 0 0 0 0 0 0 UNIQUE Null false 1000 +IDI_BANNER Never Quest Unequippable TAVERN_SIGN Misc NONE Tavern Sign 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_HARCREST Never Armor Helm HARLEQUIN_CREST Helm HARCREST Harlequin Crest 0 15 0 0 0 0 0 0 0 UNIQUE Null false 15 +IDI_STEELVEIL Never Armor Helm VIEL_OF_STEEL Helm STEELVEIL Veil of Steel 0 60 0 0 18 18 0 0 0 UNIQUE Null false 0 +IDI_GLDNELIX Never Misc Unequippable GOLDEN_ELIXIR Misc ELIXIR Golden Elixir 15 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_ANVIL Never Quest Unequippable ANVIL_OF_FURY Misc NONE Anvil of Fury 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_MUSHROOM Never Quest Unequippable BLACK_MUSHROOM Misc NONE Black Mushroom 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_BRAIN Never Quest Unequippable BRAIN Misc NONE Brain 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_FUNGALTM Never Quest Unequippable FUNGAL_TOME Misc NONE Fungal Tome 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_SPECELIX Never Misc Unequippable SPECTRAL_ELIXIR Misc ELIXIR Spectral Elixir 15 0 0 0 0 0 0 0 0 SPECELIX Null true 0 +IDI_BLDSTONE Never Quest Unequippable BLOOD_STONE Misc NONE Blood Stone 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_MAPOFDOOM Never Quest Unequippable MAP_OF_THE_STARS Misc MAPOFDOOM Cathedral Map 0 0 0 0 0 0 0 0 0 MAPOFDOOM Null true 0 +IDI_EAR Never Quest Unequippable EAR_SORCERER Misc NONE Heart 0 0 0 0 0 0 0 0 0 EAR Null false 0 +IDI_HEAL Never Misc Unequippable POTION_OF_HEALING Misc NONE Potion of Healing 0 0 0 0 0 0 0 0 0 HEAL Null true 50 +IDI_MANA Never Misc Unequippable POTION_OF_MANA Misc NONE Potion of Mana 0 0 0 0 0 0 0 0 0 MANA Null true 50 +IDI_IDENTIFY Never Misc Unequippable SCROLL_OF Misc NONE Scroll of Identify 1 0 0 0 0 0 0 0 0 SCROLL Identify true 200 +IDI_PORTAL Never Misc Unequippable SCROLL_OF Misc NONE Scroll of Town Portal 4 0 0 0 0 0 0 0 0 SCROLL TownPortal true 200 +IDI_ARMOFVAL Never Armor Armor ARKAINES_VALOR MediumArmor ARMOFVAL Arkaine's Valor 0 40 0 0 0 0 0 0 0 UNIQUE Null false 0 +IDI_FULLHEAL Never Misc Unequippable POTION_OF_FULL_HEALING Misc NONE Potion of Full Healing 1 0 0 0 0 0 0 0 0 FULLHEAL Null true 150 +IDI_FULLMANA Never Misc Unequippable POTION_OF_FULL_MANA Misc NONE Potion of Full Mana 1 0 0 0 0 0 0 0 0 FULLMANA Null true 150 +IDI_GRISWOLD Never Weapon One-handed BROAD_SWORD Sword GRISWOLD Griswold's Edge 8 50 4 12 0 0 40 0 0 UNIQUE Null false 750 +IDI_LGTFORGE Never Armor Armor BOVINE HeavyArmor BOVINE Bovine Plate 0 40 0 0 0 0 50 0 0 UNIQUE Null false 0 +IDI_LAZSTAFF Never Misc Unequippable STAFF_OF_LAZARUS Misc LAZSTAFF Staff of Lazarus 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_RESURRECT Never Misc Unequippable SCROLL_OF Misc NONE Scroll of Resurrect 1 0 0 0 0 0 0 0 0 SCROLLT Resurrect true 250 +IDI_OIL Never Misc Unequippable OIL Misc NONE Blacksmith Oil 1 0 0 0 0 0 0 0 0 OILBSMTH Null true 100 +IDI_SHORTSTAFF Never Weapon Two-handed SHORT_STAFF Staff NONE Short Staff 1 25 2 4 0 0 0 0 0 NONE Null false 20 +IDI_BARDSWORD Never Weapon One-handed SHORT_SWORD Sword NONE Sword 2 8 1 5 0 0 15 0 20 NONE Null false 20 +IDI_BARDDAGGER Never Weapon One-handed DAGGER Sword NONE Dagger 1 16 1 4 0 0 0 0 0 NONE Null false 20 +IDI_RUNEBOMB Never Quest Unequippable RUNE_BOMB Misc NONE Rune Bomb 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_THEODORE Never Quest Unequippable THEODORE Misc NONE Theodore 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_AURIC Never Misc Amulet AURIC_AMULET Misc NONE Auric Amulet 0 0 0 0 0 0 0 0 0 AURIC Null false 100 +IDI_NOTE1 Never Quest Unequippable TORN_NOTE_1 Misc NONE Torn Note 1 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_NOTE2 Never Quest Unequippable TORN_NOTE_2 Misc NONE Torn Note 2 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_NOTE3 Never Quest Unequippable TORN_NOTE_3 Misc NONE Torn Note 3 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_FULLNOTE Never Quest Unequippable RECONSTRUCTED_NOTE Misc NONE Reconstructed Note 0 0 0 0 0 0 0 0 0 NOTE Null true 0 +IDI_BROWNSUIT Never Quest Unequippable BROWN_SUIT Misc NONE Brown Suit 0 0 0 0 0 0 0 0 0 NONE Null false 0 +IDI_GREYSUIT Never Quest Unequippable GREY_SUIT Misc NONE Grey Suit 0 0 0 0 0 0 0 0 0 NONE Null false 0 + Regular Armor Helm CAP Helm NONE Cap Cap 1 15 0 0 1 3 0 0 0 NONE Null false 15 + Regular Armor Helm SKULL_CAP Helm SKULLCAP Skull Cap Cap 4 20 0 0 2 4 0 0 0 NONE Null false 25 + Regular Armor Helm HELM Helm HELM Helm Helm 8 30 0 0 4 6 25 0 0 NONE Null false 40 + Regular Armor Helm FULL_HELM Helm NONE Full Helm Helm 12 35 0 0 6 8 35 0 0 NONE Null false 90 + Regular Armor Helm CROWN Helm CROWN Crown Crown 16 40 0 0 8 12 0 0 0 NONE Null false 200 + Regular Armor Helm GREAT_HELM Helm GREATHELM Great Helm Helm 20 60 0 0 10 15 50 0 0 NONE Null false 400 + Regular Armor Armor CAPE LightArmor CAPE Cape Cape 1 12 0 0 1 5 0 0 0 NONE Null false 10 + Regular Armor Armor RAGS LightArmor RAGS Rags Rags 1 6 0 0 2 6 0 0 0 NONE Null false 5 + Regular Armor Armor CLOAK LightArmor CLOAK Cloak Cloak 2 18 0 0 3 7 0 0 0 NONE Null false 40 + Regular Armor Armor ROBE LightArmor ROBE Robe Robe 3 24 0 0 4 7 0 0 0 NONE Null false 75 + Regular Armor Armor QUILTED_ARMOR LightArmor NONE Quilted Armor Armor 4 30 0 0 7 10 0 0 0 NONE Null false 200 + Regular Armor Armor LEATHER_ARMOR LightArmor LEATHARMOR Leather Armor Armor 6 35 0 0 10 13 0 0 0 NONE Null false 300 + Regular Armor Armor HARD_LEATHER_ARMOR LightArmor NONE Hard Leather Armor Armor 7 40 0 0 11 14 0 0 0 NONE Null false 450 + Regular Armor Armor STUDDED_LEATHER_ARMOR LightArmor STUDARMOR Studded Leather Armor Armor 9 45 0 0 15 17 20 0 0 NONE Null false 700 + Regular Armor Armor RING_MAIL MediumArmor NONE Ring Mail Mail 11 50 0 0 17 20 25 0 0 NONE Null false 900 + Regular Armor Armor CHAIN_MAIL MediumArmor CHAINMAIL Chain Mail Mail 13 55 0 0 18 22 30 0 0 NONE Null false 1250 + Regular Armor Armor SCALE_MAIL MediumArmor NONE Scale Mail Mail 15 60 0 0 23 28 35 0 0 NONE Null false 2300 + Regular Armor Armor BREAST_PLATE HeavyArmor BREASTPLATE Breast Plate Plate 16 80 0 0 20 24 40 0 0 NONE Null false 2800 + Regular Armor Armor SPLINT_MAIL MediumArmor NONE Splint Mail Mail 17 65 0 0 30 35 40 0 0 NONE Null false 3250 + Regular Armor Armor FIELD_PLATE HeavyArmor PLATEMAIL Plate Mail Plate 19 75 0 0 42 50 60 0 0 NONE Null false 4600 + Regular Armor Armor FIELD_PLATE HeavyArmor NONE Field Plate Plate 21 80 0 0 40 45 65 0 0 NONE Null false 5800 + Regular Armor Armor GOTHIC_PLATE HeavyArmor NONE Gothic Plate Plate 23 100 0 0 50 60 80 0 0 NONE Null false 8000 + Regular Armor Armor FULL_PLATE_MAIL HeavyArmor FULLPLATE Full Plate Mail Plate 25 90 0 0 60 75 90 0 0 NONE Null false 6500 + Regular Armor One-handed BUCKLER Shield BUCKLER Buckler Shield 1 16 0 0 1 5 0 0 0 NONE Null false 30 + Regular Armor One-handed SMALL_SHIELD Shield SMALLSHIELD Small Shield Shield 5 24 0 0 3 8 25 0 0 NONE Null false 90 + Regular Armor One-handed LARGE_SHIELD Shield LARGESHIELD Large Shield Shield 9 32 0 0 5 10 40 0 0 NONE Null false 200 + Regular Armor One-handed KITE_SHIELD Shield KITESHIELD Kite Shield Shield 14 40 0 0 8 15 50 0 0 NONE Null false 400 + Regular Armor One-handed TOWER_SHIELD Shield GOTHSHIELD Tower Shield Shield 20 50 0 0 12 20 60 0 0 NONE Null false 850 + Regular Armor One-handed GOTHIC_SHIELD Shield GOTHSHIELD Gothic Shield Shield 23 60 0 0 14 18 80 0 0 NONE Null false 2300 + Regular Misc Unequippable POTION_OF_HEALING Misc NONE Potion of Healing 1 0 0 0 0 0 0 0 0 HEAL Null true 50 + Regular Misc Unequippable POTION_OF_FULL_HEALING Misc NONE Potion of Full Healing 1 0 0 0 0 0 0 0 0 FULLHEAL Null true 150 + Regular Misc Unequippable POTION_OF_MANA Misc NONE Potion of Mana 1 0 0 0 0 0 0 0 0 MANA Null true 50 + Regular Misc Unequippable POTION_OF_FULL_MANA Misc NONE Potion of Full Mana 1 0 0 0 0 0 0 0 0 FULLMANA Null true 150 + Regular Misc Unequippable POTION_OF_REJUVENATION Misc NONE Potion of Rejuvenation 3 0 0 0 0 0 0 0 0 REJUV Null true 120 + Regular Misc Unequippable POTION_OF_FULL_REJUVENATION Misc NONE Potion of Full Rejuvenation 7 0 0 0 0 0 0 0 0 FULLREJUV Null true 600 + Regular Misc Unequippable OIL Misc NONE Blacksmith Oil 1 0 0 0 0 0 0 0 0 OILBSMTH Null true 100 + Regular Misc Unequippable OIL Misc NONE Oil of Accuracy 1 0 0 0 0 0 0 0 0 OILACC Null true 500 + Regular Misc Unequippable OIL Misc NONE Oil of Sharpness 1 0 0 0 0 0 0 0 0 OILSHARP Null true 500 + Regular Misc Unequippable OIL Misc NONE Oil 10 0 0 0 0 0 0 0 0 OILOF Null true 0 + Regular Misc Unequippable ELIXIR_OF_STRENGTH Misc NONE Elixir of Strength 15 0 0 0 0 0 0 0 0 ELIXSTR Null true 5000 + Regular Misc Unequippable ELIXIR_OF_MAGIC Misc NONE Elixir of Magic 15 0 0 0 0 0 0 0 0 ELIXMAG Null true 5000 + Regular Misc Unequippable ELIXIR_OF_DEXTERITY Misc NONE Elixir of Dexterity 15 0 0 0 0 0 0 0 0 ELIXDEX Null true 5000 + Regular Misc Unequippable ELIXIR_OF_VITALITY Misc NONE Elixir of Vitality 20 0 0 0 0 0 0 0 0 ELIXVIT Null true 5000 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Healing 1 0 0 0 0 0 0 0 0 SCROLL Healing true 50 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Search 1 0 0 0 0 0 0 0 0 SCROLL Search true 50 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Lightning 4 0 0 0 0 0 0 0 0 SCROLLT Lightning true 150 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Identify 1 0 0 0 0 0 0 0 0 SCROLL Identify true 100 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Resurrect 1 0 0 0 0 0 0 0 0 SCROLLT Resurrect true 250 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Fire Wall 4 0 0 0 0 0 0 17 0 SCROLLT FireWall true 400 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Inferno 1 0 0 0 0 0 0 19 0 SCROLLT Inferno true 100 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Town Portal 4 0 0 0 0 0 0 0 0 SCROLL TownPortal true 200 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Flash 6 0 0 0 0 0 0 21 0 SCROLLT Flash true 500 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Infravision 8 0 0 0 0 0 0 23 0 SCROLL Infravision true 600 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Phasing 6 0 0 0 0 0 0 25 0 SCROLL Phasing true 200 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Mana Shield 8 0 0 0 0 0 0 0 0 SCROLL ManaShield true 1200 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Flame Wave 10 0 0 0 0 0 0 29 0 SCROLLT FlameWave true 650 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Fireball 8 0 0 0 0 0 0 31 0 SCROLLT Fireball true 300 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Stone Curse 6 0 0 0 0 0 0 33 0 SCROLLT StoneCurse true 800 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Chain Lightning 10 0 0 0 0 0 0 35 0 SCROLLT ChainLightning true 750 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Guardian 12 0 0 0 0 0 0 47 0 SCROLLT Guardian true 950 + Never Misc Unequippable SCROLL_OF Misc NONE Non Item 0 0 0 0 0 0 0 0 0 NONE Null false 0 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Nova 14 0 0 0 0 0 0 57 0 SCROLL Nova true 1300 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Golem 10 0 0 0 0 0 0 51 0 SCROLLT Golem true 1100 + Never Misc Unequippable SCROLL_OF Misc NONE Scroll of None 99 0 0 0 0 0 0 61 0 SCROLLT Null true 1000 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Teleport 14 0 0 0 0 0 0 81 0 SCROLL Teleport true 3000 + Regular Misc Unequippable SCROLL_OF Misc NONE Scroll of Apocalypse 22 0 0 0 0 0 0 117 0 SCROLL Apocalypse true 2000 + Regular Misc Unequippable BOOK_BLUE Misc NONE Book of 2 0 0 0 0 0 0 0 0 BOOK Null true 0 + Regular Misc Unequippable BOOK_BLUE Misc NONE Book of 8 0 0 0 0 0 0 0 0 BOOK Null true 0 + Regular Misc Unequippable BOOK_BLUE Misc NONE Book of 14 0 0 0 0 0 0 0 0 BOOK Null true 0 + Regular Misc Unequippable BOOK_BLUE Misc NONE Book of 20 0 0 0 0 0 0 0 0 BOOK Null true 0 + Regular Weapon One-handed DAGGER Sword DAGGER Dagger Dagger 1 16 1 4 0 0 0 0 0 NONE Null false 60 + Regular Weapon One-handed SHORT_SWORD Sword NONE Short Sword Sword 1 24 2 6 0 0 18 0 0 NONE Null false 120 + Regular Weapon One-handed FALCHION Sword FALCHION Falchion Sword 2 20 4 8 0 0 30 0 0 NONE Null false 250 + Regular Weapon One-handed SCIMITAR Sword SCIMITAR Scimitar Sword 4 28 3 7 0 0 23 0 23 NONE Null false 200 + Regular Weapon One-handed CLAYMORE Sword CLAYMORE Claymore Sword 5 36 1 12 0 0 35 0 0 NONE Null false 450 + Regular Weapon One-handed BLADE Sword NONE Blade Blade 4 30 3 8 0 0 25 0 30 NONE Null false 280 + Regular Weapon One-handed SABRE Sword SABRE Sabre Sabre 1 45 1 8 0 0 17 0 0 NONE Null false 170 + Regular Weapon One-handed LONG_SWORD Sword LONGSWR Long Sword Sword 6 40 2 10 0 0 30 0 30 NONE Null false 350 + Regular Weapon One-handed BROAD_SWORD Sword BROADSWR Broad Sword Sword 8 50 4 12 0 0 40 0 0 NONE Null false 750 + Regular Weapon One-handed BASTARD_SWORD Sword BASTARDSWR Bastard Sword Sword 10 60 6 15 0 0 50 0 0 NONE Null false 1000 + Regular Weapon Two-handed TWO_HANDED_SWORD Sword TWOHANDSWR Two-Handed Sword Sword 14 75 8 16 0 0 65 0 0 NONE Null false 1800 + Regular Weapon Two-handed GREAT_SWORD Sword GREATSWR Great Sword Sword 17 100 10 20 0 0 75 0 0 NONE Null false 3000 + Regular Weapon Two-handed SMALL_AXE Axe SMALLAXE Small Axe Axe 2 24 2 10 0 0 0 0 0 NONE Null false 150 + Regular Weapon Two-handed AXE Axe NONE Axe Axe 4 32 4 12 0 0 22 0 0 NONE Null false 450 + Regular Weapon Two-handed LARGE_AXE Axe LARGEAXE Large Axe Axe 6 40 6 16 0 0 30 0 0 NONE Null false 750 + Regular Weapon Two-handed BROAD_AXE Axe BROADAXE Broad Axe Axe 8 50 8 20 0 0 50 0 0 NONE Null false 1000 + Regular Weapon Two-handed BATTLE_AXE Axe BATTLEAXE Battle Axe Axe 10 60 10 25 0 0 65 0 0 NONE Null false 1500 + Regular Weapon Two-handed GREAT_AXE Axe GREATAXE Great Axe Axe 12 75 12 30 0 0 80 0 0 NONE Null false 2500 + Regular Weapon One-handed MACE Mace MACE Mace Mace 2 32 1 8 0 0 16 0 0 NONE Null false 200 + Regular Weapon One-handed MORNING_STAR Mace MORNSTAR Morning Star Mace 3 40 1 10 0 0 26 0 0 NONE Null false 300 + Regular Weapon One-handed WAR_HAMMER Mace WARHAMMER War Hammer Hammer 5 50 5 9 0 0 40 0 0 NONE Null false 600 + Regular Weapon One-handed SPIKED_CLUB Mace SPIKCLUB Spiked Club Club 4 20 3 6 0 0 18 0 0 NONE Null false 225 + Regular Weapon One-handed CLUB Mace SPIKCLUB Club Club 1 20 1 6 0 0 0 0 0 NONE Null false 20 + Regular Weapon One-handed FLAIL Mace FLAIL Flail Flail 7 36 2 12 0 0 30 0 0 NONE Null false 500 + Regular Weapon Two-handed MAUL Mace MAUL Maul Maul 10 50 6 20 0 0 55 0 0 NONE Null false 900 + Double Weapon Two-handed SHORT_BOW Bow SHORTBOW Short Bow Bow 1 30 1 4 0 0 0 0 0 NONE Null false 100 + Double Weapon Two-handed HUNTERS_BOW Bow HUNTBOW Hunter's Bow Bow 3 40 2 5 0 0 20 0 35 NONE Null false 350 + Double Weapon Two-handed HUNTERS_BOW Bow LONGBOW Long Bow Bow 5 35 1 6 0 0 25 0 30 NONE Null false 250 + Double Weapon Two-handed COMPOSITE_BOW Bow COMPBOW Composite Bow Bow 7 45 3 6 0 0 25 0 40 NONE Null false 600 + Double Weapon Two-handed SHORT_BATTLE_BOW Bow NONE Short Battle Bow Bow 9 45 3 7 0 0 30 0 50 NONE Null false 750 + Double Weapon Two-handed LONG_BATTLE_BOW Bow BATTLEBOW Long Battle Bow Bow 11 50 1 10 0 0 30 0 60 NONE Null false 1000 + Double Weapon Two-handed SHORT_WAR_BOW Bow NONE Short War Bow Bow 15 55 4 8 0 0 35 0 70 NONE Null false 1500 + Double Weapon Two-handed LONG_WAR_BOW Bow WARBOW Long War Bow Bow 19 60 1 14 0 0 45 0 80 NONE Null false 2000 + Regular Weapon Two-handed SHORT_STAFF Staff SHORTSTAFF Short Staff Staff 1 25 2 4 0 0 0 0 0 STAFF Null false 30 + Regular Weapon Two-handed LONG_STAFF Staff LONGSTAFF Long Staff Staff 4 35 4 8 0 0 0 0 0 STAFF Null false 100 + Regular Weapon Two-handed COMPOSITE_STAFF Staff COMPSTAFF Composite Staff Staff 6 45 5 10 0 0 0 0 0 STAFF Null false 500 + Regular Weapon Two-handed SHORT_STAFF Staff QUARSTAFF Quarter Staff Staff 9 55 6 12 0 0 20 0 0 STAFF Null false 1000 + Regular Weapon Two-handed WAR_STAFF Staff WARSTAFF War Staff Staff 12 75 8 16 0 0 30 0 0 STAFF Null false 1500 + Regular Misc Ring RING Ring RING Ring Ring 5 0 0 0 0 0 0 0 0 RING Null false 1000 + Regular Misc Ring RING Ring RING Ring Ring 10 0 0 0 0 0 0 0 0 RING Null false 1000 + Regular Misc Ring RING Ring RING Ring Ring 15 0 0 0 0 0 0 0 0 RING Null false 1000 + Regular Misc Amulet AMULET Amulet AMULET Amulet Amulet 8 0 0 0 0 0 0 0 0 AMULET Null false 1200 + Regular Misc Amulet AMULET Amulet AMULET Amulet Amulet 16 0 0 0 0 0 0 0 0 AMULET Null false 1200 + Regular Misc Unequippable RUNE_OF_FIRE Misc NONE Rune of Fire Rune 1 0 0 0 0 0 0 0 0 RUNEF Null true 100 + Regular Misc Unequippable RUNE_OF_LIGHTNING Misc NONE Rune of Lightning Rune 3 0 0 0 0 0 0 13 0 RUNEL Null true 200 + Regular Misc Unequippable GREATER_RUNE_OF_FIRE Misc NONE Greater Rune of Fire Rune 7 0 0 0 0 0 0 42 0 GR_RUNEF Null true 400 + Regular Misc Unequippable GREATER_RUNE_OF_LIGHTNING Misc NONE Greater Rune of Lightning Rune 7 0 0 0 0 0 0 42 0 GR_RUNEL Null true 500 + Regular Misc Unequippable RUNE_OF_STONE Misc NONE Rune of Stone Rune 7 0 0 0 0 0 0 25 0 RUNES Null true 300 +IDI_SORCERER Never Weapon Two-handed SHORT_STAFF Staff NONE Short Staff of Charged Bolt 1 25 2 4 0 0 0 20 0 STAFF ChargedBolt false 520 +IDI_ARENAPOT Never Misc Unequippable ARENA_POTION Misc NONE Arena Potion 7 0 0 0 0 0 0 0 0 ARENAPOT Null true 0 diff --git a/Packaging/resources/assets/txtdata/items/unique_itemdat.tsv b/Packaging/resources/assets/txtdata/items/unique_itemdat.tsv new file mode 100644 index 000000000..45965f88e --- /dev/null +++ b/Packaging/resources/assets/txtdata/items/unique_itemdat.tsv @@ -0,0 +1,111 @@ +name uniqueBaseItem minLevel value powers[0].type powers[0].param1 powers[0].param2 powers[1].type powers[1].param1 powers[1].param2 powers[2].type powers[2].param1 powers[2].param2 powers[3].type powers[3].param1 powers[3].param2 powers[4].type powers[4].param1 powers[4].param2 powers[5].type powers[5].param1 powers[5].param2 +The Butcher's Cleaver CLEAVER 1 3650 STR 10 10 SETDAM 4 24 SETDUR 10 10 +The Undead Crown SKCROWN 1 16650 RNDSTEALLIFE SETAC 8 8 INVCURS 77 +Empyrean Band INFRARING 1 8000 ATTRIBS 2 2 LIGHT 2 2 FASTRECOVER 1 1 ABSHALFTRAP +Optic Amulet OPTAMULET 1 9750 LIGHT 2 2 LIGHTRES 20 20 GETHIT 1 1 MAG 5 5 INVCURS 44 +Ring of Truth TRING 1 9100 LIFE 10 10 GETHIT 1 1 ALLRES 10 10 INVCURS 10 +Harlequin Crest HARCREST 1 4000 AC_CURSE 3 3 GETHIT 1 1 ATTRIBS 2 2 LIFE 7 7 MANA 7 7 INVCURS 81 +Veil of Steel STEELVEIL 1 63800 ALLRES 50 50 LIGHT_CURSE 2 2 ACP 60 60 MANA_CURSE 30 30 STR 15 15 VIT 15 15 +Arkaine's Valor ARMOFVAL 1 42000 SETAC 25 25 VIT 10 10 GETHIT 3 3 FASTRECOVER 3 3 +Griswold's Edge GRISWOLD 1 42000 FIREDAM 1 10 TOHIT 25 25 FASTATTACK 2 2 KNOCKBACK MANA 20 20 LIFE_CURSE 20 20 +Bovine Plate BOVINE 1 400 SETAC 150 150 INDESTRUCTIBLE LIGHT 5 5 ALLRES 30 30 MANA_CURSE 50 50 SPLLVLADD -2 -2 +The Rift Bow SHORTBOW 1 1800 RNDARROWVEL DAMMOD 2 2 DEX_CURSE 3 3 +The Needler SHORTBOW 2 8900 TOHIT 50 50 SETDAM 1 3 FASTATTACK 2 2 INVCURS 158 +The Celestial Bow LONGBOW 2 1200 NOMINSTR DAMMOD 2 2 SETAC 5 5 INVCURS 133 +Deadly Hunter COMPBOW 3 8750 3XDAMVDEM 10 10 TOHIT 20 20 MAG_CURSE 5 5 INVCURS 108 +Bow of the Dead COMPBOW 5 2500 TOHIT 10 10 DEX 4 4 VIT_CURSE 3 3 LIGHT_CURSE 2 2 SETDUR 30 30 INVCURS 108 +The Blackoak Bow LONGBOW 5 2500 DEX 10 10 VIT_CURSE 10 10 DAMP 50 50 LIGHT_CURSE 1 1 +Flamedart HUNTBOW 10 14250 FIRE_ARROWS 0 0 FIREDAM 1 6 TOHIT 20 20 FIRERES 40 40 +Fleshstinger LONGBOW 13 16500 DEX 15 15 TOHIT 40 40 DAMP 80 80 DUR 6 6 +Windforce WARBOW 17 37750 STR 5 5 DAMP 200 200 KNOCKBACK INVCURS 164 +Eaglehorn BATTLEBOW 26 42500 DEX 20 20 TOHIT 50 50 DAMP 100 100 INDESTRUCTIBLE INVCURS 108 +Gonnagal's Dirk DAGGER 1 7040 DEX_CURSE 5 5 DAMMOD 4 4 FASTATTACK 2 2 FIRERES 25 25 INVCURS 54 +The Defender SABRE 1 2000 SETAC 5 5 VIT 5 5 TOHIT_CURSE 5 5 +Gryphon's Claw FALCHION 1 1000 DAMP 100 100 MAG_CURSE 2 2 DEX_CURSE 5 5 INVCURS 68 +Black Razor DAGGER 1 2000 DAMP 150 150 VIT 2 2 SETDUR 5 5 INVCURS 53 +Gibbous Moon BROADSWR 2 6660 ATTRIBS 2 2 DAMP 25 25 MANA 15 15 LIGHT_CURSE 3 3 +Ice Shank LONGSWR 3 5250 FIRERES 40 40 SETDUR 15 15 STR 5 10 +The Executioner's Blade FALCHION 3 7080 DAMP 150 150 LIFE_CURSE 10 10 LIGHT_CURSE 1 1 DUR 200 200 INVCURS 58 +The Bonesaw CLAYMORE 6 4400 DAMMOD 10 10 STR 10 10 MAG_CURSE 5 5 DEX_CURSE 5 5 LIFE 10 10 MANA_CURSE 10 10 +Shadowhawk BROADSWR 8 13750 LIGHT_CURSE 2 2 STEALLIFE 5 5 TOHIT 15 15 ALLRES 5 5 +Wizardspike DAGGER 11 12920 MAG 15 15 MANA 35 35 TOHIT 25 25 ALLRES 15 15 INVCURS 50 +Lightsabre SABRE 13 19150 LIGHT 2 2 LIGHTDAM 1 10 TOHIT 20 20 LIGHTRES 50 50 +The Falcon's Talon SCIMITAR 15 7867 FASTATTACK 4 4 TOHIT 20 20 DAMP_CURSE 33 33 DEX 10 10 INVCURS 68 +Inferno LONGSWR 17 34600 FIREDAM 2 12 LIGHT 3 3 MANA 20 20 FIRERES 80 80 +Doombringer BASTARDSWR 19 18250 TOHIT 25 25 DAMP 250 250 ATTRIBS_CURSE 5 5 LIFE_CURSE 25 25 LIGHT_CURSE 2 2 +The Grizzly TWOHANDSWR 23 50000 STR 20 20 VIT_CURSE 5 5 DAMP 200 200 KNOCKBACK DUR 100 100 INVCURS 160 +The Grandfather GREATSWR 27 119800 ONEHAND ATTRIBS 5 5 TOHIT 20 20 DAMP 70 70 LIFE 20 20 INVCURS 161 +The Mangler LARGEAXE 2 2850 DAMP 200 200 DEX_CURSE 5 5 MAG_CURSE 5 5 MANA_CURSE 10 10 INVCURS 144 +Sharp Beak LARGEAXE 2 2850 LIFE 20 20 MAG_CURSE 10 10 MANA_CURSE 10 10 INVCURS 143 +BloodSlayer BROADAXE 3 2500 DAMP 100 100 3XDAMVDEM 50 50 ATTRIBS_CURSE 5 5 SPLLVLADD -1 -1 INVCURS 144 +The Celestial Axe BATTLEAXE 4 14100 NOMINSTR TOHIT 15 15 LIFE 15 15 STR_CURSE 15 15 +Wicked Axe LARGEAXE 5 31150 TOHIT 30 30 DEX 10 10 VIT_CURSE 10 10 GETHIT 1 6 INDESTRUCTIBLE INVCURS 143 +Stonecleaver BROADAXE 7 23900 LIFE 30 30 TOHIT 20 20 DAMP 50 50 LIGHTRES 40 40 INVCURS 104 +Aguinara's Hatchet SMALLAXE 12 24800 SPLLVLADD 1 1 MAG 10 10 MAGICRES 80 80 +Hellslayer BATTLEAXE 15 26200 STR 8 8 VIT 8 8 DAMP 100 100 LIFE 25 25 MANA_CURSE 25 25 +Messerschmidt's Reaver GREATAXE 25 58000 DAMP 200 200 DAMMOD 15 15 ATTRIBS 5 5 LIFE_CURSE 50 50 FIREDAM 2 12 INVCURS 163 +Crackrust MACE 1 11375 ATTRIBS 2 2 INDESTRUCTIBLE ALLRES 15 15 DAMP 50 50 SPLLVLADD -1 -1 +Hammer of Jholm MAUL 1 8700 DAMP 4 10 INDESTRUCTIBLE STR 3 3 TOHIT 15 15 +Civerb's Cudgel MACE 1 2000 3XDAMVDEM 35 35 DEX_CURSE 5 5 MAG_CURSE 2 2 +The Celestial Star FLAIL 2 7810 NOMINSTR LIGHT 2 2 DAMMOD 10 10 AC_CURSE 8 8 INVCURS 131 +Baranar's Star MORNSTAR 5 6850 TOHIT 12 12 DAMP 80 80 FASTATTACK 1 1 VIT 4 4 DEX_CURSE 4 4 SETDUR 60 60 +Gnarled Root SPIKCLUB 9 9820 TOHIT 20 20 DAMP 300 300 DEX 10 10 MAG 5 5 ALLRES 10 10 AC_CURSE 10 10 +The Cranium Basher MAUL 12 36500 DAMMOD 20 20 STR 15 15 INDESTRUCTIBLE MANA_CURSE 150 150 ALLRES 5 5 INVCURS 122 +Schaefer's Hammer WARHAMMER 16 56125 DAMP_CURSE 100 100 LIGHTDAM 1 50 LIFE 50 50 TOHIT 30 30 LIGHTRES 80 80 LIGHT 1 1 +Dreamflange MACE 26 26450 MAG 30 30 MANA 50 50 MAGICRES 50 50 LIGHT 2 2 SPLLVLADD 1 1 +Staff of Shadows LONGSTAFF 2 1250 MAG_CURSE 10 10 TOHIT 10 10 DAMP 60 60 LIGHT_CURSE 2 2 FASTATTACK 1 1 +Immolator LONGSTAFF 4 3900 FIRERES 20 20 FIREDAM 4 4 MANA 10 10 VIT_CURSE 5 5 +Storm Spire WARSTAFF 8 22500 LIGHTRES 50 50 LIGHTDAM 2 8 STR 10 10 MAG_CURSE 10 10 +Gleamsong SHORTSTAFF 8 6520 MANA 25 25 STR_CURSE 3 3 VIT_CURSE 3 3 SPELL 10 76 +Thundercall COMPSTAFF 14 22250 TOHIT 35 35 LIGHTDAM 1 10 SPELL 3 76 LIGHTRES 30 30 LIGHT 2 2 +The Protector SHORTSTAFF 16 17240 VIT 5 5 GETHIT 5 5 SETAC 40 40 SPELL 2 86 THORNS 1 3 INVCURS 162 +Naj's Puzzler LONGSTAFF 18 34000 MAG 20 20 DEX 10 10 ALLRES 20 20 SPELL 23 57 LIFE_CURSE 25 25 +Mindcry QUARSTAFF 20 41500 MAG 15 15 SPELL 13 69 ALLRES 15 15 SPLLVLADD 1 1 +Rod of Onan WARSTAFF 22 44167 SPELL 21 50 DAMP 100 100 ATTRIBS 5 5 +Helm of Spirits HELM 1 7525 STEALLIFE 5 5 INVCURS 77 +Thinking Cap SKULLCAP 6 2020 MANA 30 30 SPLLVLADD 2 2 ALLRES 20 20 SETDUR 1 1 INVCURS 93 +OverLord's Helm HELM 7 12500 STR 20 20 DEX 15 15 VIT 5 5 MAG_CURSE 20 20 SETDUR 15 15 INVCURS 99 +Fool's Crest HELM 12 10150 ATTRIBS_CURSE 4 4 LIFE 100 100 GETHIT_CURSE 1 6 THORNS 1 3 INVCURS 80 +Gotterdamerung GREATHELM 21 54900 ATTRIBS 20 20 SETAC 60 60 GETHIT 4 4 ALLRESZERO LIGHT_CURSE 4 4 INVCURS 85 +Royal Circlet CROWN 27 24875 ATTRIBS 10 10 MANA 40 40 SETAC 40 40 LIGHT 1 1 INVCURS 79 +Torn Flesh of Souls RAGS 2 4825 SETAC 8 8 VIT 10 10 GETHIT 1 1 INDESTRUCTIBLE INVCURS 92 +The Gladiator's Bane STUDARMOR 6 3450 SETAC 25 25 GETHIT 2 2 DUR 200 200 ATTRIBS_CURSE 3 3 +The Rainbow Cloak CLOAK 2 4900 SETAC 10 10 ATTRIBS 1 1 ALLRES 10 10 LIFE 5 5 DUR 50 50 INVCURS 138 +Leather of Aut LEATHARMOR 4 10550 SETAC 15 15 STR 5 5 MAG_CURSE 5 5 DEX 5 5 INDESTRUCTIBLE +Wisdom's Wrap ROBE 5 6200 MAG 5 5 MANA 10 10 LIGHTRES 25 25 SETAC 15 15 GETHIT 1 1 INVCURS 138 +Sparking Mail CHAINMAIL 9 15750 SETAC 30 30 LIGHTDAM 1 10 +Scavenger Carapace BREASTPLATE 13 14000 GETHIT 15 15 AC_CURSE 30 30 DEX 5 5 LIGHTRES 40 40 +Nightscape CAPE 16 11600 FASTRECOVER 2 2 LIGHT_CURSE 4 4 SETAC 15 15 DEX 3 3 ALLRES 20 20 INVCURS 138 +Naj's Light Plate PLATEMAIL 19 78700 NOMINSTR MAG 5 5 MANA 20 20 ALLRES 20 20 SPLLVLADD 1 1 INVCURS 159 +Demonspike Coat FULLPLATE 25 251175 SETAC 100 100 GETHIT 6 6 STR 10 10 INDESTRUCTIBLE FIRERES 50 50 +The Deflector BUCKLER 1 1500 SETAC 7 7 ALLRES 10 10 DAMP_CURSE 20 20 TOHIT_CURSE 5 5 INVCURS 83 +Split Skull Shield BUCKLER 1 2025 SETAC 10 10 LIFE 10 10 STR 2 2 LIGHT_CURSE 1 1 SETDUR 15 15 INVCURS 116 +Dragon's Breach KITESHIELD 2 19200 FIRERES 25 25 STR 5 5 SETAC 20 20 MAG_CURSE 5 5 INDESTRUCTIBLE INVCURS 117 +Blackoak Shield SMALLSHIELD 4 5725 DEX 10 10 VIT_CURSE 10 10 SETAC 18 18 LIGHT_CURSE 1 1 DUR 150 150 INVCURS 146 +Holy Defender LARGESHIELD 10 13800 SETAC 15 15 GETHIT 2 2 FIRERES 20 20 DUR 200 200 FASTBLOCK 1 1 INVCURS 146 +Stormshield GOTHSHIELD 24 49000 SETAC 40 40 GETHIT_CURSE 4 4 STR 10 10 INDESTRUCTIBLE FASTBLOCK 1 1 INVCURS 148 +Bramble RING 1 1000 ATTRIBS_CURSE 2 2 DAMMOD 3 3 MANA 10 10 INVCURS 9 +Ring of Regha RING 1 4175 MAG 10 10 MAGICRES 10 10 LIGHT 1 1 STR_CURSE 3 3 DEX_CURSE 3 3 INVCURS 11 +The Bleeder RING 2 8500 MAGICRES 20 20 MANA 30 30 LIFE_CURSE 10 10 INVCURS 8 +Constricting Ring RING 5 62000 ALLRES 75 75 DRAINLIFE INVCURS 14 +Ring of Engagement RING 11 12476 GETHIT 1 2 THORNS 1 3 SETAC 5 5 TARGAC 2 2 INVCURS 13 +Giant's Knuckle RING 8 8000 STR 60 60 DEX_CURSE 30 30 INVCURS 179 +Mercurial Ring RING 8 8000 DEX 60 60 STR_CURSE 30 30 INVCURS 176 +Xorine's Ring RING 8 8000 MAG 60 60 STR_CURSE 30 30 INVCURS 168 +Karik's Ring RING 8 8000 VIT 60 60 MAG_CURSE 30 30 INVCURS 173 +Ring of Magma RING 8 8000 FIRERES 60 60 LIGHTRES_CURSE 30 30 MAGICRES_CURSE 30 30 INVCURS 184 +Ring of the Mystics RING 8 8000 MAGICRES 60 60 FIRERES_CURSE 30 30 LIGHTRES_CURSE 30 30 INVCURS 181 +Ring of Thunder RING 8 8000 LIGHTRES 60 60 FIRERES_CURSE 30 30 MAGICRES_CURSE 30 30 INVCURS 177 +Amulet of Warding AMULET 12 30000 ALLRES 40 40 LIFE_CURSE 100 100 INVCURS 170 +Gnat Sting HUNTBOW 15 30000 MULT_ARROWS 3 3 SETDAM 1 2 FASTATTACK 1 1 INDESTRUCTIBLE INVCURS 210 +Flambeau COMPBOW 11 30000 FIREBALL 15 20 SETDAM 0 0 INDESTRUCTIBLE INVCURS 209 +Armor of Gloom FULLPLATE 25 200000 NOMINSTR SETAC 225 225 ALLRESZERO LIGHT_CURSE 2 2 INVCURS 203 +Blitzen COMPBOW 13 30000 ADDACLIFE 10 15 SETDAM 0 0 INDESTRUCTIBLE INVCURS 219 +Thunderclap WARHAMMER 13 30000 ADDMANAAC 3 6 STR 20 20 LIGHTRES 30 30 LIGHT 2 2 INDESTRUCTIBLE INVCURS 205 +Shirotachi GREATSWR 21 36000 ONEHAND FASTATTACK 4 4 TARGAC 2 2 LIGHTDAM 6 6 +Eater of Souls TWOHANDSWR 23 42000 INDESTRUCTIBLE LIFE 50 50 STEALLIFE 5 5 STEALMANA 5 5 DRAINLIFE INVCURS 200 +Diamondedge LONGSWR 17 42000 SETDUR 10 10 TOHIT 50 50 DAMP 100 100 LIGHTRES 50 50 SETAC 10 10 INVCURS 206 +Bone Chain Armor CHAINMAIL 13 36000 SETAC 40 40 ACUNDEAD INVCURS 204 +Demon Plate Armor FULLPLATE 25 80000 SETAC 80 80 ACDEMON INVCURS 225 +Acolyte's Amulet AMULET 10 10000 MANATOLIFE 50 50 INVCURS 183 +Gladiator's Ring RING 10 10000 LIFETOMANA 40 40 INVCURS 186 diff --git a/Source/.clang-format b/Source/.clang-format index d30f4466e..024bdf68e 100644 --- a/Source/.clang-format +++ b/Source/.clang-format @@ -1,6 +1,7 @@ BasedOnStyle: webkit AlignTrailingComments: true AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: All AllowShortIfStatementsOnASingleLine: WithoutElse PointerAlignment: Right diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 48e8f2df5..7a64a7dd6 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -2477,6 +2477,7 @@ int DiabloMain(int argc, char **argv) // TODO: We can probably load this much later (when the game is starting). LoadMonsterData(); + LoadItemData(); DiabloInit(); #ifdef __UWP__ diff --git a/Source/itemdat.cpp b/Source/itemdat.cpp index bb95b217f..029ee6a28 100644 --- a/Source/itemdat.cpp +++ b/Source/itemdat.cpp @@ -5,545 +5,875 @@ */ #include "itemdat.h" -#include "utils/language.h" + +#include +#include + +#include + +#include "data/file.hpp" +#include "data/iterators.hpp" +#include "spelldat.h" +#include "utils/str_cat.hpp" namespace devilution { -std::string_view ItemTypeToString(ItemType itemType) +/** Contains the data related to each item ID. */ +std::vector AllItemsList; + +/** Contains the data related to each unique item ID. */ +std::vector UniqueItems; + +/** Contains the data related to each item prefix. */ +std::vector ItemPrefixes; + +/** Contains the data related to each item suffix. */ +std::vector ItemSuffixes; + +namespace { + +tl::expected ParseItemDropRate(std::string_view value) { - switch (itemType) { - case ItemType::Misc: - return "Misc"; - case ItemType::Sword: - return "Sword"; - case ItemType::Axe: - return "Axe"; - case ItemType::Bow: - return "Bow"; - case ItemType::Mace: - return "Mace"; - case ItemType::Shield: - return "Shield"; - case ItemType::LightArmor: - return "LightArmor"; - case ItemType::Helm: - return "Helm"; - case ItemType::MediumArmor: - return "MediumArmor"; - case ItemType::HeavyArmor: - return "HeavyArmor"; - case ItemType::Staff: - return "Staff"; - case ItemType::Gold: - return "Gold"; - case ItemType::Ring: - return "Ring"; - case ItemType::Amulet: - return "Amulet"; - case ItemType::None: - return "None"; + if (value == "Never") return IDROP_NEVER; + if (value == "Regular") return IDROP_REGULAR; + if (value == "Double") return IDROP_DOUBLE; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseItemClass(std::string_view value) +{ + if (value == "None") return ICLASS_NONE; + if (value == "Weapon") return ICLASS_WEAPON; + if (value == "Armor") return ICLASS_ARMOR; + if (value == "Misc") return ICLASS_MISC; + if (value == "Gold") return ICLASS_GOLD; + if (value == "Quest") return ICLASS_QUEST; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseItemEquipType(std::string_view value) +{ + if (value == "None") return ILOC_NONE; + if (value == "One-handed") return ILOC_ONEHAND; + if (value == "Two-handed") return ILOC_TWOHAND; + if (value == "Armor") return ILOC_ARMOR; + if (value == "Helm") return ILOC_HELM; + if (value == "Ring") return ILOC_RING; + if (value == "Amulet") return ILOC_AMULET; + if (value == "Unequippable") return ILOC_UNEQUIPABLE; + if (value == "Belt") return ILOC_BELT; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseItemCursorGraphic(std::string_view value) +{ + if (value == "POTION_OF_FULL_MANA") return ICURS_POTION_OF_FULL_MANA; + if (value == "SCROLL_OF") return ICURS_SCROLL_OF; + if (value == "GOLD_SMALL") return ICURS_GOLD_SMALL; + if (value == "GOLD_MEDIUM") return ICURS_GOLD_MEDIUM; + if (value == "GOLD_LARGE") return ICURS_GOLD_LARGE; + if (value == "RING_OF_TRUTH") return ICURS_RING_OF_TRUTH; + if (value == "RING") return ICURS_RING; + if (value == "SPECTRAL_ELIXIR") return ICURS_SPECTRAL_ELIXIR; + if (value == "ARENA_POTION") return ICURS_ARENA_POTION; + if (value == "GOLDEN_ELIXIR") return ICURS_GOLDEN_ELIXIR; + if (value == "EMPYREAN_BAND") return ICURS_EMPYREAN_BAND; + if (value == "EAR_SORCERER") return ICURS_EAR_SORCERER; + if (value == "EAR_WARRIOR") return ICURS_EAR_WARRIOR; + if (value == "EAR_ROGUE") return ICURS_EAR_ROGUE; + if (value == "BLOOD_STONE") return ICURS_BLOOD_STONE; + if (value == "OIL") return ICURS_OIL; + if (value == "ELIXIR_OF_VITALITY") return ICURS_ELIXIR_OF_VITALITY; + if (value == "POTION_OF_HEALING") return ICURS_POTION_OF_HEALING; + if (value == "POTION_OF_FULL_REJUVENATION") return ICURS_POTION_OF_FULL_REJUVENATION; + if (value == "ELIXIR_OF_MAGIC") return ICURS_ELIXIR_OF_MAGIC; + if (value == "POTION_OF_FULL_HEALING") return ICURS_POTION_OF_FULL_HEALING; + if (value == "ELIXIR_OF_DEXTERITY") return ICURS_ELIXIR_OF_DEXTERITY; + if (value == "POTION_OF_REJUVENATION") return ICURS_POTION_OF_REJUVENATION; + if (value == "ELIXIR_OF_STRENGTH") return ICURS_ELIXIR_OF_STRENGTH; + if (value == "POTION_OF_MANA") return ICURS_POTION_OF_MANA; + if (value == "BRAIN") return ICURS_BRAIN; + if (value == "OPTIC_AMULET") return ICURS_OPTIC_AMULET; + if (value == "AMULET") return ICURS_AMULET; + if (value == "DAGGER") return ICURS_DAGGER; + if (value == "BLADE") return ICURS_BLADE; + if (value == "BASTARD_SWORD") return ICURS_BASTARD_SWORD; + if (value == "MACE") return ICURS_MACE; + if (value == "LONG_SWORD") return ICURS_LONG_SWORD; + if (value == "BROAD_SWORD") return ICURS_BROAD_SWORD; + if (value == "FALCHION") return ICURS_FALCHION; + if (value == "MORNING_STAR") return ICURS_MORNING_STAR; + if (value == "SHORT_SWORD") return ICURS_SHORT_SWORD; + if (value == "CLAYMORE") return ICURS_CLAYMORE; + if (value == "CLUB") return ICURS_CLUB; + if (value == "SABRE") return ICURS_SABRE; + if (value == "SPIKED_CLUB") return ICURS_SPIKED_CLUB; + if (value == "SCIMITAR") return ICURS_SCIMITAR; + if (value == "FULL_HELM") return ICURS_FULL_HELM; + if (value == "MAGIC_ROCK") return ICURS_MAGIC_ROCK; + if (value == "THE_UNDEAD_CROWN") return ICURS_THE_UNDEAD_CROWN; + if (value == "HELM") return ICURS_HELM; + if (value == "BUCKLER") return ICURS_BUCKLER; + if (value == "VIEL_OF_STEEL") return ICURS_VIEL_OF_STEEL; + if (value == "BOOK_GREY") return ICURS_BOOK_GREY; + if (value == "BOOK_RED") return ICURS_BOOK_RED; + if (value == "BOOK_BLUE") return ICURS_BOOK_BLUE; + if (value == "BLACK_MUSHROOM") return ICURS_BLACK_MUSHROOM; + if (value == "SKULL_CAP") return ICURS_SKULL_CAP; + if (value == "CAP") return ICURS_CAP; + if (value == "HARLEQUIN_CREST") return ICURS_HARLEQUIN_CREST; + if (value == "CROWN") return ICURS_CROWN; + if (value == "MAP_OF_THE_STARS") return ICURS_MAP_OF_THE_STARS; + if (value == "FUNGAL_TOME") return ICURS_FUNGAL_TOME; + if (value == "GREAT_HELM") return ICURS_GREAT_HELM; + if (value == "BATTLE_AXE") return ICURS_BATTLE_AXE; + if (value == "HUNTERS_BOW") return ICURS_HUNTERS_BOW; + if (value == "FIELD_PLATE") return ICURS_FIELD_PLATE; + if (value == "SMALL_SHIELD") return ICURS_SMALL_SHIELD; + if (value == "CLEAVER") return ICURS_CLEAVER; + if (value == "STUDDED_LEATHER_ARMOR") return ICURS_STUDDED_LEATHER_ARMOR; + if (value == "SHORT_STAFF") return ICURS_SHORT_STAFF; + if (value == "TWO_HANDED_SWORD") return ICURS_TWO_HANDED_SWORD; + if (value == "CHAIN_MAIL") return ICURS_CHAIN_MAIL; + if (value == "SMALL_AXE") return ICURS_SMALL_AXE; + if (value == "KITE_SHIELD") return ICURS_KITE_SHIELD; + if (value == "SCALE_MAIL") return ICURS_SCALE_MAIL; + if (value == "SHORT_BOW") return ICURS_SHORT_BOW; + if (value == "LONG_BATTLE_BOW") return ICURS_LONG_BATTLE_BOW; + if (value == "LONG_WAR_BOW") return ICURS_LONG_WAR_BOW; + if (value == "WAR_HAMMER") return ICURS_WAR_HAMMER; + if (value == "MAUL") return ICURS_MAUL; + if (value == "LONG_STAFF") return ICURS_LONG_STAFF; + if (value == "WAR_STAFF") return ICURS_WAR_STAFF; + if (value == "TAVERN_SIGN") return ICURS_TAVERN_SIGN; + if (value == "HARD_LEATHER_ARMOR") return ICURS_HARD_LEATHER_ARMOR; + if (value == "RAGS") return ICURS_RAGS; + if (value == "QUILTED_ARMOR") return ICURS_QUILTED_ARMOR; + if (value == "FLAIL") return ICURS_FLAIL; + if (value == "TOWER_SHIELD") return ICURS_TOWER_SHIELD; + if (value == "COMPOSITE_BOW") return ICURS_COMPOSITE_BOW; + if (value == "GREAT_SWORD") return ICURS_GREAT_SWORD; + if (value == "LEATHER_ARMOR") return ICURS_LEATHER_ARMOR; + if (value == "SPLINT_MAIL") return ICURS_SPLINT_MAIL; + if (value == "ROBE") return ICURS_ROBE; + if (value == "ANVIL_OF_FURY") return ICURS_ANVIL_OF_FURY; + if (value == "BROAD_AXE") return ICURS_BROAD_AXE; + if (value == "LARGE_AXE") return ICURS_LARGE_AXE; + if (value == "GREAT_AXE") return ICURS_GREAT_AXE; + if (value == "AXE") return ICURS_AXE; + if (value == "LARGE_SHIELD") return ICURS_LARGE_SHIELD; + if (value == "GOTHIC_SHIELD") return ICURS_GOTHIC_SHIELD; + if (value == "CLOAK") return ICURS_CLOAK; + if (value == "CAPE") return ICURS_CAPE; + if (value == "FULL_PLATE_MAIL") return ICURS_FULL_PLATE_MAIL; + if (value == "GOTHIC_PLATE") return ICURS_GOTHIC_PLATE; + if (value == "BREAST_PLATE") return ICURS_BREAST_PLATE; + if (value == "RING_MAIL") return ICURS_RING_MAIL; + if (value == "STAFF_OF_LAZARUS") return ICURS_STAFF_OF_LAZARUS; + if (value == "ARKAINES_VALOR") return ICURS_ARKAINES_VALOR; + if (value == "SHORT_WAR_BOW") return ICURS_SHORT_WAR_BOW; + if (value == "COMPOSITE_STAFF") return ICURS_COMPOSITE_STAFF; + if (value == "SHORT_BATTLE_BOW") return ICURS_SHORT_BATTLE_BOW; + if (value == "GOLD") return ICURS_GOLD; + if (value == "AURIC_AMULET") return ICURS_AURIC_AMULET; + if (value == "RUNE_BOMB") return ICURS_RUNE_BOMB; + if (value == "THEODORE") return ICURS_THEODORE; + if (value == "TORN_NOTE_1") return ICURS_TORN_NOTE_1; + if (value == "TORN_NOTE_2") return ICURS_TORN_NOTE_2; + if (value == "TORN_NOTE_3") return ICURS_TORN_NOTE_3; + if (value == "RECONSTRUCTED_NOTE") return ICURS_RECONSTRUCTED_NOTE; + if (value == "RUNE_OF_FIRE") return ICURS_RUNE_OF_FIRE; + if (value == "GREATER_RUNE_OF_FIRE") return ICURS_GREATER_RUNE_OF_FIRE; + if (value == "RUNE_OF_LIGHTNING") return ICURS_RUNE_OF_LIGHTNING; + if (value == "GREATER_RUNE_OF_LIGHTNING") return ICURS_GREATER_RUNE_OF_LIGHTNING; + if (value == "RUNE_OF_STONE") return ICURS_RUNE_OF_STONE; + if (value == "GREY_SUIT") return ICURS_GREY_SUIT; + if (value == "BROWN_SUIT") return ICURS_BROWN_SUIT; + if (value == "BOVINE") return ICURS_BOVINE; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseItemType(std::string_view value) +{ + if (value == "Misc") return ItemType::Misc; + if (value == "Sword") return ItemType::Sword; + if (value == "Axe") return ItemType::Axe; + if (value == "Bow") return ItemType::Bow; + if (value == "Mace") return ItemType::Mace; + if (value == "Shield") return ItemType::Shield; + if (value == "LightArmor") return ItemType::LightArmor; + if (value == "Helm") return ItemType::Helm; + if (value == "MediumArmor") return ItemType::MediumArmor; + if (value == "HeavyArmor") return ItemType::HeavyArmor; + if (value == "Staff") return ItemType::Staff; + if (value == "Gold") return ItemType::Gold; + if (value == "Ring") return ItemType::Ring; + if (value == "Amulet") return ItemType::Amulet; + if (value == "None") return ItemType::None; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseUniqueBaseItem(std::string_view value) +{ + if (value == "NONE") return UITYPE_NONE; + if (value == "SHORTBOW") return UITYPE_SHORTBOW; + if (value == "LONGBOW") return UITYPE_LONGBOW; + if (value == "HUNTBOW") return UITYPE_HUNTBOW; + if (value == "COMPBOW") return UITYPE_COMPBOW; + if (value == "WARBOW") return UITYPE_WARBOW; + if (value == "BATTLEBOW") return UITYPE_BATTLEBOW; + if (value == "DAGGER") return UITYPE_DAGGER; + if (value == "FALCHION") return UITYPE_FALCHION; + if (value == "CLAYMORE") return UITYPE_CLAYMORE; + if (value == "BROADSWR") return UITYPE_BROADSWR; + if (value == "SABRE") return UITYPE_SABRE; + if (value == "SCIMITAR") return UITYPE_SCIMITAR; + if (value == "LONGSWR") return UITYPE_LONGSWR; + if (value == "BASTARDSWR") return UITYPE_BASTARDSWR; + if (value == "TWOHANDSWR") return UITYPE_TWOHANDSWR; + if (value == "GREATSWR") return UITYPE_GREATSWR; + if (value == "CLEAVER") return UITYPE_CLEAVER; + if (value == "LARGEAXE") return UITYPE_LARGEAXE; + if (value == "BROADAXE") return UITYPE_BROADAXE; + if (value == "SMALLAXE") return UITYPE_SMALLAXE; + if (value == "BATTLEAXE") return UITYPE_BATTLEAXE; + if (value == "GREATAXE") return UITYPE_GREATAXE; + if (value == "MACE") return UITYPE_MACE; + if (value == "MORNSTAR") return UITYPE_MORNSTAR; + if (value == "SPIKCLUB") return UITYPE_SPIKCLUB; + if (value == "MAUL") return UITYPE_MAUL; + if (value == "WARHAMMER") return UITYPE_WARHAMMER; + if (value == "FLAIL") return UITYPE_FLAIL; + if (value == "LONGSTAFF") return UITYPE_LONGSTAFF; + if (value == "SHORTSTAFF") return UITYPE_SHORTSTAFF; + if (value == "COMPSTAFF") return UITYPE_COMPSTAFF; + if (value == "QUARSTAFF") return UITYPE_QUARSTAFF; + if (value == "WARSTAFF") return UITYPE_WARSTAFF; + if (value == "SKULLCAP") return UITYPE_SKULLCAP; + if (value == "HELM") return UITYPE_HELM; + if (value == "GREATHELM") return UITYPE_GREATHELM; + if (value == "CROWN") return UITYPE_CROWN; + if (value == "RAGS") return UITYPE_RAGS; + if (value == "STUDARMOR") return UITYPE_STUDARMOR; + if (value == "CLOAK") return UITYPE_CLOAK; + if (value == "ROBE") return UITYPE_ROBE; + if (value == "CHAINMAIL") return UITYPE_CHAINMAIL; + if (value == "LEATHARMOR") return UITYPE_LEATHARMOR; + if (value == "BREASTPLATE") return UITYPE_BREASTPLATE; + if (value == "CAPE") return UITYPE_CAPE; + if (value == "PLATEMAIL") return UITYPE_PLATEMAIL; + if (value == "FULLPLATE") return UITYPE_FULLPLATE; + if (value == "BUCKLER") return UITYPE_BUCKLER; + if (value == "SMALLSHIELD") return UITYPE_SMALLSHIELD; + if (value == "LARGESHIELD") return UITYPE_LARGESHIELD; + if (value == "KITESHIELD") return UITYPE_KITESHIELD; + if (value == "GOTHSHIELD") return UITYPE_GOTHSHIELD; + if (value == "RING") return UITYPE_RING; + if (value == "AMULET") return UITYPE_AMULET; + if (value == "SKCROWN") return UITYPE_SKCROWN; + if (value == "INFRARING") return UITYPE_INFRARING; + if (value == "OPTAMULET") return UITYPE_OPTAMULET; + if (value == "TRING") return UITYPE_TRING; + if (value == "HARCREST") return UITYPE_HARCREST; + if (value == "MAPOFDOOM") return UITYPE_MAPOFDOOM; + if (value == "ELIXIR") return UITYPE_ELIXIR; + if (value == "ARMOFVAL") return UITYPE_ARMOFVAL; + if (value == "STEELVEIL") return UITYPE_STEELVEIL; + if (value == "GRISWOLD") return UITYPE_GRISWOLD; + if (value == "LGTFORGE") return UITYPE_LGTFORGE; + if (value == "LAZSTAFF") return UITYPE_LAZSTAFF; + if (value == "BOVINE") return UITYPE_BOVINE; + if (value == "INVALID") return UITYPE_INVALID; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseItemSpecialEffect(std::string_view value) +{ + if (value == "RandomStealLife") return ItemSpecialEffect::RandomStealLife; + if (value == "RandomArrowVelocity") return ItemSpecialEffect::RandomArrowVelocity; + if (value == "FireArrows") return ItemSpecialEffect::FireArrows; + if (value == "FireDamage") return ItemSpecialEffect::FireDamage; + if (value == "LightningDamage") return ItemSpecialEffect::LightningDamage; + if (value == "DrainLife") return ItemSpecialEffect::DrainLife; + if (value == "MultipleArrows") return ItemSpecialEffect::MultipleArrows; + if (value == "Knockback") return ItemSpecialEffect::Knockback; + if (value == "StealMana3") return ItemSpecialEffect::StealMana3; + if (value == "StealMana5") return ItemSpecialEffect::StealMana5; + if (value == "StealLife3") return ItemSpecialEffect::StealLife3; + if (value == "StealLife5") return ItemSpecialEffect::StealLife5; + if (value == "QuickAttack") return ItemSpecialEffect::QuickAttack; + if (value == "FastAttack") return ItemSpecialEffect::FastAttack; + if (value == "FasterAttack") return ItemSpecialEffect::FasterAttack; + if (value == "FastestAttack") return ItemSpecialEffect::FastestAttack; + if (value == "FastHitRecovery") return ItemSpecialEffect::FastHitRecovery; + if (value == "FasterHitRecovery") return ItemSpecialEffect::FasterHitRecovery; + if (value == "FastestHitRecovery") return ItemSpecialEffect::FastestHitRecovery; + if (value == "FastBlock") return ItemSpecialEffect::FastBlock; + if (value == "LightningArrows") return ItemSpecialEffect::LightningArrows; + if (value == "Thorns") return ItemSpecialEffect::Thorns; + if (value == "NoMana") return ItemSpecialEffect::NoMana; + if (value == "HalfTrapDamage") return ItemSpecialEffect::HalfTrapDamage; + if (value == "TripleDemonDamage") return ItemSpecialEffect::TripleDemonDamage; + if (value == "ZeroResistance") return ItemSpecialEffect::ZeroResistance; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseItemMiscId(std::string_view value) +{ + if (value == "NONE") return IMISC_NONE; + if (value == "USEFIRST") return IMISC_USEFIRST; + if (value == "FULLHEAL") return IMISC_FULLHEAL; + if (value == "HEAL") return IMISC_HEAL; + if (value == "MANA") return IMISC_MANA; + if (value == "FULLMANA") return IMISC_FULLMANA; + if (value == "ELIXSTR") return IMISC_ELIXSTR; + if (value == "ELIXMAG") return IMISC_ELIXMAG; + if (value == "ELIXDEX") return IMISC_ELIXDEX; + if (value == "ELIXVIT") return IMISC_ELIXVIT; + if (value == "REJUV") return IMISC_REJUV; + if (value == "FULLREJUV") return IMISC_FULLREJUV; + if (value == "USELAST") return IMISC_USELAST; + if (value == "SCROLL") return IMISC_SCROLL; + if (value == "SCROLLT") return IMISC_SCROLLT; + if (value == "STAFF") return IMISC_STAFF; + if (value == "BOOK") return IMISC_BOOK; + if (value == "RING") return IMISC_RING; + if (value == "AMULET") return IMISC_AMULET; + if (value == "UNIQUE") return IMISC_UNIQUE; + if (value == "OILFIRST") return IMISC_OILFIRST; + if (value == "OILOF") return IMISC_OILOF; + if (value == "OILACC") return IMISC_OILACC; + if (value == "OILMAST") return IMISC_OILMAST; + if (value == "OILSHARP") return IMISC_OILSHARP; + if (value == "OILDEATH") return IMISC_OILDEATH; + if (value == "OILSKILL") return IMISC_OILSKILL; + if (value == "OILBSMTH") return IMISC_OILBSMTH; + if (value == "OILFORT") return IMISC_OILFORT; + if (value == "OILPERM") return IMISC_OILPERM; + if (value == "OILHARD") return IMISC_OILHARD; + if (value == "OILIMP") return IMISC_OILIMP; + if (value == "OILLAST") return IMISC_OILLAST; + if (value == "MAPOFDOOM") return IMISC_MAPOFDOOM; + if (value == "EAR") return IMISC_EAR; + if (value == "SPECELIX") return IMISC_SPECELIX; + if (value == "RUNEFIRST") return IMISC_RUNEFIRST; + if (value == "RUNEF") return IMISC_RUNEF; + if (value == "RUNEL") return IMISC_RUNEL; + if (value == "GR_RUNEL") return IMISC_GR_RUNEL; + if (value == "GR_RUNEF") return IMISC_GR_RUNEF; + if (value == "RUNES") return IMISC_RUNES; + if (value == "RUNELAST") return IMISC_RUNELAST; + if (value == "AURIC") return IMISC_AURIC; + if (value == "NOTE") return IMISC_NOTE; + if (value == "ARENAPOT") return IMISC_ARENAPOT; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseItemEffectType(std::string_view value) +{ + if (value == "TOHIT") return IPL_TOHIT; + if (value == "TOHIT_CURSE") return IPL_TOHIT_CURSE; + if (value == "DAMP") return IPL_DAMP; + if (value == "DAMP_CURSE") return IPL_DAMP_CURSE; + if (value == "TOHIT_DAMP") return IPL_TOHIT_DAMP; + if (value == "TOHIT_DAMP_CURSE") return IPL_TOHIT_DAMP_CURSE; + if (value == "ACP") return IPL_ACP; + if (value == "ACP_CURSE") return IPL_ACP_CURSE; + if (value == "FIRERES") return IPL_FIRERES; + if (value == "LIGHTRES") return IPL_LIGHTRES; + if (value == "MAGICRES") return IPL_MAGICRES; + if (value == "ALLRES") return IPL_ALLRES; + if (value == "SPLLVLADD") return IPL_SPLLVLADD; + if (value == "CHARGES") return IPL_CHARGES; + if (value == "FIREDAM") return IPL_FIREDAM; + if (value == "LIGHTDAM") return IPL_LIGHTDAM; + if (value == "STR") return IPL_STR; + if (value == "STR_CURSE") return IPL_STR_CURSE; + if (value == "MAG") return IPL_MAG; + if (value == "MAG_CURSE") return IPL_MAG_CURSE; + if (value == "DEX") return IPL_DEX; + if (value == "DEX_CURSE") return IPL_DEX_CURSE; + if (value == "VIT") return IPL_VIT; + if (value == "VIT_CURSE") return IPL_VIT_CURSE; + if (value == "ATTRIBS") return IPL_ATTRIBS; + if (value == "ATTRIBS_CURSE") return IPL_ATTRIBS_CURSE; + if (value == "GETHIT_CURSE") return IPL_GETHIT_CURSE; + if (value == "GETHIT") return IPL_GETHIT; + if (value == "LIFE") return IPL_LIFE; + if (value == "LIFE_CURSE") return IPL_LIFE_CURSE; + if (value == "MANA") return IPL_MANA; + if (value == "MANA_CURSE") return IPL_MANA_CURSE; + if (value == "DUR") return IPL_DUR; + if (value == "DUR_CURSE") return IPL_DUR_CURSE; + if (value == "INDESTRUCTIBLE") return IPL_INDESTRUCTIBLE; + if (value == "LIGHT") return IPL_LIGHT; + if (value == "LIGHT_CURSE") return IPL_LIGHT_CURSE; + if (value == "MULT_ARROWS") return IPL_MULT_ARROWS; + if (value == "FIRE_ARROWS") return IPL_FIRE_ARROWS; + if (value == "LIGHT_ARROWS") return IPL_LIGHT_ARROWS; + if (value == "INVCURS") return IPL_INVCURS; + if (value == "THORNS") return IPL_THORNS; + if (value == "NOMANA") return IPL_NOMANA; + if (value == "FIREBALL") return IPL_FIREBALL; + if (value == "ABSHALFTRAP") return IPL_ABSHALFTRAP; + if (value == "KNOCKBACK") return IPL_KNOCKBACK; + if (value == "STEALMANA") return IPL_STEALMANA; + if (value == "STEALLIFE") return IPL_STEALLIFE; + if (value == "TARGAC") return IPL_TARGAC; + if (value == "FASTATTACK") return IPL_FASTATTACK; + if (value == "FASTRECOVER") return IPL_FASTRECOVER; + if (value == "FASTBLOCK") return IPL_FASTBLOCK; + if (value == "DAMMOD") return IPL_DAMMOD; + if (value == "RNDARROWVEL") return IPL_RNDARROWVEL; + if (value == "SETDAM") return IPL_SETDAM; + if (value == "SETDUR") return IPL_SETDUR; + if (value == "NOMINSTR") return IPL_NOMINSTR; + if (value == "SPELL") return IPL_SPELL; + if (value == "ONEHAND") return IPL_ONEHAND; + if (value == "3XDAMVDEM") return IPL_3XDAMVDEM; + if (value == "ALLRESZERO") return IPL_ALLRESZERO; + if (value == "DRAINLIFE") return IPL_DRAINLIFE; + if (value == "RNDSTEALLIFE") return IPL_RNDSTEALLIFE; + if (value == "SETAC") return IPL_SETAC; + if (value == "ADDACLIFE") return IPL_ADDACLIFE; + if (value == "ADDMANAAC") return IPL_ADDMANAAC; + if (value == "AC_CURSE") return IPL_AC_CURSE; + if (value == "LASTDIABLO") return IPL_LASTDIABLO; + if (value == "FIRERES_CURSE") return IPL_FIRERES_CURSE; + if (value == "LIGHTRES_CURSE") return IPL_LIGHTRES_CURSE; + if (value == "MAGICRES_CURSE") return IPL_MAGICRES_CURSE; + if (value == "DEVASTATION") return IPL_DEVASTATION; + if (value == "DECAY") return IPL_DECAY; + if (value == "PERIL") return IPL_PERIL; + if (value == "JESTERS") return IPL_JESTERS; + if (value == "CRYSTALLINE") return IPL_CRYSTALLINE; + if (value == "DOPPELGANGER") return IPL_DOPPELGANGER; + if (value == "ACDEMON") return IPL_ACDEMON; + if (value == "ACUNDEAD") return IPL_ACUNDEAD; + if (value == "MANATOLIFE") return IPL_MANATOLIFE; + if (value == "LIFETOMANA") return IPL_LIFETOMANA; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseAffixItemType(std::string_view value) +{ + if (value == "Misc") return AffixItemType::Misc; + if (value == "Bow") return AffixItemType::Bow; + if (value == "Staff") return AffixItemType::Staff; + if (value == "Weapon") return AffixItemType::Weapon; + if (value == "Shield") return AffixItemType::Shield; + if (value == "Armor") return AffixItemType::Armor; + return tl::make_unexpected("Unknown enum value"); +} + +tl::expected ParseAffixAlignment(std::string_view value) +{ + if (value == "Any") return GOE_ANY; + if (value == "Evil") return GOE_EVIL; + if (value == "Good") return GOE_GOOD; + return tl::make_unexpected("Unknown enum value"); +} + +void LoadItemDat() +{ + const std::string_view filename = "txtdata\\items\\itemdat.tsv"; + tl::expected dataFileResult = DataFile::load(filename); + if (!dataFileResult.has_value()) { + DataFile::reportFatalError(dataFileResult.error(), filename); } - return ""; + + DataFile &dataFile = dataFileResult.value(); + if (tl::expected result = dataFile.skipHeader(); + !result.has_value()) { + DataFile::reportFatalError(result.error(), filename); + } + + AllItemsList.clear(); + AllItemsList.reserve(dataFile.numRecords()); + for (DataFileRecord record : dataFile) { + FieldIterator fieldIt = record.begin(); + const FieldIterator endField = record.end(); + + AllItemsList.emplace_back(); + ItemData &item = AllItemsList.back(); + + const auto advance = [&]() { + ++fieldIt; + if (fieldIt == endField) { + DataFile::reportFatalError(DataFile::Error::NotEnoughColumns, filename); + } + }; + + // Skip the first column (item ID). + + // dropRate + advance(); + if (tl::expected result = ParseItemDropRate((*fieldIt).value()); result.has_value()) { + item.iRnd = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "dropRate", *fieldIt, result.error()); + } + + // class + advance(); + if (tl::expected result = ParseItemClass((*fieldIt).value()); result.has_value()) { + item.iClass = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "class", *fieldIt, result.error()); + } + + // equipType + advance(); + if (tl::expected result = ParseItemEquipType((*fieldIt).value()); result.has_value()) { + item.iLoc = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "equipType", *fieldIt, result.error()); + } + + // cursorGraphic + advance(); + if (tl::expected result = ParseItemCursorGraphic((*fieldIt).value()); result.has_value()) { + item.iCurs = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "cursorGraphic", *fieldIt, result.error()); + } + + // itemType + advance(); + if (tl::expected result = ParseItemType((*fieldIt).value()); result.has_value()) { + item.itype = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "itemType", *fieldIt, result.error()); + } + + // uniqueBaseItem + advance(); + if (tl::expected result = ParseUniqueBaseItem((*fieldIt).value()); result.has_value()) { + item.iItemId = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "uniqueBaseItem", *fieldIt, result.error()); + } + + // name + advance(); + item.iName = (*fieldIt).value(); + + // shortName + advance(); + item.iSName = (*fieldIt).value(); + + // minMonsterLevel + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMinMLvl); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minMonsterLevel", *fieldIt); + } + + // durability + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iDurability); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "durability", *fieldIt); + } + + // minDamage + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMinDam); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minDamage", *fieldIt); + } + + // maxDamage + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMaxDam); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "maxDamage", *fieldIt); + } + + // minArmor + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMinAC); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minArmor", *fieldIt); + } + + // maxArmor + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMaxAC); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "maxArmor", *fieldIt); + } + + // minStrength + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMinStr); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minStrength", *fieldIt); + } + + // minMagic + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMinMag); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minMagic", *fieldIt); + } + + // minDexterity + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iMinDex); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minDexterity", *fieldIt); + } + + // specialEffects + advance(); + if (tl::expected result = (*fieldIt).parseEnumList(item.iFlags, ParseItemSpecialEffect); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "specialEffects", *fieldIt); + } + + // miscId + advance(); + if (tl::expected result = ParseItemMiscId((*fieldIt).value()); result.has_value()) { + item.iMiscId = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "miscId", *fieldIt, result.error()); + } + + // spell + advance(); + if (tl::expected result = ParseSpellId((*fieldIt).value()); result.has_value()) { + item.iSpell = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "spell", *fieldIt, result.error()); + } + + // usable + advance(); + if (tl::expected result = (*fieldIt).parseBool(item.iUsable); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "usable", *fieldIt); + } + + // value + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.iValue); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "value", *fieldIt); + } + } + + AllItemsList.shrink_to_fit(); } -/** Contains the data related to each item ID. */ -const ItemData AllItemsList[] = { - // clang-format off -// _item_indexes iRnd, iClass, iLoc, iCurs, itype, iItemId, iName, iSName, iMinMLvl, iDurability, iMinDam, iMaxDam, iMinAC, iMaxAC, iMinStr, iMinMag, iMinDex, iFlags, iMiscId, iSpell, iUsable, iValue -/*IDI_GOLD */ { IDROP_REGULAR, ICLASS_GOLD, ILOC_UNEQUIPABLE, ICURS_GOLD, ItemType::Gold, UITYPE_NONE, N_("Gold"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, true, 0 }, -/*IDI_WARRIOR */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_SHORT_SWORD, ItemType::Sword, UITYPE_NONE, N_("Short Sword"), nullptr, 2, 20, 2, 6, 0, 0, 18, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 50 }, -/*IDI_WARRSHLD */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_BUCKLER, ItemType::Shield, UITYPE_NONE, N_("Buckler"), nullptr, 2, 10, 0, 0, 3, 3, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 50 }, -/*IDI_WARRCLUB */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_CLUB, ItemType::Mace, UITYPE_SPIKCLUB, N_("Club"), nullptr, 1, 20, 1, 6, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 20 }, -/*IDI_ROGUE */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_BOW, ItemType::Bow, UITYPE_NONE, N_("Short Bow"), nullptr, 1, 30, 1, 4, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 100 }, -/*IDI_SORCERER */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ItemType::Staff, UITYPE_NONE, N_("Short Staff of Mana"), nullptr, 1, 25, 2, 4, 0, 0, 0, 20, 0, ItemSpecialEffect::None, IMISC_STAFF, SpellID::Mana, false, 520 }, -/*IDI_CLEAVER */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_CLEAVER, ItemType::Axe, UITYPE_CLEAVER, N_("Cleaver"), nullptr, 10, 10, 4, 24, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 2000 }, -/*IDI_SKCROWN */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_HELM, ICURS_THE_UNDEAD_CROWN, ItemType::Helm, UITYPE_SKCROWN, N_("The Undead Crown"), nullptr, 0, 50, 0, 0, 15, 15, 0, 0, 0, ItemSpecialEffect::RandomStealLife, IMISC_UNIQUE, SpellID::Null, false, 10000 }, -/*IDI_INFRARING */ { IDROP_NEVER, ICLASS_MISC, ILOC_RING, ICURS_EMPYREAN_BAND, ItemType::Ring, UITYPE_INFRARING, N_("Empyrean Band"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 8000 }, -/*IDI_ROCK */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_MAGIC_ROCK, ItemType::Misc, UITYPE_NONE, N_("Magic Rock"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_OPTAMULET */ { IDROP_NEVER, ICLASS_MISC, ILOC_AMULET, ICURS_OPTIC_AMULET, ItemType::Amulet, UITYPE_OPTAMULET, N_("Optic Amulet"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 5000 }, -/*IDI_TRING */ { IDROP_NEVER, ICLASS_MISC, ILOC_RING, ICURS_RING_OF_TRUTH, ItemType::Ring, UITYPE_TRING, N_("Ring of Truth"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 1000 }, -/*IDI_BANNER */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_TAVERN_SIGN, ItemType::Misc, UITYPE_NONE, N_("Tavern Sign"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_HARCREST */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_HELM, ICURS_HARLEQUIN_CREST, ItemType::Helm, UITYPE_HARCREST, N_("Harlequin Crest"), nullptr, 0, 15, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 15 }, -/*IDI_STEELVEIL */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_HELM, ICURS_VIEL_OF_STEEL, ItemType::Helm, UITYPE_STEELVEIL, N_("Veil of Steel"), nullptr, 0, 60, 0, 0, 18, 18, 0, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 0 }, -/*IDI_GLDNELIX */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_GOLDEN_ELIXIR, ItemType::Misc, UITYPE_ELIXIR, N_("Golden Elixir"), nullptr, 15, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_ANVIL */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_ANVIL_OF_FURY, ItemType::Misc, UITYPE_NONE, N_("Anvil of Fury"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_MUSHROOM */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_BLACK_MUSHROOM, ItemType::Misc, UITYPE_NONE, N_("Black Mushroom"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_BRAIN */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_BRAIN, ItemType::Misc, UITYPE_NONE, N_("Brain"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_FUNGALTM */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_FUNGAL_TOME, ItemType::Misc, UITYPE_NONE, N_("Fungal Tome"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_SPECELIX */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SPECTRAL_ELIXIR, ItemType::Misc, UITYPE_ELIXIR, N_("Spectral Elixir"), nullptr, 15, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SPECELIX, SpellID::Null, true, 0 }, -/*IDI_BLDSTONE */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_BLOOD_STONE, ItemType::Misc, UITYPE_NONE, N_("Blood Stone"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_MAPOFDOOM */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_MAP_OF_THE_STARS, ItemType::Misc, UITYPE_MAPOFDOOM, N_("Cathedral Map"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_MAPOFDOOM, SpellID::Null, true, 0 }, -/*IDI_EAR */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_EAR_SORCERER, ItemType::Misc, UITYPE_NONE, N_("Heart"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_EAR, SpellID::Null, false, 0 }, -/*IDI_HEAL */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_HEALING, ItemType::Misc, UITYPE_NONE, N_("Potion of Healing"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_HEAL, SpellID::Null, true, 50 }, -/*IDI_MANA */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_MANA, ItemType::Misc, UITYPE_NONE, N_("Potion of Mana"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_MANA, SpellID::Null, true, 50 }, -/*IDI_IDENTIFY */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Identify"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Identify, true, 200 }, -/*IDI_PORTAL */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Town Portal"), nullptr, 4, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::TownPortal, true, 200 }, -/*IDI_ARMOFVAL */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_ARMOR, ICURS_ARKAINES_VALOR, ItemType::MediumArmor, UITYPE_ARMOFVAL, N_("Arkaine's Valor"), nullptr, 0, 40, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 0 }, -/*IDI_FULLHEAL */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_HEALING, ItemType::Misc, UITYPE_NONE, N_("Potion of Full Healing"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_FULLHEAL, SpellID::Null, true, 150 }, -/*IDI_FULLMANA */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_MANA, ItemType::Misc, UITYPE_NONE, N_("Potion of Full Mana"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_FULLMANA, SpellID::Null, true, 150 }, -/*IDI_GRISWOLD */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_BROAD_SWORD, ItemType::Sword, UITYPE_GRISWOLD, N_("Griswold's Edge"), nullptr, 8, 50, 4, 12, 0, 0, 40, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 750 }, -/*IDI_LGTFORGE */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_ARMOR, ICURS_BOVINE, ItemType::HeavyArmor, UITYPE_BOVINE, N_("Bovine Plate"), nullptr, 0, 40, 0, 0, 0, 0, 50, 0, 0, ItemSpecialEffect::None, IMISC_UNIQUE, SpellID::Null, false, 0 }, -/*IDI_LAZSTAFF */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_STAFF_OF_LAZARUS, ItemType::Misc, UITYPE_LAZSTAFF, N_("Staff of Lazarus"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_RESURRECT */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Resurrect"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Resurrect, true, 250 }, -/*IDI_OIL */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ItemType::Misc, UITYPE_NONE, N_("Blacksmith Oil"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_OILBSMTH, SpellID::Null, true, 100 }, -/*IDI_SHORTSTAFF */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ItemType::Staff, UITYPE_NONE, N_("Short Staff"), nullptr, 1, 25, 2, 4, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 20 }, -/*IDI_BARDSWORD */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_SHORT_SWORD, ItemType::Sword, UITYPE_NONE, N_("Sword"), nullptr, 2, 8, 1, 5, 0, 0, 15, 0, 20, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 20 }, -/*IDI_BARDDAGGER */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_DAGGER, ItemType::Sword, UITYPE_NONE, N_("Dagger"), nullptr, 1, 16, 1, 4, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 20 }, -/*IDI_RUNEBOMB */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_RUNE_BOMB, ItemType::Misc, UITYPE_NONE, N_("Rune Bomb"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_THEODORE */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_THEODORE, ItemType::Misc, UITYPE_NONE, N_("Theodore"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_AURIC */ { IDROP_NEVER, ICLASS_MISC, ILOC_AMULET, ICURS_AURIC_AMULET, ItemType::Misc, UITYPE_NONE, N_("Auric Amulet"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_AURIC, SpellID::Null, false, 100 }, -/*IDI_NOTE1 */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_TORN_NOTE_1, ItemType::Misc, UITYPE_NONE, N_("Torn Note 1"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_NOTE2 */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_TORN_NOTE_2, ItemType::Misc, UITYPE_NONE, N_("Torn Note 2"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_NOTE3 */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_TORN_NOTE_3, ItemType::Misc, UITYPE_NONE, N_("Torn Note 3"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_FULLNOTE */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_RECONSTRUCTED_NOTE, ItemType::Misc, UITYPE_NONE, N_("Reconstructed Note"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NOTE, SpellID::Null, true, 0 }, -/*IDI_BROWNSUIT */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_BROWN_SUIT, ItemType::Misc, UITYPE_NONE, N_("Brown Suit"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/*IDI_GREYSUIT */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_GREY_SUIT, ItemType::Misc, UITYPE_NONE, N_("Grey Suit"), nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_CAP, ItemType::Helm, UITYPE_NONE, N_("Cap"), N_("Cap"), 1, 15, 0, 0, 1, 3, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 15 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_SKULL_CAP, ItemType::Helm, UITYPE_SKULLCAP, N_("Skull Cap"), N_("Cap"), 4, 20, 0, 0, 2, 4, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 25 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_HELM, ItemType::Helm, UITYPE_HELM, N_("Helm"), N_("Helm"), 8, 30, 0, 0, 4, 6, 25, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 40 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_FULL_HELM, ItemType::Helm, UITYPE_NONE, N_("Full Helm"), N_("Helm"), 12, 35, 0, 0, 6, 8, 35, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 90 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_CROWN, ItemType::Helm, UITYPE_CROWN, N_("Crown"), N_("Crown"), 16, 40, 0, 0, 8, 12, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 200 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_GREAT_HELM, ItemType::Helm, UITYPE_GREATHELM, N_("Great Helm"), N_("Helm"), 20, 60, 0, 0, 10, 15, 50, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 400 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_CAPE, ItemType::LightArmor, UITYPE_CAPE, N_("Cape"), N_("Cape"), 1, 12, 0, 0, 1, 5, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 10 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_RAGS, ItemType::LightArmor, UITYPE_RAGS, N_("Rags"), N_("Rags"), 1, 6, 0, 0, 2, 6, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 5 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_CLOAK, ItemType::LightArmor, UITYPE_CLOAK, N_("Cloak"), N_("Cloak"), 2, 18, 0, 0, 3, 7, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 40 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_ROBE, ItemType::LightArmor, UITYPE_ROBE, N_("Robe"), N_("Robe"), 3, 24, 0, 0, 4, 7, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 75 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_QUILTED_ARMOR, ItemType::LightArmor, UITYPE_NONE, N_("Quilted Armor"), N_("Armor"), 4, 30, 0, 0, 7, 10, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 200 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_LEATHER_ARMOR, ItemType::LightArmor, UITYPE_LEATHARMOR, N_("Leather Armor"), N_("Armor"), 6, 35, 0, 0, 10, 13, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 300 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_HARD_LEATHER_ARMOR, ItemType::LightArmor, UITYPE_NONE, N_("Hard Leather Armor"), N_("Armor"), 7, 40, 0, 0, 11, 14, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 450 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_STUDDED_LEATHER_ARMOR, ItemType::LightArmor, UITYPE_STUDARMOR, N_("Studded Leather Armor"), N_("Armor"), 9, 45, 0, 0, 15, 17, 20, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 700 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_RING_MAIL, ItemType::MediumArmor, UITYPE_NONE, N_("Ring Mail"), N_("Mail"), 11, 50, 0, 0, 17, 20, 25, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 900 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_CHAIN_MAIL, ItemType::MediumArmor, UITYPE_CHAINMAIL, N_("Chain Mail"), N_("Mail"), 13, 55, 0, 0, 18, 22, 30, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 1250 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_SCALE_MAIL, ItemType::MediumArmor, UITYPE_NONE, N_("Scale Mail"), N_("Mail"), 15, 60, 0, 0, 23, 28, 35, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 2300 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_BREAST_PLATE, ItemType::HeavyArmor, UITYPE_BREASTPLATE, N_("Breast Plate"), N_("Plate"), 16, 80, 0, 0, 20, 24, 40, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 2800 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_SPLINT_MAIL, ItemType::MediumArmor, UITYPE_NONE, N_("Splint Mail"), N_("Mail"), 17, 65, 0, 0, 30, 35, 40, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 3250 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_FIELD_PLATE, ItemType::HeavyArmor, UITYPE_PLATEMAIL, N_("Plate Mail"), N_("Plate"), 19, 75, 0, 0, 42, 50, 60, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 4600 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_FIELD_PLATE, ItemType::HeavyArmor, UITYPE_NONE, N_("Field Plate"), N_("Plate"), 21, 80, 0, 0, 40, 45, 65, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 5800 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_GOTHIC_PLATE, ItemType::HeavyArmor, UITYPE_NONE, N_("Gothic Plate"), N_("Plate"), 23, 100, 0, 0, 50, 60, 80, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 8000 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, ICURS_FULL_PLATE_MAIL, ItemType::HeavyArmor, UITYPE_FULLPLATE, N_("Full Plate Mail"), N_("Plate"), 25, 90, 0, 0, 60, 75, 90, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 6500 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_BUCKLER, ItemType::Shield, UITYPE_BUCKLER, N_("Buckler"), N_("Shield"), 1, 16, 0, 0, 1, 5, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 30 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_SMALL_SHIELD, ItemType::Shield, UITYPE_SMALLSHIELD, N_("Small Shield"), N_("Shield"), 5, 24, 0, 0, 3, 8, 25, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 90 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_LARGE_SHIELD, ItemType::Shield, UITYPE_LARGESHIELD, N_("Large Shield"), N_("Shield"), 9, 32, 0, 0, 5, 10, 40, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 200 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_KITE_SHIELD, ItemType::Shield, UITYPE_KITESHIELD, N_("Kite Shield"), N_("Shield"), 14, 40, 0, 0, 8, 15, 50, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 400 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_TOWER_SHIELD, ItemType::Shield, UITYPE_GOTHSHIELD, N_("Tower Shield"), N_("Shield"), 20, 50, 0, 0, 12, 20, 60, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 850 }, -/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_GOTHIC_SHIELD, ItemType::Shield, UITYPE_GOTHSHIELD, N_("Gothic Shield"), N_("Shield"), 23, 60, 0, 0, 14, 18, 80, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 2300 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_HEALING, ItemType::Misc, UITYPE_NONE, N_("Potion of Healing"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_HEAL, SpellID::Null, true, 50 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_HEALING, ItemType::Misc, UITYPE_NONE, N_("Potion of Full Healing"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_FULLHEAL, SpellID::Null, true, 150 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_MANA, ItemType::Misc, UITYPE_NONE, N_("Potion of Mana"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_MANA, SpellID::Null, true, 50 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_MANA, ItemType::Misc, UITYPE_NONE, N_("Potion of Full Mana"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_FULLMANA, SpellID::Null, true, 150 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_REJUVENATION, ItemType::Misc, UITYPE_NONE, N_("Potion of Rejuvenation"), nullptr, 3, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_REJUV, SpellID::Null, true, 120 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_REJUVENATION, ItemType::Misc, UITYPE_NONE, N_("Potion of Full Rejuvenation"), nullptr, 7, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_FULLREJUV, SpellID::Null, true, 600 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ItemType::Misc, UITYPE_NONE, N_("Blacksmith Oil"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_OILBSMTH, SpellID::Null, true, 100 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ItemType::Misc, UITYPE_NONE, N_("Oil of Accuracy"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_OILACC, SpellID::Null, true, 500 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ItemType::Misc, UITYPE_NONE, N_("Oil of Sharpness"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_OILSHARP, SpellID::Null, true, 500 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ItemType::Misc, UITYPE_NONE, N_("Oil"), nullptr, 10, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_OILOF, SpellID::Null, true, 0 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_STRENGTH, ItemType::Misc, UITYPE_NONE, N_("Elixir of Strength"), nullptr, 15, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_ELIXSTR, SpellID::Null, true, 5000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_MAGIC, ItemType::Misc, UITYPE_NONE, N_("Elixir of Magic"), nullptr, 15, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_ELIXMAG, SpellID::Null, true, 5000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_DEXTERITY, ItemType::Misc, UITYPE_NONE, N_("Elixir of Dexterity"), nullptr, 15, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_ELIXDEX, SpellID::Null, true, 5000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_VITALITY, ItemType::Misc, UITYPE_NONE, N_("Elixir of Vitality"), nullptr, 20, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_ELIXVIT, SpellID::Null, true, 5000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Healing"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Healing, true, 50 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Search"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Search, true, 50 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Lightning"), nullptr, 4, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Lightning, true, 150 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Identify"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Identify, true, 100 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Resurrect"), nullptr, 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Resurrect, true, 250 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Fire Wall"), nullptr, 4, 0, 0, 0, 0, 0, 0, 17, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::FireWall, true, 400 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Inferno"), nullptr, 1, 0, 0, 0, 0, 0, 0, 19, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Inferno, true, 100 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Town Portal"), nullptr, 4, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::TownPortal, true, 200 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Flash"), nullptr, 6, 0, 0, 0, 0, 0, 0, 21, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Flash, true, 500 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Infravision"), nullptr, 8, 0, 0, 0, 0, 0, 0, 23, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Infravision, true, 600 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Phasing"), nullptr, 6, 0, 0, 0, 0, 0, 0, 25, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Phasing, true, 200 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Mana Shield"), nullptr, 8, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::ManaShield, true, 1200 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Flame Wave"), nullptr, 10, 0, 0, 0, 0, 0, 0, 29, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::FlameWave, true, 650 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Fireball"), nullptr, 8, 0, 0, 0, 0, 0, 0, 31, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Fireball, true, 300 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Stone Curse"), nullptr, 6, 0, 0, 0, 0, 0, 0, 33, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::StoneCurse, true, 800 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Chain Lightning"), nullptr, 10, 0, 0, 0, 0, 0, 0, 35, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::ChainLightning, true, 750 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Guardian"), nullptr, 12, 0, 0, 0, 0, 0, 0, 47, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Guardian, true, 950 }, -/* */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, "Non Item", nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Nova"), nullptr, 14, 0, 0, 0, 0, 0, 0, 57, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Nova, true, 1300 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Golem"), nullptr, 10, 0, 0, 0, 0, 0, 0, 51, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Golem, true, 1100 }, -/* */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, "Scroll of None", nullptr, 99, 0, 0, 0, 0, 0, 0, 61, 0, ItemSpecialEffect::None, IMISC_SCROLLT, SpellID::Null, true, 1000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Teleport"), nullptr, 14, 0, 0, 0, 0, 0, 0, 81, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Teleport, true, 3000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ItemType::Misc, UITYPE_NONE, N_("Scroll of Apocalypse"), nullptr, 22, 0, 0, 0, 0, 0, 0, 117, 0, ItemSpecialEffect::None, IMISC_SCROLL, SpellID::Apocalypse, true, 2000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_BOOK_BLUE, ItemType::Misc, UITYPE_NONE, N_("Book of "), nullptr, 2, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_BOOK, SpellID::Null, true, 0 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_BOOK_BLUE, ItemType::Misc, UITYPE_NONE, N_("Book of "), nullptr, 8, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_BOOK, SpellID::Null, true, 0 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_BOOK_BLUE, ItemType::Misc, UITYPE_NONE, N_("Book of "), nullptr, 14, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_BOOK, SpellID::Null, true, 0 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_BOOK_BLUE, ItemType::Misc, UITYPE_NONE, N_("Book of "), nullptr, 20, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_BOOK, SpellID::Null, true, 0 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_DAGGER, ItemType::Sword, UITYPE_DAGGER, N_("Dagger"), N_("Dagger"), 1, 16, 1, 4, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 60 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_SHORT_SWORD, ItemType::Sword, UITYPE_NONE, N_("Short Sword"), N_("Sword"), 1, 24, 2, 6, 0, 0, 18, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 120 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_FALCHION, ItemType::Sword, UITYPE_FALCHION, N_("Falchion"), N_("Sword"), 2, 20, 4, 8, 0, 0, 30, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 250 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_SCIMITAR, ItemType::Sword, UITYPE_SCIMITAR, N_("Scimitar"), N_("Sword"), 4, 28, 3, 7, 0, 0, 23, 0, 23, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 200 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_CLAYMORE, ItemType::Sword, UITYPE_CLAYMORE, N_("Claymore"), N_("Sword"), 5, 36, 1, 12, 0, 0, 35, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 450 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_BLADE, ItemType::Sword, UITYPE_NONE, N_("Blade"), N_("Blade"), 4, 30, 3, 8, 0, 0, 25, 0, 30, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 280 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_SABRE, ItemType::Sword, UITYPE_SABRE, N_("Sabre"), N_("Sabre"), 1, 45, 1, 8, 0, 0, 17, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 170 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_LONG_SWORD, ItemType::Sword, UITYPE_LONGSWR, N_("Long Sword"), N_("Sword"), 6, 40, 2, 10, 0, 0, 30, 0, 30, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 350 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_BROAD_SWORD, ItemType::Sword, UITYPE_BROADSWR, N_("Broad Sword"), N_("Sword"), 8, 50, 4, 12, 0, 0, 40, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 750 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_BASTARD_SWORD, ItemType::Sword, UITYPE_BASTARDSWR, N_("Bastard Sword"), N_("Sword"), 10, 60, 6, 15, 0, 0, 50, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 1000 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_TWO_HANDED_SWORD, ItemType::Sword, UITYPE_TWOHANDSWR, N_("Two-Handed Sword"), N_("Sword"), 14, 75, 8, 16, 0, 0, 65, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 1800 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_GREAT_SWORD, ItemType::Sword, UITYPE_GREATSWR, N_("Great Sword"), N_("Sword"), 17, 100, 10, 20, 0, 0, 75, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 3000 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SMALL_AXE, ItemType::Axe, UITYPE_SMALLAXE, N_("Small Axe"), N_("Axe"), 2, 24, 2, 10, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 150 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_AXE, ItemType::Axe, UITYPE_NONE, N_("Axe"), N_("Axe"), 4, 32, 4, 12, 0, 0, 22, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 450 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_LARGE_AXE, ItemType::Axe, UITYPE_LARGEAXE, N_("Large Axe"), N_("Axe"), 6, 40, 6, 16, 0, 0, 30, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 750 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_BROAD_AXE, ItemType::Axe, UITYPE_BROADAXE, N_("Broad Axe"), N_("Axe"), 8, 50, 8, 20, 0, 0, 50, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 1000 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_BATTLE_AXE, ItemType::Axe, UITYPE_BATTLEAXE, N_("Battle Axe"), N_("Axe"), 10, 60, 10, 25, 0, 0, 65, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 1500 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_GREAT_AXE, ItemType::Axe, UITYPE_GREATAXE, N_("Great Axe"), N_("Axe"), 12, 75, 12, 30, 0, 0, 80, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 2500 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_MACE, ItemType::Mace, UITYPE_MACE, N_("Mace"), N_("Mace"), 2, 32, 1, 8, 0, 0, 16, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 200 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_MORNING_STAR, ItemType::Mace, UITYPE_MORNSTAR, N_("Morning Star"), N_("Mace"), 3, 40, 1, 10, 0, 0, 26, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 300 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_WAR_HAMMER, ItemType::Mace, UITYPE_WARHAMMER, N_("War Hammer"), N_("Hammer"), 5, 50, 5, 9, 0, 0, 40, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 600 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_SPIKED_CLUB, ItemType::Mace, UITYPE_SPIKCLUB, N_("Spiked Club"), N_("Club"), 4, 20, 3, 6, 0, 0, 18, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 225 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_CLUB, ItemType::Mace, UITYPE_SPIKCLUB, N_("Club"), N_("Club"), 1, 20, 1, 6, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 20 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_FLAIL, ItemType::Mace, UITYPE_FLAIL, N_("Flail"), N_("Flail"), 7, 36, 2, 12, 0, 0, 30, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 500 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_MAUL, ItemType::Mace, UITYPE_MAUL, N_("Maul"), N_("Maul"), 10, 50, 6, 20, 0, 0, 55, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 900 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_BOW, ItemType::Bow, UITYPE_SHORTBOW, N_("Short Bow"), N_("Bow"), 1, 30, 1, 4, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 100 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_HUNTERS_BOW, ItemType::Bow, UITYPE_HUNTBOW, N_("Hunter's Bow"), N_("Bow"), 3, 40, 2, 5, 0, 0, 20, 0, 35, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 350 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_HUNTERS_BOW, ItemType::Bow, UITYPE_LONGBOW, N_("Long Bow"), N_("Bow"), 5, 35, 1, 6, 0, 0, 25, 0, 30, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 250 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_COMPOSITE_BOW, ItemType::Bow, UITYPE_COMPBOW, N_("Composite Bow"), N_("Bow"), 7, 45, 3, 6, 0, 0, 25, 0, 40, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 600 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_BATTLE_BOW, ItemType::Bow, UITYPE_NONE, N_("Short Battle Bow"), N_("Bow"), 9, 45, 3, 7, 0, 0, 30, 0, 50, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 750 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_LONG_BATTLE_BOW, ItemType::Bow, UITYPE_BATTLEBOW, N_("Long Battle Bow"), N_("Bow"), 11, 50, 1, 10, 0, 0, 30, 0, 60, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 1000 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_WAR_BOW, ItemType::Bow, UITYPE_NONE, N_("Short War Bow"), N_("Bow"), 15, 55, 4, 8, 0, 0, 35, 0, 70, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 1500 }, -/* */ { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_LONG_WAR_BOW, ItemType::Bow, UITYPE_WARBOW, N_("Long War Bow"), N_("Bow"), 19, 60, 1, 14, 0, 0, 45, 0, 80, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 2000 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ItemType::Staff, UITYPE_SHORTSTAFF, N_("Short Staff"), N_("Staff"), 1, 25, 2, 4, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_STAFF, SpellID::Null, false, 30 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_LONG_STAFF, ItemType::Staff, UITYPE_LONGSTAFF, N_("Long Staff"), N_("Staff"), 4, 35, 4, 8, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_STAFF, SpellID::Null, false, 100 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_COMPOSITE_STAFF, ItemType::Staff, UITYPE_COMPSTAFF, N_("Composite Staff"), N_("Staff"), 6, 45, 5, 10, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_STAFF, SpellID::Null, false, 500 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ItemType::Staff, UITYPE_QUARSTAFF, N_("Quarter Staff"), N_("Staff"), 9, 55, 6, 12, 0, 0, 20, 0, 0, ItemSpecialEffect::None, IMISC_STAFF, SpellID::Null, false, 1000 }, -/* */ { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_WAR_STAFF, ItemType::Staff, UITYPE_WARSTAFF, N_("War Staff"), N_("Staff"), 12, 75, 8, 16, 0, 0, 30, 0, 0, ItemSpecialEffect::None, IMISC_STAFF, SpellID::Null, false, 1500 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_RING, ICURS_RING, ItemType::Ring, UITYPE_RING, N_("Ring"), N_("Ring"), 5, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_RING, SpellID::Null, false, 1000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_RING, ICURS_RING, ItemType::Ring, UITYPE_RING, N_("Ring"), N_("Ring"), 10, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_RING, SpellID::Null, false, 1000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_RING, ICURS_RING, ItemType::Ring, UITYPE_RING, N_("Ring"), N_("Ring"), 15, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_RING, SpellID::Null, false, 1000 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_AMULET, ICURS_AMULET, ItemType::Amulet, UITYPE_AMULET, N_("Amulet"), N_("Amulet"), 8, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_AMULET, SpellID::Null, false, 1200 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_AMULET, ICURS_AMULET, ItemType::Amulet, UITYPE_AMULET, N_("Amulet"), N_("Amulet"), 16, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_AMULET, SpellID::Null, false, 1200 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_RUNE_OF_FIRE, ItemType::Misc, UITYPE_NONE, N_("Rune of Fire"), N_("Rune"), 1, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_RUNEF, SpellID::Null, true, 100 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_RUNE_OF_LIGHTNING, ItemType::Misc, UITYPE_NONE, N_("Rune of Lightning"), N_("Rune"), 3, 0, 0, 0, 0, 0, 0, 13, 0, ItemSpecialEffect::None, IMISC_RUNEL, SpellID::Null, true, 200 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_GREATER_RUNE_OF_FIRE, ItemType::Misc, UITYPE_NONE, N_("Greater Rune of Fire"), N_("Rune"), 7, 0, 0, 0, 0, 0, 0, 42, 0, ItemSpecialEffect::None, IMISC_GR_RUNEF, SpellID::Null, true, 400 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_GREATER_RUNE_OF_LIGHTNING, ItemType::Misc, UITYPE_NONE, N_("Greater Rune of Lightning"), N_("Rune"), 7, 0, 0, 0, 0, 0, 0, 42, 0, ItemSpecialEffect::None, IMISC_GR_RUNEL, SpellID::Null, true, 500 }, -/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_RUNE_OF_STONE, ItemType::Misc, UITYPE_NONE, N_("Rune of Stone"), N_("Rune"), 7, 0, 0, 0, 0, 0, 0, 25, 0, ItemSpecialEffect::None, IMISC_RUNES, SpellID::Null, true, 300 }, -/*IDI_SORCERER */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ItemType::Staff, UITYPE_NONE, N_("Short Staff of Charged Bolt"), nullptr, 1, 25, 2, 4, 0, 0, 0, 20, 0, ItemSpecialEffect::None, IMISC_STAFF, SpellID::ChargedBolt, false, 520 }, -/*IDI_ARENAPOT */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ARENA_POTION, ItemType::Misc, UITYPE_NONE, N_("Arena Potion"), nullptr, 7, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_ARENAPOT, SpellID::Null, true, 0 }, -/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_INVALID, ICURS_POTION_OF_FULL_MANA, ItemType::Misc, UITYPE_NONE, nullptr, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, ItemSpecialEffect::None, IMISC_NONE, SpellID::Null, false, 0 }, - // clang-format on -}; +void ParseItemPower(devilution::FieldIterator &fieldIt, const FieldIterator &endField, + std::string_view filename, std::string_view fieldName, ItemPower &power) +{ + const auto advance = [&]() { + ++fieldIt; + if (fieldIt == endField) { + DataFile::reportFatalError(DataFile::Error::NotEnoughColumns, filename); + } + }; -/** Contains the data related to each item prefix. */ -const PLStruct ItemPrefixes[] = { - // clang-format off -// PLName, { type, param1, param2 } PLMinLvl, PLIType, PLGOE, PLDouble, PLOk, minVal, maxVal, multVal - // TRANSLATORS: Item prefix section. -{ N_("Tin"), { IPL_TOHIT_CURSE, 6, 10 }, 3, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, true, false, 0, 0, -3 }, -{ N_("Brass"), { IPL_TOHIT_CURSE, 1, 5 }, 1, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, true, false, 0, 0, -2 }, -{ N_("Bronze"), { IPL_TOHIT, 1, 5 }, 1, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, true, true, 100, 500, 2 }, -{ N_("Iron"), { IPL_TOHIT, 6, 10 }, 4, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, true, true, 600, 1000, 3 }, -{ N_("Steel"), { IPL_TOHIT, 11, 15 }, 6, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, true, true, 1100, 1500, 5 }, -{ N_("Silver"), { IPL_TOHIT, 16, 20 }, 9, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_GOOD, true, true, 1600, 2000, 7 }, -{ N_("Gold"), { IPL_TOHIT, 21, 30 }, 12, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_GOOD, true, true, 2100, 3000, 9 }, -{ N_("Platinum"), { IPL_TOHIT, 31, 40 }, 16, AffixItemType::Weapon | AffixItemType::Bow, GOE_GOOD, true, true, 3100, 4000, 11 }, -{ N_("Mithril"), { IPL_TOHIT, 41, 60 }, 20, AffixItemType::Weapon | AffixItemType::Bow, GOE_GOOD, true, true, 4100, 6000, 13 }, -{ N_("Meteoric"), { IPL_TOHIT, 61, 80 }, 23, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, true, true, 6100, 10000, 15 }, -{ N_("Weird"), { IPL_TOHIT, 81, 100 }, 35, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, true, true, 10100, 14000, 17 }, -{ N_("Strange"), { IPL_TOHIT, 101, 150 }, 60, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, true, true, 14100, 20000, 20 }, -{ N_("Useless"), { IPL_DAMP_CURSE, 100, 100 }, 5, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, false, 0, 0, -8 }, -{ N_("Bent"), { IPL_DAMP_CURSE, 50, 75 }, 3, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, false, 0, 0, -4 }, -{ N_("Weak"), { IPL_DAMP_CURSE, 25, 45 }, 1, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, false, 0, 0, -3 }, -{ N_("Jagged"), { IPL_DAMP, 20, 35 }, 4, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, true, 250, 450, 3 }, -{ N_("Deadly"), { IPL_DAMP, 36, 50 }, 6, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, true, 500, 700, 4 }, -{ N_("Heavy"), { IPL_DAMP, 51, 65 }, 9, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, true, 750, 950, 5 }, -{ N_("Vicious"), { IPL_DAMP, 66, 80 }, 12, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_EVIL, true, true, 1000, 1450, 8 }, -{ N_("Brutal"), { IPL_DAMP, 81, 95 }, 16, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, true, 1500, 1950, 10 }, -{ N_("Massive"), { IPL_DAMP, 96, 110 }, 20, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, true, 2000, 2450, 13 }, -{ N_("Savage"), { IPL_DAMP, 111, 125 }, 23, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, true, true, 2500, 3000, 15 }, -{ N_("Ruthless"), { IPL_DAMP, 126, 150 }, 35, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, true, true, 10100, 15000, 17 }, -{ N_("Merciless"), { IPL_DAMP, 151, 175 }, 60, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, true, true, 15000, 20000, 20 }, -{ N_("Clumsy"), { IPL_TOHIT_DAMP_CURSE, 50, 75 }, 5, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, false, 0, 0, -7 }, -{ N_("Dull"), { IPL_TOHIT_DAMP_CURSE, 25, 45 }, 1, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, false, 0, 0, -5 }, -{ N_("Sharp"), { IPL_TOHIT_DAMP, 20, 35 }, 1, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, false, 350, 950, 5 }, -{ N_("Fine"), { IPL_TOHIT_DAMP, 36, 50 }, 6, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, true, 1100, 1700, 7 }, -{ N_("Warrior's"), { IPL_TOHIT_DAMP, 51, 65 }, 10, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, true, true, 1850, 2450, 13 }, -{ N_("Soldier's"), { IPL_TOHIT_DAMP, 66, 80 }, 15, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, true, true, 2600, 3950, 17 }, -{ N_("Lord's"), { IPL_TOHIT_DAMP, 81, 95 }, 19, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, true, true, 4100, 5950, 21 }, -{ N_("Knight's"), { IPL_TOHIT_DAMP, 96, 110 }, 23, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, true, true, 6100, 8450, 26 }, -{ N_("Master's"), { IPL_TOHIT_DAMP, 111, 125 }, 28, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, true, true, 8600, 13000, 30 }, -{ N_("Champion's"), { IPL_TOHIT_DAMP, 126, 150 }, 40, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, true, true, 15200, 24000, 33 }, -{ N_("King's"), { IPL_TOHIT_DAMP, 151, 175 }, 28, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, true, true, 24100, 35000, 38 }, -{ N_("Vulnerable"), { IPL_ACP_CURSE, 51, 100 }, 3, AffixItemType::Armor | AffixItemType::Shield, GOE_ANY, true, false, 0, 0, -3 }, -{ N_("Rusted"), { IPL_ACP_CURSE, 25, 50 }, 1, AffixItemType::Armor | AffixItemType::Shield, GOE_ANY, true, false, 0, 0, -2 }, -{ N_("Fine"), { IPL_ACP, 20, 30 }, 1, AffixItemType::Armor | AffixItemType::Shield, GOE_ANY, true, true, 20, 100, 2 }, -{ N_("Strong"), { IPL_ACP, 31, 40 }, 3, AffixItemType::Armor | AffixItemType::Shield, GOE_ANY, true, true, 120, 200, 3 }, -{ N_("Grand"), { IPL_ACP, 41, 55 }, 6, AffixItemType::Armor | AffixItemType::Shield, GOE_ANY, true, true, 220, 300, 5 }, -{ N_("Valiant"), { IPL_ACP, 56, 70 }, 10, AffixItemType::Armor | AffixItemType::Shield, GOE_ANY, true, true, 320, 400, 7 }, -{ N_("Glorious"), { IPL_ACP, 71, 90 }, 14, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, true, true, 420, 600, 9 }, -{ N_("Blessed"), { IPL_ACP, 91, 110 }, 19, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, true, true, 620, 800, 11 }, -{ N_("Saintly"), { IPL_ACP, 111, 130 }, 24, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, true, true, 820, 1200, 13 }, -{ N_("Awesome"), { IPL_ACP, 131, 150 }, 28, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, true, true, 1220, 2000, 15 }, -{ N_("Holy"), { IPL_ACP, 151, 170 }, 35, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, true, true, 5200, 6000, 17 }, -{ N_("Godly"), { IPL_ACP, 171, 200 }, 60, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, true, true, 6200, 7000, 20 }, -{ N_("Red"), { IPL_FIRERES, 10, 20 }, 4, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 500, 1500, 2 }, -{ N_("Crimson"), { IPL_FIRERES, 21, 30 }, 10, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 2100, 3000, 2 }, -{ N_("Crimson"), { IPL_FIRERES, 31, 40 }, 16, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 3100, 4000, 2 }, -{ N_("Garnet"), { IPL_FIRERES, 41, 50 }, 20, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 8200, 12000, 3 }, -{ N_("Ruby"), { IPL_FIRERES, 51, 60 }, 26, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 17100, 20000, 5 }, -{ N_("Blue"), { IPL_LIGHTRES, 10, 20 }, 4, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 500, 1500, 2 }, -{ N_("Azure"), { IPL_LIGHTRES, 21, 30 }, 10, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 2100, 3000, 2 }, -{ N_("Lapis"), { IPL_LIGHTRES, 31, 40 }, 16, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 3100, 4000, 2 }, -{ N_("Cobalt"), { IPL_LIGHTRES, 41, 50 }, 20, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 8200, 12000, 3 }, -{ N_("Sapphire"), { IPL_LIGHTRES, 51, 60 }, 26, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 17100, 20000, 5 }, -{ N_("White"), { IPL_MAGICRES, 10, 20 }, 4, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 500, 1500, 2 }, -{ N_("Pearl"), { IPL_MAGICRES, 21, 30 }, 10, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 2100, 3000, 2 }, -{ N_("Ivory"), { IPL_MAGICRES, 31, 40 }, 16, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 3100, 4000, 2 }, -{ N_("Crystal"), { IPL_MAGICRES, 41, 50 }, 20, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 8200, 12000, 3 }, -{ N_("Diamond"), { IPL_MAGICRES, 51, 60 }, 26, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 17100, 20000, 5 }, -{ N_("Topaz"), { IPL_ALLRES, 10, 15 }, 8, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 2000, 5000, 3 }, -{ N_("Amber"), { IPL_ALLRES, 16, 20 }, 12, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 7400, 10000, 3 }, -{ N_("Jade"), { IPL_ALLRES, 21, 30 }, 18, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 11000, 15000, 3 }, -{ N_("Obsidian"), { IPL_ALLRES, 31, 40 }, 24, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 24000, 40000, 4 }, -{ N_("Emerald"), { IPL_ALLRES, 41, 50 }, 31, AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 61000, 75000, 7 }, -{ N_("Hyena's"), { IPL_MANA_CURSE, 11, 25 }, 4, AffixItemType::Staff | AffixItemType::Misc, GOE_ANY, false, false, 100, 1000, -2 }, -{ N_("Frog's"), { IPL_MANA_CURSE, 1, 10 }, 1, AffixItemType::Staff | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("Spider's"), { IPL_MANA, 10, 15 }, 1, AffixItemType::Staff | AffixItemType::Misc, GOE_EVIL, false, true, 500, 1000, 2 }, -{ N_("Raven's"), { IPL_MANA, 15, 20 }, 5, AffixItemType::Staff | AffixItemType::Misc, GOE_ANY, false, true, 1100, 2000, 3 }, -{ N_("Snake's"), { IPL_MANA, 21, 30 }, 9, AffixItemType::Staff | AffixItemType::Misc, GOE_ANY, false, true, 2100, 4000, 5 }, -{ N_("Serpent's"), { IPL_MANA, 30, 40 }, 15, AffixItemType::Staff | AffixItemType::Misc, GOE_ANY, false, true, 4100, 6000, 7 }, -{ N_("Drake's"), { IPL_MANA, 41, 50 }, 21, AffixItemType::Staff | AffixItemType::Misc, GOE_ANY, false, true, 6100, 10000, 9 }, -{ N_("Dragon's"), { IPL_MANA, 51, 60 }, 27, AffixItemType::Staff | AffixItemType::Misc, GOE_ANY, false, true, 10100, 15000, 11 }, -{ N_("Wyrm's"), { IPL_MANA, 61, 80 }, 35, AffixItemType::Staff, GOE_ANY, false, true, 15100, 19000, 12 }, -{ N_("Hydra's"), { IPL_MANA, 81, 100 }, 60, AffixItemType::Staff, GOE_ANY, false, true, 19100, 30000, 13 }, -{ N_("Angel's"), { IPL_SPLLVLADD, 1, 1 }, 15, AffixItemType::Staff, GOE_GOOD, false, true, 25000, 25000, 2 }, -{ N_("Arch-Angel's"), { IPL_SPLLVLADD, 2, 2 }, 25, AffixItemType::Staff, GOE_GOOD, false, true, 50000, 50000, 3 }, -{ N_("Plentiful"), { IPL_CHARGES, 2, 2 }, 4, AffixItemType::Staff, GOE_ANY, false, true, 2000, 2000, 2 }, -{ N_("Bountiful"), { IPL_CHARGES, 3, 3 }, 9, AffixItemType::Staff, GOE_ANY, false, true, 3000, 3000, 3 }, -{ N_("Flaming"), { IPL_FIREDAM, 1, 10 }, 7, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 5000, 5000, 2 }, -{ N_("Lightning"), { IPL_LIGHTDAM, 2, 20 }, 18, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 10000, 10000, 2 }, -{ N_("Jester's"), { IPL_JESTERS, 1, 1 }, 7, AffixItemType::Weapon, GOE_ANY, false, true, 1200, 1200, 3 }, -{ N_("Crystalline"), { IPL_CRYSTALLINE, 30, 70 }, 5, AffixItemType::Weapon, GOE_ANY, false, true, 1000, 3000, 3 }, - // TRANSLATORS: Item prefix section end. -{ N_("Doppelganger's"), { IPL_DOPPELGANGER, 81, 95 }, 11, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 2000, 2400, 10 }, -{ "", { IPL_INVALID, 0, 0 }, 0, AffixItemType::None, GOE_ANY, false, false, 0, 0, 0 }, - // clang-format on -}; + if (tl::expected result = ParseItemEffectType((*fieldIt).value()); result.has_value()) { + power.type = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, StrCat(fieldName, ".type"), *fieldIt, result.error()); + } -/** Contains the data related to each item suffix. */ -const PLStruct ItemSuffixes[] = { - // clang-format off -// PLName, { type, param1, param2 } PLMinLvl, PLIType, PLGOE, PLDouble, PLOk, minVal, maxVal, multVal - // TRANSLATORS: Item suffix section. All items will have a word binding word. (Format: {:s} of {:s} - e.g. Rags of Valor) -{ N_("quality"), { IPL_DAMMOD, 1, 2 }, 2, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 100, 200, 2 }, -{ N_("maiming"), { IPL_DAMMOD, 3, 5 }, 7, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 1300, 1500, 3 }, -{ N_("slaying"), { IPL_DAMMOD, 6, 8 }, 15, AffixItemType::Weapon, GOE_ANY, false, true, 2600, 3000, 5 }, -{ N_("gore"), { IPL_DAMMOD, 9, 12 }, 25, AffixItemType::Weapon, GOE_ANY, false, true, 4100, 5000, 8 }, -{ N_("carnage"), { IPL_DAMMOD, 13, 16 }, 35, AffixItemType::Weapon, GOE_ANY, false, true, 5100, 10000, 10 }, -{ N_("slaughter"), { IPL_DAMMOD, 17, 20 }, 60, AffixItemType::Weapon, GOE_ANY, false, true, 10100, 15000, 13 }, -{ N_("pain"), { IPL_GETHIT_CURSE, 2, 4 }, 4, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -4 }, -{ N_("tears"), { IPL_GETHIT_CURSE, 1, 1 }, 2, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("health"), { IPL_GETHIT, 1, 1 }, 2, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_GOOD, false, true, 200, 200, 2 }, -{ N_("protection"), { IPL_GETHIT, 2, 2 }, 6, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, false, true, 400, 800, 4 }, -{ N_("absorption"), { IPL_GETHIT, 3, 3 }, 12, AffixItemType::Armor | AffixItemType::Shield, GOE_GOOD, false, true, 1001, 2500, 10 }, -{ N_("deflection"), { IPL_GETHIT, 4, 4 }, 20, AffixItemType::Armor, GOE_GOOD, false, true, 2500, 6500, 15 }, -{ N_("osmosis"), { IPL_GETHIT, 5, 6 }, 50, AffixItemType::Armor, GOE_GOOD, false, true, 7500, 10000, 20 }, -{ N_("frailty"), { IPL_STR_CURSE, 6, 10 }, 3, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -3 }, -{ N_("weakness"), { IPL_STR_CURSE, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("strength"), { IPL_STR, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 200, 1000, 2 }, -{ N_("might"), { IPL_STR, 6, 10 }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 1200, 2000, 3 }, -{ N_("power"), { IPL_STR, 11, 15 }, 11, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 2200, 3000, 4 }, -{ N_("giants"), { IPL_STR, 16, 20 }, 17, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 3200, 5000, 7 }, -{ N_("titans"), { IPL_STR, 21, 30 }, 23, AffixItemType::Weapon | AffixItemType::Misc, GOE_ANY, false, true, 5200, 10000, 10 }, -{ N_("paralysis"), { IPL_DEX_CURSE, 6, 10 }, 3, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -3 }, -{ N_("atrophy"), { IPL_DEX_CURSE, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("dexterity"), { IPL_DEX, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 200, 1000, 2 }, -{ N_("skill"), { IPL_DEX, 6, 10 }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 1200, 2000, 3 }, -{ N_("accuracy"), { IPL_DEX, 11, 15 }, 11, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 2200, 3000, 4 }, -{ N_("precision"), { IPL_DEX, 16, 20 }, 17, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 3200, 5000, 7 }, -{ N_("perfection"), { IPL_DEX, 21, 30 }, 23, AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 5200, 10000, 10 }, -{ N_("the fool"), { IPL_MAG_CURSE, 6, 10 }, 3, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -3 }, -{ N_("dyslexia"), { IPL_MAG_CURSE, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("magic"), { IPL_MAG, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 200, 1000, 2 }, -{ N_("the mind"), { IPL_MAG, 6, 10 }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 1200, 2000, 3 }, -{ N_("brilliance"), { IPL_MAG, 11, 15 }, 11, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 2200, 3000, 4 }, -{ N_("sorcery"), { IPL_MAG, 16, 20 }, 17, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 3200, 5000, 7 }, -{ N_("wizardry"), { IPL_MAG, 21, 30 }, 23, AffixItemType::Staff | AffixItemType::Misc, GOE_ANY, false, true, 5200, 10000, 10 }, -{ N_("illness"), { IPL_VIT_CURSE, 6, 10 }, 3, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -3 }, -{ N_("disease"), { IPL_VIT_CURSE, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("vitality"), { IPL_VIT, 1, 5 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_GOOD, false, true, 200, 1000, 2 }, -{ N_("zest"), { IPL_VIT, 6, 10 }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_GOOD, false, true, 1200, 2000, 3 }, -{ N_("vim"), { IPL_VIT, 11, 15 }, 11, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_GOOD, false, true, 2200, 3000, 4 }, -{ N_("vigor"), { IPL_VIT, 16, 20 }, 17, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_GOOD, false, true, 3200, 5000, 7 }, -{ N_("life"), { IPL_VIT, 21, 30 }, 23, AffixItemType::Misc, GOE_GOOD, false, true, 5200, 10000, 10 }, -{ N_("trouble"), { IPL_ATTRIBS_CURSE, 6, 10 }, 12, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -10 }, -{ N_("the pit"), { IPL_ATTRIBS_CURSE, 1, 5 }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -5 }, -{ N_("the sky"), { IPL_ATTRIBS, 1, 3 }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 800, 4000, 5 }, -{ N_("the moon"), { IPL_ATTRIBS, 4, 7 }, 11, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 4800, 8000, 10 }, -{ N_("the stars"), { IPL_ATTRIBS, 8, 11 }, 17, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 8800, 12000, 15 }, -{ N_("the heavens"), { IPL_ATTRIBS, 12, 15 }, 25, AffixItemType::Weapon | AffixItemType::Bow | AffixItemType::Misc, GOE_ANY, false, true, 12800, 20000, 20 }, -{ N_("the zodiac"), { IPL_ATTRIBS, 16, 20 }, 30, AffixItemType::Misc, GOE_ANY, false, true, 20800, 40000, 30 }, -{ N_("the vulture"), { IPL_LIFE_CURSE, 11, 25 }, 4, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -4 }, -{ N_("the jackal"), { IPL_LIFE_CURSE, 1, 10 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("the fox"), { IPL_LIFE, 10, 15 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_ANY, false, true, 100, 1000, 2 }, -{ N_("the jaguar"), { IPL_LIFE, 16, 20 }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_ANY, false, true, 1100, 2000, 3 }, -{ N_("the eagle"), { IPL_LIFE, 21, 30 }, 9, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_ANY, false, true, 2100, 4000, 5 }, -{ N_("the wolf"), { IPL_LIFE, 30, 40 }, 15, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_ANY, false, true, 4100, 6000, 7 }, -{ N_("the tiger"), { IPL_LIFE, 41, 50 }, 21, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_ANY, false, true, 6100, 10000, 9 }, -{ N_("the lion"), { IPL_LIFE, 51, 60 }, 27, AffixItemType::Armor | AffixItemType::Misc, GOE_ANY, false, true, 10100, 15000, 11 }, -{ N_("the mammoth"), { IPL_LIFE, 61, 80 }, 35, AffixItemType::Armor, GOE_ANY, false, true, 15100, 19000, 12 }, -{ N_("the whale"), { IPL_LIFE, 81, 100 }, 60, AffixItemType::Armor, GOE_ANY, false, true, 19100, 30000, 13 }, -{ N_("fragility"), { IPL_DUR_CURSE, 100, 100 }, 3, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon, GOE_EVIL, false, false, 0, 0, -4 }, -{ N_("brittleness"), { IPL_DUR_CURSE, 26, 75 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("sturdiness"), { IPL_DUR, 26, 75 }, 1, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 100, 100, 2 }, -{ N_("craftsmanship"), { IPL_DUR, 51, 100 }, 6, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 200, 200, 2 }, -{ N_("structure"), { IPL_DUR, 101, 200 }, 12, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 300, 300, 2 }, -{ N_("the ages"), { IPL_INDESTRUCTIBLE }, 25, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 600, 600, 5 }, -{ N_("the dark"), { IPL_LIGHT_CURSE, 4, 4 }, 6, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -3 }, -{ N_("the night"), { IPL_LIGHT_CURSE, 2, 2 }, 3, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Misc, GOE_EVIL, false, false, 0, 0, -2 }, -{ N_("light"), { IPL_LIGHT, 2, 2 }, 4, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Misc, GOE_GOOD, false, true, 750, 750, 2 }, -{ N_("radiance"), { IPL_LIGHT, 4, 4 }, 8, AffixItemType::Armor | AffixItemType::Weapon | AffixItemType::Misc, GOE_GOOD, false, true, 1500, 1500, 3 }, -{ N_("flame"), { IPL_FIRE_ARROWS, 1, 3 }, 1, AffixItemType::Bow, GOE_ANY, false, true, 2000, 2000, 2 }, -{ N_("fire"), { IPL_FIRE_ARROWS, 1, 6 }, 11, AffixItemType::Bow, GOE_ANY, false, true, 4000, 4000, 4 }, -{ N_("burning"), { IPL_FIRE_ARROWS, 1, 16 }, 35, AffixItemType::Bow, GOE_ANY, false, true, 6000, 6000, 6 }, -{ N_("shock"), { IPL_LIGHT_ARROWS, 1, 6 }, 13, AffixItemType::Bow, GOE_ANY, false, true, 6000, 6000, 2 }, -{ N_("lightning"), { IPL_LIGHT_ARROWS, 1, 10 }, 21, AffixItemType::Bow, GOE_ANY, false, true, 8000, 8000, 4 }, -{ N_("thunder"), { IPL_LIGHT_ARROWS, 1, 20 }, 60, AffixItemType::Bow, GOE_ANY, false, true, 12000, 12000, 6 }, -{ N_("many"), { IPL_DUR, 100, 100 }, 3, AffixItemType::Bow, GOE_ANY, false, true, 750, 750, 2 }, -{ N_("plenty"), { IPL_DUR, 200, 200 }, 7, AffixItemType::Bow, GOE_ANY, false, true, 1500, 1500, 3 }, -{ N_("thorns"), { IPL_THORNS, 1, 3 }, 1, AffixItemType::Armor | AffixItemType::Shield, GOE_ANY, false, true, 500, 500, 2 }, -{ N_("corruption"), { IPL_NOMANA }, 5, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Weapon, GOE_EVIL, false, false, -1000, -1000, 2 }, -{ N_("thieves"), { IPL_ABSHALFTRAP }, 11, AffixItemType::Armor | AffixItemType::Shield | AffixItemType::Misc, GOE_ANY, false, true, 1500, 1500, 2 }, -{ N_("the bear"), { IPL_KNOCKBACK }, 5, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_EVIL, false, true, 750, 750, 2 }, -{ N_("the bat"), { IPL_STEALMANA, 3, 3 }, 8, AffixItemType::Weapon, GOE_ANY, false, true, 7500, 7500, 3 }, -{ N_("vampires"), { IPL_STEALMANA, 5, 5 }, 19, AffixItemType::Weapon, GOE_ANY, false, true, 15000, 15000, 3 }, -{ N_("the leech"), { IPL_STEALLIFE, 3, 3 }, 8, AffixItemType::Weapon, GOE_ANY, false, true, 7500, 7500, 3 }, -{ N_("blood"), { IPL_STEALLIFE, 5, 5 }, 19, AffixItemType::Weapon, GOE_ANY, false, true, 15000, 15000, 3 }, -{ N_("piercing"), { IPL_TARGAC, 1, 1 }, 1, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, false, true, 1000, 1000, 3 }, -{ N_("puncturing"), { IPL_TARGAC, 2, 2 }, 9, AffixItemType::Weapon | AffixItemType::Bow, GOE_ANY, false, true, 2000, 2000, 6 }, -{ N_("bashing"), { IPL_TARGAC, 3, 3 }, 17, AffixItemType::Weapon, GOE_ANY, false, true, 4000, 4000, 12 }, -{ N_("readiness"), { IPL_FASTATTACK, 1, 1 }, 1, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 2000, 2000, 2 }, -{ N_("swiftness"), { IPL_FASTATTACK, 2, 2 }, 10, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 4000, 4000, 4 }, -{ N_("speed"), { IPL_FASTATTACK, 3, 3 }, 19, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 8000, 8000, 8 }, -{ N_("haste"), { IPL_FASTATTACK, 4, 4 }, 27, AffixItemType::Weapon | AffixItemType::Staff, GOE_ANY, false, true, 16000, 16000, 16 }, -{ N_("balance"), { IPL_FASTRECOVER, 1, 1 }, 1, AffixItemType::Armor | AffixItemType::Misc, GOE_ANY, false, true, 2000, 2000, 2 }, -{ N_("stability"), { IPL_FASTRECOVER, 2, 2 }, 10, AffixItemType::Armor | AffixItemType::Misc, GOE_ANY, false, true, 4000, 4000, 4 }, -{ N_("harmony"), { IPL_FASTRECOVER, 3, 3 }, 20, AffixItemType::Armor | AffixItemType::Misc, GOE_ANY, false, true, 8000, 8000, 8 }, -{ N_("blocking"), { IPL_FASTBLOCK, 1, 1 }, 5, AffixItemType::Shield, GOE_ANY, false, true, 4000, 4000, 4 }, -{ N_("devastation"), { IPL_DEVASTATION, 1, 1 }, 1, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 1200, 1200, 3 }, -{ N_("decay"), { IPL_DECAY, 150, 250 }, 1, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 200, 200, 2 }, - // TRANSLATORS: Item suffix section end. -{ N_("peril"), { IPL_PERIL, 1, 1 }, 5, AffixItemType::Weapon | AffixItemType::Staff | AffixItemType::Bow, GOE_ANY, false, true, 500, 500, 1 }, -{ "", { }, 0, AffixItemType::None, GOE_ANY, false, false, 0, 0, 0 }, - // clang-format on -}; + // param1 + advance(); + if (!(*fieldIt).value().empty()) { + if (tl::expected result = (*fieldIt).parseInt(power.param1); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, StrCat(fieldName, ".param1"), *fieldIt); + } + } -/** Contains the data related to each unique item ID. */ -const UniqueItem UniqueItems[] = { - // clang-format off -// UIName, UIItemId, UIMinLvl, UINumPL, UIValue, { ItemPower[0], ItemPower[1], ItemPower[2], ItemPower[3], ItemPower[4], ItemPower[5] } - // TRANSLATORS: Unique Item section -{ N_("The Butcher's Cleaver"), UITYPE_CLEAVER, 1, 3, 3650, { { IPL_STR, 10, 10 }, { IPL_SETDAM, 4, 24 }, { IPL_SETDUR, 10, 10 }, { }, { }, { } } }, -{ N_("The Undead Crown"), UITYPE_SKCROWN, 1, 3, 16650, { { IPL_RNDSTEALLIFE }, { IPL_SETAC, 8, 8 }, { IPL_INVCURS, 77 }, { }, { }, { } } }, -{ N_("Empyrean Band"), UITYPE_INFRARING, 1, 4, 8000, { { IPL_ATTRIBS, 2, 2 }, { IPL_LIGHT, 2, 2 }, { IPL_FASTRECOVER, 1, 1 }, { IPL_ABSHALFTRAP }, { }, { } } }, -{ N_("Optic Amulet"), UITYPE_OPTAMULET, 1, 5, 9750, { { IPL_LIGHT, 2, 2 }, { IPL_LIGHTRES, 20, 20 }, { IPL_GETHIT, 1, 1 }, { IPL_MAG, 5, 5 }, { IPL_INVCURS, 44 }, { } } }, -{ N_("Ring of Truth"), UITYPE_TRING, 1, 4, 9100, { { IPL_LIFE, 10, 10 }, { IPL_GETHIT, 1, 1 }, { IPL_ALLRES, 10, 10 }, { IPL_INVCURS, 10 }, { }, { } } }, -{ N_("Harlequin Crest"), UITYPE_HARCREST, 1, 6, 4000, { { IPL_AC_CURSE, 3, 3 }, { IPL_GETHIT, 1, 1 }, { IPL_ATTRIBS, 2, 2 }, { IPL_LIFE, 7, 7 }, { IPL_MANA, 7, 7 }, { IPL_INVCURS, 81 } } }, -{ N_("Veil of Steel"), UITYPE_STEELVEIL, 1, 6, 63800, { { IPL_ALLRES, 50, 50 }, { IPL_LIGHT_CURSE, 2, 2 }, { IPL_ACP, 60, 60 }, { IPL_MANA_CURSE, 30, 30 }, { IPL_STR, 15, 15 }, { IPL_VIT, 15, 15 } } }, -{ N_("Arkaine's Valor"), UITYPE_ARMOFVAL, 1, 4, 42000, { { IPL_SETAC, 25, 25 }, { IPL_VIT, 10, 10 }, { IPL_GETHIT, 3, 3 }, { IPL_FASTRECOVER, 3, 3 }, { }, { } } }, -{ N_("Griswold's Edge"), UITYPE_GRISWOLD, 1, 6, 42000, { { IPL_FIREDAM, 1, 10 }, { IPL_TOHIT, 25, 25 }, { IPL_FASTATTACK, 2, 2 }, { IPL_KNOCKBACK }, { IPL_MANA, 20, 20 }, { IPL_LIFE_CURSE, 20, 20 } } }, -{ N_("Bovine Plate"), UITYPE_BOVINE, 1, 6, 400, { { IPL_SETAC, 150, 150 }, { IPL_INDESTRUCTIBLE }, { IPL_LIGHT, 5, 5 }, { IPL_ALLRES, 30, 30 }, { IPL_MANA_CURSE, 50, 50 }, { IPL_SPLLVLADD, -2, -2 } } }, -{ N_("The Rift Bow"), UITYPE_SHORTBOW, 1, 3, 1800, { { IPL_RNDARROWVEL }, { IPL_DAMMOD, 2, 2 }, { IPL_DEX_CURSE, 3, 3 }, { }, { }, { } } }, -{ N_("The Needler"), UITYPE_SHORTBOW, 2, 4, 8900, { { IPL_TOHIT, 50, 50 }, { IPL_SETDAM, 1, 3 }, { IPL_FASTATTACK, 2, 2 }, { IPL_INVCURS, 158 }, { }, { } } }, -{ N_("The Celestial Bow"), UITYPE_LONGBOW, 2, 4, 1200, { { IPL_NOMINSTR }, { IPL_DAMMOD, 2, 2 }, { IPL_SETAC, 5, 5 }, { IPL_INVCURS, 133 }, { }, { } } }, -{ N_("Deadly Hunter"), UITYPE_COMPBOW, 3, 4, 8750, { { IPL_3XDAMVDEM, 10, 10 }, { IPL_TOHIT, 20, 20 }, { IPL_MAG_CURSE, 5, 5 }, { IPL_INVCURS, 108 }, { }, { } } }, -{ N_("Bow of the Dead"), UITYPE_COMPBOW, 5, 6, 2500, { { IPL_TOHIT, 10, 10 }, { IPL_DEX, 4, 4 }, { IPL_VIT_CURSE, 3, 3 }, { IPL_LIGHT_CURSE, 2, 2 }, { IPL_SETDUR, 30, 30 }, { IPL_INVCURS, 108 } } }, -{ N_("The Blackoak Bow"), UITYPE_LONGBOW, 5, 4, 2500, { { IPL_DEX, 10, 10 }, { IPL_VIT_CURSE, 10, 10 }, { IPL_DAMP, 50, 50 }, { IPL_LIGHT_CURSE, 1, 1 }, { }, { } } }, -{ N_("Flamedart"), UITYPE_HUNTBOW, 10, 4, 14250, { { IPL_FIRE_ARROWS, 0, 0 }, { IPL_FIREDAM, 1, 6 }, { IPL_TOHIT, 20, 20 }, { IPL_FIRERES, 40, 40 }, { }, { } } }, -{ N_("Fleshstinger"), UITYPE_LONGBOW, 13, 4, 16500, { { IPL_DEX, 15, 15 }, { IPL_TOHIT, 40, 40 }, { IPL_DAMP, 80, 80 }, { IPL_DUR, 6, 6 }, { }, { } } }, -{ N_("Windforce"), UITYPE_WARBOW, 17, 4, 37750, { { IPL_STR, 5, 5 }, { IPL_DAMP, 200, 200 }, { IPL_KNOCKBACK }, { IPL_INVCURS, 164 }, { }, { } } }, -{ N_("Eaglehorn"), UITYPE_BATTLEBOW, 26, 5, 42500, { { IPL_DEX, 20, 20 }, { IPL_TOHIT, 50, 50 }, { IPL_DAMP, 100, 100 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 108 }, { } } }, -{ N_("Gonnagal's Dirk"), UITYPE_DAGGER, 1, 5, 7040, { { IPL_DEX_CURSE, 5, 5 }, { IPL_DAMMOD, 4, 4 }, { IPL_FASTATTACK, 2, 2 }, { IPL_FIRERES, 25, 25 }, { IPL_INVCURS, 54 }, { } } }, -{ N_("The Defender"), UITYPE_SABRE, 1, 3, 2000, { { IPL_SETAC, 5, 5 }, { IPL_VIT, 5, 5 }, { IPL_TOHIT_CURSE, 5, 5 }, { }, { }, { } } }, -{ N_("Gryphon's Claw"), UITYPE_FALCHION, 1, 4, 1000, { { IPL_DAMP, 100, 100 }, { IPL_MAG_CURSE, 2, 2 }, { IPL_DEX_CURSE, 5, 5 }, { IPL_INVCURS, 68 }, { }, { } } }, -{ N_("Black Razor"), UITYPE_DAGGER, 1, 4, 2000, { { IPL_DAMP, 150, 150 }, { IPL_VIT, 2, 2 }, { IPL_SETDUR, 5, 5 }, { IPL_INVCURS, 53 }, { }, { } } }, -{ N_("Gibbous Moon"), UITYPE_BROADSWR, 2, 4, 6660, { { IPL_ATTRIBS, 2, 2 }, { IPL_DAMP, 25, 25 }, { IPL_MANA, 15, 15 }, { IPL_LIGHT_CURSE, 3, 3 }, { }, { } } }, -{ N_("Ice Shank"), UITYPE_LONGSWR, 3, 3, 5250, { { IPL_FIRERES, 40, 40 }, { IPL_SETDUR, 15, 15 }, { IPL_STR, 5, 10 }, { }, { }, { } } }, -{ N_("The Executioner's Blade"), UITYPE_FALCHION, 3, 5, 7080, { { IPL_DAMP, 150, 150 }, { IPL_LIFE_CURSE, 10, 10 }, { IPL_LIGHT_CURSE, 1, 1 }, { IPL_DUR, 200, 200 }, { IPL_INVCURS, 58 }, { } } }, -{ N_("The Bonesaw"), UITYPE_CLAYMORE, 6, 6, 4400, { { IPL_DAMMOD, 10, 10 }, { IPL_STR, 10, 10 }, { IPL_MAG_CURSE, 5, 5 }, { IPL_DEX_CURSE, 5, 5 }, { IPL_LIFE, 10, 10 }, { IPL_MANA_CURSE, 10, 10 } } }, -{ N_("Shadowhawk"), UITYPE_BROADSWR, 8, 4, 13750, { { IPL_LIGHT_CURSE, 2, 2 }, { IPL_STEALLIFE, 5, 5 }, { IPL_TOHIT, 15, 15 }, { IPL_ALLRES, 5, 5 }, { }, { } } }, -{ N_("Wizardspike"), UITYPE_DAGGER, 11, 5, 12920, { { IPL_MAG, 15, 15 }, { IPL_MANA, 35, 35 }, { IPL_TOHIT, 25, 25 }, { IPL_ALLRES, 15, 15 }, { IPL_INVCURS, 50 }, { } } }, -{ N_("Lightsabre"), UITYPE_SABRE, 13, 4, 19150, { { IPL_LIGHT, 2, 2 }, { IPL_LIGHTDAM, 1, 10 }, { IPL_TOHIT, 20, 20 }, { IPL_LIGHTRES, 50, 50 }, { }, { } } }, -{ N_("The Falcon's Talon"), UITYPE_SCIMITAR, 15, 5, 7867, { { IPL_FASTATTACK, 4, 4 }, { IPL_TOHIT, 20, 20 }, { IPL_DAMP_CURSE, 33, 33 }, { IPL_DEX, 10, 10 }, { IPL_INVCURS, 68 }, { } } }, -{ N_("Inferno"), UITYPE_LONGSWR, 17, 4, 34600, { { IPL_FIREDAM, 2, 12 }, { IPL_LIGHT, 3, 3 }, { IPL_MANA, 20, 20 }, { IPL_FIRERES, 80, 80 }, { }, { } } }, -{ N_("Doombringer"), UITYPE_BASTARDSWR, 19, 5, 18250, { { IPL_TOHIT, 25, 25 }, { IPL_DAMP, 250, 250 }, { IPL_ATTRIBS_CURSE, 5, 5 }, { IPL_LIFE_CURSE, 25, 25 }, { IPL_LIGHT_CURSE, 2, 2 }, { } } }, -{ N_("The Grizzly"), UITYPE_TWOHANDSWR, 23, 6, 50000, { { IPL_STR, 20, 20 }, { IPL_VIT_CURSE, 5, 5 }, { IPL_DAMP, 200, 200 }, { IPL_KNOCKBACK }, { IPL_DUR, 100, 100 }, { IPL_INVCURS, 160 } } }, -{ N_("The Grandfather"), UITYPE_GREATSWR, 27, 6, 119800, { { IPL_ONEHAND }, { IPL_ATTRIBS, 5, 5 }, { IPL_TOHIT, 20, 20 }, { IPL_DAMP, 70, 70 }, { IPL_LIFE, 20, 20 }, { IPL_INVCURS, 161 } } }, -{ N_("The Mangler"), UITYPE_LARGEAXE, 2, 5, 2850, { { IPL_DAMP, 200, 200 }, { IPL_DEX_CURSE, 5, 5 }, { IPL_MAG_CURSE, 5, 5 }, { IPL_MANA_CURSE, 10, 10 }, { IPL_INVCURS, 144 }, { } } }, -{ N_("Sharp Beak"), UITYPE_LARGEAXE, 2, 4, 2850, { { IPL_LIFE, 20, 20 }, { IPL_MAG_CURSE, 10, 10 }, { IPL_MANA_CURSE, 10, 10 }, { IPL_INVCURS, 143 }, { }, { } } }, -{ N_("BloodSlayer"), UITYPE_BROADAXE, 3, 5, 2500, { { IPL_DAMP, 100, 100 }, { IPL_3XDAMVDEM, 50, 50 }, { IPL_ATTRIBS_CURSE, 5, 5 }, { IPL_SPLLVLADD, -1, -1 }, { IPL_INVCURS, 144 }, { } } }, -{ N_("The Celestial Axe"), UITYPE_BATTLEAXE, 4, 4, 14100, { { IPL_NOMINSTR }, { IPL_TOHIT, 15, 15 }, { IPL_LIFE, 15, 15 }, { IPL_STR_CURSE, 15, 15 }, { }, { } } }, -{ N_("Wicked Axe"), UITYPE_LARGEAXE, 5, 6, 31150, { { IPL_TOHIT, 30, 30 }, { IPL_DEX, 10, 10 }, { IPL_VIT_CURSE, 10, 10 }, { IPL_GETHIT, 1, 6 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 143 } } }, -{ N_("Stonecleaver"), UITYPE_BROADAXE, 7, 5, 23900, { { IPL_LIFE, 30, 30 }, { IPL_TOHIT, 20, 20 }, { IPL_DAMP, 50, 50 }, { IPL_LIGHTRES, 40, 40 }, { IPL_INVCURS, 104 }, { } } }, -{ N_("Aguinara's Hatchet"), UITYPE_SMALLAXE, 12, 3, 24800, { { IPL_SPLLVLADD, 1, 1 }, { IPL_MAG, 10, 10 }, { IPL_MAGICRES, 80, 80 }, { }, { }, { } } }, -{ N_("Hellslayer"), UITYPE_BATTLEAXE, 15, 5, 26200, { { IPL_STR, 8, 8 }, { IPL_VIT, 8, 8 }, { IPL_DAMP, 100, 100 }, { IPL_LIFE, 25, 25 }, { IPL_MANA_CURSE, 25, 25 }, { } } }, -{ N_("Messerschmidt's Reaver"), UITYPE_GREATAXE, 25, 6, 58000, { { IPL_DAMP, 200, 200 }, { IPL_DAMMOD, 15, 15 }, { IPL_ATTRIBS, 5, 5 }, { IPL_LIFE_CURSE, 50, 50 }, { IPL_FIREDAM, 2, 12 }, { IPL_INVCURS, 163 } } }, -{ N_("Crackrust"), UITYPE_MACE, 1, 5, 11375, { { IPL_ATTRIBS, 2, 2 }, { IPL_INDESTRUCTIBLE }, { IPL_ALLRES, 15, 15 }, { IPL_DAMP, 50, 50 }, { IPL_SPLLVLADD, -1, -1 }, { } } }, -{ N_("Hammer of Jholm"), UITYPE_MAUL, 1, 4, 8700, { { IPL_DAMP, 4, 10 }, { IPL_INDESTRUCTIBLE }, { IPL_STR, 3, 3 }, { IPL_TOHIT, 15, 15 }, { }, { } } }, -{ N_("Civerb's Cudgel"), UITYPE_MACE, 1, 3, 2000, { { IPL_3XDAMVDEM, 35, 35 }, { IPL_DEX_CURSE, 5, 5 }, { IPL_MAG_CURSE, 2, 2 }, { }, { }, { } } }, -{ N_("The Celestial Star"), UITYPE_FLAIL, 2, 5, 7810, { { IPL_NOMINSTR }, { IPL_LIGHT, 2, 2 }, { IPL_DAMMOD, 10, 10 }, { IPL_AC_CURSE, 8, 8 }, { IPL_INVCURS, 131 }, { } } }, -{ N_("Baranar's Star"), UITYPE_MORNSTAR, 5, 6, 6850, { { IPL_TOHIT, 12, 12 }, { IPL_DAMP, 80, 80 }, { IPL_FASTATTACK, 1, 1 }, { IPL_VIT, 4, 4 }, { IPL_DEX_CURSE, 4, 4 }, { IPL_SETDUR, 60, 60 } } }, -{ N_("Gnarled Root"), UITYPE_SPIKCLUB, 9, 6, 9820, { { IPL_TOHIT, 20, 20 }, { IPL_DAMP, 300, 300 }, { IPL_DEX, 10, 10 }, { IPL_MAG, 5, 5 }, { IPL_ALLRES, 10, 10 }, { IPL_AC_CURSE, 10, 10 } } }, -{ N_("The Cranium Basher"), UITYPE_MAUL, 12, 6, 36500, { { IPL_DAMMOD, 20, 20 }, { IPL_STR, 15, 15 }, { IPL_INDESTRUCTIBLE }, { IPL_MANA_CURSE, 150, 150 }, { IPL_ALLRES, 5, 5 }, { IPL_INVCURS, 122 } } }, -{ N_("Schaefer's Hammer"), UITYPE_WARHAMMER, 16, 6, 56125, { { IPL_DAMP_CURSE, 100, 100 }, { IPL_LIGHTDAM, 1, 50 }, { IPL_LIFE, 50, 50 }, { IPL_TOHIT, 30, 30 }, { IPL_LIGHTRES, 80, 80 }, { IPL_LIGHT, 1, 1 } } }, -{ N_("Dreamflange"), UITYPE_MACE, 26, 5, 26450, { { IPL_MAG, 30, 30 }, { IPL_MANA, 50, 50 }, { IPL_MAGICRES, 50, 50 }, { IPL_LIGHT, 2, 2 }, { IPL_SPLLVLADD, 1, 1 }, { } } }, -{ N_("Staff of Shadows"), UITYPE_LONGSTAFF, 2, 5, 1250, { { IPL_MAG_CURSE, 10, 10 }, { IPL_TOHIT, 10, 10 }, { IPL_DAMP, 60, 60 }, { IPL_LIGHT_CURSE, 2, 2 }, { IPL_FASTATTACK, 1, 1 }, { } } }, -{ N_("Immolator"), UITYPE_LONGSTAFF, 4, 4, 3900, { { IPL_FIRERES, 20, 20 }, { IPL_FIREDAM, 4, 4 }, { IPL_MANA, 10, 10 }, { IPL_VIT_CURSE, 5, 5 }, { }, { } } }, -{ N_("Storm Spire"), UITYPE_WARSTAFF, 8, 4, 22500, { { IPL_LIGHTRES, 50, 50 }, { IPL_LIGHTDAM, 2, 8 }, { IPL_STR, 10, 10 }, { IPL_MAG_CURSE, 10, 10 }, { }, { } } }, -{ N_("Gleamsong"), UITYPE_SHORTSTAFF, 8, 4, 6520, { { IPL_MANA, 25, 25 }, { IPL_STR_CURSE, 3, 3 }, { IPL_VIT_CURSE, 3, 3 }, { IPL_SPELL, 10, 76 }, { }, { } } }, -{ N_("Thundercall"), UITYPE_COMPSTAFF, 14, 5, 22250, { { IPL_TOHIT, 35, 35 }, { IPL_LIGHTDAM, 1, 10 }, { IPL_SPELL, 3, 76 }, { IPL_LIGHTRES, 30, 30 }, { IPL_LIGHT, 2, 2 }, { } } }, -{ N_("The Protector"), UITYPE_SHORTSTAFF, 16, 6, 17240, { { IPL_VIT, 5, 5 }, { IPL_GETHIT, 5, 5 }, { IPL_SETAC, 40, 40 }, { IPL_SPELL, 2, 86 }, { IPL_THORNS, 1, 3 }, { IPL_INVCURS, 162 } } }, -{ N_("Naj's Puzzler"), UITYPE_LONGSTAFF, 18, 5, 34000, { { IPL_MAG, 20, 20 }, { IPL_DEX, 10, 10 }, { IPL_ALLRES, 20, 20 }, { IPL_SPELL, 23, 57 }, { IPL_LIFE_CURSE, 25, 25 }, { } } }, -{ N_("Mindcry"), UITYPE_QUARSTAFF, 20, 4, 41500, { { IPL_MAG, 15, 15 }, { IPL_SPELL, 13, 69 }, { IPL_ALLRES, 15, 15 }, { IPL_SPLLVLADD, 1, 1 }, { }, { } } }, -{ N_("Rod of Onan"), UITYPE_WARSTAFF, 22, 3, 44167, { { IPL_SPELL, 21, 50 }, { IPL_DAMP, 100, 100 }, { IPL_ATTRIBS, 5, 5 }, { }, { }, { } } }, -{ N_("Helm of Spirits"), UITYPE_HELM, 1, 2, 7525, { { IPL_STEALLIFE, 5, 5 }, { IPL_INVCURS, 77 }, { }, { }, { }, { } } }, -{ N_("Thinking Cap"), UITYPE_SKULLCAP, 6, 5, 2020, { { IPL_MANA, 30, 30 }, { IPL_SPLLVLADD, 2, 2 }, { IPL_ALLRES, 20, 20 }, { IPL_SETDUR, 1, 1 }, { IPL_INVCURS, 93 }, { } } }, -{ N_("OverLord's Helm"), UITYPE_HELM, 7, 6, 12500, { { IPL_STR, 20, 20 }, { IPL_DEX, 15, 15 }, { IPL_VIT, 5, 5 }, { IPL_MAG_CURSE, 20, 20 }, { IPL_SETDUR, 15, 15 }, { IPL_INVCURS, 99 } } }, -{ N_("Fool's Crest"), UITYPE_HELM, 12, 5, 10150, { { IPL_ATTRIBS_CURSE, 4, 4 }, { IPL_LIFE, 100, 100 }, { IPL_GETHIT_CURSE, 1, 6 }, { IPL_THORNS, 1, 3 }, { IPL_INVCURS, 80 }, { } } }, -{ N_("Gotterdamerung"), UITYPE_GREATHELM, 21, 6, 54900, { { IPL_ATTRIBS, 20, 20 }, { IPL_SETAC, 60, 60 }, { IPL_GETHIT, 4, 4 }, { IPL_ALLRESZERO }, { IPL_LIGHT_CURSE, 4, 4 }, { IPL_INVCURS, 85 } } }, -{ N_("Royal Circlet"), UITYPE_CROWN, 27, 5, 24875, { { IPL_ATTRIBS, 10, 10 }, { IPL_MANA, 40, 40 }, { IPL_SETAC, 40, 40 }, { IPL_LIGHT, 1, 1 }, { IPL_INVCURS, 79 }, { } } }, -{ N_("Torn Flesh of Souls"), UITYPE_RAGS, 2, 5, 4825, { { IPL_SETAC, 8, 8 }, { IPL_VIT, 10, 10 }, { IPL_GETHIT, 1, 1 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 92 }, { } } }, -{ N_("The Gladiator's Bane"), UITYPE_STUDARMOR, 6, 4, 3450, { { IPL_SETAC, 25, 25 }, { IPL_GETHIT, 2, 2 }, { IPL_DUR, 200, 200 }, { IPL_ATTRIBS_CURSE, 3, 3 }, { }, { } } }, -{ N_("The Rainbow Cloak"), UITYPE_CLOAK, 2, 6, 4900, { { IPL_SETAC, 10, 10 }, { IPL_ATTRIBS, 1, 1 }, { IPL_ALLRES, 10, 10 }, { IPL_LIFE, 5, 5 }, { IPL_DUR, 50, 50 }, { IPL_INVCURS, 138 } } }, -{ N_("Leather of Aut"), UITYPE_LEATHARMOR, 4, 5, 10550, { { IPL_SETAC, 15, 15 }, { IPL_STR, 5, 5 }, { IPL_MAG_CURSE, 5, 5 }, { IPL_DEX, 5, 5 }, { IPL_INDESTRUCTIBLE }, { } } }, -{ N_("Wisdom's Wrap"), UITYPE_ROBE, 5, 6, 6200, { { IPL_MAG, 5, 5 }, { IPL_MANA, 10, 10 }, { IPL_LIGHTRES, 25, 25 }, { IPL_SETAC, 15, 15 }, { IPL_GETHIT, 1, 1 }, { IPL_INVCURS, 138 } } }, -{ N_("Sparking Mail"), UITYPE_CHAINMAIL, 9, 2, 15750, { { IPL_SETAC, 30, 30 }, { IPL_LIGHTDAM, 1, 10 }, { }, { }, { }, { } } }, -{ N_("Scavenger Carapace"), UITYPE_BREASTPLATE, 13, 4, 14000, { { IPL_GETHIT, 15, 15 }, { IPL_AC_CURSE, 30, 30 }, { IPL_DEX, 5, 5 }, { IPL_LIGHTRES, 40, 40 }, { }, { } } }, -{ N_("Nightscape"), UITYPE_CAPE, 16, 6, 11600, { { IPL_FASTRECOVER, 2, 2 }, { IPL_LIGHT_CURSE, 4, 4 }, { IPL_SETAC, 15, 15 }, { IPL_DEX, 3, 3 }, { IPL_ALLRES, 20, 20 }, { IPL_INVCURS, 138 } } }, -{ N_("Naj's Light Plate"), UITYPE_PLATEMAIL, 19, 6, 78700, { { IPL_NOMINSTR }, { IPL_MAG, 5, 5 }, { IPL_MANA, 20, 20 }, { IPL_ALLRES, 20, 20 }, { IPL_SPLLVLADD, 1, 1 }, { IPL_INVCURS, 159 } } }, -{ N_("Demonspike Coat"), UITYPE_FULLPLATE, 25, 5, 251175, { { IPL_SETAC, 100, 100 }, { IPL_GETHIT, 6, 6 }, { IPL_STR, 10, 10 }, { IPL_INDESTRUCTIBLE }, { IPL_FIRERES, 50, 50 }, { } } }, -{ N_("The Deflector"), UITYPE_BUCKLER, 1, 5, 1500, { { IPL_SETAC, 7, 7 }, { IPL_ALLRES, 10, 10 }, { IPL_DAMP_CURSE, 20, 20 }, { IPL_TOHIT_CURSE, 5, 5 }, { IPL_INVCURS, 83 }, { } } }, -{ N_("Split Skull Shield"), UITYPE_BUCKLER, 1, 6, 2025, { { IPL_SETAC, 10, 10 }, { IPL_LIFE, 10, 10 }, { IPL_STR, 2, 2 }, { IPL_LIGHT_CURSE, 1, 1 }, { IPL_SETDUR, 15, 15 }, { IPL_INVCURS, 116 } } }, -{ N_("Dragon's Breach"), UITYPE_KITESHIELD, 2, 6, 19200, { { IPL_FIRERES, 25, 25 }, { IPL_STR, 5, 5 }, { IPL_SETAC, 20, 20 }, { IPL_MAG_CURSE, 5, 5 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 117 } } }, -{ N_("Blackoak Shield"), UITYPE_SMALLSHIELD, 4, 6, 5725, { { IPL_DEX, 10, 10 }, { IPL_VIT_CURSE, 10, 10 }, { IPL_SETAC, 18, 18 }, { IPL_LIGHT_CURSE, 1, 1 }, { IPL_DUR, 150, 150 }, { IPL_INVCURS, 146 } } }, -{ N_("Holy Defender"), UITYPE_LARGESHIELD, 10, 6, 13800, { { IPL_SETAC, 15, 15 }, { IPL_GETHIT, 2, 2 }, { IPL_FIRERES, 20, 20 }, { IPL_DUR, 200, 200 }, { IPL_FASTBLOCK, 1, 1 }, { IPL_INVCURS, 146 } } }, -{ N_("Stormshield"), UITYPE_GOTHSHIELD, 24, 6, 49000, { { IPL_SETAC, 40, 40 }, { IPL_GETHIT_CURSE, 4, 4 }, { IPL_STR, 10, 10 }, { IPL_INDESTRUCTIBLE }, { IPL_FASTBLOCK, 1, 1 }, { IPL_INVCURS, 148 } } }, -{ N_("Bramble"), UITYPE_RING, 1, 4, 1000, { { IPL_ATTRIBS_CURSE, 2, 2 }, { IPL_DAMMOD, 3, 3 }, { IPL_MANA, 10, 10 }, { IPL_INVCURS, 9 }, { }, { } } }, -{ N_("Ring of Regha"), UITYPE_RING, 1, 6, 4175, { { IPL_MAG, 10, 10 }, { IPL_MAGICRES, 10, 10 }, { IPL_LIGHT, 1, 1 }, { IPL_STR_CURSE, 3, 3 }, { IPL_DEX_CURSE, 3, 3 }, { IPL_INVCURS, 11 } } }, -{ N_("The Bleeder"), UITYPE_RING, 2, 4, 8500, { { IPL_MAGICRES, 20, 20 }, { IPL_MANA, 30, 30 }, { IPL_LIFE_CURSE, 10, 10 }, { IPL_INVCURS, 8 }, { }, { } } }, -{ N_("Constricting Ring"), UITYPE_RING, 5, 3, 62000, { { IPL_ALLRES, 75, 75 }, { IPL_DRAINLIFE }, { IPL_INVCURS, 14 }, { }, { }, { } } }, -{ N_("Ring of Engagement"), UITYPE_RING, 11, 5, 12476, { { IPL_GETHIT, 1, 2 }, { IPL_THORNS, 1, 3 }, { IPL_SETAC, 5, 5 }, { IPL_TARGAC, 2, 2 }, { IPL_INVCURS, 13 }, { } } }, -{ N_("Giant's Knuckle"), UITYPE_RING, 8, 3, 8000, { { IPL_STR, 60, 60 }, { IPL_DEX_CURSE, 30, 30 }, { IPL_INVCURS, 179 }, { }, { }, { } } }, -{ N_("Mercurial Ring"), UITYPE_RING, 8, 3, 8000, { { IPL_DEX, 60, 60 }, { IPL_STR_CURSE, 30, 30 }, { IPL_INVCURS, 176 }, { }, { }, { } } }, -{ N_("Xorine's Ring"), UITYPE_RING, 8, 3, 8000, { { IPL_MAG, 60, 60 }, { IPL_STR_CURSE, 30, 30 }, { IPL_INVCURS, 168 }, { }, { }, { } } }, -{ N_("Karik's Ring"), UITYPE_RING, 8, 3, 8000, { { IPL_VIT, 60, 60 }, { IPL_MAG_CURSE, 30, 30 }, { IPL_INVCURS, 173 }, { }, { }, { } } }, -{ N_("Ring of Magma"), UITYPE_RING, 8, 4, 8000, { { IPL_FIRERES, 60, 60 }, { IPL_LIGHTRES_CURSE, 30, 30 }, { IPL_MAGICRES_CURSE, 30, 30 }, { IPL_INVCURS, 184 }, { }, { } } }, -{ N_("Ring of the Mystics"), UITYPE_RING, 8, 4, 8000, { { IPL_MAGICRES, 60, 60 }, { IPL_FIRERES_CURSE, 30, 30 }, { IPL_LIGHTRES_CURSE, 30, 30 }, { IPL_INVCURS, 181 }, { }, { } } }, -{ N_("Ring of Thunder"), UITYPE_RING, 8, 4, 8000, { { IPL_LIGHTRES, 60, 60 }, { IPL_FIRERES_CURSE, 30, 30 }, { IPL_MAGICRES_CURSE, 30, 30 }, { IPL_INVCURS, 177 }, { }, { } } }, -{ N_("Amulet of Warding"), UITYPE_AMULET, 12, 3, 30000, { { IPL_ALLRES, 40, 40 }, { IPL_LIFE_CURSE, 100, 100 }, { IPL_INVCURS, 170 }, { }, { }, { } } }, -{ N_("Gnat Sting"), UITYPE_HUNTBOW, 15, 5, 30000, { { IPL_MULT_ARROWS, 3, 3 }, { IPL_SETDAM, 1, 2 }, { IPL_FASTATTACK, 1, 1 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 210 }, { } } }, -{ N_("Flambeau"), UITYPE_COMPBOW, 11, 4, 30000, { { IPL_FIREBALL, 15, 20 }, { IPL_SETDAM, 0, 0 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 209 }, { }, { } } }, -{ N_("Armor of Gloom"), UITYPE_FULLPLATE, 25, 5, 200000, { { IPL_NOMINSTR }, { IPL_SETAC, 225, 225 }, { IPL_ALLRESZERO }, { IPL_LIGHT_CURSE, 2, 2 }, { IPL_INVCURS, 203 }, { } } }, -{ N_("Blitzen"), UITYPE_COMPBOW, 13, 4, 30000, { { IPL_ADDACLIFE, 10, 15 }, { IPL_SETDAM, 0, 0 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 219 }, { }, { } } }, -{ N_("Thunderclap"), UITYPE_WARHAMMER, 13, 6, 30000, { { IPL_ADDMANAAC, 3, 6 }, { IPL_STR, 20, 20 }, { IPL_LIGHTRES, 30, 30 }, { IPL_LIGHT, 2, 2 }, { IPL_INDESTRUCTIBLE }, { IPL_INVCURS, 205 } } }, -{ N_("Shirotachi"), UITYPE_GREATSWR, 21, 4, 36000, { { IPL_ONEHAND }, { IPL_FASTATTACK, 4, 4 }, { IPL_TARGAC, 2, 2 }, { IPL_LIGHTDAM, 6, 6 }, { }, { } } }, -{ N_("Eater of Souls"), UITYPE_TWOHANDSWR, 23, 6, 42000, { { IPL_INDESTRUCTIBLE }, { IPL_LIFE, 50, 50 }, { IPL_STEALLIFE, 5, 5 }, { IPL_STEALMANA, 5, 5 }, { IPL_DRAINLIFE }, { IPL_INVCURS, 200 } } }, -{ N_("Diamondedge"), UITYPE_LONGSWR, 17, 6, 42000, { { IPL_SETDUR, 10, 10 }, { IPL_TOHIT, 50, 50 }, { IPL_DAMP, 100, 100 }, { IPL_LIGHTRES, 50, 50 }, { IPL_SETAC, 10, 10 }, { IPL_INVCURS, 206 } } }, -{ N_("Bone Chain Armor"), UITYPE_CHAINMAIL, 13, 3, 36000, { { IPL_SETAC, 40, 40 }, { IPL_ACUNDEAD }, { IPL_INVCURS, 204 }, { }, { }, { } } }, -{ N_("Demon Plate Armor"), UITYPE_FULLPLATE, 25, 3, 80000, { { IPL_SETAC, 80, 80 }, { IPL_ACDEMON }, { IPL_INVCURS, 225 }, { }, { }, { } } }, -{ N_("Acolyte's Amulet"), UITYPE_AMULET, 10, 2, 10000, { { IPL_MANATOLIFE, 50, 50 }, { IPL_INVCURS, 183 }, { }, { }, { }, { } } }, - // TRANSLATORS: Unique Item section end. -{ N_("Gladiator's Ring"), UITYPE_RING, 10, 2, 10000, { { IPL_LIFETOMANA, 40, 40 }, { IPL_INVCURS, 186 }, { }, { }, { }, { } } }, -{ "", UITYPE_INVALID, 0, 0, 0, { { }, { }, { }, { }, { }, { } } }, - // clang-format on -}; + // param2 + advance(); + if (!(*fieldIt).value().empty()) { + if (tl::expected result = (*fieldIt).parseInt(power.param2); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, StrCat(fieldName, ".param2"), *fieldIt); + } + } +} + +void LoadUniqueItemDat() +{ + const std::string_view filename = "txtdata\\items\\unique_itemdat.tsv"; + tl::expected dataFileResult = DataFile::load(filename); + if (!dataFileResult.has_value()) { + DataFile::reportFatalError(dataFileResult.error(), filename); + } + + DataFile &dataFile = dataFileResult.value(); + if (tl::expected result = dataFile.skipHeader(); + !result.has_value()) { + DataFile::reportFatalError(result.error(), filename); + } + + UniqueItems.clear(); + UniqueItems.reserve(dataFile.numRecords()); + for (DataFileRecord record : dataFile) { + FieldIterator fieldIt = record.begin(); + const FieldIterator endField = record.end(); + + UniqueItems.emplace_back(); + UniqueItem &item = UniqueItems.back(); + + const auto advance = [&]() { + ++fieldIt; + if (fieldIt == endField) { + DataFile::reportFatalError(DataFile::Error::NotEnoughColumns, filename); + } + }; + + // name + item.UIName = (*fieldIt).value(); + + // uniqueBaseItem + advance(); + if (tl::expected result = ParseUniqueBaseItem((*fieldIt).value()); result.has_value()) { + item.UIItemId = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "class", *fieldIt, result.error()); + } + + // minLevel + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.UIMinLvl); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minLevel", *fieldIt); + } + + // value + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.UIValue); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "value", *fieldIt); + } + + // powers (up to 6) + item.UINumPL = 0; + for (size_t i = 0; i < 6; ++i) { + // type + advance(); + if ((*fieldIt).value().empty()) + continue; + ParseItemPower(fieldIt, endField, filename, StrCat("powers[", i, "]"), item.powers[item.UINumPL++]); + } + } + + UniqueItems.shrink_to_fit(); +} + +void LoadItemAffixesDat(std::string_view filename, std::vector &out) +{ + tl::expected dataFileResult = DataFile::load(filename); + if (!dataFileResult.has_value()) { + DataFile::reportFatalError(dataFileResult.error(), filename); + } + + DataFile &dataFile = dataFileResult.value(); + if (tl::expected result = dataFile.skipHeader(); + !result.has_value()) { + DataFile::reportFatalError(result.error(), filename); + } + + out.clear(); + out.reserve(dataFile.numRecords()); + for (DataFileRecord record : dataFile) { + FieldIterator fieldIt = record.begin(); + const FieldIterator endField = record.end(); + + out.emplace_back(); + PLStruct &item = out.back(); + + const auto advance = [&]() { + ++fieldIt; + if (fieldIt == endField) { + DataFile::reportFatalError(DataFile::Error::NotEnoughColumns, filename); + } + }; + + // name + item.PLName = (*fieldIt).value(); + + // power + advance(); + ParseItemPower(fieldIt, endField, filename, "power", item.power); + + // minLevel + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.PLMinLvl); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minLevel", *fieldIt); + } + + // itemTypes + advance(); + if (tl::expected result = (*fieldIt).parseEnumList(item.PLIType, ParseAffixItemType); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "itemTypes", *fieldIt); + } + + // alignment + advance(); + if (tl::expected result = ParseAffixAlignment((*fieldIt).value()); result.has_value()) { + item.PLGOE = *std::move(result); + } else { + DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "alignment", *fieldIt, result.error()); + } + + // doubleChance + advance(); + if (tl::expected result = (*fieldIt).parseBool(item.PLDouble); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "doubleChance", *fieldIt); + } + + // useful + advance(); + if (tl::expected result = (*fieldIt).parseBool(item.PLOk); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "useful", *fieldIt); + } + + // minVal + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.minVal); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "minVal", *fieldIt); + } + + // maxVal + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.maxVal); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "maxVal", *fieldIt); + } + + // multVal + advance(); + if (tl::expected result = (*fieldIt).parseInt(item.multVal); !result.has_value()) { + DataFile::reportFatalFieldError(result.error(), filename, "multVal", *fieldIt); + } + } + + out.shrink_to_fit(); +} + +} // namespace + +void LoadItemData() +{ + LoadItemDat(); + LoadUniqueItemDat(); + LoadItemAffixesDat("txtdata\\items\\item_prefixes.tsv", ItemPrefixes); + LoadItemAffixesDat("txtdata\\items\\item_suffixes.tsv", ItemSuffixes); +} + +std::string_view ItemTypeToString(ItemType itemType) +{ + switch (itemType) { + case ItemType::Misc: return "Misc"; + case ItemType::Sword: return "Sword"; + case ItemType::Axe: return "Axe"; + case ItemType::Bow: return "Bow"; + case ItemType::Mace: return "Mace"; + case ItemType::Shield: return "Shield"; + case ItemType::LightArmor: return "LightArmor"; + case ItemType::Helm: return "Helm"; + case ItemType::MediumArmor: return "MediumArmor"; + case ItemType::HeavyArmor: return "HeavyArmor"; + case ItemType::Staff: return "Staff"; + case ItemType::Gold: return "Gold"; + case ItemType::Ring: return "Ring"; + case ItemType::Amulet: return "Amulet"; + case ItemType::None: return "None"; + } + return ""; +} } // namespace devilution diff --git a/Source/itemdat.h b/Source/itemdat.h index 625e0a5b3..adeb35221 100644 --- a/Source/itemdat.h +++ b/Source/itemdat.h @@ -7,6 +7,7 @@ #include #include +#include #include "objdat.h" #include "spelldat.h" @@ -443,8 +444,8 @@ struct ItemData { enum item_cursor_graphic iCurs; enum ItemType itype; enum unique_base_item iItemId; - const char *iName; - const char *iSName; + std::string iName; + std::string iSName; uint8_t iMinMLvl; uint8_t iDurability; uint8_t iMinDam; @@ -572,7 +573,7 @@ struct ItemPower { }; struct PLStruct { - const char *PLName; + std::string PLName; ItemPower power; int8_t PLMinLvl; AffixItemType PLIType; // AffixItemType as bit flags @@ -585,7 +586,7 @@ struct PLStruct { }; struct UniqueItem { - const char *UIName; + std::string UIName; enum unique_base_item UIItemId; int8_t UIMinLvl; uint8_t UINumPL; @@ -593,9 +594,11 @@ struct UniqueItem { ItemPower powers[6]; }; -extern const ItemData AllItemsList[]; -extern const PLStruct ItemPrefixes[]; -extern const PLStruct ItemSuffixes[]; -extern const UniqueItem UniqueItems[]; +extern std::vector AllItemsList; +extern std::vector ItemPrefixes; +extern std::vector ItemSuffixes; +extern std::vector UniqueItems; + +void LoadItemData(); } // namespace devilution diff --git a/Source/items.cpp b/Source/items.cpp index be5149bfd..abe985202 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -1086,7 +1086,7 @@ int GetStaffPrefixId(int lvl, bool onlygood, bool hellfireItem) if (FlipCoin(10) || onlygood) { int nl = 0; int l[256]; - for (int j = 0; ItemPrefixes[j].power.type != IPL_INVALID; j++) { + for (int j = 0, n = static_cast(ItemPrefixes.size()); j < n; ++j) { if (!IsPrefixValidForItemType(j, AffixItemType::Staff, hellfireItem) || ItemPrefixes[j].PLMinLvl > lvl) continue; if (onlygood && !ItemPrefixes[j].PLOk) @@ -1194,7 +1194,7 @@ void GetItemPowerPrefixAndSuffix(int minlvl, int maxlvl, AffixItemType flgs, boo onlygood = true; if (allocatePrefix) { int nt = 0; - for (int j = 0; ItemPrefixes[j].power.type != IPL_INVALID; j++) { + for (int j = 0, n = static_cast(ItemPrefixes.size()); j < n; ++j) { if (!IsPrefixValidForItemType(j, flgs, hellfireItem)) continue; if (ItemPrefixes[j].PLMinLvl < minlvl || ItemPrefixes[j].PLMinLvl > maxlvl) @@ -1218,7 +1218,7 @@ void GetItemPowerPrefixAndSuffix(int minlvl, int maxlvl, AffixItemType flgs, boo } if (allocateSuffix) { int nl = 0; - for (int j = 0; ItemSuffixes[j].power.type != IPL_INVALID; j++) { + for (int j = 0, n = static_cast(ItemSuffixes.size()); j < n; ++j) { if (IsSuffixValidForItemType(j, flgs, hellfireItem) && ItemSuffixes[j].PLMinLvl >= minlvl && ItemSuffixes[j].PLMinLvl <= maxlvl && !((goe == GOE_GOOD && ItemSuffixes[j].PLGOE == GOE_EVIL) || (goe == GOE_EVIL && ItemSuffixes[j].PLGOE == GOE_GOOD)) @@ -1451,7 +1451,7 @@ _unique_items CheckUnique(Item &item, int lvl, int uper, bool recreate) return UITEM_INVALID; int numu = 0; - for (int j = 0; UniqueItems[j].UIItemId != UITYPE_INVALID; j++) { + for (int j = 0, n = static_cast(UniqueItems.size()); j < n; ++j) { if (!IsUniqueAvailable(j)) break; if (UniqueItems[j].UIItemId == AllItemsList[item.IDidx].iItemId @@ -4629,11 +4629,11 @@ std::string DebugSpawnUniqueItem(std::string itemName) UniqueItem uniqueItem; bool foundUnique = false; int uniqueIndex = 0; - for (int j = 0; UniqueItems[j].UIItemId != UITYPE_INVALID; j++) { + for (int j = 0, n = static_cast(UniqueItems.size()); j < n; ++j) { if (!IsUniqueAvailable(j)) break; - const std::string tmp = AsciiStrToLower(UniqueItems[j].UIName); + const std::string tmp = AsciiStrToLower(std::string_view(UniqueItems[j].UIName)); if (tmp.find(itemName) != std::string::npos) { itemName = tmp; uniqueItem = UniqueItems[j]; diff --git a/Source/spelldat.cpp b/Source/spelldat.cpp index 3ff75ef32..f3bb911ab 100644 --- a/Source/spelldat.cpp +++ b/Source/spelldat.cpp @@ -4,6 +4,11 @@ * Implementation of all spell data. */ #include "spelldat.h" + +#include + +#include + #include "utils/language.h" namespace devilution { @@ -75,4 +80,61 @@ const SpellData SpellsData[] = { // clang-format on }; +tl::expected ParseSpellId(std::string_view value) +{ + if (value == "Null") return SpellID::Null; + if (value == "Firebolt") return SpellID::Firebolt; + if (value == "Healing") return SpellID::Healing; + if (value == "Lightning") return SpellID::Lightning; + if (value == "Flash") return SpellID::Flash; + if (value == "Identify") return SpellID::Identify; + if (value == "FireWall") return SpellID::FireWall; + if (value == "TownPortal") return SpellID::TownPortal; + if (value == "StoneCurse") return SpellID::StoneCurse; + if (value == "Infravision") return SpellID::Infravision; + if (value == "Phasing") return SpellID::Phasing; + if (value == "ManaShield") return SpellID::ManaShield; + if (value == "Fireball") return SpellID::Fireball; + if (value == "Guardian") return SpellID::Guardian; + if (value == "ChainLightning") return SpellID::ChainLightning; + if (value == "FlameWave") return SpellID::FlameWave; + if (value == "DoomSerpents") return SpellID::DoomSerpents; + if (value == "BloodRitual") return SpellID::BloodRitual; + if (value == "Nova") return SpellID::Nova; + if (value == "Invisibility") return SpellID::Invisibility; + if (value == "Inferno") return SpellID::Inferno; + if (value == "Golem") return SpellID::Golem; + if (value == "Rage") return SpellID::Rage; + if (value == "Teleport") return SpellID::Teleport; + if (value == "Apocalypse") return SpellID::Apocalypse; + if (value == "Etherealize") return SpellID::Etherealize; + if (value == "ItemRepair") return SpellID::ItemRepair; + if (value == "StaffRecharge") return SpellID::StaffRecharge; + if (value == "TrapDisarm") return SpellID::TrapDisarm; + if (value == "Elemental") return SpellID::Elemental; + if (value == "ChargedBolt") return SpellID::ChargedBolt; + if (value == "HolyBolt") return SpellID::HolyBolt; + if (value == "Resurrect") return SpellID::Resurrect; + if (value == "Telekinesis") return SpellID::Telekinesis; + if (value == "HealOther") return SpellID::HealOther; + if (value == "BloodStar") return SpellID::BloodStar; + if (value == "BoneSpirit") return SpellID::BoneSpirit; + if (value == "Mana") return SpellID::Mana; + if (value == "Magi") return SpellID::Magi; + if (value == "Jester") return SpellID::Jester; + if (value == "LightningWall") return SpellID::LightningWall; + if (value == "Immolation") return SpellID::Immolation; + if (value == "Warp") return SpellID::Warp; + if (value == "Reflect") return SpellID::Reflect; + if (value == "Berserk") return SpellID::Berserk; + if (value == "RingOfFire") return SpellID::RingOfFire; + if (value == "Search") return SpellID::Search; + if (value == "RuneOfFire") return SpellID::RuneOfFire; + if (value == "RuneOfLight") return SpellID::RuneOfLight; + if (value == "RuneOfNova") return SpellID::RuneOfNova; + if (value == "RuneOfImmolation") return SpellID::RuneOfImmolation; + if (value == "RuneOfStone") return SpellID::RuneOfStone; + return tl::make_unexpected("Unknown enum value"); +} + } // namespace devilution diff --git a/Source/spelldat.h b/Source/spelldat.h index 85f1942f5..d2076756e 100644 --- a/Source/spelldat.h +++ b/Source/spelldat.h @@ -6,8 +6,11 @@ #pragma once #include +#include #include +#include + #include "effects.h" #include "utils/enum_traits.h" @@ -85,6 +88,8 @@ enum class SpellID : int8_t { Invalid = -1, }; +tl::expected ParseSpellId(std::string_view value); + enum class MagicType : uint8_t { Fire, Lightning, diff --git a/Source/translation_dummy.cpp b/Source/translation_dummy.cpp index 7e101e621..c60f27e09 100644 --- a/Source/translation_dummy.cpp +++ b/Source/translation_dummy.cpp @@ -244,3 +244,540 @@ const char *WEBWIDOW_NAME = P_("monster", "Webwidow"); const char *FLESHDANCER_NAME = P_("monster", "Fleshdancer"); const char *GRIMSPIKE_NAME = P_("monster", "Grimspike"); const char *DOOMLOCK_NAME = P_("monster", "Doomlock"); +const char *IDI_GOLD_NAME = N_("Gold"); +const char *IDI_WARRIOR_NAME = N_("Short Sword"); +const char *IDI_WARRSHLD_NAME = N_("Buckler"); +const char *IDI_WARRCLUB_NAME = N_("Club"); +const char *IDI_ROGUE_NAME = N_("Short Bow"); +const char *IDI_SORCERER_NAME = N_("Short Staff of Mana"); +const char *IDI_CLEAVER_NAME = N_("Cleaver"); +const char *IDI_SKCROWN_NAME = N_("The Undead Crown"); +const char *IDI_INFRARING_NAME = N_("Empyrean Band"); +const char *IDI_ROCK_NAME = N_("Magic Rock"); +const char *IDI_OPTAMULET_NAME = N_("Optic Amulet"); +const char *IDI_TRING_NAME = N_("Ring of Truth"); +const char *IDI_BANNER_NAME = N_("Tavern Sign"); +const char *IDI_HARCREST_NAME = N_("Harlequin Crest"); +const char *IDI_STEELVEIL_NAME = N_("Veil of Steel"); +const char *IDI_GLDNELIX_NAME = N_("Golden Elixir"); +const char *IDI_ANVIL_NAME = N_("Anvil of Fury"); +const char *IDI_MUSHROOM_NAME = N_("Black Mushroom"); +const char *IDI_BRAIN_NAME = N_("Brain"); +const char *IDI_FUNGALTM_NAME = N_("Fungal Tome"); +const char *IDI_SPECELIX_NAME = N_("Spectral Elixir"); +const char *IDI_BLDSTONE_NAME = N_("Blood Stone"); +const char *IDI_MAPOFDOOM_NAME = N_("Cathedral Map"); +const char *IDI_EAR_NAME = N_("Heart"); +const char *IDI_HEAL_NAME = N_("Potion of Healing"); +const char *IDI_MANA_NAME = N_("Potion of Mana"); +const char *IDI_IDENTIFY_NAME = N_("Scroll of Identify"); +const char *IDI_PORTAL_NAME = N_("Scroll of Town Portal"); +const char *IDI_ARMOFVAL_NAME = N_("Arkaine's Valor"); +const char *IDI_FULLHEAL_NAME = N_("Potion of Full Healing"); +const char *IDI_FULLMANA_NAME = N_("Potion of Full Mana"); +const char *IDI_GRISWOLD_NAME = N_("Griswold's Edge"); +const char *IDI_LGTFORGE_NAME = N_("Bovine Plate"); +const char *IDI_LAZSTAFF_NAME = N_("Staff of Lazarus"); +const char *IDI_RESURRECT_NAME = N_("Scroll of Resurrect"); +const char *IDI_OIL_NAME = N_("Blacksmith Oil"); +const char *IDI_SHORTSTAFF_NAME = N_("Short Staff"); +const char *IDI_BARDSWORD_NAME = N_("Sword"); +const char *IDI_BARDDAGGER_NAME = N_("Dagger"); +const char *IDI_RUNEBOMB_NAME = N_("Rune Bomb"); +const char *IDI_THEODORE_NAME = N_("Theodore"); +const char *IDI_AURIC_NAME = N_("Auric Amulet"); +const char *IDI_NOTE1_NAME = N_("Torn Note 1"); +const char *IDI_NOTE2_NAME = N_("Torn Note 2"); +const char *IDI_NOTE3_NAME = N_("Torn Note 3"); +const char *IDI_FULLNOTE_NAME = N_("Reconstructed Note"); +const char *IDI_BROWNSUIT_NAME = N_("Brown Suit"); +const char *IDI_GREYSUIT_NAME = N_("Grey Suit"); +const char *ITEM_48_NAME = N_("Cap"); +const char *ITEM_48_SHORT_NAME = N_("Cap"); +const char *ITEM_49_NAME = N_("Skull Cap"); +const char *ITEM_49_SHORT_NAME = N_("Cap"); +const char *ITEM_50_NAME = N_("Helm"); +const char *ITEM_50_SHORT_NAME = N_("Helm"); +const char *ITEM_51_NAME = N_("Full Helm"); +const char *ITEM_51_SHORT_NAME = N_("Helm"); +const char *ITEM_52_NAME = N_("Crown"); +const char *ITEM_52_SHORT_NAME = N_("Crown"); +const char *ITEM_53_NAME = N_("Great Helm"); +const char *ITEM_53_SHORT_NAME = N_("Helm"); +const char *ITEM_54_NAME = N_("Cape"); +const char *ITEM_54_SHORT_NAME = N_("Cape"); +const char *ITEM_55_NAME = N_("Rags"); +const char *ITEM_55_SHORT_NAME = N_("Rags"); +const char *ITEM_56_NAME = N_("Cloak"); +const char *ITEM_56_SHORT_NAME = N_("Cloak"); +const char *ITEM_57_NAME = N_("Robe"); +const char *ITEM_57_SHORT_NAME = N_("Robe"); +const char *ITEM_58_NAME = N_("Quilted Armor"); +const char *ITEM_58_SHORT_NAME = N_("Armor"); +const char *ITEM_59_NAME = N_("Leather Armor"); +const char *ITEM_59_SHORT_NAME = N_("Armor"); +const char *ITEM_60_NAME = N_("Hard Leather Armor"); +const char *ITEM_60_SHORT_NAME = N_("Armor"); +const char *ITEM_61_NAME = N_("Studded Leather Armor"); +const char *ITEM_61_SHORT_NAME = N_("Armor"); +const char *ITEM_62_NAME = N_("Ring Mail"); +const char *ITEM_62_SHORT_NAME = N_("Mail"); +const char *ITEM_63_NAME = N_("Chain Mail"); +const char *ITEM_63_SHORT_NAME = N_("Mail"); +const char *ITEM_64_NAME = N_("Scale Mail"); +const char *ITEM_64_SHORT_NAME = N_("Mail"); +const char *ITEM_65_NAME = N_("Breast Plate"); +const char *ITEM_65_SHORT_NAME = N_("Plate"); +const char *ITEM_66_NAME = N_("Splint Mail"); +const char *ITEM_66_SHORT_NAME = N_("Mail"); +const char *ITEM_67_NAME = N_("Plate Mail"); +const char *ITEM_67_SHORT_NAME = N_("Plate"); +const char *ITEM_68_NAME = N_("Field Plate"); +const char *ITEM_68_SHORT_NAME = N_("Plate"); +const char *ITEM_69_NAME = N_("Gothic Plate"); +const char *ITEM_69_SHORT_NAME = N_("Plate"); +const char *ITEM_70_NAME = N_("Full Plate Mail"); +const char *ITEM_70_SHORT_NAME = N_("Plate"); +const char *ITEM_71_NAME = N_("Buckler"); +const char *ITEM_71_SHORT_NAME = N_("Shield"); +const char *ITEM_72_NAME = N_("Small Shield"); +const char *ITEM_72_SHORT_NAME = N_("Shield"); +const char *ITEM_73_NAME = N_("Large Shield"); +const char *ITEM_73_SHORT_NAME = N_("Shield"); +const char *ITEM_74_NAME = N_("Kite Shield"); +const char *ITEM_74_SHORT_NAME = N_("Shield"); +const char *ITEM_75_NAME = N_("Tower Shield"); +const char *ITEM_75_SHORT_NAME = N_("Shield"); +const char *ITEM_76_NAME = N_("Gothic Shield"); +const char *ITEM_76_SHORT_NAME = N_("Shield"); +const char *ITEM_77_NAME = N_("Potion of Healing"); +const char *ITEM_78_NAME = N_("Potion of Full Healing"); +const char *ITEM_79_NAME = N_("Potion of Mana"); +const char *ITEM_80_NAME = N_("Potion of Full Mana"); +const char *ITEM_81_NAME = N_("Potion of Rejuvenation"); +const char *ITEM_82_NAME = N_("Potion of Full Rejuvenation"); +const char *ITEM_83_NAME = N_("Blacksmith Oil"); +const char *ITEM_84_NAME = N_("Oil of Accuracy"); +const char *ITEM_85_NAME = N_("Oil of Sharpness"); +const char *ITEM_86_NAME = N_("Oil"); +const char *ITEM_87_NAME = N_("Elixir of Strength"); +const char *ITEM_88_NAME = N_("Elixir of Magic"); +const char *ITEM_89_NAME = N_("Elixir of Dexterity"); +const char *ITEM_90_NAME = N_("Elixir of Vitality"); +const char *ITEM_91_NAME = N_("Scroll of Healing"); +const char *ITEM_92_NAME = N_("Scroll of Search"); +const char *ITEM_93_NAME = N_("Scroll of Lightning"); +const char *ITEM_94_NAME = N_("Scroll of Identify"); +const char *ITEM_95_NAME = N_("Scroll of Resurrect"); +const char *ITEM_96_NAME = N_("Scroll of Fire Wall"); +const char *ITEM_97_NAME = N_("Scroll of Inferno"); +const char *ITEM_98_NAME = N_("Scroll of Town Portal"); +const char *ITEM_99_NAME = N_("Scroll of Flash"); +const char *ITEM_100_NAME = N_("Scroll of Infravision"); +const char *ITEM_101_NAME = N_("Scroll of Phasing"); +const char *ITEM_102_NAME = N_("Scroll of Mana Shield"); +const char *ITEM_103_NAME = N_("Scroll of Flame Wave"); +const char *ITEM_104_NAME = N_("Scroll of Fireball"); +const char *ITEM_105_NAME = N_("Scroll of Stone Curse"); +const char *ITEM_106_NAME = N_("Scroll of Chain Lightning"); +const char *ITEM_107_NAME = N_("Scroll of Guardian"); +const char *ITEM_109_NAME = N_("Scroll of Nova"); +const char *ITEM_110_NAME = N_("Scroll of Golem"); +const char *ITEM_112_NAME = N_("Scroll of Teleport"); +const char *ITEM_113_NAME = N_("Scroll of Apocalypse"); +const char *ITEM_114_NAME = N_("Book of "); +const char *ITEM_115_NAME = N_("Book of "); +const char *ITEM_116_NAME = N_("Book of "); +const char *ITEM_117_NAME = N_("Book of "); +const char *ITEM_118_NAME = N_("Dagger"); +const char *ITEM_118_SHORT_NAME = N_("Dagger"); +const char *ITEM_119_NAME = N_("Short Sword"); +const char *ITEM_119_SHORT_NAME = N_("Sword"); +const char *ITEM_120_NAME = N_("Falchion"); +const char *ITEM_120_SHORT_NAME = N_("Sword"); +const char *ITEM_121_NAME = N_("Scimitar"); +const char *ITEM_121_SHORT_NAME = N_("Sword"); +const char *ITEM_122_NAME = N_("Claymore"); +const char *ITEM_122_SHORT_NAME = N_("Sword"); +const char *ITEM_123_NAME = N_("Blade"); +const char *ITEM_123_SHORT_NAME = N_("Blade"); +const char *ITEM_124_NAME = N_("Sabre"); +const char *ITEM_124_SHORT_NAME = N_("Sabre"); +const char *ITEM_125_NAME = N_("Long Sword"); +const char *ITEM_125_SHORT_NAME = N_("Sword"); +const char *ITEM_126_NAME = N_("Broad Sword"); +const char *ITEM_126_SHORT_NAME = N_("Sword"); +const char *ITEM_127_NAME = N_("Bastard Sword"); +const char *ITEM_127_SHORT_NAME = N_("Sword"); +const char *ITEM_128_NAME = N_("Two-Handed Sword"); +const char *ITEM_128_SHORT_NAME = N_("Sword"); +const char *ITEM_129_NAME = N_("Great Sword"); +const char *ITEM_129_SHORT_NAME = N_("Sword"); +const char *ITEM_130_NAME = N_("Small Axe"); +const char *ITEM_130_SHORT_NAME = N_("Axe"); +const char *ITEM_131_NAME = N_("Axe"); +const char *ITEM_131_SHORT_NAME = N_("Axe"); +const char *ITEM_132_NAME = N_("Large Axe"); +const char *ITEM_132_SHORT_NAME = N_("Axe"); +const char *ITEM_133_NAME = N_("Broad Axe"); +const char *ITEM_133_SHORT_NAME = N_("Axe"); +const char *ITEM_134_NAME = N_("Battle Axe"); +const char *ITEM_134_SHORT_NAME = N_("Axe"); +const char *ITEM_135_NAME = N_("Great Axe"); +const char *ITEM_135_SHORT_NAME = N_("Axe"); +const char *ITEM_136_NAME = N_("Mace"); +const char *ITEM_136_SHORT_NAME = N_("Mace"); +const char *ITEM_137_NAME = N_("Morning Star"); +const char *ITEM_137_SHORT_NAME = N_("Mace"); +const char *ITEM_138_NAME = N_("War Hammer"); +const char *ITEM_138_SHORT_NAME = N_("Hammer"); +const char *ITEM_139_NAME = N_("Spiked Club"); +const char *ITEM_139_SHORT_NAME = N_("Club"); +const char *ITEM_140_NAME = N_("Club"); +const char *ITEM_140_SHORT_NAME = N_("Club"); +const char *ITEM_141_NAME = N_("Flail"); +const char *ITEM_141_SHORT_NAME = N_("Flail"); +const char *ITEM_142_NAME = N_("Maul"); +const char *ITEM_142_SHORT_NAME = N_("Maul"); +const char *ITEM_143_NAME = N_("Short Bow"); +const char *ITEM_143_SHORT_NAME = N_("Bow"); +const char *ITEM_144_NAME = N_("Hunter's Bow"); +const char *ITEM_144_SHORT_NAME = N_("Bow"); +const char *ITEM_145_NAME = N_("Long Bow"); +const char *ITEM_145_SHORT_NAME = N_("Bow"); +const char *ITEM_146_NAME = N_("Composite Bow"); +const char *ITEM_146_SHORT_NAME = N_("Bow"); +const char *ITEM_147_NAME = N_("Short Battle Bow"); +const char *ITEM_147_SHORT_NAME = N_("Bow"); +const char *ITEM_148_NAME = N_("Long Battle Bow"); +const char *ITEM_148_SHORT_NAME = N_("Bow"); +const char *ITEM_149_NAME = N_("Short War Bow"); +const char *ITEM_149_SHORT_NAME = N_("Bow"); +const char *ITEM_150_NAME = N_("Long War Bow"); +const char *ITEM_150_SHORT_NAME = N_("Bow"); +const char *ITEM_151_NAME = N_("Short Staff"); +const char *ITEM_151_SHORT_NAME = N_("Staff"); +const char *ITEM_152_NAME = N_("Long Staff"); +const char *ITEM_152_SHORT_NAME = N_("Staff"); +const char *ITEM_153_NAME = N_("Composite Staff"); +const char *ITEM_153_SHORT_NAME = N_("Staff"); +const char *ITEM_154_NAME = N_("Quarter Staff"); +const char *ITEM_154_SHORT_NAME = N_("Staff"); +const char *ITEM_155_NAME = N_("War Staff"); +const char *ITEM_155_SHORT_NAME = N_("Staff"); +const char *ITEM_156_NAME = N_("Ring"); +const char *ITEM_156_SHORT_NAME = N_("Ring"); +const char *ITEM_157_NAME = N_("Ring"); +const char *ITEM_157_SHORT_NAME = N_("Ring"); +const char *ITEM_158_NAME = N_("Ring"); +const char *ITEM_158_SHORT_NAME = N_("Ring"); +const char *ITEM_159_NAME = N_("Amulet"); +const char *ITEM_159_SHORT_NAME = N_("Amulet"); +const char *ITEM_160_NAME = N_("Amulet"); +const char *ITEM_160_SHORT_NAME = N_("Amulet"); +const char *ITEM_161_NAME = N_("Rune of Fire"); +const char *ITEM_161_SHORT_NAME = N_("Rune"); +const char *ITEM_162_NAME = N_("Rune of Lightning"); +const char *ITEM_162_SHORT_NAME = N_("Rune"); +const char *ITEM_163_NAME = N_("Greater Rune of Fire"); +const char *ITEM_163_SHORT_NAME = N_("Rune"); +const char *ITEM_164_NAME = N_("Greater Rune of Lightning"); +const char *ITEM_164_SHORT_NAME = N_("Rune"); +const char *ITEM_165_NAME = N_("Rune of Stone"); +const char *ITEM_165_SHORT_NAME = N_("Rune"); +const char *IDI_SORCERER_NAME = N_("Short Staff of Charged Bolt"); +const char *IDI_ARENAPOT_NAME = N_("Arena Potion"); +const char *UNIQUE_ITEM_0_NAME = N_("The Butcher's Cleaver"); +const char *UNIQUE_ITEM_1_NAME = N_("The Undead Crown"); +const char *UNIQUE_ITEM_2_NAME = N_("Empyrean Band"); +const char *UNIQUE_ITEM_3_NAME = N_("Optic Amulet"); +const char *UNIQUE_ITEM_4_NAME = N_("Ring of Truth"); +const char *UNIQUE_ITEM_5_NAME = N_("Harlequin Crest"); +const char *UNIQUE_ITEM_6_NAME = N_("Veil of Steel"); +const char *UNIQUE_ITEM_7_NAME = N_("Arkaine's Valor"); +const char *UNIQUE_ITEM_8_NAME = N_("Griswold's Edge"); +const char *UNIQUE_ITEM_9_NAME = N_("Bovine Plate"); +const char *UNIQUE_ITEM_10_NAME = N_("The Rift Bow"); +const char *UNIQUE_ITEM_11_NAME = N_("The Needler"); +const char *UNIQUE_ITEM_12_NAME = N_("The Celestial Bow"); +const char *UNIQUE_ITEM_13_NAME = N_("Deadly Hunter"); +const char *UNIQUE_ITEM_14_NAME = N_("Bow of the Dead"); +const char *UNIQUE_ITEM_15_NAME = N_("The Blackoak Bow"); +const char *UNIQUE_ITEM_16_NAME = N_("Flamedart"); +const char *UNIQUE_ITEM_17_NAME = N_("Fleshstinger"); +const char *UNIQUE_ITEM_18_NAME = N_("Windforce"); +const char *UNIQUE_ITEM_19_NAME = N_("Eaglehorn"); +const char *UNIQUE_ITEM_20_NAME = N_("Gonnagal's Dirk"); +const char *UNIQUE_ITEM_21_NAME = N_("The Defender"); +const char *UNIQUE_ITEM_22_NAME = N_("Gryphon's Claw"); +const char *UNIQUE_ITEM_23_NAME = N_("Black Razor"); +const char *UNIQUE_ITEM_24_NAME = N_("Gibbous Moon"); +const char *UNIQUE_ITEM_25_NAME = N_("Ice Shank"); +const char *UNIQUE_ITEM_26_NAME = N_("The Executioner's Blade"); +const char *UNIQUE_ITEM_27_NAME = N_("The Bonesaw"); +const char *UNIQUE_ITEM_28_NAME = N_("Shadowhawk"); +const char *UNIQUE_ITEM_29_NAME = N_("Wizardspike"); +const char *UNIQUE_ITEM_30_NAME = N_("Lightsabre"); +const char *UNIQUE_ITEM_31_NAME = N_("The Falcon's Talon"); +const char *UNIQUE_ITEM_32_NAME = N_("Inferno"); +const char *UNIQUE_ITEM_33_NAME = N_("Doombringer"); +const char *UNIQUE_ITEM_34_NAME = N_("The Grizzly"); +const char *UNIQUE_ITEM_35_NAME = N_("The Grandfather"); +const char *UNIQUE_ITEM_36_NAME = N_("The Mangler"); +const char *UNIQUE_ITEM_37_NAME = N_("Sharp Beak"); +const char *UNIQUE_ITEM_38_NAME = N_("BloodSlayer"); +const char *UNIQUE_ITEM_39_NAME = N_("The Celestial Axe"); +const char *UNIQUE_ITEM_40_NAME = N_("Wicked Axe"); +const char *UNIQUE_ITEM_41_NAME = N_("Stonecleaver"); +const char *UNIQUE_ITEM_42_NAME = N_("Aguinara's Hatchet"); +const char *UNIQUE_ITEM_43_NAME = N_("Hellslayer"); +const char *UNIQUE_ITEM_44_NAME = N_("Messerschmidt's Reaver"); +const char *UNIQUE_ITEM_45_NAME = N_("Crackrust"); +const char *UNIQUE_ITEM_46_NAME = N_("Hammer of Jholm"); +const char *UNIQUE_ITEM_47_NAME = N_("Civerb's Cudgel"); +const char *UNIQUE_ITEM_48_NAME = N_("The Celestial Star"); +const char *UNIQUE_ITEM_49_NAME = N_("Baranar's Star"); +const char *UNIQUE_ITEM_50_NAME = N_("Gnarled Root"); +const char *UNIQUE_ITEM_51_NAME = N_("The Cranium Basher"); +const char *UNIQUE_ITEM_52_NAME = N_("Schaefer's Hammer"); +const char *UNIQUE_ITEM_53_NAME = N_("Dreamflange"); +const char *UNIQUE_ITEM_54_NAME = N_("Staff of Shadows"); +const char *UNIQUE_ITEM_55_NAME = N_("Immolator"); +const char *UNIQUE_ITEM_56_NAME = N_("Storm Spire"); +const char *UNIQUE_ITEM_57_NAME = N_("Gleamsong"); +const char *UNIQUE_ITEM_58_NAME = N_("Thundercall"); +const char *UNIQUE_ITEM_59_NAME = N_("The Protector"); +const char *UNIQUE_ITEM_60_NAME = N_("Naj's Puzzler"); +const char *UNIQUE_ITEM_61_NAME = N_("Mindcry"); +const char *UNIQUE_ITEM_62_NAME = N_("Rod of Onan"); +const char *UNIQUE_ITEM_63_NAME = N_("Helm of Spirits"); +const char *UNIQUE_ITEM_64_NAME = N_("Thinking Cap"); +const char *UNIQUE_ITEM_65_NAME = N_("OverLord's Helm"); +const char *UNIQUE_ITEM_66_NAME = N_("Fool's Crest"); +const char *UNIQUE_ITEM_67_NAME = N_("Gotterdamerung"); +const char *UNIQUE_ITEM_68_NAME = N_("Royal Circlet"); +const char *UNIQUE_ITEM_69_NAME = N_("Torn Flesh of Souls"); +const char *UNIQUE_ITEM_70_NAME = N_("The Gladiator's Bane"); +const char *UNIQUE_ITEM_71_NAME = N_("The Rainbow Cloak"); +const char *UNIQUE_ITEM_72_NAME = N_("Leather of Aut"); +const char *UNIQUE_ITEM_73_NAME = N_("Wisdom's Wrap"); +const char *UNIQUE_ITEM_74_NAME = N_("Sparking Mail"); +const char *UNIQUE_ITEM_75_NAME = N_("Scavenger Carapace"); +const char *UNIQUE_ITEM_76_NAME = N_("Nightscape"); +const char *UNIQUE_ITEM_77_NAME = N_("Naj's Light Plate"); +const char *UNIQUE_ITEM_78_NAME = N_("Demonspike Coat"); +const char *UNIQUE_ITEM_79_NAME = N_("The Deflector"); +const char *UNIQUE_ITEM_80_NAME = N_("Split Skull Shield"); +const char *UNIQUE_ITEM_81_NAME = N_("Dragon's Breach"); +const char *UNIQUE_ITEM_82_NAME = N_("Blackoak Shield"); +const char *UNIQUE_ITEM_83_NAME = N_("Holy Defender"); +const char *UNIQUE_ITEM_84_NAME = N_("Stormshield"); +const char *UNIQUE_ITEM_85_NAME = N_("Bramble"); +const char *UNIQUE_ITEM_86_NAME = N_("Ring of Regha"); +const char *UNIQUE_ITEM_87_NAME = N_("The Bleeder"); +const char *UNIQUE_ITEM_88_NAME = N_("Constricting Ring"); +const char *UNIQUE_ITEM_89_NAME = N_("Ring of Engagement"); +const char *UNIQUE_ITEM_90_NAME = N_("Giant's Knuckle"); +const char *UNIQUE_ITEM_91_NAME = N_("Mercurial Ring"); +const char *UNIQUE_ITEM_92_NAME = N_("Xorine's Ring"); +const char *UNIQUE_ITEM_93_NAME = N_("Karik's Ring"); +const char *UNIQUE_ITEM_94_NAME = N_("Ring of Magma"); +const char *UNIQUE_ITEM_95_NAME = N_("Ring of the Mystics"); +const char *UNIQUE_ITEM_96_NAME = N_("Ring of Thunder"); +const char *UNIQUE_ITEM_97_NAME = N_("Amulet of Warding"); +const char *UNIQUE_ITEM_98_NAME = N_("Gnat Sting"); +const char *UNIQUE_ITEM_99_NAME = N_("Flambeau"); +const char *UNIQUE_ITEM_100_NAME = N_("Armor of Gloom"); +const char *UNIQUE_ITEM_101_NAME = N_("Blitzen"); +const char *UNIQUE_ITEM_102_NAME = N_("Thunderclap"); +const char *UNIQUE_ITEM_103_NAME = N_("Shirotachi"); +const char *UNIQUE_ITEM_104_NAME = N_("Eater of Souls"); +const char *UNIQUE_ITEM_105_NAME = N_("Diamondedge"); +const char *UNIQUE_ITEM_106_NAME = N_("Bone Chain Armor"); +const char *UNIQUE_ITEM_107_NAME = N_("Demon Plate Armor"); +const char *UNIQUE_ITEM_108_NAME = N_("Acolyte's Amulet"); +const char *UNIQUE_ITEM_109_NAME = N_("Gladiator's Ring"); +const char *ITEM_PREFIX_0_NAME = N_("Tin"); +const char *ITEM_PREFIX_1_NAME = N_("Brass"); +const char *ITEM_PREFIX_2_NAME = N_("Bronze"); +const char *ITEM_PREFIX_3_NAME = N_("Iron"); +const char *ITEM_PREFIX_4_NAME = N_("Steel"); +const char *ITEM_PREFIX_5_NAME = N_("Silver"); +const char *ITEM_PREFIX_6_NAME = N_("Gold"); +const char *ITEM_PREFIX_7_NAME = N_("Platinum"); +const char *ITEM_PREFIX_8_NAME = N_("Mithril"); +const char *ITEM_PREFIX_9_NAME = N_("Meteoric"); +const char *ITEM_PREFIX_10_NAME = N_("Weird"); +const char *ITEM_PREFIX_11_NAME = N_("Strange"); +const char *ITEM_PREFIX_12_NAME = N_("Useless"); +const char *ITEM_PREFIX_13_NAME = N_("Bent"); +const char *ITEM_PREFIX_14_NAME = N_("Weak"); +const char *ITEM_PREFIX_15_NAME = N_("Jagged"); +const char *ITEM_PREFIX_16_NAME = N_("Deadly"); +const char *ITEM_PREFIX_17_NAME = N_("Heavy"); +const char *ITEM_PREFIX_18_NAME = N_("Vicious"); +const char *ITEM_PREFIX_19_NAME = N_("Brutal"); +const char *ITEM_PREFIX_20_NAME = N_("Massive"); +const char *ITEM_PREFIX_21_NAME = N_("Savage"); +const char *ITEM_PREFIX_22_NAME = N_("Ruthless"); +const char *ITEM_PREFIX_23_NAME = N_("Merciless"); +const char *ITEM_PREFIX_24_NAME = N_("Clumsy"); +const char *ITEM_PREFIX_25_NAME = N_("Dull"); +const char *ITEM_PREFIX_26_NAME = N_("Sharp"); +const char *ITEM_PREFIX_27_NAME = N_("Fine"); +const char *ITEM_PREFIX_28_NAME = N_("Warrior's"); +const char *ITEM_PREFIX_29_NAME = N_("Soldier's"); +const char *ITEM_PREFIX_30_NAME = N_("Lord's"); +const char *ITEM_PREFIX_31_NAME = N_("Knight's"); +const char *ITEM_PREFIX_32_NAME = N_("Master's"); +const char *ITEM_PREFIX_33_NAME = N_("Champion's"); +const char *ITEM_PREFIX_34_NAME = N_("King's"); +const char *ITEM_PREFIX_35_NAME = N_("Vulnerable"); +const char *ITEM_PREFIX_36_NAME = N_("Rusted"); +const char *ITEM_PREFIX_37_NAME = N_("Fine"); +const char *ITEM_PREFIX_38_NAME = N_("Strong"); +const char *ITEM_PREFIX_39_NAME = N_("Grand"); +const char *ITEM_PREFIX_40_NAME = N_("Valiant"); +const char *ITEM_PREFIX_41_NAME = N_("Glorious"); +const char *ITEM_PREFIX_42_NAME = N_("Blessed"); +const char *ITEM_PREFIX_43_NAME = N_("Saintly"); +const char *ITEM_PREFIX_44_NAME = N_("Awesome"); +const char *ITEM_PREFIX_45_NAME = N_("Holy"); +const char *ITEM_PREFIX_46_NAME = N_("Godly"); +const char *ITEM_PREFIX_47_NAME = N_("Red"); +const char *ITEM_PREFIX_48_NAME = N_("Crimson"); +const char *ITEM_PREFIX_49_NAME = N_("Crimson"); +const char *ITEM_PREFIX_50_NAME = N_("Garnet"); +const char *ITEM_PREFIX_51_NAME = N_("Ruby"); +const char *ITEM_PREFIX_52_NAME = N_("Blue"); +const char *ITEM_PREFIX_53_NAME = N_("Azure"); +const char *ITEM_PREFIX_54_NAME = N_("Lapis"); +const char *ITEM_PREFIX_55_NAME = N_("Cobalt"); +const char *ITEM_PREFIX_56_NAME = N_("Sapphire"); +const char *ITEM_PREFIX_57_NAME = N_("White"); +const char *ITEM_PREFIX_58_NAME = N_("Pearl"); +const char *ITEM_PREFIX_59_NAME = N_("Ivory"); +const char *ITEM_PREFIX_60_NAME = N_("Crystal"); +const char *ITEM_PREFIX_61_NAME = N_("Diamond"); +const char *ITEM_PREFIX_62_NAME = N_("Topaz"); +const char *ITEM_PREFIX_63_NAME = N_("Amber"); +const char *ITEM_PREFIX_64_NAME = N_("Jade"); +const char *ITEM_PREFIX_65_NAME = N_("Obsidian"); +const char *ITEM_PREFIX_66_NAME = N_("Emerald"); +const char *ITEM_PREFIX_67_NAME = N_("Hyena's"); +const char *ITEM_PREFIX_68_NAME = N_("Frog's"); +const char *ITEM_PREFIX_69_NAME = N_("Spider's"); +const char *ITEM_PREFIX_70_NAME = N_("Raven's"); +const char *ITEM_PREFIX_71_NAME = N_("Snake's"); +const char *ITEM_PREFIX_72_NAME = N_("Serpent's"); +const char *ITEM_PREFIX_73_NAME = N_("Drake's"); +const char *ITEM_PREFIX_74_NAME = N_("Dragon's"); +const char *ITEM_PREFIX_75_NAME = N_("Wyrm's"); +const char *ITEM_PREFIX_76_NAME = N_("Hydra's"); +const char *ITEM_PREFIX_77_NAME = N_("Angel's"); +const char *ITEM_PREFIX_78_NAME = N_("Arch-Angel's"); +const char *ITEM_PREFIX_79_NAME = N_("Plentiful"); +const char *ITEM_PREFIX_80_NAME = N_("Bountiful"); +const char *ITEM_PREFIX_81_NAME = N_("Flaming"); +const char *ITEM_PREFIX_82_NAME = N_("Lightning"); +const char *ITEM_PREFIX_83_NAME = N_("Jester's"); +const char *ITEM_PREFIX_84_NAME = N_("Crystalline"); +const char *ITEM_PREFIX_85_NAME = N_("Doppelganger's"); +const char *ITEM_SUFFIX_0_NAME = N_("quality"); +const char *ITEM_SUFFIX_1_NAME = N_("maiming"); +const char *ITEM_SUFFIX_2_NAME = N_("slaying"); +const char *ITEM_SUFFIX_3_NAME = N_("gore"); +const char *ITEM_SUFFIX_4_NAME = N_("carnage"); +const char *ITEM_SUFFIX_5_NAME = N_("slaughter"); +const char *ITEM_SUFFIX_6_NAME = N_("pain"); +const char *ITEM_SUFFIX_7_NAME = N_("tears"); +const char *ITEM_SUFFIX_8_NAME = N_("health"); +const char *ITEM_SUFFIX_9_NAME = N_("protection"); +const char *ITEM_SUFFIX_10_NAME = N_("absorption"); +const char *ITEM_SUFFIX_11_NAME = N_("deflection"); +const char *ITEM_SUFFIX_12_NAME = N_("osmosis"); +const char *ITEM_SUFFIX_13_NAME = N_("frailty"); +const char *ITEM_SUFFIX_14_NAME = N_("weakness"); +const char *ITEM_SUFFIX_15_NAME = N_("strength"); +const char *ITEM_SUFFIX_16_NAME = N_("might"); +const char *ITEM_SUFFIX_17_NAME = N_("power"); +const char *ITEM_SUFFIX_18_NAME = N_("giants"); +const char *ITEM_SUFFIX_19_NAME = N_("titans"); +const char *ITEM_SUFFIX_20_NAME = N_("paralysis"); +const char *ITEM_SUFFIX_21_NAME = N_("atrophy"); +const char *ITEM_SUFFIX_22_NAME = N_("dexterity"); +const char *ITEM_SUFFIX_23_NAME = N_("skill"); +const char *ITEM_SUFFIX_24_NAME = N_("accuracy"); +const char *ITEM_SUFFIX_25_NAME = N_("precision"); +const char *ITEM_SUFFIX_26_NAME = N_("perfection"); +const char *ITEM_SUFFIX_27_NAME = N_("the fool"); +const char *ITEM_SUFFIX_28_NAME = N_("dyslexia"); +const char *ITEM_SUFFIX_29_NAME = N_("magic"); +const char *ITEM_SUFFIX_30_NAME = N_("the mind"); +const char *ITEM_SUFFIX_31_NAME = N_("brilliance"); +const char *ITEM_SUFFIX_32_NAME = N_("sorcery"); +const char *ITEM_SUFFIX_33_NAME = N_("wizardry"); +const char *ITEM_SUFFIX_34_NAME = N_("illness"); +const char *ITEM_SUFFIX_35_NAME = N_("disease"); +const char *ITEM_SUFFIX_36_NAME = N_("vitality"); +const char *ITEM_SUFFIX_37_NAME = N_("zest"); +const char *ITEM_SUFFIX_38_NAME = N_("vim"); +const char *ITEM_SUFFIX_39_NAME = N_("vigor"); +const char *ITEM_SUFFIX_40_NAME = N_("life"); +const char *ITEM_SUFFIX_41_NAME = N_("trouble"); +const char *ITEM_SUFFIX_42_NAME = N_("the pit"); +const char *ITEM_SUFFIX_43_NAME = N_("the sky"); +const char *ITEM_SUFFIX_44_NAME = N_("the moon"); +const char *ITEM_SUFFIX_45_NAME = N_("the stars"); +const char *ITEM_SUFFIX_46_NAME = N_("the heavens"); +const char *ITEM_SUFFIX_47_NAME = N_("the zodiac"); +const char *ITEM_SUFFIX_48_NAME = N_("the vulture"); +const char *ITEM_SUFFIX_49_NAME = N_("the jackal"); +const char *ITEM_SUFFIX_50_NAME = N_("the fox"); +const char *ITEM_SUFFIX_51_NAME = N_("the jaguar"); +const char *ITEM_SUFFIX_52_NAME = N_("the eagle"); +const char *ITEM_SUFFIX_53_NAME = N_("the wolf"); +const char *ITEM_SUFFIX_54_NAME = N_("the tiger"); +const char *ITEM_SUFFIX_55_NAME = N_("the lion"); +const char *ITEM_SUFFIX_56_NAME = N_("the mammoth"); +const char *ITEM_SUFFIX_57_NAME = N_("the whale"); +const char *ITEM_SUFFIX_58_NAME = N_("fragility"); +const char *ITEM_SUFFIX_59_NAME = N_("brittleness"); +const char *ITEM_SUFFIX_60_NAME = N_("sturdiness"); +const char *ITEM_SUFFIX_61_NAME = N_("craftsmanship"); +const char *ITEM_SUFFIX_62_NAME = N_("structure"); +const char *ITEM_SUFFIX_63_NAME = N_("the ages"); +const char *ITEM_SUFFIX_64_NAME = N_("the dark"); +const char *ITEM_SUFFIX_65_NAME = N_("the night"); +const char *ITEM_SUFFIX_66_NAME = N_("light"); +const char *ITEM_SUFFIX_67_NAME = N_("radiance"); +const char *ITEM_SUFFIX_68_NAME = N_("flame"); +const char *ITEM_SUFFIX_69_NAME = N_("fire"); +const char *ITEM_SUFFIX_70_NAME = N_("burning"); +const char *ITEM_SUFFIX_71_NAME = N_("shock"); +const char *ITEM_SUFFIX_72_NAME = N_("lightning"); +const char *ITEM_SUFFIX_73_NAME = N_("thunder"); +const char *ITEM_SUFFIX_74_NAME = N_("many"); +const char *ITEM_SUFFIX_75_NAME = N_("plenty"); +const char *ITEM_SUFFIX_76_NAME = N_("thorns"); +const char *ITEM_SUFFIX_77_NAME = N_("corruption"); +const char *ITEM_SUFFIX_78_NAME = N_("thieves"); +const char *ITEM_SUFFIX_79_NAME = N_("the bear"); +const char *ITEM_SUFFIX_80_NAME = N_("the bat"); +const char *ITEM_SUFFIX_81_NAME = N_("vampires"); +const char *ITEM_SUFFIX_82_NAME = N_("the leech"); +const char *ITEM_SUFFIX_83_NAME = N_("blood"); +const char *ITEM_SUFFIX_84_NAME = N_("piercing"); +const char *ITEM_SUFFIX_85_NAME = N_("puncturing"); +const char *ITEM_SUFFIX_86_NAME = N_("bashing"); +const char *ITEM_SUFFIX_87_NAME = N_("readiness"); +const char *ITEM_SUFFIX_88_NAME = N_("swiftness"); +const char *ITEM_SUFFIX_89_NAME = N_("speed"); +const char *ITEM_SUFFIX_90_NAME = N_("haste"); +const char *ITEM_SUFFIX_91_NAME = N_("balance"); +const char *ITEM_SUFFIX_92_NAME = N_("stability"); +const char *ITEM_SUFFIX_93_NAME = N_("harmony"); +const char *ITEM_SUFFIX_94_NAME = N_("blocking"); +const char *ITEM_SUFFIX_95_NAME = N_("devastation"); +const char *ITEM_SUFFIX_96_NAME = N_("decay"); +const char *ITEM_SUFFIX_97_NAME = N_("peril"); diff --git a/test/.clang-format b/test/.clang-format index d30f4466e..024bdf68e 100644 --- a/test/.clang-format +++ b/test/.clang-format @@ -1,6 +1,7 @@ BasedOnStyle: webkit AlignTrailingComments: true AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: All AllowShortIfStatementsOnASingleLine: WithoutElse PointerAlignment: Right diff --git a/test/inv_test.cpp b/test/inv_test.cpp index cca25eae5..e3a19391b 100644 --- a/test/inv_test.cpp +++ b/test/inv_test.cpp @@ -15,6 +15,11 @@ public: Players.resize(1); MyPlayer = &Players[0]; } + + static void SetUpTestSuite() + { + LoadItemData(); + } }; /* Set up a given item as a spell scroll, allowing for its usage. */ diff --git a/test/pack_test.cpp b/test/pack_test.cpp index 6271a2bc5..7e45a927c 100644 --- a/test/pack_test.cpp +++ b/test/pack_test.cpp @@ -411,6 +411,11 @@ public: Players.resize(1); MyPlayer = &Players[0]; } + + static void SetUpTestSuite() + { + LoadItemData(); + } }; TEST_F(PackTest, UnPackItem_diablo) @@ -943,9 +948,14 @@ public: }; SwapLE(testPack); + UnPackPlayer(testPack, *MyPlayer); + } + + static void SetUpTestSuite() + { LoadPlayerDataFiles(); LoadMonsterData(); - UnPackPlayer(testPack, *MyPlayer); + LoadItemData(); } }; diff --git a/test/player_test.cpp b/test/player_test.cpp index 4e9934062..a423b9698 100644 --- a/test/player_test.cpp +++ b/test/player_test.cpp @@ -180,6 +180,7 @@ static void AssertPlayer(Player &player) TEST(Player, CreatePlayer) { LoadPlayerDataFiles(); + LoadItemData(); Players.resize(1); CreatePlayer(Players[0], HeroClass::Rogue); AssertPlayer(Players[0]); diff --git a/test/timedemo_test.cpp b/test/timedemo_test.cpp index 9762e5c73..de7a28951 100644 --- a/test/timedemo_test.cpp +++ b/test/timedemo_test.cpp @@ -54,6 +54,7 @@ void RunTimedemo(std::string timedemoFolderName) LoadPlayerDataFiles(); LoadMonsterData(); + LoadItemData(); pfile_ui_set_hero_infos(Dummy_GetHeroInfo); gbLoadGame = true; diff --git a/test/writehero_test.cpp b/test/writehero_test.cpp index 8591aa26c..0cf3f5aec 100644 --- a/test/writehero_test.cpp +++ b/test/writehero_test.cpp @@ -375,6 +375,7 @@ TEST(Writehero, pfile_write_hero) MyPlayer = &Players[MyPlayerId]; LoadPlayerDataFiles(); + LoadItemData(); _uiheroinfo info {}; info.heroclass = HeroClass::Rogue; pfile_ui_save_create(&info); diff --git a/tools/extract_translation_data.py b/tools/extract_translation_data.py index c16c58751..283bf77c9 100755 --- a/tools/extract_translation_data.py +++ b/tools/extract_translation_data.py @@ -6,6 +6,10 @@ root = pathlib.Path(__file__).resolve().parent.parent translation_dummy_path = root.joinpath("Source/translation_dummy.cpp") monstdat_path = root.joinpath("Packaging/resources/assets/txtdata/monsters/monstdat.tsv") unique_monstdat_path = root.joinpath("Packaging/resources/assets/txtdata/monsters/unique_monstdat.tsv") +itemdat_path = root.joinpath("Packaging/resources/assets/txtdata/items/itemdat.tsv") +unique_itemdat_path = root.joinpath("Packaging/resources/assets/txtdata/items/unique_itemdat.tsv") +item_prefixes_path = root.joinpath("Packaging/resources/assets/txtdata/items/item_prefixes.tsv") +item_suffixes_path = root.joinpath("Packaging/resources/assets/txtdata/items/item_suffixes.tsv") with open(translation_dummy_path, 'w') as temp_source: temp_source.write(f'/**\n') @@ -21,10 +25,40 @@ with open(translation_dummy_path, 'w') as temp_source: for row in reader: name = row['name'] var_name = row['_monster_id'] + "_NAME" - temp_source.write(f'const char *' + var_name + ' = P_("monster", "' + name + '");\n') + temp_source.write(f'const char *{var_name} = P_("monster", "{name}");\n') with open(unique_monstdat_path, 'r') as tsv: reader = csv.DictReader(tsv, delimiter='\t') for row in reader: name = row['name'] var_name = name.upper().replace(' ', '_').replace('-', '_') + "_NAME" - temp_source.write(f'const char *' + var_name + ' = P_("monster", "' + name + '");\n') + temp_source.write(f'const char *{var_name} = P_("monster", "{name}");\n') + with open(itemdat_path, 'r') as tsv: + reader = csv.DictReader(tsv, delimiter='\t') + for i, row in enumerate(reader): + id = row['id'] + name = row['name'] + if name == 'Scroll of None' or name == 'Non Item': + continue + shortName = row['shortName'] + var_name = id if id else f'ITEM_{i}' + temp_source.write(f'const char *{var_name}_NAME = N_("{name}");\n') + if shortName: + temp_source.write(f'const char *{var_name}_SHORT_NAME = N_("{shortName}");\n') + with open(unique_itemdat_path, 'r') as tsv: + reader = csv.DictReader(tsv, delimiter='\t') + for i, row in enumerate(reader): + name = row['name'] + var_name = f'UNIQUE_ITEM_{i}' + temp_source.write(f'const char *{var_name}_NAME = N_("{name}");\n') + with open(item_prefixes_path, 'r') as tsv: + reader = csv.DictReader(tsv, delimiter='\t') + for i, row in enumerate(reader): + name = row['name'] + var_name = f'ITEM_PREFIX_{i}' + temp_source.write(f'const char *{var_name}_NAME = N_("{name}");\n') + with open(item_suffixes_path, 'r') as tsv: + reader = csv.DictReader(tsv, delimiter='\t') + for i, row in enumerate(reader): + name = row['name'] + var_name = f'ITEM_SUFFIX_{i}' + temp_source.write(f'const char *{var_name}_NAME = N_("{name}");\n')