Browse Source

Migrate monstdat to a data file

We may want to migrate this to 1 file per monster but for now the
migration is as close to the hard-coded version as possible.

Sprites that are used by multiple monsters are only loaded from disk
once.
pull/6799/head
Gleb Mazovetskiy 2 years ago
parent
commit
2eae121931
  1. 1
      CMake/Assets.cmake
  2. 139
      Packaging/resources/assets/txtdata/monsters/monstdat.tsv
  3. 15
      Source/data/file.cpp
  4. 2
      Source/data/file.hpp
  5. 50
      Source/data/iterators.hpp
  6. 4
      Source/diablo.cpp
  7. 2
      Source/lua/modules/dev/monsters.cpp
  8. 627
      Source/monstdat.cpp
  9. 83
      Source/monstdat.h
  10. 4
      Source/monster.cpp
  11. 146
      Source/translation_dummy.cpp
  12. 2
      test/pack_test.cpp
  13. 2
      test/timedemo_test.cpp
  14. 23
      tools/extract_translation_data.py

1
CMake/Assets.cmake

@ -155,6 +155,7 @@ set(devilutionx_assets
txtdata/classes/rogue/attributes.tsv
txtdata/classes/sorcerer/attributes.tsv
txtdata/classes/warrior/attributes.tsv
txtdata/monsters/monstdat.tsv
ui_art/diablo.pal
ui_art/hellfire.pal
ui_art/creditsw.clx

139
Packaging/resources/assets/txtdata/monsters/monstdat.tsv

@ -0,0 +1,139 @@
_monster_id name assetsSuffix soundSuffix trnFile availability width image hasSpecial hasSpecialSound frames[6] rate[6] minDunLvl maxDunLvl level hitPointsMinimum hitPointsMaximum ai abilityFlags intelligence toHit animFrameNum minDamage maxDamage toHitSpecial animFrameNumSpecial minDamageSpecial maxDamageSpecial armorClass monsterClass resistance resistanceHell selectionType treasure exp
MT_NZOMBIE Zombie zombie\zombie Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 1 2 1 4 7 Zombie 0 10 8 2 5 0 0 0 0 5 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 54
MT_BZOMBIE Ghoul zombie\zombie zombie\bluered Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 2 3 2 7 11 Zombie 1 10 8 3 10 0 0 0 0 10 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 58
MT_GZOMBIE Rotting Carcass zombie\zombie zombie\grey Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 2 4 4 15 25 Zombie 2 25 8 5 15 0 0 0 0 15 Undead IMMUNE_MAGIC IMMUNE_MAGIC,RESIST_FIRE 3 136
MT_YZOMBIE Black Death zombie\zombie zombie\yellow Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 3 5 6 25 40 Zombie 3 30 8 6 22 0 0 0 0 20 Undead IMMUNE_MAGIC IMMUNE_MAGIC,RESIST_LIGHTNING 3 240
MT_RFALLSP Fallen One falspear\phall falspear\fallent Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 1 2 1 1 4 Fallen 0 15 7 1 3 0 5 0 0 0 Animal 3 46
MT_DFALLSP Carver falspear\phall falspear\dark Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 2 3 3 4 8 Fallen 2 20 7 2 5 0 5 0 0 5 Animal 3 80
MT_YFALLSP Devil Kin falspear\phall Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 2 4 5 12 24 Fallen 2 25 7 3 7 0 5 0 0 10 Animal RESIST_FIRE 3 155
MT_BFALLSP Dark One falspear\phall falspear\blue Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 3 5 7 20 36 Fallen 3 30 7 4 8 0 5 0 0 15 Animal RESIST_LIGHTNING 3 255
MT_WSKELAX Skeleton skelaxe\sklax skelaxe\white Always 128 553 true false 12,8,13,6,17,16 5,1,1,1,1,1 1 2 1 2 4 SkeletonMelee 0 20 8 1 4 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 64
MT_TSKELAX Corpse Axe skelaxe\sklax skelaxe\skelt Always 128 553 true false 12,8,13,6,17,16 4,1,1,1,1,1 2 3 2 4 7 SkeletonMelee 1 25 8 3 5 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 68
MT_RSKELAX Burning Dead skelaxe\sklax Always 128 553 true false 12,8,13,6,17,16 2,1,1,1,1,1 2 4 4 8 12 SkeletonMelee 2 30 8 3 7 0 0 0 0 5 Undead IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 154
MT_XSKELAX Horror skelaxe\sklax skelaxe\black Always 128 553 true false 12,8,13,6,17,16 3,1,1,1,1,1 3 5 6 12 20 SkeletonMelee 3 35 8 4 9 0 0 0 0 15 Undead IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 264
MT_RFALLSD Fallen One falsword\fall falsword\fallent Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 1 2 1 2 5 Fallen 0 15 8 1 4 0 5 0 0 10 Animal 3 52
MT_DFALLSD Carver falsword\fall falsword\dark Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 2 3 3 5 9 Fallen 1 20 8 2 7 0 5 0 0 15 Animal 3 90
MT_YFALLSD Devil Kin falsword\fall Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 2 4 5 16 24 Fallen 2 25 8 4 10 0 5 0 0 20 Animal RESIST_FIRE 3 180
MT_BFALLSD Dark One falsword\fall falsword\blue Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 3 5 7 24 36 Fallen 3 30 8 4 12 0 5 0 0 25 Animal RESIST_LIGHTNING 3 280
MT_NSCAV Scavenger scav\scav Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 1 3 2 3 6 Scavenger 0 20 7 1 5 0 0 0 0 10 Animal RESIST_FIRE 3 80
MT_BSCAV Plague Eater scav\scav scav\scavbr Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 2 4 4 12 24 Scavenger 1 30 7 1 8 0 0 0 0 20 Animal RESIST_LIGHTNING 3 188
MT_WSCAV Shadow Beast scav\scav scav\scavbe Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 3 5 6 24 36 Scavenger 2 35 7 3 12 0 0 0 0 25 Animal RESIST_FIRE 3 375
MT_YSCAV Bone Gasher scav\scav scav\scavw Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 4 6 8 28 40 Scavenger 3 35 7 5 15 0 0 0 0 30 Animal RESIST_MAGIC RESIST_LIGHTNING 3 552
MT_WSKELBW Skeleton skelbow\sklbw skelbow\white Always 128 567 true false 9,8,16,5,16,16 4,1,1,1,1,1 2 3 3 2 4 SkeletonRanged 0 15 12 1 2 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 110
MT_TSKELBW Corpse Bow skelbow\sklbw skelbow\skelt Always 128 567 true false 9,8,16,5,16,16 4,1,1,1,1,1 2 4 5 8 16 SkeletonRanged 1 25 12 1 4 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 210
MT_RSKELBW Burning Dead skelbow\sklbw Always 128 567 true false 9,8,16,5,16,16 2,1,1,1,1,1 3 5 7 10 24 SkeletonRanged 2 30 12 1 6 0 0 0 0 5 Undead IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 364
MT_XSKELBW Horror skelbow\sklbw skelbow\black Always 128 567 true false 9,8,16,5,16,16 3,1,1,1,1,1 4 6 9 15 45 SkeletonRanged 3 35 12 2 9 0 0 0 0 15 Undead IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 594
MT_WSKELSD Skeleton Captain skelsd\sklsr skelsd\white Always 128 575 true true 13,8,12,7,15,16 4,1,1,1,1,1 1 3 2 3 6 SkeletonMelee 0 20 8 2 7 0 0 0 0 10 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 90
MT_TSKELSD Corpse Captain skelsd\sklsr skelsd\skelt Always 128 575 true false 13,8,12,7,15,16 4,1,1,1,1,1 2 4 4 12 20 SkeletonMelee 1 30 8 3 9 0 0 0 0 5 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 200
MT_RSKELSD Burning Dead Captain skelsd\sklsr Always 128 575 true false 13,8,12,7,15,16 4,1,1,1,1,1 3 5 6 16 30 SkeletonMelee 2 35 8 4 10 0 0 0 0 15 Undead IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 393
MT_XSKELSD Horror Captain skelsd\sklsr skelsd\black Always 128 575 true false 13,8,12,7,15,16 4,1,1,1,1,1 4 6 8 35 50 SkeletonMelee SEARCH 3 40 8 5 14 0 0 0 0 30 Undead IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 604
MT_INVILORD Invisible Lord tsneak\tsneak Never 128 800 false false 13,13,15,11,16,0 2,1,1,1,1,1 19 20 14 278 278 SkeletonMelee SEARCH,CAN_OPEN_DOOR 3 65 8 16 30 0 0 0 0 60 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 3 2000
MT_SNEAK Hidden sneak\sneak Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 2 5 5 8 24 Sneak HIDDEN 0 35 8 3 6 0 0 0 0 25 Demon 3 278
MT_STALKER Stalker sneak\sneak sneak\sneakv2 Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 5 7 9 30 45 Sneak HIDDEN,SEARCH 1 40 8 8 16 0 0 0 0 30 Demon 3 630
MT_UNSEEN Unseen sneak\sneak sneak\sneakv3 Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 6 8 11 35 50 Sneak HIDDEN,SEARCH 2 45 8 12 20 0 0 0 0 30 Demon RESIST_MAGIC IMMUNE_MAGIC 3 935
MT_ILLWEAV Illusion Weaver sneak\sneak sneak\sneakv1 Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 8 10 13 40 60 Sneak HIDDEN,SEARCH 3 60 8 16 24 0 0 0 0 30 Demon RESIST_MAGIC,RESIST_FIRE IMMUNE_MAGIC,RESIST_FIRE 3 1500
MT_LRDSAYTR Satyr Lord goatlord\goatl newsfx\satyr Retail 160 800 false false 13,13,14,9,16,0 2,1,1,1,1,1 21 22 28 160 200 SkeletonMelee SEARCH 3 90 8 20 30 0 0 0 0 70 Animal RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 2800
MT_NGOATMC Flesh Clan goatmace\goat Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 4 6 8 30 45 GoatMelee SEARCH,CAN_OPEN_DOOR 0 50 8 4 10 0 0 0 0 40 Demon 3 460
MT_BGOATMC Stone Clan goatmace\goat goatmace\beige Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 5 7 10 40 55 GoatMelee SEARCH,CAN_OPEN_DOOR 1 60 8 6 12 0 0 0 0 40 Demon RESIST_MAGIC IMMUNE_MAGIC 3 685
MT_RGOATMC Fire Clan goatmace\goat goatmace\red Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 6 8 12 50 65 GoatMelee SEARCH,CAN_OPEN_DOOR 2 70 8 8 16 0 0 0 0 45 Demon RESIST_FIRE IMMUNE_FIRE 3 906
MT_GGOATMC Night Clan goatmace\goat goatmace\gray Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 7 9 14 55 70 GoatMelee SEARCH,CAN_OPEN_DOOR 3 80 8 10 20 15 0 30 30 50 Demon RESIST_MAGIC IMMUNE_MAGIC 3 1190
MT_FIEND Fiend bat\bat bat\red Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 2 3 3 3 6 Bat 0 35 5 1 6 0 0 0 0 0 Animal 6 None 102
MT_BLINK Blink bat\bat Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 3 5 7 12 28 Bat 1 45 5 1 8 0 0 0 0 15 Animal 6 None 340
MT_GLOOM Gloom bat\bat bat\grey Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 4 6 9 28 36 Bat SEARCH 2 70 5 4 12 0 0 0 0 35 Animal RESIST_MAGIC RESIST_MAGIC 6 None 509
MT_FAMILIAR Familiar bat\bat bat\orange Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 6 8 13 20 35 Bat SEARCH 3 50 5 4 16 0 0 0 0 35 Demon RESIST_MAGIC,IMMUNE_LIGHTNING RESIST_MAGIC,IMMUNE_LIGHTNING 6 None 448
MT_NGOATBW Flesh Clan goatbow\goatb Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 4 6 8 20 35 GoatRanged CAN_OPEN_DOOR 0 35 13 1 7 0 0 0 0 35 Demon 3 448
MT_BGOATBW Stone Clan goatbow\goatb goatbow\beige Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 5 7 10 30 40 GoatRanged CAN_OPEN_DOOR 1 40 13 2 9 0 0 0 0 35 Demon RESIST_MAGIC IMMUNE_MAGIC 3 645
MT_RGOATBW Fire Clan goatbow\goatb goatbow\red Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 6 8 12 40 50 GoatRanged SEARCH,CAN_OPEN_DOOR 2 45 13 3 11 0 0 0 0 35 Demon RESIST_FIRE IMMUNE_FIRE 3 822
MT_GGOATBW Night Clan goatbow\goatb goatbow\gray Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 7 9 14 50 65 GoatRanged SEARCH,CAN_OPEN_DOOR 3 50 13 4 13 15 0 0 0 40 Demon RESIST_MAGIC IMMUNE_MAGIC 3 1092
MT_NACID Acid Beast acid\acid Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 6 8 11 40 66 Acid 0 40 8 4 12 25 8 0 0 30 Animal IMMUNE_ACID IMMUNE_MAGIC,IMMUNE_ACID 3 846
MT_RACID Poison Spitter acid\acid acid\acidblk Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 8 10 15 60 85 Acid 1 45 8 4 16 25 8 0 0 30 Animal IMMUNE_ACID IMMUNE_MAGIC,IMMUNE_ACID 3 1248
MT_BACID Pit Beast acid\acid acid\acidb Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 10 12 21 80 110 Acid 2 55 8 8 18 35 8 0 0 35 Animal RESIST_MAGIC,IMMUNE_ACID IMMUNE_MAGIC,RESIST_LIGHTNING,IMMUNE_ACID 3 2060
MT_XACID Lava Maw acid\acid acid\acidr Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 12 14 25 100 150 Acid 3 65 8 10 20 40 8 0 0 35 Animal RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_ACID IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_ACID 3 2940
MT_SKING Skeleton King sking\sking skelaxe\white Never 160 1010 true true 8,6,16,6,16,6 2,1,1,1,1,2 4 4 9 140 140 SkeletonKing SEARCH,CAN_OPEN_DOOR 3 60 8 6 16 0 0 0 0 70 Undead IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 Uniq(SKCROWN) 570
MT_CLEAVER The Butcher fatc\fatc Never 128 980 false false 10,8,12,6,16,0 1,1,1,1,1,1 1 1 1 320 320 Butcher 3 50 8 6 12 0 0 0 0 50 Demon RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 Uniq(CLEAVER) 710
MT_FAT Overlord fat\fat Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 5 7 10 60 80 Fat 0 55 8 6 12 0 0 0 0 55 Demon RESIST_FIRE 3 635
MT_MUDMAN Mud Man fat\fat fat\blue Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 7 9 14 100 125 Fat SEARCH 1 60 8 8 16 0 0 0 0 60 Demon IMMUNE_LIGHTNING 3 1165
MT_TOAD Toad Demon fat\fat fat\fatb Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 8 10 16 135 160 Fat SEARCH 2 70 8 8 16 40 0 8 20 65 Demon IMMUNE_MAGIC IMMUNE_MAGIC,RESIST_LIGHTNING 3 1380
MT_FLAYED Flayed One fat\fat fat\fatf Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 10 12 20 160 200 Fat SEARCH 3 85 8 10 20 0 0 0 0 70 Demon RESIST_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 2058
MT_WYRM Wyrm worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 5 7 11 60 90 SkeletonMelee 0 40 8 4 10 0 0 0 0 25 Animal RESIST_MAGIC RESIST_MAGIC 3 660
MT_CAVSLUG Cave Slug worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 6 8 13 75 110 SkeletonMelee 1 50 8 6 13 0 0 0 0 30 Animal RESIST_MAGIC RESIST_MAGIC 3 994
MT_DVLWYRM Devil Wyrm worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 7 9 15 100 140 SkeletonMelee 2 55 8 8 16 0 0 0 0 30 Animal RESIST_MAGIC,RESIST_FIRE RESIST_MAGIC,RESIST_FIRE 3 1320
MT_DEVOUR Devourer worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 8 10 17 125 200 SkeletonMelee 3 60 8 10 20 0 0 0 0 35 Animal RESIST_MAGIC,RESIST_FIRE RESIST_MAGIC,RESIST_FIRE 3 1827
MT_NMAGMA Magma Demon magma\magma Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 8 9 13 50 70 Magma SEARCH,CAN_OPEN_DOOR 0 45 4 2 10 50 13 0 0 45 Demon IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 1076
MT_YMAGMA Blood Stone magma\magma magma\yellow Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 8 10 14 55 75 Magma SEARCH,CAN_OPEN_DOOR 1 50 4 2 12 50 14 0 0 45 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 1309
MT_BMAGMA Hell Stone magma\magma magma\blue Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 9 11 16 60 80 Magma SEARCH,CAN_OPEN_DOOR 2 60 4 2 20 60 14 0 0 50 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 1680
MT_WMAGMA Lava Lord magma\magma magma\wierd Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 9 11 18 70 85 Magma SEARCH,CAN_OPEN_DOOR 3 75 4 4 24 60 14 0 0 60 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 2124
MT_HORNED Horned Demon rhino\rhino Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 7 9 13 40 80 Rhino SEARCH,CAN_OPEN_DOOR 0 60 7 2 16 100 0 5 32 40 Animal RESIST_FIRE 7 1172
MT_MUDRUN Mud Runner rhino\rhino rhino\orange Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 8 10 15 50 90 Rhino SEARCH,CAN_OPEN_DOOR 1 70 7 6 18 100 0 12 36 45 Animal RESIST_FIRE 7 1404
MT_FROSTC Frost Charger rhino\rhino rhino\blue Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 9 11 17 60 100 Rhino SEARCH,CAN_OPEN_DOOR 2 80 7 8 20 100 0 20 40 50 Animal IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 7 1720
MT_OBLORD Obsidian Lord rhino\rhino rhino\rhinob Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 10 12 19 70 110 Rhino SEARCH,CAN_OPEN_DOOR 3 90 7 10 22 100 0 20 50 55 Animal IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 1809
MT_BONEDMN oldboned demskel\demskl Never 128 1740 true true 10,8,20,6,24,16 3,1,1,1,1,1 24 24 12 70 70 Storm 0 60 8 6 14 12 0 0 0 50 Demon IMMUNE_MAGIC IMMUNE_MAGIC 7 1344
MT_REDDTH Red Death thin\thin thin\thinv3 Never 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 8 10 16 96 96 Storm 1 75 5 10 20 0 0 0 0 60 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 2168
MT_LTCHDMN Litch Demon thin\thin thin\thinv3 Never 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 9 11 18 110 110 Storm 2 80 5 10 24 0 0 0 0 45 Demon IMMUNE_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2736
MT_UDEDBLRG Undead Balrog thin\thin thin\thinv3 Never 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 11 13 22 130 130 Storm 3 85 5 12 30 0 0 0 0 65 Demon IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 7 3575
MT_INCIN Incinerator fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 21 22 16 30 45 FireMan 0 75 8 8 16 0 0 0 0 25 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 1888
MT_FLAMLRD Flame Lord fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 22 23 18 40 55 FireMan 1 75 8 10 20 0 0 0 0 25 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 2250
MT_DOOMFIRE Doom Fire fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 23 24 20 50 65 FireMan 2 80 8 12 24 0 0 0 0 30 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 2740
MT_HELLBURN Hell Burner fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 24 24 22 60 80 FireMan 3 85 8 15 30 0 0 0 0 30 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 3355
MT_STORM Red Storm thin\thin thin\thinv3 Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 9 11 18 55 110 Storm SEARCH,CAN_OPEN_DOOR 0 80 5 8 18 75 8 4 16 30 Demon IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2160
MT_RSTORM Storm Rider thin\thin Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 10 12 20 60 120 Storm SEARCH,CAN_OPEN_DOOR 1 80 5 8 18 80 8 4 16 30 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2391
MT_STORML Storm Lord thin\thin thin\thinv2 Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 11 13 22 75 135 Storm SEARCH,CAN_OPEN_DOOR 2 85 5 12 24 75 8 4 16 35 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2775
MT_MAEL Maelstrom thin\thin thin\thinv1 Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 12 14 24 90 150 Storm SEARCH,CAN_OPEN_DOOR 3 90 5 12 28 75 8 4 16 40 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 3177
MT_BIGFALL Devil Kin Brute bigfall\fallg newsfx\kbrute Retail 128 800 true false 10,8,11,8,17,0 1,1,1,1,2,2 21 22 27 120 160 SkeletonMelee SEARCH,CAN_OPEN_DOOR 3 100 6 18 24 0 0 0 0 70 Animal RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 3 2400
MT_WINGED Winged-Demon gargoyle\gargo Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,2 5 7 9 45 60 Gargoyle CAN_OPEN_DOOR 0 50 7 10 16 0 0 0 0 45 Demon IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 6 662
MT_GARGOYLE Gargoyle gargoyle\gargo gargoyle\gare Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,2 7 9 13 60 90 Gargoyle CAN_OPEN_DOOR 1 65 7 10 16 0 0 0 0 45 Demon IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 6 1205
MT_BLOODCLW Blood Claw gargoyle\gargo gargoyle\gargbr Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,1 9 11 19 75 125 Gargoyle CAN_OPEN_DOOR 2 80 7 14 22 0 0 0 0 50 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 6 1873
MT_DEATHW Death Wing gargoyle\gargo gargoyle\gargb Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,1 10 12 23 90 150 Gargoyle CAN_OPEN_DOOR 3 95 7 16 28 0 0 0 0 60 Demon IMMUNE_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 6 2278
MT_MEGA Slayer mega\mega Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 10 12 20 120 140 Mega SEARCH,CAN_OPEN_DOOR 0 100 8 12 20 0 3 0 0 60 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE 7 2300
MT_GUARD Guardian mega\mega mega\guard Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 11 13 22 140 160 Mega SEARCH,CAN_OPEN_DOOR 1 110 8 14 22 0 3 0 0 65 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE 7 2714
MT_VTEXLRD Vortex Lord mega\mega mega\vtexl Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 12 14 24 160 180 Mega SEARCH,CAN_OPEN_DOOR 2 120 8 18 24 0 3 0 0 70 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 3252
MT_BALROG Balrog mega\mega mega\balr Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 13 15 26 180 200 Mega SEARCH,CAN_OPEN_DOOR 3 130 8 22 30 0 3 0 0 75 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 3643
MT_NSNAKE Cave Viper snake\snake Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 11 13 21 100 150 Snake SEARCH 0 90 8 8 20 0 0 0 0 60 Demon IMMUNE_MAGIC IMMUNE_MAGIC 7 2725
MT_RSNAKE Fire Drake snake\snake snake\snakr Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 12 14 23 120 170 Snake SEARCH 1 105 8 12 24 0 0 0 0 65 Demon IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 3139
MT_BSNAKE Gold Viper snake\snake snake\snakg Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 13 14 25 140 180 Snake SEARCH 2 120 8 15 26 0 0 0 0 70 Demon IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 7 3540
MT_GSNAKE Azure Drake snake\snake snake\snakb Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 15 16 27 160 200 Snake SEARCH 3 130 8 18 30 0 0 0 0 75 Demon RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 7 3791
MT_NBLACK Black Knight black\black Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 12 14 24 150 150 SkeletonMelee SEARCH 0 110 8 15 20 0 0 0 0 75 Demon RESIST_MAGIC,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_LIGHTNING 7 3360
MT_RTBLACK Doom Guard black\black black\blkkntrt Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 13 15 26 165 165 SkeletonMelee SEARCH 0 130 8 18 25 0 0 0 0 75 Demon RESIST_MAGIC,RESIST_FIRE RESIST_MAGIC,IMMUNE_FIRE 7 3650
MT_BTBLACK Steel Lord black\black black\blkkntbt Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 14 16 28 180 180 SkeletonMelee SEARCH 1 120 8 20 30 0 0 0 0 80 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 4252
MT_RBLACK Blood Knight black\black black\blkkntbe Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 13 14 30 200 200 SkeletonMelee SEARCH 1 130 8 25 35 0 0 0 0 85 Demon IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 7 5130
MT_UNRAV The Shredded unrav\unrav newsfx\shred Retail 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 17 18 23 70 90 SkeletonMelee 0 75 7 4 12 0 0 0 0 65 Undead RESIST_FIRE,RESIST_LIGHTNING RESIST_FIRE,RESIST_LIGHTNING 3 900
MT_HOLOWONE Hollow One unrav\unrav acid\acid Never 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 18 19 27 135 240 SkeletonMelee 1 75 7 12 24 0 0 0 0 75 Undead IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 4374
MT_PAINMSTR Pain Master unrav\unrav acid\acid Never 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 19 20 29 110 200 SkeletonMelee 2 80 7 16 30 0 0 0 0 80 Undead IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 5147
MT_REALWEAV Reality Weaver unrav\unrav acid\acid Never 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 20 20 30 135 240 SkeletonMelee 3 85 7 20 35 0 0 0 0 85 Undead RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 5925
MT_SUCCUBUS Succubus succ\scbs Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 12 14 24 120 150 Succubus CAN_OPEN_DOOR 0 100 10 1 20 0 0 0 0 60 Demon RESIST_MAGIC IMMUNE_MAGIC,RESIST_FIRE 3 3696
MT_SNOWWICH Snow Witch succ\scbs succ\succb Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 13 15 26 135 175 Succubus CAN_OPEN_DOOR 1 110 10 1 24 0 0 0 0 65 Demon RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 4084
MT_HLSPWN Hell Spawn succ\scbs succ\succrw Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 14 16 28 150 200 Succubus SEARCH,CAN_OPEN_DOOR 2 115 10 1 30 0 0 0 0 75 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 4480
MT_SOLBRNR Soul Burner succ\scbs succ\succbw Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 15 16 30 140 225 Succubus SEARCH,CAN_OPEN_DOOR 3 120 10 1 35 0 0 0 0 85 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 4644
MT_COUNSLR Counselor mage\mage Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 13 14 25 70 70 Counselor CAN_OPEN_DOOR 0 90 8 8 20 0 0 0 0 0 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 7 4070
MT_MAGISTR Magistrate mage\mage mage\cnselg Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 14 15 27 85 85 Counselor CAN_OPEN_DOOR 1 100 8 10 24 0 0 0 0 0 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 4478
MT_CABALIST Cabalist mage\mage mage\cnselgd Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 15 16 29 120 120 Counselor CAN_OPEN_DOOR 2 110 8 14 30 0 0 0 0 0 Demon RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 7 4929
MT_ADVOCATE Advocate mage\mage mage\cnselbk Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 16 16 30 145 145 Counselor CAN_OPEN_DOOR 3 120 8 15 25 0 0 0 0 0 Demon IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 4968
MT_GOLEM Golem golem\golem golem\golm Never 96 386 true false 0,16,12,0,12,20 1,1,1,1,1,1 1 1 12 1 1 Golem CAN_OPEN_DOOR 0 0 7 1 1 0 0 0 0 1 Demon 0 0
MT_DIABLO The Dark Lord diablo\diablo Never 160 2000 true true 16,6,16,6,16,16 1,1,1,1,1,1 26 26 45 3333 3333 Diablo KNOCKBACK,SEARCH,CAN_OPEN_DOOR 3 220 4 30 60 0 11 0 0 90 Demon IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 7 31666
MT_DARKMAGE The Arch-Litch Malignus darkmage\dmage darkmage\dmag Never 128 1060 true false 6,1,21,6,23,18 1,1,1,1,1,1 21 21 30 160 160 Counselor CAN_OPEN_DOOR 3 120 8 20 40 0 0 0 0 70 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 4968
MT_HELLBOAR Hellboar fork\fork newsfx\hboar Retail 188 800 false false 10,10,15,6,16,0 2,1,1,1,1,1 17 18 23 80 100 SkeletonMelee KNOCKBACK,SEARCH 2 70 7 16 24 0 0 0 0 60 Demon RESIST_FIRE,RESIST_LIGHTNING 3 750
MT_STINGER Stinger scorp\scorp newsfx\stingr Retail 64 305 false false 10,10,12,6,15,0 2,1,1,1,1,1 17 18 22 30 40 SkeletonMelee 3 85 8 1 20 0 0 0 0 50 Animal RESIST_LIGHTNING 1 500
MT_PSYCHORB Psychorb eye\eye newsfx\psyco Retail 156 800 false false 12,13,13,7,21,0 2,1,1,1,1,1 17 18 22 20 30 Psychorb 3 80 8 10 10 0 0 0 0 40 Animal RESIST_FIRE 6 450
MT_ARACHNON Arachnon spider\spider newsfx\slord Retail 148 800 false false 12,10,15,6,20,0 2,1,1,1,1,1 17 18 22 60 80 SkeletonMelee SEARCH 3 50 8 5 15 0 0 0 0 50 Animal RESIST_LIGHTNING 7 500
MT_FELLTWIN Felltwin tsneak\tsneak newsfx\ftwin Retail 128 800 false false 13,13,15,11,16,0 2,1,1,1,1,1 17 18 22 50 70 SkeletonMelee SEARCH,CAN_OPEN_DOOR 3 70 8 10 18 0 0 0 0 50 Demon RESIST_FIRE,RESIST_LIGHTNING 3 600
MT_HORKSPWN Hork Spawn spawn\spawn newsfx\hspawn Retail 164 520 false true 15,12,14,11,14,0 1,1,1,1,1,1 18 19 22 30 30 SkeletonMelee 3 60 8 10 25 0 0 0 0 25 Demon RESIST_MAGIC RESIST_MAGIC 3 250
MT_VENMTAIL Venomtail wscorp\wscorp newsfx\stingr Retail 86 305 false false 10,10,12,6,15,0 2,1,1,1,1,1 19 20 24 40 50 SkeletonMelee 3 85 8 1 30 0 0 0 0 60 Animal RESIST_LIGHTNING IMMUNE_LIGHTNING 1 1000
MT_NECRMORB Necromorb eye2\eye2 newsfx\psyco Retail 140 800 false false 12,13,13,7,21,0 2,1,1,1,1,1 19 20 24 30 40 Necromorb 3 80 8 20 20 0 0 0 0 50 Animal RESIST_FIRE IMMUNE_FIRE,RESIST_LIGHTNING 6 1100
MT_SPIDLORD Spider Lord bspidr\bspidr newsfx\slord Retail 148 800 true true 12,10,15,6,20,10 2,1,1,1,1,1 19 20 24 80 100 Acid SEARCH 3 60 8 8 20 75 8 10 10 60 Animal RESIST_LIGHTNING RESIST_FIRE,IMMUNE_LIGHTNING 7 1250
MT_LASHWORM Lashworm clasp\clasp newsfx\lworm Retail 176 800 false false 10,12,15,6,16,0 1,1,1,1,1,1 19 20 20 30 30 SkeletonMelee 3 90 8 12 20 0 0 0 0 50 Animal RESIST_FIRE 3 600
MT_TORCHANT Torchant antworm\worm newsfx\tchant Retail 192 800 false false 14,12,12,6,20,0 2,1,1,1,1,1 19 20 22 60 80 Torchant 3 75 8 20 30 0 0 0 0 70 Animal IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 1250
MT_HORKDMN Hork Demon horkd\horkd newsfx\hdemon Never 138 800 true true 15,8,16,6,16,9 2,1,1,1,1,2 19 19 27 120 160 SkeletonMelee 3 60 8 20 35 80 8 0 0 80 Demon RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_LIGHTNING 7 2000
MT_DEFILER Hell Bug hellbug\hellbg newsfx\defile Never 198 800 true true 8,8,14,6,14,12 1,1,1,1,1,1 20 20 30 240 240 SkeletonMelee SEARCH 3 110 8 20 30 90 8 50 60 80 Demon RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 5000
MT_GRAVEDIG Gravedigger gravdg\gravdg newsfx\gdiggr Retail 124 800 true true 24,24,12,6,16,16 2,1,1,1,1,1 21 21 26 120 240 Scavenger CAN_OPEN_DOOR 3 80 6 2 12 0 0 0 0 20 Undead IMMUNE_LIGHTNING RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 3 2000
MT_TOMBRAT Tomb Rat rat\rat newsfx\tmbrat Retail 104 550 false false 11,8,12,6,20,0 2,1,1,1,1,1 21 22 24 80 120 SkeletonMelee 3 120 8 12 25 0 0 0 0 30 Animal RESIST_FIRE,RESIST_LIGHTNING 3 1800
MT_FIREBAT Firebat hellbat\helbat newsfx\helbat Retail 96 550 false false 18,16,14,6,18,11 2,1,1,1,1,1 21 22 24 60 80 FireBat 3 100 8 15 20 0 0 0 0 70 Animal IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 2400
MT_SKLWING Skullwing demskel\demskl newsfx\swing skelaxe\skelt Retail 128 1740 true false 10,8,20,6,24,16 3,1,1,1,1,1 21 22 27 70 70 SkeletonMelee 0 75 7 15 20 75 9 15 20 80 Undead RESIST_FIRE,RESIST_LIGHTNING RESIST_FIRE,RESIST_LIGHTNING 7 3000
MT_LICH Lich lich\lich newsfx\lich Retail 96 800 false true 12,10,10,7,21,0 2,1,1,1,2,1 21 22 25 80 100 Lich 3 100 8 15 20 0 0 0 0 60 Undead RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 3 3000
MT_CRYPTDMN Crypt Demon bubba\bubba newsfx\crypt Retail 154 800 false true 8,18,12,8,21,0 3,1,1,1,1,1 22 23 28 200 240 SkeletonMelee 3 100 8 20 40 0 0 0 0 85 Demon IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 3200
MT_HELLBAT Hellbat hellbat2\bhelbt newsfx\helbat Retail 96 550 true false 18,16,14,6,18,11 2,1,1,1,1,1 23 24 29 100 140 Torchant 3 110 8 30 30 0 0 0 0 80 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 3600
MT_BONEDEMN Bone Demon demskel\demskl newsfx\swing Retail 128 1740 true true 10,8,20,6,24,16 3,1,1,1,1,1 23 24 30 240 280 BoneDemon 0 100 8 40 50 160 12 50 50 50 Undead IMMUNE_FIRE,IMMUNE_LIGHTNING IMMUNE_FIRE,IMMUNE_LIGHTNING 7 5000
MT_ARCHLICH Arch Lich lich2\lich2 newsfx\lich Retail 136 800 false true 12,10,10,7,21,0 2,1,1,1,2,1 23 24 30 180 200 ArchLich 3 120 8 30 30 0 0 0 0 75 Undead RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 4000
MT_BICLOPS Biclops byclps\byclps newsfx\biclop Retail 180 800 false false 10,11,16,6,16,0 2,1,1,1,2,1 23 24 30 200 240 SkeletonMelee KNOCKBACK,CAN_OPEN_DOOR 3 90 8 40 50 0 0 0 0 80 Demon RESIST_LIGHTNING RESIST_FIRE,RESIST_LIGHTNING 3 4000
MT_FLESTHNG Flesh Thing flesh\flesh newsfx\flesht Retail 164 800 false true 15,24,15,6,16,0 1,1,1,1,1,1 23 24 28 300 400 SkeletonMelee 3 150 8 12 18 0 0 0 0 70 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 3 4000
MT_REAPER Reaper reaper\reap newsfx\reaper Retail 180 800 false false 12,10,14,6,16,0 2,1,1,1,1,1 23 24 30 260 300 SkeletonMelee 3 120 8 30 35 0 0 0 0 90 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 6000
MT_NAKRUL Na-Krul nkr\nkr newsfx\nakrul Never 226 1200 true true 2,6,16,3,16,16 1,1,1,1,1,1 31 31 40 1332 1332 SkeletonMelee KNOCKBACK,SEARCH,CAN_OPEN_DOOR 3 150 7 40 50 150 10 40 50 125 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 13333
1 _monster_id name assetsSuffix soundSuffix trnFile availability width image hasSpecial hasSpecialSound frames[6] rate[6] minDunLvl maxDunLvl level hitPointsMinimum hitPointsMaximum ai abilityFlags intelligence toHit animFrameNum minDamage maxDamage toHitSpecial animFrameNumSpecial minDamageSpecial maxDamageSpecial armorClass monsterClass resistance resistanceHell selectionType treasure exp
2 MT_NZOMBIE Zombie zombie\zombie Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 1 2 1 4 7 Zombie 0 10 8 2 5 0 0 0 0 5 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 54
3 MT_BZOMBIE Ghoul zombie\zombie zombie\bluered Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 2 3 2 7 11 Zombie 1 10 8 3 10 0 0 0 0 10 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 58
4 MT_GZOMBIE Rotting Carcass zombie\zombie zombie\grey Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 2 4 4 15 25 Zombie 2 25 8 5 15 0 0 0 0 15 Undead IMMUNE_MAGIC IMMUNE_MAGIC,RESIST_FIRE 3 136
5 MT_YZOMBIE Black Death zombie\zombie zombie\yellow Always 128 799 false false 11,24,12,6,16,0 4,1,1,1,1,1 3 5 6 25 40 Zombie 3 30 8 6 22 0 0 0 0 20 Undead IMMUNE_MAGIC IMMUNE_MAGIC,RESIST_LIGHTNING 3 240
6 MT_RFALLSP Fallen One falspear\phall falspear\fallent Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 1 2 1 1 4 Fallen 0 15 7 1 3 0 5 0 0 0 Animal 3 46
7 MT_DFALLSP Carver falspear\phall falspear\dark Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 2 3 3 4 8 Fallen 2 20 7 2 5 0 5 0 0 5 Animal 3 80
8 MT_YFALLSP Devil Kin falspear\phall Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 2 4 5 12 24 Fallen 2 25 7 3 7 0 5 0 0 10 Animal RESIST_FIRE 3 155
9 MT_BFALLSP Dark One falspear\phall falspear\blue Always 128 543 true true 11,11,13,11,18,13 3,1,1,1,1,1 3 5 7 20 36 Fallen 3 30 7 4 8 0 5 0 0 15 Animal RESIST_LIGHTNING 3 255
10 MT_WSKELAX Skeleton skelaxe\sklax skelaxe\white Always 128 553 true false 12,8,13,6,17,16 5,1,1,1,1,1 1 2 1 2 4 SkeletonMelee 0 20 8 1 4 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 64
11 MT_TSKELAX Corpse Axe skelaxe\sklax skelaxe\skelt Always 128 553 true false 12,8,13,6,17,16 4,1,1,1,1,1 2 3 2 4 7 SkeletonMelee 1 25 8 3 5 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 68
12 MT_RSKELAX Burning Dead skelaxe\sklax Always 128 553 true false 12,8,13,6,17,16 2,1,1,1,1,1 2 4 4 8 12 SkeletonMelee 2 30 8 3 7 0 0 0 0 5 Undead IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 154
13 MT_XSKELAX Horror skelaxe\sklax skelaxe\black Always 128 553 true false 12,8,13,6,17,16 3,1,1,1,1,1 3 5 6 12 20 SkeletonMelee 3 35 8 4 9 0 0 0 0 15 Undead IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 264
14 MT_RFALLSD Fallen One falsword\fall falsword\fallent Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 1 2 1 2 5 Fallen 0 15 8 1 4 0 5 0 0 10 Animal 3 52
15 MT_DFALLSD Carver falsword\fall falsword\dark Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 2 3 3 5 9 Fallen 1 20 8 2 7 0 5 0 0 15 Animal 3 90
16 MT_YFALLSD Devil Kin falsword\fall Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 2 4 5 16 24 Fallen 2 25 8 4 10 0 5 0 0 20 Animal RESIST_FIRE 3 180
17 MT_BFALLSD Dark One falsword\fall falsword\blue Always 128 623 true true 12,12,13,11,14,15 3,1,1,1,1,1 3 5 7 24 36 Fallen 3 30 8 4 12 0 5 0 0 25 Animal RESIST_LIGHTNING 3 280
18 MT_NSCAV Scavenger scav\scav Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 1 3 2 3 6 Scavenger 0 20 7 1 5 0 0 0 0 10 Animal RESIST_FIRE 3 80
19 MT_BSCAV Plague Eater scav\scav scav\scavbr Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 2 4 4 12 24 Scavenger 1 30 7 1 8 0 0 0 0 20 Animal RESIST_LIGHTNING 3 188
20 MT_WSCAV Shadow Beast scav\scav scav\scavbe Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 3 5 6 24 36 Scavenger 2 35 7 3 12 0 0 0 0 25 Animal RESIST_FIRE 3 375
21 MT_YSCAV Bone Gasher scav\scav scav\scavw Always 128 410 true false 12,8,12,6,20,11 2,1,1,1,1,1 4 6 8 28 40 Scavenger 3 35 7 5 15 0 0 0 0 30 Animal RESIST_MAGIC RESIST_LIGHTNING 3 552
22 MT_WSKELBW Skeleton skelbow\sklbw skelbow\white Always 128 567 true false 9,8,16,5,16,16 4,1,1,1,1,1 2 3 3 2 4 SkeletonRanged 0 15 12 1 2 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 110
23 MT_TSKELBW Corpse Bow skelbow\sklbw skelbow\skelt Always 128 567 true false 9,8,16,5,16,16 4,1,1,1,1,1 2 4 5 8 16 SkeletonRanged 1 25 12 1 4 0 0 0 0 0 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 210
24 MT_RSKELBW Burning Dead skelbow\sklbw Always 128 567 true false 9,8,16,5,16,16 2,1,1,1,1,1 3 5 7 10 24 SkeletonRanged 2 30 12 1 6 0 0 0 0 5 Undead IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 364
25 MT_XSKELBW Horror skelbow\sklbw skelbow\black Always 128 567 true false 9,8,16,5,16,16 3,1,1,1,1,1 4 6 9 15 45 SkeletonRanged 3 35 12 2 9 0 0 0 0 15 Undead IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 594
26 MT_WSKELSD Skeleton Captain skelsd\sklsr skelsd\white Always 128 575 true true 13,8,12,7,15,16 4,1,1,1,1,1 1 3 2 3 6 SkeletonMelee 0 20 8 2 7 0 0 0 0 10 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 90
27 MT_TSKELSD Corpse Captain skelsd\sklsr skelsd\skelt Always 128 575 true false 13,8,12,7,15,16 4,1,1,1,1,1 2 4 4 12 20 SkeletonMelee 1 30 8 3 9 0 0 0 0 5 Undead IMMUNE_MAGIC IMMUNE_MAGIC 3 200
28 MT_RSKELSD Burning Dead Captain skelsd\sklsr Always 128 575 true false 13,8,12,7,15,16 4,1,1,1,1,1 3 5 6 16 30 SkeletonMelee 2 35 8 4 10 0 0 0 0 15 Undead IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 393
29 MT_XSKELSD Horror Captain skelsd\sklsr skelsd\black Always 128 575 true false 13,8,12,7,15,16 4,1,1,1,1,1 4 6 8 35 50 SkeletonMelee SEARCH 3 40 8 5 14 0 0 0 0 30 Undead IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 604
30 MT_INVILORD Invisible Lord tsneak\tsneak Never 128 800 false false 13,13,15,11,16,0 2,1,1,1,1,1 19 20 14 278 278 SkeletonMelee SEARCH,CAN_OPEN_DOOR 3 65 8 16 30 0 0 0 0 60 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 3 2000
31 MT_SNEAK Hidden sneak\sneak Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 2 5 5 8 24 Sneak HIDDEN 0 35 8 3 6 0 0 0 0 25 Demon 3 278
32 MT_STALKER Stalker sneak\sneak sneak\sneakv2 Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 5 7 9 30 45 Sneak HIDDEN,SEARCH 1 40 8 8 16 0 0 0 0 30 Demon 3 630
33 MT_UNSEEN Unseen sneak\sneak sneak\sneakv3 Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 6 8 11 35 50 Sneak HIDDEN,SEARCH 2 45 8 12 20 0 0 0 0 30 Demon RESIST_MAGIC IMMUNE_MAGIC 3 935
34 MT_ILLWEAV Illusion Weaver sneak\sneak sneak\sneakv1 Retail 128 992 true false 16,8,12,8,24,15 2,1,1,1,1,1 8 10 13 40 60 Sneak HIDDEN,SEARCH 3 60 8 16 24 0 0 0 0 30 Demon RESIST_MAGIC,RESIST_FIRE IMMUNE_MAGIC,RESIST_FIRE 3 1500
35 MT_LRDSAYTR Satyr Lord goatlord\goatl newsfx\satyr Retail 160 800 false false 13,13,14,9,16,0 2,1,1,1,1,1 21 22 28 160 200 SkeletonMelee SEARCH 3 90 8 20 30 0 0 0 0 70 Animal RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 2800
36 MT_NGOATMC Flesh Clan goatmace\goat Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 4 6 8 30 45 GoatMelee SEARCH,CAN_OPEN_DOOR 0 50 8 4 10 0 0 0 0 40 Demon 3 460
37 MT_BGOATMC Stone Clan goatmace\goat goatmace\beige Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 5 7 10 40 55 GoatMelee SEARCH,CAN_OPEN_DOOR 1 60 8 6 12 0 0 0 0 40 Demon RESIST_MAGIC IMMUNE_MAGIC 3 685
38 MT_RGOATMC Fire Clan goatmace\goat goatmace\red Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 6 8 12 50 65 GoatMelee SEARCH,CAN_OPEN_DOOR 2 70 8 8 16 0 0 0 0 45 Demon RESIST_FIRE IMMUNE_FIRE 3 906
39 MT_GGOATMC Night Clan goatmace\goat goatmace\gray Retail 128 1030 true false 12,8,12,6,20,12 2,1,1,1,1,1 7 9 14 55 70 GoatMelee SEARCH,CAN_OPEN_DOOR 3 80 8 10 20 15 0 30 30 50 Demon RESIST_MAGIC IMMUNE_MAGIC 3 1190
40 MT_FIEND Fiend bat\bat bat\red Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 2 3 3 3 6 Bat 0 35 5 1 6 0 0 0 0 0 Animal 6 None 102
41 MT_BLINK Blink bat\bat Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 3 5 7 12 28 Bat 1 45 5 1 8 0 0 0 0 15 Animal 6 None 340
42 MT_GLOOM Gloom bat\bat bat\grey Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 4 6 9 28 36 Bat SEARCH 2 70 5 4 12 0 0 0 0 35 Animal RESIST_MAGIC RESIST_MAGIC 6 None 509
43 MT_FAMILIAR Familiar bat\bat bat\orange Always 96 364 false false 9,13,10,9,13,0 1,1,1,1,1,1 6 8 13 20 35 Bat SEARCH 3 50 5 4 16 0 0 0 0 35 Demon RESIST_MAGIC,IMMUNE_LIGHTNING RESIST_MAGIC,IMMUNE_LIGHTNING 6 None 448
44 MT_NGOATBW Flesh Clan goatbow\goatb Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 4 6 8 20 35 GoatRanged CAN_OPEN_DOOR 0 35 13 1 7 0 0 0 0 35 Demon 3 448
45 MT_BGOATBW Stone Clan goatbow\goatb goatbow\beige Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 5 7 10 30 40 GoatRanged CAN_OPEN_DOOR 1 40 13 2 9 0 0 0 0 35 Demon RESIST_MAGIC IMMUNE_MAGIC 3 645
46 MT_RGOATBW Fire Clan goatbow\goatb goatbow\red Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 6 8 12 40 50 GoatRanged SEARCH,CAN_OPEN_DOOR 2 45 13 3 11 0 0 0 0 35 Demon RESIST_FIRE IMMUNE_FIRE 3 822
47 MT_GGOATBW Night Clan goatbow\goatb goatbow\gray Retail 128 1040 false false 12,8,16,6,20,0 3,1,1,1,1,1 7 9 14 50 65 GoatRanged SEARCH,CAN_OPEN_DOOR 3 50 13 4 13 15 0 0 0 40 Demon RESIST_MAGIC IMMUNE_MAGIC 3 1092
48 MT_NACID Acid Beast acid\acid Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 6 8 11 40 66 Acid 0 40 8 4 12 25 8 0 0 30 Animal IMMUNE_ACID IMMUNE_MAGIC,IMMUNE_ACID 3 846
49 MT_RACID Poison Spitter acid\acid acid\acidblk Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 8 10 15 60 85 Acid 1 45 8 4 16 25 8 0 0 30 Animal IMMUNE_ACID IMMUNE_MAGIC,IMMUNE_ACID 3 1248
50 MT_BACID Pit Beast acid\acid acid\acidb Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 10 12 21 80 110 Acid 2 55 8 8 18 35 8 0 0 35 Animal RESIST_MAGIC,IMMUNE_ACID IMMUNE_MAGIC,RESIST_LIGHTNING,IMMUNE_ACID 3 2060
51 MT_XACID Lava Maw acid\acid acid\acidr Retail 128 716 true true 13,8,12,8,16,12 1,1,1,1,1,1 12 14 25 100 150 Acid 3 65 8 10 20 40 8 0 0 35 Animal RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_ACID IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_ACID 3 2940
52 MT_SKING Skeleton King sking\sking skelaxe\white Never 160 1010 true true 8,6,16,6,16,6 2,1,1,1,1,2 4 4 9 140 140 SkeletonKing SEARCH,CAN_OPEN_DOOR 3 60 8 6 16 0 0 0 0 70 Undead IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 Uniq(SKCROWN) 570
53 MT_CLEAVER The Butcher fatc\fatc Never 128 980 false false 10,8,12,6,16,0 1,1,1,1,1,1 1 1 1 320 320 Butcher 3 50 8 6 12 0 0 0 0 50 Demon RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 Uniq(CLEAVER) 710
54 MT_FAT Overlord fat\fat Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 5 7 10 60 80 Fat 0 55 8 6 12 0 0 0 0 55 Demon RESIST_FIRE 3 635
55 MT_MUDMAN Mud Man fat\fat fat\blue Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 7 9 14 100 125 Fat SEARCH 1 60 8 8 16 0 0 0 0 60 Demon IMMUNE_LIGHTNING 3 1165
56 MT_TOAD Toad Demon fat\fat fat\fatb Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 8 10 16 135 160 Fat SEARCH 2 70 8 8 16 40 0 8 20 65 Demon IMMUNE_MAGIC IMMUNE_MAGIC,RESIST_LIGHTNING 3 1380
57 MT_FLAYED Flayed One fat\fat fat\fatf Retail 128 1130 true false 8,10,15,6,16,10 4,1,1,1,1,1 10 12 20 160 200 Fat SEARCH 3 85 8 10 20 0 0 0 0 70 Demon RESIST_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 2058
58 MT_WYRM Wyrm worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 5 7 11 60 90 SkeletonMelee 0 40 8 4 10 0 0 0 0 25 Animal RESIST_MAGIC RESIST_MAGIC 3 660
59 MT_CAVSLUG Cave Slug worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 6 8 13 75 110 SkeletonMelee 1 50 8 6 13 0 0 0 0 30 Animal RESIST_MAGIC RESIST_MAGIC 3 994
60 MT_DVLWYRM Devil Wyrm worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 7 9 15 100 140 SkeletonMelee 2 55 8 8 16 0 0 0 0 30 Animal RESIST_MAGIC,RESIST_FIRE RESIST_MAGIC,RESIST_FIRE 3 1320
61 MT_DEVOUR Devourer worm\worm Never 160 2420 false false 13,13,13,11,19,0 1,1,1,1,1,1 8 10 17 125 200 SkeletonMelee 3 60 8 10 20 0 0 0 0 35 Animal RESIST_MAGIC,RESIST_FIRE RESIST_MAGIC,RESIST_FIRE 3 1827
62 MT_NMAGMA Magma Demon magma\magma Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 8 9 13 50 70 Magma SEARCH,CAN_OPEN_DOOR 0 45 4 2 10 50 13 0 0 45 Demon IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 1076
63 MT_YMAGMA Blood Stone magma\magma magma\yellow Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 8 10 14 55 75 Magma SEARCH,CAN_OPEN_DOOR 1 50 4 2 12 50 14 0 0 45 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 1309
64 MT_BMAGMA Hell Stone magma\magma magma\blue Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 9 11 16 60 80 Magma SEARCH,CAN_OPEN_DOOR 2 60 4 2 20 60 14 0 0 50 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 1680
65 MT_WMAGMA Lava Lord magma\magma magma\wierd Retail 128 1680 true true 8,10,14,7,18,18 2,1,1,1,1,1 9 11 18 70 85 Magma SEARCH,CAN_OPEN_DOOR 3 75 4 4 24 60 14 0 0 60 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 2124
66 MT_HORNED Horned Demon rhino\rhino Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 7 9 13 40 80 Rhino SEARCH,CAN_OPEN_DOOR 0 60 7 2 16 100 0 5 32 40 Animal RESIST_FIRE 7 1172
67 MT_MUDRUN Mud Runner rhino\rhino rhino\orange Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 8 10 15 50 90 Rhino SEARCH,CAN_OPEN_DOOR 1 70 7 6 18 100 0 12 36 45 Animal RESIST_FIRE 7 1404
68 MT_FROSTC Frost Charger rhino\rhino rhino\blue Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 9 11 17 60 100 Rhino SEARCH,CAN_OPEN_DOOR 2 80 7 8 20 100 0 20 40 50 Animal IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 7 1720
69 MT_OBLORD Obsidian Lord rhino\rhino rhino\rhinob Retail 160 1630 true true 8,8,14,6,16,6 2,1,1,1,1,1 10 12 19 70 110 Rhino SEARCH,CAN_OPEN_DOOR 3 90 7 10 22 100 0 20 50 55 Animal IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 1809
70 MT_BONEDMN oldboned demskel\demskl Never 128 1740 true true 10,8,20,6,24,16 3,1,1,1,1,1 24 24 12 70 70 Storm 0 60 8 6 14 12 0 0 0 50 Demon IMMUNE_MAGIC IMMUNE_MAGIC 7 1344
71 MT_REDDTH Red Death thin\thin thin\thinv3 Never 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 8 10 16 96 96 Storm 1 75 5 10 20 0 0 0 0 60 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 2168
72 MT_LTCHDMN Litch Demon thin\thin thin\thinv3 Never 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 9 11 18 110 110 Storm 2 80 5 10 24 0 0 0 0 45 Demon IMMUNE_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2736
73 MT_UDEDBLRG Undead Balrog thin\thin thin\thinv3 Never 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 11 13 22 130 130 Storm 3 85 5 12 30 0 0 0 0 65 Demon IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 7 3575
74 MT_INCIN Incinerator fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 21 22 16 30 45 FireMan 0 75 8 8 16 0 0 0 0 25 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 1888
75 MT_FLAMLRD Flame Lord fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 22 23 18 40 55 FireMan 1 75 8 10 20 0 0 0 0 25 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 3 2250
76 MT_DOOMFIRE Doom Fire fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 23 24 20 50 65 FireMan 2 80 8 12 24 0 0 0 0 30 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 2740
77 MT_HELLBURN Hell Burner fireman\firem Never 128 1460 true false 14,19,20,8,14,23 1,1,1,1,1,1 24 24 22 60 80 FireMan 3 85 8 15 30 0 0 0 0 30 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 3355
78 MT_STORM Red Storm thin\thin thin\thinv3 Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 9 11 18 55 110 Storm SEARCH,CAN_OPEN_DOOR 0 80 5 8 18 75 8 4 16 30 Demon IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2160
79 MT_RSTORM Storm Rider thin\thin Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 10 12 20 60 120 Storm SEARCH,CAN_OPEN_DOOR 1 80 5 8 18 80 8 4 16 30 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2391
80 MT_STORML Storm Lord thin\thin thin\thinv2 Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 11 13 22 75 135 Storm SEARCH,CAN_OPEN_DOOR 2 85 5 12 24 75 8 4 16 35 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 2775
81 MT_MAEL Maelstrom thin\thin thin\thinv1 Retail 160 1740 true true 8,8,18,4,17,14 3,1,1,1,1,1 12 14 24 90 150 Storm SEARCH,CAN_OPEN_DOOR 3 90 5 12 28 75 8 4 16 40 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 7 3177
82 MT_BIGFALL Devil Kin Brute bigfall\fallg newsfx\kbrute Retail 128 800 true false 10,8,11,8,17,0 1,1,1,1,2,2 21 22 27 120 160 SkeletonMelee SEARCH,CAN_OPEN_DOOR 3 100 6 18 24 0 0 0 0 70 Animal RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 3 2400
83 MT_WINGED Winged-Demon gargoyle\gargo Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,2 5 7 9 45 60 Gargoyle CAN_OPEN_DOOR 0 50 7 10 16 0 0 0 0 45 Demon IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 6 662
84 MT_GARGOYLE Gargoyle gargoyle\gargo gargoyle\gare Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,2 7 9 13 60 90 Gargoyle CAN_OPEN_DOOR 1 65 7 10 16 0 0 0 0 45 Demon IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_LIGHTNING 6 1205
85 MT_BLOODCLW Blood Claw gargoyle\gargo gargoyle\gargbr Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,1 9 11 19 75 125 Gargoyle CAN_OPEN_DOOR 2 80 7 14 22 0 0 0 0 50 Demon IMMUNE_MAGIC,IMMUNE_FIRE IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 6 1873
86 MT_DEATHW Death Wing gargoyle\gargo gargoyle\gargb Retail 160 1650 true false 14,14,14,10,18,14 1,1,1,1,1,1 10 12 23 90 150 Gargoyle CAN_OPEN_DOOR 3 95 7 16 28 0 0 0 0 60 Demon IMMUNE_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 6 2278
87 MT_MEGA Slayer mega\mega Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 10 12 20 120 140 Mega SEARCH,CAN_OPEN_DOOR 0 100 8 12 20 0 3 0 0 60 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE 7 2300
88 MT_GUARD Guardian mega\mega mega\guard Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 11 13 22 140 160 Mega SEARCH,CAN_OPEN_DOOR 1 110 8 14 22 0 3 0 0 65 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE 7 2714
89 MT_VTEXLRD Vortex Lord mega\mega mega\vtexl Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 12 14 24 160 180 Mega SEARCH,CAN_OPEN_DOOR 2 120 8 18 24 0 3 0 0 70 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 3252
90 MT_BALROG Balrog mega\mega mega\balr Retail 160 2220 true true 6,7,14,1,24,5 3,1,1,1,2,1 13 15 26 180 200 Mega SEARCH,CAN_OPEN_DOOR 3 130 8 22 30 0 3 0 0 75 Demon RESIST_MAGIC,IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 3643
91 MT_NSNAKE Cave Viper snake\snake Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 11 13 21 100 150 Snake SEARCH 0 90 8 8 20 0 0 0 0 60 Demon IMMUNE_MAGIC IMMUNE_MAGIC 7 2725
92 MT_RSNAKE Fire Drake snake\snake snake\snakr Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 12 14 23 120 170 Snake SEARCH 1 105 8 12 24 0 0 0 0 65 Demon IMMUNE_MAGIC,RESIST_FIRE IMMUNE_MAGIC,IMMUNE_FIRE 7 3139
93 MT_BSNAKE Gold Viper snake\snake snake\snakg Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 13 14 25 140 180 Snake SEARCH 2 120 8 15 26 0 0 0 0 70 Demon IMMUNE_MAGIC,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 7 3540
94 MT_GSNAKE Azure Drake snake\snake snake\snakb Retail 160 1270 false false 12,11,13,5,18,0 2,1,1,1,1,1 15 16 27 160 200 Snake SEARCH 3 130 8 18 30 0 0 0 0 75 Demon RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 7 3791
95 MT_NBLACK Black Knight black\black Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 12 14 24 150 150 SkeletonMelee SEARCH 0 110 8 15 20 0 0 0 0 75 Demon RESIST_MAGIC,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_LIGHTNING 7 3360
96 MT_RTBLACK Doom Guard black\black black\blkkntrt Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 13 15 26 165 165 SkeletonMelee SEARCH 0 130 8 18 25 0 0 0 0 75 Demon RESIST_MAGIC,RESIST_FIRE RESIST_MAGIC,IMMUNE_FIRE 7 3650
97 MT_BTBLACK Steel Lord black\black black\blkkntbt Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 14 16 28 180 180 SkeletonMelee SEARCH 1 120 8 20 30 0 0 0 0 80 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 4252
98 MT_RBLACK Blood Knight black\black black\blkkntbe Retail 160 2120 false false 8,8,16,4,24,0 2,1,1,1,1,1 13 14 30 200 200 SkeletonMelee SEARCH 1 130 8 25 35 0 0 0 0 85 Demon IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 7 5130
99 MT_UNRAV The Shredded unrav\unrav newsfx\shred Retail 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 17 18 23 70 90 SkeletonMelee 0 75 7 4 12 0 0 0 0 65 Undead RESIST_FIRE,RESIST_LIGHTNING RESIST_FIRE,RESIST_LIGHTNING 3 900
100 MT_HOLOWONE Hollow One unrav\unrav acid\acid Never 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 18 19 27 135 240 SkeletonMelee 1 75 7 12 24 0 0 0 0 75 Undead IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 4374
101 MT_PAINMSTR Pain Master unrav\unrav acid\acid Never 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 19 20 29 110 200 SkeletonMelee 2 80 7 16 30 0 0 0 0 80 Undead IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 5147
102 MT_REALWEAV Reality Weaver unrav\unrav acid\acid Never 96 484 false false 10,10,12,5,16,0 1,1,1,1,1,1 20 20 30 135 240 SkeletonMelee 3 85 7 20 35 0 0 0 0 85 Undead RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 5925
103 MT_SUCCUBUS Succubus succ\scbs Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 12 14 24 120 150 Succubus CAN_OPEN_DOOR 0 100 10 1 20 0 0 0 0 60 Demon RESIST_MAGIC IMMUNE_MAGIC,RESIST_FIRE 3 3696
104 MT_SNOWWICH Snow Witch succ\scbs succ\succb Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 13 15 26 135 175 Succubus CAN_OPEN_DOOR 1 110 10 1 24 0 0 0 0 65 Demon RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_LIGHTNING 3 4084
105 MT_HLSPWN Hell Spawn succ\scbs succ\succrw Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 14 16 28 150 200 Succubus SEARCH,CAN_OPEN_DOOR 2 115 10 1 30 0 0 0 0 75 Demon RESIST_MAGIC,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 4480
106 MT_SOLBRNR Soul Burner succ\scbs succ\succbw Retail 128 980 false false 14,8,16,7,24,0 1,1,1,1,1,1 15 16 30 140 225 Succubus SEARCH,CAN_OPEN_DOOR 3 120 10 1 35 0 0 0 0 85 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 4644
107 MT_COUNSLR Counselor mage\mage Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 13 14 25 70 70 Counselor CAN_OPEN_DOOR 0 90 8 8 20 0 0 0 0 0 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 7 4070
108 MT_MAGISTR Magistrate mage\mage mage\cnselg Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 14 15 27 85 85 Counselor CAN_OPEN_DOOR 1 100 8 10 24 0 0 0 0 0 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 4478
109 MT_CABALIST Cabalist mage\mage mage\cnselgd Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 15 16 29 120 120 Counselor CAN_OPEN_DOOR 2 110 8 14 30 0 0 0 0 0 Demon RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 7 4929
110 MT_ADVOCATE Advocate mage\mage mage\cnselbk Retail 128 2000 true false 12,1,20,8,28,20 1,1,1,1,1,1 16 16 30 145 145 Counselor CAN_OPEN_DOOR 3 120 8 15 25 0 0 0 0 0 Demon IMMUNE_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 4968
111 MT_GOLEM Golem golem\golem golem\golm Never 96 386 true false 0,16,12,0,12,20 1,1,1,1,1,1 1 1 12 1 1 Golem CAN_OPEN_DOOR 0 0 7 1 1 0 0 0 0 1 Demon 0 0
112 MT_DIABLO The Dark Lord diablo\diablo Never 160 2000 true true 16,6,16,6,16,16 1,1,1,1,1,1 26 26 45 3333 3333 Diablo KNOCKBACK,SEARCH,CAN_OPEN_DOOR 3 220 4 30 60 0 11 0 0 90 Demon IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 7 31666
113 MT_DARKMAGE The Arch-Litch Malignus darkmage\dmage darkmage\dmag Never 128 1060 true false 6,1,21,6,23,18 1,1,1,1,1,1 21 21 30 160 160 Counselor CAN_OPEN_DOOR 3 120 8 20 40 0 0 0 0 70 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 4968
114 MT_HELLBOAR Hellboar fork\fork newsfx\hboar Retail 188 800 false false 10,10,15,6,16,0 2,1,1,1,1,1 17 18 23 80 100 SkeletonMelee KNOCKBACK,SEARCH 2 70 7 16 24 0 0 0 0 60 Demon RESIST_FIRE,RESIST_LIGHTNING 3 750
115 MT_STINGER Stinger scorp\scorp newsfx\stingr Retail 64 305 false false 10,10,12,6,15,0 2,1,1,1,1,1 17 18 22 30 40 SkeletonMelee 3 85 8 1 20 0 0 0 0 50 Animal RESIST_LIGHTNING 1 500
116 MT_PSYCHORB Psychorb eye\eye newsfx\psyco Retail 156 800 false false 12,13,13,7,21,0 2,1,1,1,1,1 17 18 22 20 30 Psychorb 3 80 8 10 10 0 0 0 0 40 Animal RESIST_FIRE 6 450
117 MT_ARACHNON Arachnon spider\spider newsfx\slord Retail 148 800 false false 12,10,15,6,20,0 2,1,1,1,1,1 17 18 22 60 80 SkeletonMelee SEARCH 3 50 8 5 15 0 0 0 0 50 Animal RESIST_LIGHTNING 7 500
118 MT_FELLTWIN Felltwin tsneak\tsneak newsfx\ftwin Retail 128 800 false false 13,13,15,11,16,0 2,1,1,1,1,1 17 18 22 50 70 SkeletonMelee SEARCH,CAN_OPEN_DOOR 3 70 8 10 18 0 0 0 0 50 Demon RESIST_FIRE,RESIST_LIGHTNING 3 600
119 MT_HORKSPWN Hork Spawn spawn\spawn newsfx\hspawn Retail 164 520 false true 15,12,14,11,14,0 1,1,1,1,1,1 18 19 22 30 30 SkeletonMelee 3 60 8 10 25 0 0 0 0 25 Demon RESIST_MAGIC RESIST_MAGIC 3 250
120 MT_VENMTAIL Venomtail wscorp\wscorp newsfx\stingr Retail 86 305 false false 10,10,12,6,15,0 2,1,1,1,1,1 19 20 24 40 50 SkeletonMelee 3 85 8 1 30 0 0 0 0 60 Animal RESIST_LIGHTNING IMMUNE_LIGHTNING 1 1000
121 MT_NECRMORB Necromorb eye2\eye2 newsfx\psyco Retail 140 800 false false 12,13,13,7,21,0 2,1,1,1,1,1 19 20 24 30 40 Necromorb 3 80 8 20 20 0 0 0 0 50 Animal RESIST_FIRE IMMUNE_FIRE,RESIST_LIGHTNING 6 1100
122 MT_SPIDLORD Spider Lord bspidr\bspidr newsfx\slord Retail 148 800 true true 12,10,15,6,20,10 2,1,1,1,1,1 19 20 24 80 100 Acid SEARCH 3 60 8 8 20 75 8 10 10 60 Animal RESIST_LIGHTNING RESIST_FIRE,IMMUNE_LIGHTNING 7 1250
123 MT_LASHWORM Lashworm clasp\clasp newsfx\lworm Retail 176 800 false false 10,12,15,6,16,0 1,1,1,1,1,1 19 20 20 30 30 SkeletonMelee 3 90 8 12 20 0 0 0 0 50 Animal RESIST_FIRE 3 600
124 MT_TORCHANT Torchant antworm\worm newsfx\tchant Retail 192 800 false false 14,12,12,6,20,0 2,1,1,1,1,1 19 20 22 60 80 Torchant 3 75 8 20 30 0 0 0 0 70 Animal IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 1250
125 MT_HORKDMN Hork Demon horkd\horkd newsfx\hdemon Never 138 800 true true 15,8,16,6,16,9 2,1,1,1,1,2 19 19 27 120 160 SkeletonMelee 3 60 8 20 35 80 8 0 0 80 Demon RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_LIGHTNING 7 2000
126 MT_DEFILER Hell Bug hellbug\hellbg newsfx\defile Never 198 800 true true 8,8,14,6,14,12 1,1,1,1,1,1 20 20 30 240 240 SkeletonMelee SEARCH 3 110 8 20 30 90 8 50 60 80 Demon RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 5000
127 MT_GRAVEDIG Gravedigger gravdg\gravdg newsfx\gdiggr Retail 124 800 true true 24,24,12,6,16,16 2,1,1,1,1,1 21 21 26 120 240 Scavenger CAN_OPEN_DOOR 3 80 6 2 12 0 0 0 0 20 Undead IMMUNE_LIGHTNING RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 3 2000
128 MT_TOMBRAT Tomb Rat rat\rat newsfx\tmbrat Retail 104 550 false false 11,8,12,6,20,0 2,1,1,1,1,1 21 22 24 80 120 SkeletonMelee 3 120 8 12 25 0 0 0 0 30 Animal RESIST_FIRE,RESIST_LIGHTNING 3 1800
129 MT_FIREBAT Firebat hellbat\helbat newsfx\helbat Retail 96 550 false false 18,16,14,6,18,11 2,1,1,1,1,1 21 22 24 60 80 FireBat 3 100 8 15 20 0 0 0 0 70 Animal IMMUNE_FIRE RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 7 2400
130 MT_SKLWING Skullwing demskel\demskl newsfx\swing skelaxe\skelt Retail 128 1740 true false 10,8,20,6,24,16 3,1,1,1,1,1 21 22 27 70 70 SkeletonMelee 0 75 7 15 20 75 9 15 20 80 Undead RESIST_FIRE,RESIST_LIGHTNING RESIST_FIRE,RESIST_LIGHTNING 7 3000
131 MT_LICH Lich lich\lich newsfx\lich Retail 96 800 false true 12,10,10,7,21,0 2,1,1,1,2,1 21 22 25 80 100 Lich 3 100 8 15 20 0 0 0 0 60 Undead RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING 3 3000
132 MT_CRYPTDMN Crypt Demon bubba\bubba newsfx\crypt Retail 154 800 false true 8,18,12,8,21,0 3,1,1,1,1,1 22 23 28 200 240 SkeletonMelee 3 100 8 20 40 0 0 0 0 85 Demon IMMUNE_MAGIC,RESIST_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING 3 3200
133 MT_HELLBAT Hellbat hellbat2\bhelbt newsfx\helbat Retail 96 550 true false 18,16,14,6,18,11 2,1,1,1,1,1 23 24 29 100 140 Torchant 3 110 8 30 30 0 0 0 0 80 Demon RESIST_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING RESIST_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 3600
134 MT_BONEDEMN Bone Demon demskel\demskl newsfx\swing Retail 128 1740 true true 10,8,20,6,24,16 3,1,1,1,1,1 23 24 30 240 280 BoneDemon 0 100 8 40 50 160 12 50 50 50 Undead IMMUNE_FIRE,IMMUNE_LIGHTNING IMMUNE_FIRE,IMMUNE_LIGHTNING 7 5000
135 MT_ARCHLICH Arch Lich lich2\lich2 newsfx\lich Retail 136 800 false true 12,10,10,7,21,0 2,1,1,1,2,1 23 24 30 180 200 ArchLich 3 120 8 30 30 0 0 0 0 75 Undead RESIST_MAGIC,RESIST_FIRE,IMMUNE_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 4000
136 MT_BICLOPS Biclops byclps\byclps newsfx\biclop Retail 180 800 false false 10,11,16,6,16,0 2,1,1,1,2,1 23 24 30 200 240 SkeletonMelee KNOCKBACK,CAN_OPEN_DOOR 3 90 8 40 50 0 0 0 0 80 Demon RESIST_LIGHTNING RESIST_FIRE,RESIST_LIGHTNING 3 4000
137 MT_FLESTHNG Flesh Thing flesh\flesh newsfx\flesht Retail 164 800 false true 15,24,15,6,16,0 1,1,1,1,1,1 23 24 28 300 400 SkeletonMelee 3 150 8 12 18 0 0 0 0 70 Demon RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING RESIST_MAGIC,RESIST_FIRE,RESIST_LIGHTNING 3 4000
138 MT_REAPER Reaper reaper\reap newsfx\reaper Retail 180 800 false false 12,10,14,6,16,0 2,1,1,1,1,1 23 24 30 260 300 SkeletonMelee 3 120 8 30 35 0 0 0 0 90 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 3 6000
139 MT_NAKRUL Na-Krul nkr\nkr newsfx\nakrul Never 226 1200 true true 2,6,16,3,16,16 1,1,1,1,1,1 31 31 40 1332 1332 SkeletonMelee KNOCKBACK,SEARCH,CAN_OPEN_DOOR 3 150 7 40 50 150 10 40 50 125 Demon IMMUNE_MAGIC,IMMUNE_FIRE,RESIST_LIGHTNING IMMUNE_MAGIC,IMMUNE_FIRE,IMMUNE_LIGHTNING 7 13333

15
Source/data/file.cpp

@ -47,24 +47,31 @@ void DataFile::reportFatalError(Error code, std::string_view fileName)
}
}
void DataFile::reportFatalFieldError(DataFileField::Error code, std::string_view fileName, std::string_view fieldName, const DataFileField &field)
void DataFile::reportFatalFieldError(DataFileField::Error code, std::string_view fileName, std::string_view fieldName, const DataFileField &field, std::string_view details)
{
std::string detailsStr;
if (!details.empty()) {
detailsStr = StrCat("\n", details);
}
switch (code) {
case DataFileField::Error::NotANumber:
app_fatal(fmt::format(fmt::runtime(_(
/* TRANSLATORS: Error message when parsing a data file and a text value is encountered when a number is expected. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
"Non-numeric value {0} for {1} in {2} at row {3} and column {4}")),
field.currentValue(), fieldName, fileName, field.row(), field.column()));
field.currentValue(), fieldName, fileName, field.row(), field.column())
.append(detailsStr));
case DataFileField::Error::OutOfRange:
app_fatal(fmt::format(fmt::runtime(_(
/* TRANSLATORS: Error message when parsing a data file and we find a number larger than expected. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
"Out of range value {0} for {1} in {2} at row {3} and column {4}")),
field.currentValue(), fieldName, fileName, field.row(), field.column()));
field.currentValue(), fieldName, fileName, field.row(), field.column())
.append(detailsStr));
case DataFileField::Error::InvalidValue:
app_fatal(fmt::format(fmt::runtime(_(
/* TRANSLATORS: Error message when we find an unrecognised value in a key column. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
"Invalid value {0} for {1} in {2} at row {3} and column {4}")),
field.currentValue(), fieldName, fileName, field.row(), field.column()));
field.currentValue(), fieldName, fileName, field.row(), field.column())
.append(detailsStr));
}
}

2
Source/data/file.hpp

@ -75,7 +75,7 @@ public:
static tl::expected<DataFile, Error> load(std::string_view path);
static void reportFatalError(Error code, std::string_view fileName);
static void reportFatalFieldError(DataFileField::Error code, std::string_view fileName, std::string_view fieldName, const DataFileField &field);
static void reportFatalFieldError(DataFileField::Error code, std::string_view fileName, std::string_view fieldName, const DataFileField &field, std::string_view details = {});
void resetHeader()
{

50
Source/data/iterators.hpp

@ -4,9 +4,11 @@
#include <ostream>
#include <expected.hpp>
#include <function_ref.hpp>
#include "parser.hpp"
#include "utils/parse_int.hpp"
#include "utils/str_split.hpp"
namespace devilution {
@ -111,6 +113,54 @@ public:
return mapError(result.ec);
}
[[nodiscard]] tl::expected<void, Error> parseBool(bool &destination)
{
const std::string_view str = value();
if (str == "true") {
destination = true;
return {};
}
if (str == "false") {
destination = false;
return {};
}
return tl::make_unexpected(DataFileField::Error::InvalidValue);
}
template <typename T, size_t N>
[[nodiscard]] tl::expected<void, Error> parseIntArray(T (&destination)[N])
{
size_t i = 0;
for (const std::string_view part : SplitByChar(value(), ',')) {
if (i == N)
return tl::make_unexpected(Error::InvalidValue);
const std::from_chars_result result
= std::from_chars(part.data(), part.data() + part.size(), destination[i]);
if (result.ec != std::errc())
return mapError(result.ec);
++i;
}
if (i != N)
return tl::make_unexpected(Error::InvalidValue);
return {};
}
template <typename T, typename ParseFn>
[[nodiscard]] tl::expected<void, Error> parseEnumList(T &destination, ParseFn &&parseFn)
{
destination = {};
const std::string_view str = value();
if (str.empty())
return {};
for (const std::string_view part : SplitByChar(str, ',')) {
auto result = parseFn(part);
if (!result.has_value())
return tl::make_unexpected(Error::InvalidValue);
destination |= result.value();
}
return {};
}
template <typename T>
[[nodiscard]] tl::expected<T, Error> asInt()
{

4
Source/diablo.cpp

@ -57,6 +57,7 @@
#include "menu.h"
#include "minitext.h"
#include "missiles.h"
#include "monstdat.h"
#include "movie.h"
#include "multi.h"
#include "nthread.h"
@ -2474,6 +2475,9 @@ int DiabloMain(int argc, char **argv)
// Load dynamic data before we go into the menu as we need to initialise player characters in memory pretty early.
LoadPlayerDataFiles();
// TODO: We can probably load this much later (when the game is starting).
LoadMonsterData();
DiabloInit();
#ifdef __UWP__
onInitialized();

2
Source/lua/modules/dev/monsters.cpp

@ -105,7 +105,7 @@ std::string DebugCmdSpawnMonster(std::string name, std::optional<unsigned> count
for (int i = 0; i < NUM_MTYPES; i++) {
auto mondata = MonstersData[i];
const std::string monsterName = AsciiStrToLower(mondata.name);
const std::string monsterName = AsciiStrToLower(std::string_view(mondata.name));
if (monsterName.find(name) == std::string::npos)
continue;
mtype = i;

627
Source/monstdat.cpp

@ -6,7 +6,11 @@
#include "monstdat.h"
#include <cstdint>
#include <unordered_map>
#include <expected.hpp>
#include "data/file.hpp"
#include "items.h"
#include "monster.h"
#include "textdat.h"
@ -22,220 +26,17 @@ constexpr uint16_t Uniq(_unique_items item)
return static_cast<uint16_t>(T_UNIQ) + item;
}
const char *const MonsterSpritePaths[] = {
"zombie\\zombie", // Zombie
"falspear\\phall", // FallenSpear
"falsword\\fall", // FallenSword
"skelaxe\\sklax", // SkeletonAxe
"skelbow\\sklbw", // SkeletonBow
"skelsd\\sklsr", // SkeletonCapt
"demskel\\demskl", // SkeletonDemo
"sking\\sking", // SkeletonKing
"scav\\scav", // Scavenger
"tsneak\\tsneak", // InvisibleLor
"sneak\\sneak", // Hidden
"goatmace\\goat", // GoatMace
"goatbow\\goatb", // GoatBow
"goatlord\\goatl", // GoatLord
"bat\\bat", // Bat
"acid\\acid", // AcidBeast
"fat\\fat", // Overlord
"fatc\\fatc", // Butcher
"worm\\worm", // Wyrm
"magma\\magma", // MagmaDemon
"rhino\\rhino", // HornedDemon
"thin\\thin", // StormRider
"fireman\\firem", // Incinerator
"bigfall\\fallg", // DevilKinBrut
"gargoyle\\gargo", // Gargoyle
"mega\\mega", // Slayer
"snake\\snake", // Viper
"black\\black", // BlackKnight
"unrav\\unrav", // Shredded
"succ\\scbs", // Succubus
"mage\\mage", // Counselor
"golem\\golem", // Golem
"diablo\\diablo", // Diablo
"darkmage\\dmage", // ArchLitch
"fork\\fork", // Hellboar
"scorp\\scorp", // Stinger
"eye\\eye", // Psychorb
"spider\\spider", // Arachnon
"spawn\\spawn", // HorkSpawn
"wscorp\\wscorp", // Venomtail
"eye2\\eye2", // Necromorb
"bspidr\\bspidr", // SpiderLord
"clasp\\clasp", // Lashworm
"antworm\\worm", // Torchant
"horkd\\horkd", // HorkDemon
"hellbug\\hellbg", // HellBug
"gravdg\\gravdg", // Gravedigger
"rat\\rat", // Rat
"hellbat\\helbat", // Firebat
"lich\\lich", // Lich
"bubba\\bubba", // CryptDemon
"hellbat2\\bhelbt", // Hellbat
"lich2\\lich2", // ArchLich
"byclps\\byclps", // Biclops
"flesh\\flesh", // FleshThing
"reaper\\reap", // Reaper
"nkr\\nkr", // NaKrul
};
std::vector<std::string> MonsterSpritePaths;
} // namespace
const char *MonsterData::spritePath() const
{
return MonsterSpritePaths[static_cast<size_t>(spriteId)];
return MonsterSpritePaths[static_cast<size_t>(spriteId)].c_str();
}
/** Contains the data related to each monster ID. */
const MonsterData MonstersData[] = {
// clang-format off
// _monster_id name, soundSuffix, trnFile, spriteId, availability, width, image, hasSpecial, hasSpecialSound, frames[6], rate[6], minDunLvl, maxDunLvl, level, hitPointsMinimum, hitPointsMaximum, ai, abilityFlags, intelligence, toHit, animFrameNum, minDamage, maxDamage, toHitSpecial, animFrameNumSpecial, minDamageSpecial, maxDamageSpecial, armorClass, monsterClass, resistance, resistanceHell, selectionType, treasure, exp
// TRANSLATORS: Monster Block start
/* MT_NZOMBIE */ { P_("monster", "Zombie"), nullptr, nullptr, MonsterSpriteId::Zombie, MonsterAvailability::Always, 128, 799, false, false, { 11, 24, 12, 6, 16, 0 }, { 4, 1, 1, 1, 1, 1 }, 1, 2, 1, 4, 7, MonsterAIID::Zombie, 0, 0, 10, 8, 2, 5, 0, 0, 0, 0, 5, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 54 },
/* MT_BZOMBIE */ { P_("monster", "Ghoul"), nullptr, "zombie\\bluered", MonsterSpriteId::Zombie, MonsterAvailability::Always, 128, 799, false, false, { 11, 24, 12, 6, 16, 0 }, { 4, 1, 1, 1, 1, 1 }, 2, 3, 2, 7, 11, MonsterAIID::Zombie, 0, 1, 10, 8, 3, 10, 0, 0, 0, 0, 10, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 58 },
/* MT_GZOMBIE */ { P_("monster", "Rotting Carcass"), nullptr, "zombie\\grey", MonsterSpriteId::Zombie, MonsterAvailability::Always, 128, 799, false, false, { 11, 24, 12, 6, 16, 0 }, { 4, 1, 1, 1, 1, 1 }, 2, 4, 4, 15, 25, MonsterAIID::Zombie, 0, 2, 25, 8, 5, 15, 0, 0, 0, 0, 15, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC | RESIST_FIRE, 3, 0, 136 },
/* MT_YZOMBIE */ { P_("monster", "Black Death"), nullptr, "zombie\\yellow", MonsterSpriteId::Zombie, MonsterAvailability::Always, 128, 799, false, false, { 11, 24, 12, 6, 16, 0 }, { 4, 1, 1, 1, 1, 1 }, 3, 5, 6, 25, 40, MonsterAIID::Zombie, 0, 3, 30, 8, 6, 22, 0, 0, 0, 0, 20, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC | RESIST_LIGHTNING, 3, 0, 240 },
/* MT_RFALLSP */ { P_("monster", "Fallen One"), nullptr, "falspear\\fallent", MonsterSpriteId::FallenSpear, MonsterAvailability::Always, 128, 543, true, true, { 11, 11, 13, 11, 18, 13 }, { 3, 1, 1, 1, 1, 1 }, 1, 2, 1, 1, 4, MonsterAIID::Fallen, 0, 0, 15, 7, 1, 3, 0, 5, 0, 0, 0, MonsterClass::Animal, 0, 0, 3, 0, 46 },
/* MT_DFALLSP */ { P_("monster", "Carver"), nullptr, "falspear\\dark", MonsterSpriteId::FallenSpear, MonsterAvailability::Always, 128, 543, true, true, { 11, 11, 13, 11, 18, 13 }, { 3, 1, 1, 1, 1, 1 }, 2, 3, 3, 4, 8, MonsterAIID::Fallen, 0, 2, 20, 7, 2, 5, 0, 5, 0, 0, 5, MonsterClass::Animal, 0, 0, 3, 0, 80 },
/* MT_YFALLSP */ { P_("monster", "Devil Kin"), nullptr, nullptr, MonsterSpriteId::FallenSpear, MonsterAvailability::Always, 128, 543, true, true, { 11, 11, 13, 11, 18, 13 }, { 3, 1, 1, 1, 1, 1 }, 2, 4, 5, 12, 24, MonsterAIID::Fallen, 0, 2, 25, 7, 3, 7, 0, 5, 0, 0, 10, MonsterClass::Animal, 0, RESIST_FIRE, 3, 0, 155 },
/* MT_BFALLSP */ { P_("monster", "Dark One"), nullptr, "falspear\\blue", MonsterSpriteId::FallenSpear, MonsterAvailability::Always, 128, 543, true, true, { 11, 11, 13, 11, 18, 13 }, { 3, 1, 1, 1, 1, 1 }, 3, 5, 7, 20, 36, MonsterAIID::Fallen, 0, 3, 30, 7, 4, 8, 0, 5, 0, 0, 15, MonsterClass::Animal, 0, RESIST_LIGHTNING, 3, 0, 255 },
/* MT_WSKELAX */ { P_("monster", "Skeleton"), nullptr, "skelaxe\\white", MonsterSpriteId::SkeletonAxe, MonsterAvailability::Always, 128, 553, true, false, { 12, 8, 13, 6, 17, 16 }, { 5, 1, 1, 1, 1, 1 }, 1, 2, 1, 2, 4, MonsterAIID::SkeletonMelee, 0, 0, 20, 8, 1, 4, 0, 0, 0, 0, 0, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 64 },
/* MT_TSKELAX */ { P_("monster", "Corpse Axe"), nullptr, "skelaxe\\skelt", MonsterSpriteId::SkeletonAxe, MonsterAvailability::Always, 128, 553, true, false, { 12, 8, 13, 6, 17, 16 }, { 4, 1, 1, 1, 1, 1 }, 2, 3, 2, 4, 7, MonsterAIID::SkeletonMelee, 0, 1, 25, 8, 3, 5, 0, 0, 0, 0, 0, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 68 },
/* MT_RSKELAX */ { P_("monster", "Burning Dead"), nullptr, nullptr, MonsterSpriteId::SkeletonAxe, MonsterAvailability::Always, 128, 553, true, false, { 12, 8, 13, 6, 17, 16 }, { 2, 1, 1, 1, 1, 1 }, 2, 4, 4, 8, 12, MonsterAIID::SkeletonMelee, 0, 2, 30, 8, 3, 7, 0, 0, 0, 0, 5, MonsterClass::Undead, IMMUNE_MAGIC | RESIST_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 3, 0, 154 },
/* MT_XSKELAX */ { P_("monster", "Horror"), nullptr, "skelaxe\\black", MonsterSpriteId::SkeletonAxe, MonsterAvailability::Always, 128, 553, true, false, { 12, 8, 13, 6, 17, 16 }, { 3, 1, 1, 1, 1, 1 }, 3, 5, 6, 12, 20, MonsterAIID::SkeletonMelee, 0, 3, 35, 8, 4, 9, 0, 0, 0, 0, 15, MonsterClass::Undead, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_LIGHTNING, 3, 0, 264 },
/* MT_RFALLSD */ { P_("monster", "Fallen One"), nullptr, "falsword\\fallent", MonsterSpriteId::FallenSword, MonsterAvailability::Always, 128, 623, true, true, { 12, 12, 13, 11, 14, 15 }, { 3, 1, 1, 1, 1, 1 }, 1, 2, 1, 2, 5, MonsterAIID::Fallen, 0, 0, 15, 8, 1, 4, 0, 5, 0, 0, 10, MonsterClass::Animal, 0, 0, 3, 0, 52 },
/* MT_DFALLSD */ { P_("monster", "Carver"), nullptr, "falsword\\dark", MonsterSpriteId::FallenSword, MonsterAvailability::Always, 128, 623, true, true, { 12, 12, 13, 11, 14, 15 }, { 3, 1, 1, 1, 1, 1 }, 2, 3, 3, 5, 9, MonsterAIID::Fallen, 0, 1, 20, 8, 2, 7, 0, 5, 0, 0, 15, MonsterClass::Animal, 0, 0, 3, 0, 90 },
/* MT_YFALLSD */ { P_("monster", "Devil Kin"), nullptr, nullptr, MonsterSpriteId::FallenSword, MonsterAvailability::Always, 128, 623, true, true, { 12, 12, 13, 11, 14, 15 }, { 3, 1, 1, 1, 1, 1 }, 2, 4, 5, 16, 24, MonsterAIID::Fallen, 0, 2, 25, 8, 4, 10, 0, 5, 0, 0, 20, MonsterClass::Animal, 0, RESIST_FIRE, 3, 0, 180 },
/* MT_BFALLSD */ { P_("monster", "Dark One"), nullptr, "falsword\\blue", MonsterSpriteId::FallenSword, MonsterAvailability::Always, 128, 623, true, true, { 12, 12, 13, 11, 14, 15 }, { 3, 1, 1, 1, 1, 1 }, 3, 5, 7, 24, 36, MonsterAIID::Fallen, 0, 3, 30, 8, 4, 12, 0, 5, 0, 0, 25, MonsterClass::Animal, 0, RESIST_LIGHTNING, 3, 0, 280 },
/* MT_NSCAV */ { P_("monster", "Scavenger"), nullptr, nullptr, MonsterSpriteId::Scavenger, MonsterAvailability::Always, 128, 410, true, false, { 12, 8, 12, 6, 20, 11 }, { 2, 1, 1, 1, 1, 1 }, 1, 3, 2, 3, 6, MonsterAIID::Scavenger, 0, 0, 20, 7, 1, 5, 0, 0, 0, 0, 10, MonsterClass::Animal, 0, RESIST_FIRE, 3, 0, 80 },
/* MT_BSCAV */ { P_("monster", "Plague Eater"), nullptr, "scav\\scavbr", MonsterSpriteId::Scavenger, MonsterAvailability::Always, 128, 410, true, false, { 12, 8, 12, 6, 20, 11 }, { 2, 1, 1, 1, 1, 1 }, 2, 4, 4, 12, 24, MonsterAIID::Scavenger, 0, 1, 30, 7, 1, 8, 0, 0, 0, 0, 20, MonsterClass::Animal, 0, RESIST_LIGHTNING, 3, 0, 188 },
/* MT_WSCAV */ { P_("monster", "Shadow Beast"), nullptr, "scav\\scavbe", MonsterSpriteId::Scavenger, MonsterAvailability::Always, 128, 410, true, false, { 12, 8, 12, 6, 20, 11 }, { 2, 1, 1, 1, 1, 1 }, 3, 5, 6, 24, 36, MonsterAIID::Scavenger, 0, 2, 35, 7, 3, 12, 0, 0, 0, 0, 25, MonsterClass::Animal, 0, RESIST_FIRE, 3, 0, 375 },
/* MT_YSCAV */ { P_("monster", "Bone Gasher"), nullptr, "scav\\scavw", MonsterSpriteId::Scavenger, MonsterAvailability::Always, 128, 410, true, false, { 12, 8, 12, 6, 20, 11 }, { 2, 1, 1, 1, 1, 1 }, 4, 6, 8, 28, 40, MonsterAIID::Scavenger, 0, 3, 35, 7, 5, 15, 0, 0, 0, 0, 30, MonsterClass::Animal, RESIST_MAGIC, RESIST_LIGHTNING, 3, 0, 552 },
/* MT_WSKELBW */ { P_("monster", "Skeleton"), nullptr, "skelbow\\white", MonsterSpriteId::SkeletonBow, MonsterAvailability::Always, 128, 567, true, false, { 9, 8, 16, 5, 16, 16 }, { 4, 1, 1, 1, 1, 1 }, 2, 3, 3, 2, 4, MonsterAIID::SkeletonRanged, 0, 0, 15, 12, 1, 2, 0, 0, 0, 0, 0, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 110 },
/* MT_TSKELBW */ { P_("monster", "Corpse Bow"), nullptr, "skelbow\\skelt", MonsterSpriteId::SkeletonBow, MonsterAvailability::Always, 128, 567, true, false, { 9, 8, 16, 5, 16, 16 }, { 4, 1, 1, 1, 1, 1 }, 2, 4, 5, 8, 16, MonsterAIID::SkeletonRanged, 0, 1, 25, 12, 1, 4, 0, 0, 0, 0, 0, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 210 },
/* MT_RSKELBW */ { P_("monster", "Burning Dead"), nullptr, nullptr, MonsterSpriteId::SkeletonBow, MonsterAvailability::Always, 128, 567, true, false, { 9, 8, 16, 5, 16, 16 }, { 2, 1, 1, 1, 1, 1 }, 3, 5, 7, 10, 24, MonsterAIID::SkeletonRanged, 0, 2, 30, 12, 1, 6, 0, 0, 0, 0, 5, MonsterClass::Undead, IMMUNE_MAGIC | RESIST_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 3, 0, 364 },
/* MT_XSKELBW */ { P_("monster", "Horror"), nullptr, "skelbow\\black", MonsterSpriteId::SkeletonBow, MonsterAvailability::Always, 128, 567, true, false, { 9, 8, 16, 5, 16, 16 }, { 3, 1, 1, 1, 1, 1 }, 4, 6, 9, 15, 45, MonsterAIID::SkeletonRanged, 0, 3, 35, 12, 2, 9, 0, 0, 0, 0, 15, MonsterClass::Undead, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_LIGHTNING, 3, 0, 594 },
/* MT_WSKELSD */ { P_("monster", "Skeleton Captain"), nullptr, "skelsd\\white", MonsterSpriteId::SkeletonCaptain, MonsterAvailability::Always, 128, 575, true, true, { 13, 8, 12, 7, 15, 16 }, { 4, 1, 1, 1, 1, 1 }, 1, 3, 2, 3, 6, MonsterAIID::SkeletonMelee, 0, 0, 20, 8, 2, 7, 0, 0, 0, 0, 10, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 90 },
/* MT_TSKELSD */ { P_("monster", "Corpse Captain"), nullptr, "skelsd\\skelt", MonsterSpriteId::SkeletonCaptain, MonsterAvailability::Always, 128, 575, true, false, { 13, 8, 12, 7, 15, 16 }, { 4, 1, 1, 1, 1, 1 }, 2, 4, 4, 12, 20, MonsterAIID::SkeletonMelee, 0, 1, 30, 8, 3, 9, 0, 0, 0, 0, 5, MonsterClass::Undead, IMMUNE_MAGIC, IMMUNE_MAGIC, 3, 0, 200 },
/* MT_RSKELSD */ { P_("monster", "Burning Dead Captain"), nullptr, nullptr, MonsterSpriteId::SkeletonCaptain, MonsterAvailability::Always, 128, 575, true, false, { 13, 8, 12, 7, 15, 16 }, { 4, 1, 1, 1, 1, 1 }, 3, 5, 6, 16, 30, MonsterAIID::SkeletonMelee, 0, 2, 35, 8, 4, 10, 0, 0, 0, 0, 15, MonsterClass::Undead, IMMUNE_MAGIC | RESIST_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 3, 0, 393 },
/* MT_XSKELSD */ { P_("monster", "Horror Captain"), nullptr, "skelsd\\black", MonsterSpriteId::SkeletonCaptain, MonsterAvailability::Always, 128, 575, true, false, { 13, 8, 12, 7, 15, 16 }, { 4, 1, 1, 1, 1, 1 }, 4, 6, 8, 35, 50, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 3, 40, 8, 5, 14, 0, 0, 0, 0, 30, MonsterClass::Undead, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_LIGHTNING, 3, 0, 604 },
/* MT_INVILORD*/ { P_("monster", "Invisible Lord"), nullptr, nullptr, MonsterSpriteId::InvisibleLord, MonsterAvailability::Never, 128, 800, false, false, { 13, 13, 15, 11, 16, 0 }, { 2, 1, 1, 1, 1, 1 }, 19, 20, 14, 278, 278, MonsterAIID::SkeletonMelee, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 65, 8, 16, 30, 0, 0, 0, 0, 60, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 2000 },
/* MT_SNEAK */ { P_("monster", "Hidden"), nullptr, nullptr, MonsterSpriteId::Hidden, MonsterAvailability::Retail, 128, 992, true, false, { 16, 8, 12, 8, 24, 15 }, { 2, 1, 1, 1, 1, 1 }, 2, 5, 5, 8, 24, MonsterAIID::Sneak, MFLAG_HIDDEN, 0, 35, 8, 3, 6, 0, 0, 0, 0, 25, MonsterClass::Demon, 0, 0, 3, 0, 278 },
/* MT_STALKER */ { P_("monster", "Stalker"), nullptr, "sneak\\sneakv2", MonsterSpriteId::Hidden, MonsterAvailability::Retail, 128, 992, true, false, { 16, 8, 12, 8, 24, 15 }, { 2, 1, 1, 1, 1, 1 }, 5, 7, 9, 30, 45, MonsterAIID::Sneak, MFLAG_HIDDEN | MFLAG_SEARCH, 1, 40, 8, 8, 16, 0, 0, 0, 0, 30, MonsterClass::Demon, 0, 0, 3, 0, 630 },
/* MT_UNSEEN */ { P_("monster", "Unseen"), nullptr, "sneak\\sneakv3", MonsterSpriteId::Hidden, MonsterAvailability::Retail, 128, 992, true, false, { 16, 8, 12, 8, 24, 15 }, { 2, 1, 1, 1, 1, 1 }, 6, 8, 11, 35, 50, MonsterAIID::Sneak, MFLAG_HIDDEN | MFLAG_SEARCH, 2, 45, 8, 12, 20, 0, 0, 0, 0, 30, MonsterClass::Demon, RESIST_MAGIC, IMMUNE_MAGIC, 3, 0, 935 },
/* MT_ILLWEAV */ { P_("monster", "Illusion Weaver"), nullptr, "sneak\\sneakv1", MonsterSpriteId::Hidden, MonsterAvailability::Retail, 128, 992, true, false, { 16, 8, 12, 8, 24, 15 }, { 2, 1, 1, 1, 1, 1 }, 8, 10, 13, 40, 60, MonsterAIID::Sneak, MFLAG_HIDDEN | MFLAG_SEARCH, 3, 60, 8, 16, 24, 0, 0, 0, 0, 30, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE, IMMUNE_MAGIC | RESIST_FIRE, 3, 0, 1500 },
/* MT_LRDSAYTR*/ { P_("monster", "Satyr Lord"), "newsfx\\satyr", nullptr, MonsterSpriteId::GoatLord, MonsterAvailability::Retail, 160, 800, false, false, { 13, 13, 14, 9, 16, 0 }, { 2, 1, 1, 1, 1, 1 }, 21, 22, 28, 160, 200, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 3, 90, 8, 20, 30, 0, 0, 0, 0, 70, MonsterClass::Animal, RESIST_FIRE | RESIST_LIGHTNING, RESIST_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 3, 0, 2800 },
/* MT_NGOATMC */ { P_("monster", "Flesh Clan"), nullptr, nullptr, MonsterSpriteId::GoatMace, MonsterAvailability::Retail, 128, 1030, true, false, { 12, 8, 12, 6, 20, 12 }, { 2, 1, 1, 1, 1, 1 }, 4, 6, 8, 30, 45, MonsterAIID::GoatMelee, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 0, 50, 8, 4, 10, 0, 0, 0, 0, 40, MonsterClass::Demon, 0, 0, 3, 0, 460 },
/* MT_BGOATMC */ { P_("monster", "Stone Clan"), nullptr, "goatmace\\beige", MonsterSpriteId::GoatMace, MonsterAvailability::Retail, 128, 1030, true, false, { 12, 8, 12, 6, 20, 12 }, { 2, 1, 1, 1, 1, 1 }, 5, 7, 10, 40, 55, MonsterAIID::GoatMelee, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 1, 60, 8, 6, 12, 0, 0, 0, 0, 40, MonsterClass::Demon, RESIST_MAGIC, IMMUNE_MAGIC, 3, 0, 685 },
/* MT_RGOATMC */ { P_("monster", "Fire Clan"), nullptr, "goatmace\\red", MonsterSpriteId::GoatMace, MonsterAvailability::Retail, 128, 1030, true, false, { 12, 8, 12, 6, 20, 12 }, { 2, 1, 1, 1, 1, 1 }, 6, 8, 12, 50, 65, MonsterAIID::GoatMelee, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 2, 70, 8, 8, 16, 0, 0, 0, 0, 45, MonsterClass::Demon, RESIST_FIRE, IMMUNE_FIRE, 3, 0, 906 },
/* MT_GGOATMC */ { P_("monster", "Night Clan"), nullptr, "goatmace\\gray", MonsterSpriteId::GoatMace, MonsterAvailability::Retail, 128, 1030, true, false, { 12, 8, 12, 6, 20, 12 }, { 2, 1, 1, 1, 1, 1 }, 7, 9, 14, 55, 70, MonsterAIID::GoatMelee, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 80, 8, 10, 20, 15, 0, 30, 30, 50, MonsterClass::Demon, RESIST_MAGIC, IMMUNE_MAGIC, 3, 0, 1190 },
/* MT_FIEND */ { P_("monster", "Fiend"), nullptr, "bat\\red", MonsterSpriteId::Bat, MonsterAvailability::Always, 96, 364, false, false, { 9, 13, 10, 9, 13, 0 }, { 1, 1, 1, 1, 1, 1 }, 2, 3, 3, 3, 6, MonsterAIID::Bat, 0, 0, 35, 5, 1, 6, 0, 0, 0, 0, 0, MonsterClass::Animal, 0, 0, 6, T_NODROP, 102 },
/* MT_BLINK */ { P_("monster", "Blink"), nullptr, nullptr, MonsterSpriteId::Bat, MonsterAvailability::Always, 96, 364, false, false, { 9, 13, 10, 9, 13, 0 }, { 1, 1, 1, 1, 1, 1 }, 3, 5, 7, 12, 28, MonsterAIID::Bat, 0, 1, 45, 5, 1, 8, 0, 0, 0, 0, 15, MonsterClass::Animal, 0, 0, 6, T_NODROP, 340 },
/* MT_GLOOM */ { P_("monster", "Gloom"), nullptr, "bat\\grey", MonsterSpriteId::Bat, MonsterAvailability::Always, 96, 364, false, false, { 9, 13, 10, 9, 13, 0 }, { 1, 1, 1, 1, 1, 1 }, 4, 6, 9, 28, 36, MonsterAIID::Bat, MFLAG_SEARCH, 2, 70, 5, 4, 12, 0, 0, 0, 0, 35, MonsterClass::Animal, RESIST_MAGIC, RESIST_MAGIC, 6, T_NODROP, 509 },
/* MT_FAMILIAR*/ { P_("monster", "Familiar"), nullptr, "bat\\orange", MonsterSpriteId::Bat, MonsterAvailability::Always, 96, 364, false, false, { 9, 13, 10, 9, 13, 0 }, { 1, 1, 1, 1, 1, 1 }, 6, 8, 13, 20, 35, MonsterAIID::Bat, MFLAG_SEARCH, 3, 50, 5, 4, 16, 0, 0, 0, 0, 35, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_LIGHTNING, RESIST_MAGIC | IMMUNE_LIGHTNING, 6, T_NODROP, 448 },
/* MT_NGOATBW */ { P_("monster", "Flesh Clan"), nullptr, nullptr, MonsterSpriteId::GoatBow, MonsterAvailability::Retail, 128, 1040, false, false, { 12, 8, 16, 6, 20, 0 }, { 3, 1, 1, 1, 1, 1 }, 4, 6, 8, 20, 35, MonsterAIID::GoatRanged, MFLAG_CAN_OPEN_DOOR, 0, 35, 13, 1, 7, 0, 0, 0, 0, 35, MonsterClass::Demon, 0, 0, 3, 0, 448 },
/* MT_BGOATBW */ { P_("monster", "Stone Clan"), nullptr, "goatbow\\beige", MonsterSpriteId::GoatBow, MonsterAvailability::Retail, 128, 1040, false, false, { 12, 8, 16, 6, 20, 0 }, { 3, 1, 1, 1, 1, 1 }, 5, 7, 10, 30, 40, MonsterAIID::GoatRanged, MFLAG_CAN_OPEN_DOOR, 1, 40, 13, 2, 9, 0, 0, 0, 0, 35, MonsterClass::Demon, RESIST_MAGIC, IMMUNE_MAGIC, 3, 0, 645 },
/* MT_RGOATBW */ { P_("monster", "Fire Clan"), nullptr, "goatbow\\red", MonsterSpriteId::GoatBow, MonsterAvailability::Retail, 128, 1040, false, false, { 12, 8, 16, 6, 20, 0 }, { 3, 1, 1, 1, 1, 1 }, 6, 8, 12, 40, 50, MonsterAIID::GoatRanged, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 2, 45, 13, 3, 11, 0, 0, 0, 0, 35, MonsterClass::Demon, RESIST_FIRE, IMMUNE_FIRE, 3, 0, 822 },
/* MT_GGOATBW */ { P_("monster", "Night Clan"), nullptr, "goatbow\\gray", MonsterSpriteId::GoatBow, MonsterAvailability::Retail, 128, 1040, false, false, { 12, 8, 16, 6, 20, 0 }, { 3, 1, 1, 1, 1, 1 }, 7, 9, 14, 50, 65, MonsterAIID::GoatRanged, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 50, 13, 4, 13, 15, 0, 0, 0, 40, MonsterClass::Demon, RESIST_MAGIC, IMMUNE_MAGIC, 3, 0, 1092 },
/* MT_NACID */ { P_("monster", "Acid Beast"), nullptr, nullptr, MonsterSpriteId::AcidBeast, MonsterAvailability::Retail, 128, 716, true, true, { 13, 8, 12, 8, 16, 12 }, { 1, 1, 1, 1, 1, 1 }, 6, 8, 11, 40, 66, MonsterAIID::Acid, 0, 0, 40, 8, 4, 12, 25, 8, 0, 0, 30, MonsterClass::Animal, IMMUNE_ACID, IMMUNE_MAGIC | IMMUNE_ACID, 3, 0, 846 },
/* MT_RACID */ { P_("monster", "Poison Spitter"), nullptr, "acid\\acidblk", MonsterSpriteId::AcidBeast, MonsterAvailability::Retail, 128, 716, true, true, { 13, 8, 12, 8, 16, 12 }, { 1, 1, 1, 1, 1, 1 }, 8, 10, 15, 60, 85, MonsterAIID::Acid, 0, 1, 45, 8, 4, 16, 25, 8, 0, 0, 30, MonsterClass::Animal, IMMUNE_ACID, IMMUNE_MAGIC | IMMUNE_ACID, 3, 0, 1248 },
/* MT_BACID */ { P_("monster", "Pit Beast"), nullptr, "acid\\acidb", MonsterSpriteId::AcidBeast, MonsterAvailability::Retail, 128, 716, true, true, { 13, 8, 12, 8, 16, 12 }, { 1, 1, 1, 1, 1, 1 }, 10, 12, 21, 80, 110, MonsterAIID::Acid, 0, 2, 55, 8, 8, 18, 35, 8, 0, 0, 35, MonsterClass::Animal, RESIST_MAGIC | IMMUNE_ACID, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_ACID, 3, 0, 2060 },
/* MT_XACID */ { P_("monster", "Lava Maw"), nullptr, "acid\\acidr", MonsterSpriteId::AcidBeast, MonsterAvailability::Retail, 128, 716, true, true, { 13, 8, 12, 8, 16, 12 }, { 1, 1, 1, 1, 1, 1 }, 12, 14, 25, 100, 150, MonsterAIID::Acid, 0, 3, 65, 8, 10, 20, 40, 8, 0, 0, 35, MonsterClass::Animal, RESIST_MAGIC | IMMUNE_FIRE | IMMUNE_ACID, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_ACID, 3, 0, 2940 },
/* MT_SKING */ { P_("monster", "Skeleton King"), nullptr, "skelaxe\\white", MonsterSpriteId::SkeletonKing, MonsterAvailability::Never, 160, 1010, true, true, { 8, 6, 16, 6, 16, 6 }, { 2, 1, 1, 1, 1, 2 }, 4, 4, 9, 140, 140, MonsterAIID::SkeletonKing, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 60, 8, 6, 16, 0, 0, 0, 0, 70, MonsterClass::Undead, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, Uniq(UITEM_SKCROWN), 570 },
/* MT_CLEAVER */ { P_("monster", "The Butcher"), nullptr, nullptr, MonsterSpriteId::Butcher, MonsterAvailability::Never, 128, 980, false, false, { 10, 8, 12, 6, 16, 0 }, { 1, 1, 1, 1, 1, 1 }, 1, 1, 1, 320, 320, MonsterAIID::Butcher, 0, 3, 50, 8, 6, 12, 0, 0, 0, 0, 50, MonsterClass::Demon, RESIST_FIRE | RESIST_LIGHTNING, RESIST_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 3, Uniq(UITEM_CLEAVER), 710 },
/* MT_FAT */ { P_("monster", "Overlord"), nullptr, nullptr, MonsterSpriteId::Overlord, MonsterAvailability::Retail, 128, 1130, true, false, { 8, 10, 15, 6, 16, 10 }, { 4, 1, 1, 1, 1, 1 }, 5, 7, 10, 60, 80, MonsterAIID::Fat, 0, 0, 55, 8, 6, 12, 0, 0, 0, 0, 55, MonsterClass::Demon, 0, RESIST_FIRE, 3, 0, 635 },
/* MT_MUDMAN, */ { P_("monster", "Mud Man"), nullptr, "fat\\blue", MonsterSpriteId::Overlord, MonsterAvailability::Retail, 128, 1130, true, false, { 8, 10, 15, 6, 16, 10 }, { 4, 1, 1, 1, 1, 1 }, 7, 9, 14, 100, 125, MonsterAIID::Fat, MFLAG_SEARCH, 1, 60, 8, 8, 16, 0, 0, 0, 0, 60, MonsterClass::Demon, 0, IMMUNE_LIGHTNING, 3, 0, 1165 },
/* MT_TOAD */ { P_("monster", "Toad Demon"), nullptr, "fat\\fatb", MonsterSpriteId::Overlord, MonsterAvailability::Retail, 128, 1130, true, false, { 8, 10, 15, 6, 16, 10 }, { 4, 1, 1, 1, 1, 1 }, 8, 10, 16, 135, 160, MonsterAIID::Fat, MFLAG_SEARCH, 2, 70, 8, 8, 16, 40, 0, 8, 20, 65, MonsterClass::Demon, IMMUNE_MAGIC, IMMUNE_MAGIC | RESIST_LIGHTNING, 3, 0, 1380 },
/* MT_FLAYED */ { P_("monster", "Flayed One"), nullptr, "fat\\fatf", MonsterSpriteId::Overlord, MonsterAvailability::Retail, 128, 1130, true, false, { 8, 10, 15, 6, 16, 10 }, { 4, 1, 1, 1, 1, 1 }, 10, 12, 20, 160, 200, MonsterAIID::Fat, MFLAG_SEARCH, 3, 85, 8, 10, 20, 0, 0, 0, 0, 70, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 3, 0, 2058 },
/* MT_WYRM */ { P_("monster", "Wyrm"), nullptr, nullptr, MonsterSpriteId::Wyrm, MonsterAvailability::Never, 160, 2420, false, false, { 13, 13, 13, 11, 19, 0 }, { 1, 1, 1, 1, 1, 1 }, 5, 7, 11, 60, 90, MonsterAIID::SkeletonMelee, 0, 0, 40, 8, 4, 10, 0, 0, 0, 0, 25, MonsterClass::Animal, RESIST_MAGIC, RESIST_MAGIC, 3, 0, 660 },
/* MT_CAVSLUG */ { P_("monster", "Cave Slug"), nullptr, nullptr, MonsterSpriteId::Wyrm, MonsterAvailability::Never, 160, 2420, false, false, { 13, 13, 13, 11, 19, 0 }, { 1, 1, 1, 1, 1, 1 }, 6, 8, 13, 75, 110, MonsterAIID::SkeletonMelee, 0, 1, 50, 8, 6, 13, 0, 0, 0, 0, 30, MonsterClass::Animal, RESIST_MAGIC, RESIST_MAGIC, 3, 0, 994 },
/* MT_DVLWYRM */ { P_("monster", "Devil Wyrm"), nullptr, nullptr, MonsterSpriteId::Wyrm, MonsterAvailability::Never, 160, 2420, false, false, { 13, 13, 13, 11, 19, 0 }, { 1, 1, 1, 1, 1, 1 }, 7, 9, 15, 100, 140, MonsterAIID::SkeletonMelee, 0, 2, 55, 8, 8, 16, 0, 0, 0, 0, 30, MonsterClass::Animal, RESIST_MAGIC | RESIST_FIRE, RESIST_MAGIC | RESIST_FIRE, 3, 0, 1320 },
/* MT_DEVOUR */ { P_("monster", "Devourer"), nullptr, nullptr, MonsterSpriteId::Wyrm, MonsterAvailability::Never, 160, 2420, false, false, { 13, 13, 13, 11, 19, 0 }, { 1, 1, 1, 1, 1, 1 }, 8, 10, 17, 125, 200, MonsterAIID::SkeletonMelee, 0, 3, 60, 8, 10, 20, 0, 0, 0, 0, 35, MonsterClass::Animal, RESIST_MAGIC | RESIST_FIRE, RESIST_MAGIC | RESIST_FIRE, 3, 0, 1827 },
/* MT_NMAGMA */ { P_("monster", "Magma Demon"), nullptr, nullptr, MonsterSpriteId::MagmaDemon, MonsterAvailability::Retail, 128, 1680, true, true, { 8, 10, 14, 7, 18, 18 }, { 2, 1, 1, 1, 1, 1 }, 8, 9, 13, 50, 70, MonsterAIID::Magma, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 0, 45, 4, 2, 10, 50, 13, 0, 0, 45, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 7, 0, 1076 },
/* MT_YMAGMA */ { P_("monster", "Blood Stone"), nullptr, "magma\\yellow", MonsterSpriteId::MagmaDemon, MonsterAvailability::Retail, 128, 1680, true, true, { 8, 10, 14, 7, 18, 18 }, { 2, 1, 1, 1, 1, 1 }, 8, 10, 14, 55, 75, MonsterAIID::Magma, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 1, 50, 4, 2, 12, 50, 14, 0, 0, 45, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 7, 0, 1309 },
/* MT_BMAGMA */ { P_("monster", "Hell Stone"), nullptr, "magma\\blue", MonsterSpriteId::MagmaDemon, MonsterAvailability::Retail, 128, 1680, true, true, { 8, 10, 14, 7, 18, 18 }, { 2, 1, 1, 1, 1, 1 }, 9, 11, 16, 60, 80, MonsterAIID::Magma, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 2, 60, 4, 2, 20, 60, 14, 0, 0, 50, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 7, 0, 1680 },
/* MT_WMAGMA */ { P_("monster", "Lava Lord"), nullptr, "magma\\wierd", MonsterSpriteId::MagmaDemon, MonsterAvailability::Retail, 128, 1680, true, true, { 8, 10, 14, 7, 18, 18 }, { 2, 1, 1, 1, 1, 1 }, 9, 11, 18, 70, 85, MonsterAIID::Magma, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 75, 4, 4, 24, 60, 14, 0, 0, 60, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 7, 0, 2124 },
/* MT_HORNED */ { P_("monster", "Horned Demon"), nullptr, nullptr, MonsterSpriteId::HornedDemon, MonsterAvailability::Retail, 160, 1630, true, true, { 8, 8, 14, 6, 16, 6 }, { 2, 1, 1, 1, 1, 1 }, 7, 9, 13, 40, 80, MonsterAIID::Rhino, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 0, 60, 7, 2, 16, 100, 0, 5, 32, 40, MonsterClass::Animal, 0, RESIST_FIRE, 7, 0, 1172 },
/* MT_MUDRUN */ { P_("monster", "Mud Runner"), nullptr, "rhino\\orange", MonsterSpriteId::HornedDemon, MonsterAvailability::Retail, 160, 1630, true, true, { 8, 8, 14, 6, 16, 6 }, { 2, 1, 1, 1, 1, 1 }, 8, 10, 15, 50, 90, MonsterAIID::Rhino, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 1, 70, 7, 6, 18, 100, 0, 12, 36, 45, MonsterClass::Animal, 0, RESIST_FIRE, 7, 0, 1404 },
/* MT_FROSTC */ { P_("monster", "Frost Charger"), nullptr, "rhino\\blue", MonsterSpriteId::HornedDemon, MonsterAvailability::Retail, 160, 1630, true, true, { 8, 8, 14, 6, 16, 6 }, { 2, 1, 1, 1, 1, 1 }, 9, 11, 17, 60, 100, MonsterAIID::Rhino, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 2, 80, 7, 8, 20, 100, 0, 20, 40, 50, MonsterClass::Animal, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_LIGHTNING, 7, 0, 1720 },
/* MT_OBLORD */ { P_("monster", "Obsidian Lord"), nullptr, "rhino\\rhinob", MonsterSpriteId::HornedDemon, MonsterAvailability::Retail, 160, 1630, true, true, { 8, 8, 14, 6, 16, 6 }, { 2, 1, 1, 1, 1, 1 }, 10, 12, 19, 70, 110, MonsterAIID::Rhino, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 90, 7, 10, 22, 100, 0, 20, 50, 55, MonsterClass::Animal, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, 0, 1809 },
/* MT_BONEDMN */ { P_("monster", "oldboned"), nullptr, nullptr, MonsterSpriteId::SkeletonDemon, MonsterAvailability::Never, 128, 1740, true, true, { 10, 8, 20, 6, 24, 16 }, { 3, 1, 1, 1, 1, 1 }, 24, 24, 12, 70, 70, MonsterAIID::Storm, 0, 0, 60, 8, 6, 14, 12, 0, 0, 0, 50, MonsterClass::Demon, IMMUNE_MAGIC, IMMUNE_MAGIC, 7, 0, 1344 },
/* MT_REDDTH */ { P_("monster", "Red Death"), nullptr, "thin\\thinv3", MonsterSpriteId::StormRider, MonsterAvailability::Never, 160, 1740, true, true, { 8, 8, 18, 4, 17, 14 }, { 3, 1, 1, 1, 1, 1 }, 8, 10, 16, 96, 96, MonsterAIID::Storm, 0, 1, 75, 5, 10, 20, 0, 0, 0, 0, 60, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 7, 0, 2168 },
/* MT_LTCHDMN */ { P_("monster", "Litch Demon"), nullptr, "thin\\thinv3", MonsterSpriteId::StormRider, MonsterAvailability::Never, 160, 1740, true, true, { 8, 8, 18, 4, 17, 14 }, { 3, 1, 1, 1, 1, 1 }, 9, 11, 18, 110, 110, MonsterAIID::Storm, 0, 2, 80, 5, 10, 24, 0, 0, 0, 0, 45, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_LIGHTNING, IMMUNE_MAGIC | IMMUNE_LIGHTNING, 7, 0, 2736 },
/* MT_UDEDBLRG*/ { P_("monster", "Undead Balrog"), nullptr, "thin\\thinv3", MonsterSpriteId::StormRider, MonsterAvailability::Never, 160, 1740, true, true, { 8, 8, 18, 4, 17, 14 }, { 3, 1, 1, 1, 1, 1 }, 11, 13, 22, 130, 130, MonsterAIID::Storm, 0, 3, 85, 5, 12, 30, 0, 0, 0, 0, 65, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, 7, 0, 3575 },
/* MT_INCIN */ { P_("monster", "Incinerator"), nullptr, nullptr, MonsterSpriteId::Incinerator, MonsterAvailability::Never, 128, 1460, true, false, { 14, 19, 20, 8, 14, 23 }, { 1, 1, 1, 1, 1, 1 }, 21, 22, 16, 30, 45, MonsterAIID::FireMan, 0, 0, 75, 8, 8, 16, 0, 0, 0, 0, 25, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 3, 0, 1888 },
/* MT_FLAMLRD */ { P_("monster", "Flame Lord"), nullptr, nullptr, MonsterSpriteId::Incinerator, MonsterAvailability::Never, 128, 1460, true, false, { 14, 19, 20, 8, 14, 23 }, { 1, 1, 1, 1, 1, 1 }, 22, 23, 18, 40, 55, MonsterAIID::FireMan, 0, 1, 75, 8, 10, 20, 0, 0, 0, 0, 25, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 3, 0, 2250 },
/* MT_DOOMFIRE*/ { P_("monster", "Doom Fire"), nullptr, nullptr, MonsterSpriteId::Incinerator, MonsterAvailability::Never, 128, 1460, true, false, { 14, 19, 20, 8, 14, 23 }, { 1, 1, 1, 1, 1, 1 }, 23, 24, 20, 50, 65, MonsterAIID::FireMan, 0, 2, 80, 8, 12, 24, 0, 0, 0, 0, 30, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 3, 0, 2740 },
/* MT_HELLBURN*/ { P_("monster", "Hell Burner"), nullptr, nullptr, MonsterSpriteId::Incinerator, MonsterAvailability::Never, 128, 1460, true, false, { 14, 19, 20, 8, 14, 23 }, { 1, 1, 1, 1, 1, 1 }, 24, 24, 22, 60, 80, MonsterAIID::FireMan, 0, 3, 85, 8, 15, 30, 0, 0, 0, 0, 30, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 3, 0, 3355 },
/* MT_STORM */ { P_("monster", "Red Storm"), nullptr, "thin\\thinv3", MonsterSpriteId::StormRider, MonsterAvailability::Retail, 160, 1740, true, true, { 8, 8, 18, 4, 17, 14 }, { 3, 1, 1, 1, 1, 1 }, 9, 11, 18, 55, 110, MonsterAIID::Storm, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 0, 80, 5, 8, 18, 75, 8, 4, 16, 30, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_LIGHTNING, 7, 0, 2160 },
/* MT_RSTORM */ { P_("monster", "Storm Rider"), nullptr, nullptr, MonsterSpriteId::StormRider, MonsterAvailability::Retail, 160, 1740, true, true, { 8, 8, 18, 4, 17, 14 }, { 3, 1, 1, 1, 1, 1 }, 10, 12, 20, 60, 120, MonsterAIID::Storm, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 1, 80, 5, 8, 18, 80, 8, 4, 16, 30, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_LIGHTNING, IMMUNE_MAGIC | IMMUNE_LIGHTNING, 7, 0, 2391 },
/* MT_STORML */ { P_("monster", "Storm Lord"), nullptr, "thin\\thinv2", MonsterSpriteId::StormRider, MonsterAvailability::Retail, 160, 1740, true, true, { 8, 8, 18, 4, 17, 14 }, { 3, 1, 1, 1, 1, 1 }, 11, 13, 22, 75, 135, MonsterAIID::Storm, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 2, 85, 5, 12, 24, 75, 8, 4, 16, 35, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_LIGHTNING, IMMUNE_MAGIC | IMMUNE_LIGHTNING, 7, 0, 2775 },
/* MT_MAEL */ { P_("monster", "Maelstrom"), nullptr, "thin\\thinv1", MonsterSpriteId::StormRider, MonsterAvailability::Retail, 160, 1740, true, true, { 8, 8, 18, 4, 17, 14 }, { 3, 1, 1, 1, 1, 1 }, 12, 14, 24, 90, 150, MonsterAIID::Storm, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 90, 5, 12, 28, 75, 8, 4, 16, 40, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_LIGHTNING, IMMUNE_MAGIC | IMMUNE_LIGHTNING, 7, 0, 3177 },
/* MT_BIGFALL */ { P_("monster", "Devil Kin Brute"), "newsfx\\kbrute", nullptr, MonsterSpriteId::DevilKinBrute, MonsterAvailability::Retail, 128, 800, true, false, { 10, 8, 11, 8, 17, 0 }, { 1, 1, 1, 1, 2, 2 }, 21, 22, 27, 120, 160, MonsterAIID::SkeletonMelee, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 100, 6, 18, 24, 0, 0, 0, 0, 70, MonsterClass::Animal, RESIST_FIRE | RESIST_LIGHTNING, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 2400 },
/* MT_WINGED */ { P_("monster", "Winged-Demon"), nullptr, nullptr, MonsterSpriteId::Gargoyle, MonsterAvailability::Retail, 160, 1650, true, false, { 14, 14, 14, 10, 18, 14 }, { 1, 1, 1, 1, 1, 2 }, 5, 7, 9, 45, 60, MonsterAIID::Gargoyle, MFLAG_CAN_OPEN_DOOR, 0, 50, 7, 10, 16, 0, 0, 0, 0, 45, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 6, 0, 662 },
/* MT_GARGOYLE*/ { P_("monster", "Gargoyle"), nullptr, "gargoyle\\gare", MonsterSpriteId::Gargoyle, MonsterAvailability::Retail, 160, 1650, true, false, { 14, 14, 14, 10, 18, 14 }, { 1, 1, 1, 1, 1, 2 }, 7, 9, 13, 60, 90, MonsterAIID::Gargoyle, MFLAG_CAN_OPEN_DOOR, 1, 65, 7, 10, 16, 0, 0, 0, 0, 45, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_LIGHTNING, 6, 0, 1205 },
/* MT_BLOODCLW*/ { P_("monster", "Blood Claw"), nullptr, "gargoyle\\gargbr", MonsterSpriteId::Gargoyle, MonsterAvailability::Retail, 160, 1650, true, false, { 14, 14, 14, 10, 18, 14 }, { 1, 1, 1, 1, 1, 1 }, 9, 11, 19, 75, 125, MonsterAIID::Gargoyle, MFLAG_CAN_OPEN_DOOR, 2, 80, 7, 14, 22, 0, 0, 0, 0, 50, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 6, 0, 1873 },
/* MT_DEATHW */ { P_("monster", "Death Wing"), nullptr, "gargoyle\\gargb", MonsterSpriteId::Gargoyle, MonsterAvailability::Retail, 160, 1650, true, false, { 14, 14, 14, 10, 18, 14 }, { 1, 1, 1, 1, 1, 1 }, 10, 12, 23, 90, 150, MonsterAIID::Gargoyle, MFLAG_CAN_OPEN_DOOR, 3, 95, 7, 16, 28, 0, 0, 0, 0, 60, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_LIGHTNING, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, 6, 0, 2278 },
/* MT_MEGA */ { P_("monster", "Slayer"), nullptr, nullptr, MonsterSpriteId::Slayer, MonsterAvailability::Retail, 160, 2220, true, true, { 6, 7, 14, 1, 24, 5 }, { 3, 1, 1, 1, 2, 1 }, 10, 12, 20, 120, 140, MonsterAIID::Mega, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 0, 100, 8, 12, 20, 0, 3, 0, 0, 60, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE, RESIST_MAGIC | IMMUNE_FIRE, 7, 0, 2300 },
/* MT_GUARD */ { P_("monster", "Guardian"), nullptr, "mega\\guard", MonsterSpriteId::Slayer, MonsterAvailability::Retail, 160, 2220, true, true, { 6, 7, 14, 1, 24, 5 }, { 3, 1, 1, 1, 2, 1 }, 11, 13, 22, 140, 160, MonsterAIID::Mega, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 1, 110, 8, 14, 22, 0, 3, 0, 0, 65, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE, RESIST_MAGIC | IMMUNE_FIRE, 7, 0, 2714 },
/* MT_VTEXLRD */ { P_("monster", "Vortex Lord"), nullptr, "mega\\vtexl", MonsterSpriteId::Slayer, MonsterAvailability::Retail, 160, 2220, true, true, { 6, 7, 14, 1, 24, 5 }, { 3, 1, 1, 1, 2, 1 }, 12, 14, 24, 160, 180, MonsterAIID::Mega, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 2, 120, 8, 18, 24, 0, 3, 0, 0, 70, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 7, 0, 3252 },
/* MT_BALROG */ { P_("monster", "Balrog"), nullptr, "mega\\balr", MonsterSpriteId::Slayer, MonsterAvailability::Retail, 160, 2220, true, true, { 6, 7, 14, 1, 24, 5 }, { 3, 1, 1, 1, 2, 1 }, 13, 15, 26, 180, 200, MonsterAIID::Mega, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 130, 8, 22, 30, 0, 3, 0, 0, 75, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 7, 0, 3643 },
/* MT_NSNAKE */ { P_("monster", "Cave Viper"), nullptr, nullptr, MonsterSpriteId::Viper, MonsterAvailability::Retail, 160, 1270, false, false, { 12, 11, 13, 5, 18, 0 }, { 2, 1, 1, 1, 1, 1 }, 11, 13, 21, 100, 150, MonsterAIID::Snake, MFLAG_SEARCH, 0, 90, 8, 8, 20, 0, 0, 0, 0, 60, MonsterClass::Demon, IMMUNE_MAGIC, IMMUNE_MAGIC, 7, 0, 2725 },
/* MT_RSNAKE */ { P_("monster", "Fire Drake"), nullptr, "snake\\snakr", MonsterSpriteId::Viper, MonsterAvailability::Retail, 160, 1270, false, false, { 12, 11, 13, 5, 18, 0 }, { 2, 1, 1, 1, 1, 1 }, 12, 14, 23, 120, 170, MonsterAIID::Snake, MFLAG_SEARCH, 1, 105, 8, 12, 24, 0, 0, 0, 0, 65, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE, IMMUNE_MAGIC | IMMUNE_FIRE, 7, 0, 3139 },
/* MT_BSNAKE */ { P_("monster", "Gold Viper"), nullptr, "snake\\snakg", MonsterSpriteId::Viper, MonsterAvailability::Retail, 160, 1270, false, false, { 12, 11, 13, 5, 18, 0 }, { 2, 1, 1, 1, 1, 1 }, 13, 14, 25, 140, 180, MonsterAIID::Snake, MFLAG_SEARCH, 2, 120, 8, 15, 26, 0, 0, 0, 0, 70, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_LIGHTNING, 7, 0, 3540 },
/* MT_GSNAKE */ { P_("monster", "Azure Drake"), nullptr, "snake\\snakb", MonsterSpriteId::Viper, MonsterAvailability::Retail, 160, 1270, false, false, { 12, 11, 13, 5, 18, 0 }, { 2, 1, 1, 1, 1, 1 }, 15, 16, 27, 160, 200, MonsterAIID::Snake, MFLAG_SEARCH, 3, 130, 8, 18, 30, 0, 0, 0, 0, 75, MonsterClass::Demon, RESIST_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, 7, 0, 3791 },
/* MT_NBLACK */ { P_("monster", "Black Knight"), nullptr, nullptr, MonsterSpriteId::BlackKnight, MonsterAvailability::Retail, 160, 2120, false, false, { 8, 8, 16, 4, 24, 0 }, { 2, 1, 1, 1, 1, 1 }, 12, 14, 24, 150, 150, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 0, 110, 8, 15, 20, 0, 0, 0, 0, 75, MonsterClass::Demon, RESIST_MAGIC | RESIST_LIGHTNING, RESIST_MAGIC | IMMUNE_LIGHTNING, 7, 0, 3360 },
/* MT_RTBLACK */ { P_("monster", "Doom Guard"), nullptr, "black\\blkkntrt", MonsterSpriteId::BlackKnight, MonsterAvailability::Retail, 160, 2120, false, false, { 8, 8, 16, 4, 24, 0 }, { 2, 1, 1, 1, 1, 1 }, 13, 15, 26, 165, 165, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 0, 130, 8, 18, 25, 0, 0, 0, 0, 75, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE, RESIST_MAGIC | IMMUNE_FIRE, 7, 0, 3650 },
/* MT_BTBLACK */ { P_("monster", "Steel Lord"), nullptr, "black\\blkkntbt", MonsterSpriteId::BlackKnight, MonsterAvailability::Retail, 160, 2120, false, false, { 8, 8, 16, 4, 24, 0 }, { 2, 1, 1, 1, 1, 1 }, 14, 16, 28, 180, 180, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 1, 120, 8, 20, 30, 0, 0, 0, 0, 80, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 7, 0, 4252 },
/* MT_RBLACK */ { P_("monster", "Blood Knight"), nullptr, "black\\blkkntbe", MonsterSpriteId::BlackKnight, MonsterAvailability::Retail, 160, 2120, false, false, { 8, 8, 16, 4, 24, 0 }, { 2, 1, 1, 1, 1, 1 }, 13, 14, 30, 200, 200, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 1, 130, 8, 25, 35, 0, 0, 0, 0, 85, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, 7, 0, 5130 },
/* MT_UNRAV */ { P_("monster", "The Shredded"), "newsfx\\shred", nullptr, MonsterSpriteId::Shredded, MonsterAvailability::Retail, 96, 484, false, false, { 10, 10, 12, 5, 16, 0 }, { 1, 1, 1, 1, 1, 1 }, 17, 18, 23, 70, 90, MonsterAIID::SkeletonMelee, 0, 0, 75, 7, 4, 12, 0, 0, 0, 0, 65, MonsterClass::Undead, RESIST_FIRE | RESIST_LIGHTNING, RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 900 },
/* MT_HOLOWONE*/ { P_("monster", "Hollow One"), "acid\\acid", nullptr, MonsterSpriteId::Shredded, MonsterAvailability::Never, 96, 484, false, false, { 10, 10, 12, 5, 16, 0 }, { 1, 1, 1, 1, 1, 1 }, 18, 19, 27, 135, 240, MonsterAIID::SkeletonMelee, 0, 1, 75, 7, 12, 24, 0, 0, 0, 0, 75, MonsterClass::Undead, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 3, 0, 4374 },
/* MT_PAINMSTR*/ { P_("monster", "Pain Master"), "acid\\acid", nullptr, MonsterSpriteId::Shredded, MonsterAvailability::Never, 96, 484, false, false, { 10, 10, 12, 5, 16, 0 }, { 1, 1, 1, 1, 1, 1 }, 19, 20, 29, 110, 200, MonsterAIID::SkeletonMelee, 0, 2, 80, 7, 16, 30, 0, 0, 0, 0, 80, MonsterClass::Undead, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 3, 0, 5147 },
/* MT_REALWEAV*/ { P_("monster", "Reality Weaver"), "acid\\acid", nullptr, MonsterSpriteId::Shredded, MonsterAvailability::Never, 96, 484, false, false, { 10, 10, 12, 5, 16, 0 }, { 1, 1, 1, 1, 1, 1 }, 20, 20, 30, 135, 240, MonsterAIID::SkeletonMelee, 0, 3, 85, 7, 20, 35, 0, 0, 0, 0, 85, MonsterClass::Undead, RESIST_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, RESIST_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 3, 0, 5925 },
/* MT_SUCCUBUS*/ { P_("monster", "Succubus"), nullptr, nullptr, MonsterSpriteId::Succubus, MonsterAvailability::Retail, 128, 980, false, false, { 14, 8, 16, 7, 24, 0 }, { 1, 1, 1, 1, 1, 1 }, 12, 14, 24, 120, 150, MonsterAIID::Succubus, MFLAG_CAN_OPEN_DOOR, 0, 100, 10, 1, 20, 0, 0, 0, 0, 60, MonsterClass::Demon, RESIST_MAGIC, IMMUNE_MAGIC | RESIST_FIRE, 3, 0, 3696 },
/* MT_SNOWWICH*/ { P_("monster", "Snow Witch"), nullptr, "succ\\succb", MonsterSpriteId::Succubus, MonsterAvailability::Retail, 128, 980, false, false, { 14, 8, 16, 7, 24, 0 }, { 1, 1, 1, 1, 1, 1 }, 13, 15, 26, 135, 175, MonsterAIID::Succubus, MFLAG_CAN_OPEN_DOOR, 1, 110, 10, 1, 24, 0, 0, 0, 0, 65, MonsterClass::Demon, RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_LIGHTNING, 3, 0, 4084 },
/* MT_HLSPWN */ { P_("monster", "Hell Spawn"), nullptr, "succ\\succrw", MonsterSpriteId::Succubus, MonsterAvailability::Retail, 128, 980, false, false, { 14, 8, 16, 7, 24, 0 }, { 1, 1, 1, 1, 1, 1 }, 14, 16, 28, 150, 200, MonsterAIID::Succubus, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 2, 115, 10, 1, 30, 0, 0, 0, 0, 75, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 3, 0, 4480 },
/* MT_SOLBRNR */ { P_("monster", "Soul Burner"), nullptr, "succ\\succbw", MonsterSpriteId::Succubus, MonsterAvailability::Retail, 128, 980, false, false, { 14, 8, 16, 7, 24, 0 }, { 1, 1, 1, 1, 1, 1 }, 15, 16, 30, 140, 225, MonsterAIID::Succubus, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 120, 10, 1, 35, 0, 0, 0, 0, 85, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 3, 0, 4644 },
/* MT_COUNSLR */ { P_("monster", "Counselor"), nullptr, nullptr, MonsterSpriteId::Counselor, MonsterAvailability::Retail, 128, 2000, true, false, { 12, 1, 20, 8, 28, 20 }, { 1, 1, 1, 1, 1, 1 }, 13, 14, 25, 70, 70, MonsterAIID::Counselor, MFLAG_CAN_OPEN_DOOR, 0, 90, 8, 8, 20, 0, 0, 0, 0, 0, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, 7, 0, 4070 },
/* MT_MAGISTR */ { P_("monster", "Magistrate"), nullptr, "mage\\cnselg", MonsterSpriteId::Counselor, MonsterAvailability::Retail, 128, 2000, true, false, { 12, 1, 20, 8, 28, 20 }, { 1, 1, 1, 1, 1, 1 }, 14, 15, 27, 85, 85, MonsterAIID::Counselor, MFLAG_CAN_OPEN_DOOR, 1, 100, 8, 10, 24, 0, 0, 0, 0, 0, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 7, 0, 4478 },
/* MT_CABALIST*/ { P_("monster", "Cabalist"), nullptr, "mage\\cnselgd", MonsterSpriteId::Counselor, MonsterAvailability::Retail, 128, 2000, true, false, { 12, 1, 20, 8, 28, 20 }, { 1, 1, 1, 1, 1, 1 }, 15, 16, 29, 120, 120, MonsterAIID::Counselor, MFLAG_CAN_OPEN_DOOR, 2, 110, 8, 14, 30, 0, 0, 0, 0, 0, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, 7, 0, 4929 },
/* MT_ADVOCATE*/ { P_("monster", "Advocate"), nullptr, "mage\\cnselbk", MonsterSpriteId::Counselor, MonsterAvailability::Retail, 128, 2000, true, false, { 12, 1, 20, 8, 28, 20 }, { 1, 1, 1, 1, 1, 1 }, 16, 16, 30, 145, 145, MonsterAIID::Counselor, MFLAG_CAN_OPEN_DOOR, 3, 120, 8, 15, 25, 0, 0, 0, 0, 0, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, 0, 4968 },
/* MT_GOLEM */ { P_("monster", "Golem"), "golem\\golm", nullptr, MonsterSpriteId::Golem, MonsterAvailability::Never, 96, 386, true, false, { 0, 16, 12, 0, 12, 20 }, { 1, 1, 1, 1, 1, 1 }, 1, 1, 12, 1, 1, MonsterAIID::Golem, MFLAG_CAN_OPEN_DOOR, 0, 0, 7, 1, 1, 0, 0, 0, 0, 1, MonsterClass::Demon, 0, 0, 0, 0, 0 },
/* MT_DIABLO */ { P_("monster", "The Dark Lord"), nullptr, nullptr, MonsterSpriteId::Diablo, MonsterAvailability::Never, 160, 2000, true, true, { 16, 6, 16, 6, 16, 16 }, { 1, 1, 1, 1, 1, 1 }, 26, 26, 45, 3333, 3333, MonsterAIID::Diablo, MFLAG_KNOCKBACK | MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 220, 4, 30, 60, 0, 11, 0, 0, 90, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, 7, 0, 31666 },
/* MT_DARKMAGE*/ { P_("monster", "The Arch-Litch Malignus"), "darkmage\\dmag", nullptr, MonsterSpriteId::ArchLitch, MonsterAvailability::Never, 128, 1060, true, false, { 6, 1, 21, 6, 23, 18 }, { 1, 1, 1, 1, 1, 1 }, 21, 21, 30, 160, 160, MonsterAIID::Counselor, MFLAG_CAN_OPEN_DOOR, 3, 120, 8, 20, 40, 0, 0, 0, 0, 70, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, 0, 4968 },
/* MT_HELLBOAR*/ { P_("monster", "Hellboar"), "newsfx\\hboar", nullptr, MonsterSpriteId::Hellboar, MonsterAvailability::Retail, 188, 800, false, false, { 10, 10, 15, 6, 16, 0 }, { 2, 1, 1, 1, 1, 1 }, 17, 18, 23, 80, 100, MonsterAIID::SkeletonMelee, MFLAG_KNOCKBACK | MFLAG_SEARCH, 2, 70, 7, 16, 24, 0, 0, 0, 0, 60, MonsterClass::Demon, 0, RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 750 },
/* MT_STINGER */ { P_("monster", "Stinger"), "newsfx\\stingr", nullptr, MonsterSpriteId::Stinger, MonsterAvailability::Retail, 64, 305, false, false, { 10, 10, 12, 6, 15, 0 }, { 2, 1, 1, 1, 1, 1 }, 17, 18, 22, 30, 40, MonsterAIID::SkeletonMelee, 0, 3, 85, 8, 1, 20, 0, 0, 0, 0, 50, MonsterClass::Animal, 0, RESIST_LIGHTNING, 1, 0, 500 },
/* MT_PSYCHORB*/ { P_("monster", "Psychorb"), "newsfx\\psyco", nullptr, MonsterSpriteId::Psychorb, MonsterAvailability::Retail, 156, 800, false, false, { 12, 13, 13, 7, 21, 0 }, { 2, 1, 1, 1, 1, 1 }, 17, 18, 22, 20, 30, MonsterAIID::Psychorb, 0, 3, 80, 8, 10, 10, 0, 0, 0, 0, 40, MonsterClass::Animal, 0, RESIST_FIRE, 6, 0, 450 },
/* MT_ARACHNON*/ { P_("monster", "Arachnon"), "newsfx\\slord", nullptr, MonsterSpriteId::Arachnon, MonsterAvailability::Retail, 148, 800, false, false, { 12, 10, 15, 6, 20, 0 }, { 2, 1, 1, 1, 1, 1 }, 17, 18, 22, 60, 80, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 3, 50, 8, 5, 15, 0, 0, 0, 0, 50, MonsterClass::Animal, 0, RESIST_LIGHTNING, 7, 0, 500 },
/* MT_FELLTWIN*/ { P_("monster", "Felltwin"), "newsfx\\ftwin", nullptr, MonsterSpriteId::InvisibleLord, MonsterAvailability::Retail, 128, 800, false, false, { 13, 13, 15, 11, 16, 0 }, { 2, 1, 1, 1, 1, 1 }, 17, 18, 22, 50, 70, MonsterAIID::SkeletonMelee, MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 70, 8, 10, 18, 0, 0, 0, 0, 50, MonsterClass::Demon, 0, RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 600 },
/* MT_HORKSPWN*/ { P_("monster", "Hork Spawn"), "newsfx\\hspawn", nullptr, MonsterSpriteId::HorkSpawn, MonsterAvailability::Retail, 164, 520, false, true, { 15, 12, 14, 11, 14, 0 }, { 1, 1, 1, 1, 1, 1 }, 18, 19, 22, 30, 30, MonsterAIID::SkeletonMelee, 0, 3, 60, 8, 10, 25, 0, 0, 0, 0, 25, MonsterClass::Demon, RESIST_MAGIC, RESIST_MAGIC, 3, 0, 250 },
/* MT_VENMTAIL*/ { P_("monster", "Venomtail"), "newsfx\\stingr", nullptr, MonsterSpriteId::Venomtail, MonsterAvailability::Retail, 86, 305, false, false, { 10, 10, 12, 6, 15, 0 }, { 2, 1, 1, 1, 1, 1 }, 19, 20, 24, 40, 50, MonsterAIID::SkeletonMelee, 0, 3, 85, 8, 1, 30, 0, 0, 0, 0, 60, MonsterClass::Animal, RESIST_LIGHTNING, IMMUNE_LIGHTNING, 1, 0, 1000 },
/* MT_NECRMORB*/ { P_("monster", "Necromorb"), "newsfx\\psyco", nullptr, MonsterSpriteId::Necromorb, MonsterAvailability::Retail, 140, 800, false, false, { 12, 13, 13, 7, 21, 0 }, { 2, 1, 1, 1, 1, 1 }, 19, 20, 24, 30, 40, MonsterAIID::Necromorb, 0, 3, 80, 8, 20, 20, 0, 0, 0, 0, 50, MonsterClass::Animal, RESIST_FIRE, IMMUNE_FIRE | RESIST_LIGHTNING, 6, 0, 1100 },
/* MT_SPIDLORD*/ { P_("monster", "Spider Lord"), "newsfx\\slord", nullptr, MonsterSpriteId::SpiderLord, MonsterAvailability::Retail, 148, 800, true, true, { 12, 10, 15, 6, 20, 10 }, { 2, 1, 1, 1, 1, 1 }, 19, 20, 24, 80, 100, MonsterAIID::Acid, MFLAG_SEARCH, 3, 60, 8, 8, 20, 75, 8, 10, 10, 60, MonsterClass::Animal, RESIST_LIGHTNING, RESIST_FIRE | IMMUNE_LIGHTNING, 7, 0, 1250 },
/* MT_LASHWORM*/ { P_("monster", "Lashworm"), "newsfx\\lworm", nullptr, MonsterSpriteId::Lashworm, MonsterAvailability::Retail, 176, 800, false, false, { 10, 12, 15, 6, 16, 0 }, { 1, 1, 1, 1, 1, 1 }, 19, 20, 20, 30, 30, MonsterAIID::SkeletonMelee, 0, 3, 90, 8, 12, 20, 0, 0, 0, 0, 50, MonsterClass::Animal, 0, RESIST_FIRE, 3, 0, 600 },
/* MT_TORCHANT*/ { P_("monster", "Torchant"), "newsfx\\tchant", nullptr, MonsterSpriteId::Torchant, MonsterAvailability::Retail, 192, 800, false, false, { 14, 12, 12, 6, 20, 0 }, { 2, 1, 1, 1, 1, 1 }, 19, 20, 22, 60, 80, MonsterAIID::Torchant, 0, 3, 75, 8, 20, 30, 0, 0, 0, 0, 70, MonsterClass::Animal, IMMUNE_FIRE, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 7, 0, 1250 },
/* MT_HORKDMN */ { P_("monster", "Hork Demon"), "newsfx\\hdemon", nullptr, MonsterSpriteId::HorkDemon, MonsterAvailability::Never, 138, 800, true, true, { 15, 8, 16, 6, 16, 9 }, { 2, 1, 1, 1, 1, 2 }, 19, 19, 27, 120, 160, MonsterAIID::SkeletonMelee, 0, 3, 60, 8, 20, 35, 80, 8, 0, 0, 80, MonsterClass::Demon, RESIST_LIGHTNING, RESIST_MAGIC | IMMUNE_LIGHTNING, 7, 0, 2000 },
/* MT_DEFILER */ { P_("monster", "Hell Bug"), "newsfx\\defile", nullptr, MonsterSpriteId::HellBug, MonsterAvailability::Never, 198, 800, true, true, { 8, 8, 14, 6, 14, 12 }, { 1, 1, 1, 1, 1, 1 }, 20, 20, 30, 240, 240, MonsterAIID::SkeletonMelee, MFLAG_SEARCH, 3, 110, 8, 20, 30, 90, 8, 50, 60, 80, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, RESIST_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, 0, 5000 },
/* MT_GRAVEDIG*/ { P_("monster", "Gravedigger"), "newsfx\\gdiggr", nullptr, MonsterSpriteId::Gravedigger, MonsterAvailability::Retail, 124, 800, true, true, { 24, 24, 12, 6, 16, 16 }, { 2, 1, 1, 1, 1, 1 }, 21, 21, 26, 120, 240, MonsterAIID::Scavenger, MFLAG_CAN_OPEN_DOOR, 3, 80, 6, 2, 12, 0, 0, 0, 0, 20, MonsterClass::Undead, IMMUNE_LIGHTNING, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, 3, 0, 2000 },
/* MT_TOMBRAT */ { P_("monster", "Tomb Rat"), "newsfx\\tmbrat", nullptr, MonsterSpriteId::Rat, MonsterAvailability::Retail, 104, 550, false, false, { 11, 8, 12, 6, 20, 0 }, { 2, 1, 1, 1, 1, 1 }, 21, 22, 24, 80, 120, MonsterAIID::SkeletonMelee, 0, 3, 120, 8, 12, 25, 0, 0, 0, 0, 30, MonsterClass::Animal, 0, RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 1800 },
/* MT_FIREBAT */ { P_("monster", "Firebat"), "newsfx\\helbat", nullptr, MonsterSpriteId::Firebat, MonsterAvailability::Retail, 96, 550, false, false, { 18, 16, 14, 6, 18, 11 }, { 2, 1, 1, 1, 1, 1 }, 21, 22, 24, 60, 80, MonsterAIID::FireBat, 0, 3, 100, 8, 15, 20, 0, 0, 0, 0, 70, MonsterClass::Animal, IMMUNE_FIRE, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 7, 0, 2400 },
/* MT_SKLWING */ { P_("monster", "Skullwing"), "newsfx\\swing", "skelaxe\\skelt", MonsterSpriteId::SkeletonDemon, MonsterAvailability::Retail, 128, 1740, true, false, { 10, 8, 20, 6, 24, 16 }, { 3, 1, 1, 1, 1, 1 }, 21, 22, 27, 70, 70, MonsterAIID::SkeletonMelee, 0, 0, 75, 7, 15, 20, 75, 9, 15, 20, 80, MonsterClass::Undead, RESIST_FIRE | RESIST_LIGHTNING, RESIST_FIRE | RESIST_LIGHTNING, 7, 0, 3000 },
/* MT_LICH */ { P_("monster", "Lich"), "newsfx\\lich", nullptr, MonsterSpriteId::Lich, MonsterAvailability::Retail, 96, 800, false, true, { 12, 10, 10, 7, 21, 0 }, { 2, 1, 1, 1, 2, 1 }, 21, 22, 25, 80, 100, MonsterAIID::Lich, 0, 3, 100, 8, 15, 20, 0, 0, 0, 0, 60, MonsterClass::Undead, RESIST_LIGHTNING, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, 3, 0, 3000 },
/* MT_CRYPTDMN*/ { P_("monster", "Crypt Demon"), "newsfx\\crypt", nullptr, MonsterSpriteId::CryptDemon, MonsterAvailability::Retail, 154, 800, false, true, { 8, 18, 12, 8, 21, 0 }, { 3, 1, 1, 1, 1, 1 }, 22, 23, 28, 200, 240, MonsterAIID::SkeletonMelee, 0, 3, 100, 8, 20, 40, 0, 0, 0, 0, 85, MonsterClass::Demon, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, 3, 0, 3200 },
/* MT_HELLBAT */ { P_("monster", "Hellbat"), "newsfx\\helbat", nullptr, MonsterSpriteId::Hellbat, MonsterAvailability::Retail, 96, 550, true, false, { 18, 16, 14, 6, 18, 11 }, { 2, 1, 1, 1, 1, 1 }, 23, 24, 29, 100, 140, MonsterAIID::Torchant, 0, 3, 110, 8, 30, 30, 0, 0, 0, 0, 80, MonsterClass::Demon, RESIST_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, RESIST_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, 0, 3600 },
/* MT_BONEDEMN*/ { P_("monster", "Bone Demon"), "newsfx\\swing", nullptr, MonsterSpriteId::SkeletonDemon, MonsterAvailability::Retail, 128, 1740, true, true, { 10, 8, 20, 6, 24, 16 }, { 3, 1, 1, 1, 1, 1 }, 23, 24, 30, 240, 280, MonsterAIID::BoneDemon, 0, 0, 100, 8, 40, 50, 160, 12, 50, 50, 50, MonsterClass::Undead, IMMUNE_FIRE | IMMUNE_LIGHTNING, IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, 0, 5000 },
/* MT_ARCHLICH*/ { P_("monster", "Arch Lich"), "newsfx\\lich", nullptr, MonsterSpriteId::ArchLich, MonsterAvailability::Retail, 136, 800, false, true, { 12, 10, 10, 7, 21, 0 }, { 2, 1, 1, 1, 2, 1 }, 23, 24, 30, 180, 200, MonsterAIID::ArchLich, 0, 3, 120, 8, 30, 30, 0, 0, 0, 0, 75, MonsterClass::Undead, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 3, 0, 4000 },
/* MT_BICLOPS */ { P_("monster", "Biclops"), "newsfx\\biclop", nullptr, MonsterSpriteId::Biclops, MonsterAvailability::Retail, 180, 800, false, false, { 10, 11, 16, 6, 16, 0 }, { 2, 1, 1, 1, 2, 1 }, 23, 24, 30, 200, 240, MonsterAIID::SkeletonMelee, MFLAG_KNOCKBACK | MFLAG_CAN_OPEN_DOOR, 3, 90, 8, 40, 50, 0, 0, 0, 0, 80, MonsterClass::Demon, RESIST_LIGHTNING, RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 4000 },
/* MT_FLESTHNG*/ { P_("monster", "Flesh Thing"), "newsfx\\flesht", nullptr, MonsterSpriteId::FleshThing, MonsterAvailability::Retail, 164, 800, false, true, { 15, 24, 15, 6, 16, 0 }, { 1, 1, 1, 1, 1, 1 }, 23, 24, 28, 300, 400, MonsterAIID::SkeletonMelee, 0, 3, 150, 8, 12, 18, 0, 0, 0, 0, 70, MonsterClass::Demon, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING, 3, 0, 4000 },
/* MT_REAPER */ { P_("monster", "Reaper"), "newsfx\\reaper", nullptr, MonsterSpriteId::Reaper, MonsterAvailability::Retail, 180, 800, false, false, { 12, 10, 14, 6, 16, 0 }, { 2, 1, 1, 1, 1, 1 }, 23, 24, 30, 260, 300, MonsterAIID::SkeletonMelee, 0, 3, 120, 8, 30, 35, 0, 0, 0, 0, 90, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 3, 0, 6000 },
// TRANSLATORS: Monster Block end
/* MT_NAKRUL */ { P_("monster", "Na-Krul"), "newsfx\\nakrul", nullptr, MonsterSpriteId::NaKrul, MonsterAvailability::Never, 226, 1200, true, true, { 2, 6, 16, 3, 16, 16 }, { 1, 1, 1, 1, 1, 1 }, 31, 31, 40, 1332, 1332, MonsterAIID::SkeletonMelee, MFLAG_KNOCKBACK | MFLAG_SEARCH | MFLAG_CAN_OPEN_DOOR, 3, 150, 7, 40, 50, 150, 10, 40, 50, 125, MonsterClass::Demon, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING, 7, 0, 13333 },
// clang-format on
};
std::vector<MonsterData> MonstersData;
/**
* Map between .DUN file value and monster type enum
@ -400,6 +201,420 @@ const _monster_id MonstConvTbl[] = {
MT_LRDSAYTR,
};
tl::expected<MonsterAvailability, std::string> ParseMonsterAvailability(std::string_view value)
{
if (value == "Always")
return MonsterAvailability::Always;
if (value == "Never")
return MonsterAvailability::Never;
if (value == "Retail")
return MonsterAvailability::Retail;
return tl::make_unexpected("Expected one of: Always, Never, or Retail");
}
tl::expected<MonsterAIID, std::string> ParseAiId(std::string_view value)
{
if (value == "Zombie")
return MonsterAIID::Zombie;
if (value == "Fat")
return MonsterAIID::Fat;
if (value == "SkeletonMelee")
return MonsterAIID::SkeletonMelee;
if (value == "SkeletonRanged")
return MonsterAIID::SkeletonRanged;
if (value == "Scavenger")
return MonsterAIID::Scavenger;
if (value == "Rhino")
return MonsterAIID::Rhino;
if (value == "GoatMelee")
return MonsterAIID::GoatMelee;
if (value == "GoatRanged")
return MonsterAIID::GoatRanged;
if (value == "Fallen")
return MonsterAIID::Fallen;
if (value == "Magma")
return MonsterAIID::Magma;
if (value == "SkeletonKing")
return MonsterAIID::SkeletonKing;
if (value == "Bat")
return MonsterAIID::Bat;
if (value == "Gargoyle")
return MonsterAIID::Gargoyle;
if (value == "Butcher")
return MonsterAIID::Butcher;
if (value == "Succubus")
return MonsterAIID::Succubus;
if (value == "Sneak")
return MonsterAIID::Sneak;
if (value == "Storm")
return MonsterAIID::Storm;
if (value == "FireMan")
return MonsterAIID::FireMan;
if (value == "Gharbad")
return MonsterAIID::Gharbad;
if (value == "Acid")
return MonsterAIID::Acid;
if (value == "AcidUnique")
return MonsterAIID::AcidUnique;
if (value == "Golem")
return MonsterAIID::Golem;
if (value == "Zhar")
return MonsterAIID::Zhar;
if (value == "Snotspill")
return MonsterAIID::Snotspill;
if (value == "Snake")
return MonsterAIID::Snake;
if (value == "Counselor")
return MonsterAIID::Counselor;
if (value == "Mega")
return MonsterAIID::Mega;
if (value == "Diablo")
return MonsterAIID::Diablo;
if (value == "Lazarus")
return MonsterAIID::Lazarus;
if (value == "LazarusSuccubus")
return MonsterAIID::LazarusSuccubus;
if (value == "Lachdanan")
return MonsterAIID::Lachdanan;
if (value == "Warlord")
return MonsterAIID::Warlord;
if (value == "FireBat")
return MonsterAIID::FireBat;
if (value == "Torchant")
return MonsterAIID::Torchant;
if (value == "HorkDemon")
return MonsterAIID::HorkDemon;
if (value == "Lich")
return MonsterAIID::Lich;
if (value == "ArchLich")
return MonsterAIID::ArchLich;
if (value == "Psychorb")
return MonsterAIID::Psychorb;
if (value == "Necromorb")
return MonsterAIID::Necromorb;
if (value == "BoneDemon")
return MonsterAIID::BoneDemon;
return tl::make_unexpected("Unknown enum value");
}
tl::expected<monster_flag, std::string> ParseMonsterFlag(std::string_view value)
{
if (value == "HIDDEN")
return MFLAG_HIDDEN;
if (value == "LOCK_ANIMATION")
return MFLAG_LOCK_ANIMATION;
if (value == "ALLOW_SPECIAL")
return MFLAG_ALLOW_SPECIAL;
if (value == "TARGETS_MONSTER")
return MFLAG_TARGETS_MONSTER;
if (value == "GOLEM")
return MFLAG_GOLEM;
if (value == "QUEST_COMPLETE")
return MFLAG_QUEST_COMPLETE;
if (value == "KNOCKBACK")
return MFLAG_KNOCKBACK;
if (value == "SEARCH")
return MFLAG_SEARCH;
if (value == "CAN_OPEN_DOOR")
return MFLAG_CAN_OPEN_DOOR;
if (value == "NO_ENEMY")
return MFLAG_NO_ENEMY;
if (value == "BERSERK")
return MFLAG_BERSERK;
if (value == "NOLIFESTEAL")
return MFLAG_NOLIFESTEAL;
return tl::make_unexpected("Unknown enum value");
}
tl::expected<MonsterClass, std::string> ParseMonsterClass(std::string_view value)
{
if (value == "Undead")
return MonsterClass::Undead;
if (value == "Demon")
return MonsterClass::Demon;
if (value == "Animal")
return MonsterClass::Animal;
return tl::make_unexpected("Unknown enum value");
}
tl::expected<monster_resistance, std::string> ParseMonsterResistance(std::string_view value)
{
if (value == "RESIST_MAGIC")
return RESIST_MAGIC;
if (value == "RESIST_FIRE")
return RESIST_FIRE;
if (value == "RESIST_LIGHTNING")
return RESIST_LIGHTNING;
if (value == "IMMUNE_MAGIC")
return IMMUNE_MAGIC;
if (value == "IMMUNE_FIRE")
return IMMUNE_FIRE;
if (value == "IMMUNE_LIGHTNING")
return IMMUNE_LIGHTNING;
if (value == "IMMUNE_ACID")
return IMMUNE_ACID;
return tl::make_unexpected("Unknown enum value");
}
void LoadMonsterData()
{
const std::string_view filename = "txtdata\\monsters\\monstdat.tsv";
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::load(filename);
if (!dataFileResult.has_value()) {
DataFile::reportFatalError(dataFileResult.error(), filename);
}
DataFile &dataFile = dataFileResult.value();
if (tl::expected<void, DataFile::Error> result = dataFile.skipHeader();
!result.has_value()) {
DataFile::reportFatalError(result.error(), filename);
}
MonstersData.clear();
std::unordered_map<std::string, size_t> spritePathToId;
for (DataFileRecord record : dataFile) {
FieldIterator fieldIt = record.begin();
const FieldIterator endField = record.end();
MonstersData.emplace_back();
MonsterData &monster = MonstersData.back();
const auto advance = [&]() {
++fieldIt;
if (fieldIt == endField) {
DataFile::reportFatalError(DataFile::Error::NotEnoughColumns, filename);
}
};
// Skip the first column (monster ID).
// name
advance();
monster.name = (*fieldIt).value();
// assetsSuffix
advance();
{
std::string assetsSuffix { (*fieldIt).value() };
const auto [it, inserted] = spritePathToId.emplace(assetsSuffix, spritePathToId.size());
if (inserted)
MonsterSpritePaths.push_back(it->first);
monster.spriteId = it->second;
}
// soundSuffix
advance();
monster.soundSuffix = (*fieldIt).value();
// trnFile
advance();
monster.trnFile = (*fieldIt).value();
// availability
advance();
if (tl::expected<MonsterAvailability, std::string> result = ParseMonsterAvailability((*fieldIt).value()); result.has_value()) {
monster.availability = *std::move(result);
} else {
DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "availability", *fieldIt, result.error());
}
// width
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.width); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "width", *fieldIt);
}
// image
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.image); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "image", *fieldIt);
}
// hasSpecial
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseBool(monster.hasSpecial); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "hasSpecial", *fieldIt);
}
// hasSpecialSound
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseBool(monster.hasSpecialSound); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "hasSpecialSound", *fieldIt);
}
// frames[6]
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseIntArray(monster.frames); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "frames", *fieldIt);
}
// rate[6]
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseIntArray(monster.rate); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "rate", *fieldIt);
}
// minDunLvl
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.minDunLvl); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "minDunLvl", *fieldIt);
}
// maxDunLvl
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.maxDunLvl); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "maxDunLvl", *fieldIt);
}
// level
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.level); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "level", *fieldIt);
}
// hitPointsMinimum
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.hitPointsMinimum); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "hitPointsMinimum", *fieldIt);
}
// hitPointsMaximum
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.hitPointsMaximum); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "hitPointsMaximum", *fieldIt);
}
// ai
advance();
if (tl::expected<MonsterAIID, std::string> result = ParseAiId((*fieldIt).value()); result.has_value()) {
monster.ai = *std::move(result);
} else {
DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "ai", *fieldIt, result.error());
}
// abilityFlags
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseEnumList(monster.abilityFlags, ParseMonsterFlag); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "abilityFlags", *fieldIt);
}
// intelligence
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.intelligence); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "intelligence", *fieldIt);
}
// toHit
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.toHit); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "toHit", *fieldIt);
}
// animFrameNum
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.animFrameNum); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "animFrameNum", *fieldIt);
}
// minDamage
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.minDamage); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "minDamage", *fieldIt);
}
// maxDamage
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.maxDamage); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "maxDamage", *fieldIt);
}
// toHitSpecial
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.toHitSpecial); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "toHitSpecial", *fieldIt);
}
// animFrameNumSpecial
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.animFrameNumSpecial); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "animFrameNumSpecial", *fieldIt);
}
// minDamageSpecial
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.minDamageSpecial); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "minDamageSpecial", *fieldIt);
}
// maxDamageSpecial
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.maxDamageSpecial); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "maxDamageSpecial", *fieldIt);
}
// armorClass
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.armorClass); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "armorClass", *fieldIt);
}
// monsterClass
advance();
if (tl::expected<MonsterClass, std::string> result = ParseMonsterClass((*fieldIt).value()); result.has_value()) {
monster.monsterClass = *std::move(result);
} else {
DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "monsterClass", *fieldIt, result.error());
}
// resistance
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseEnumList(monster.resistance, ParseMonsterResistance); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "resistance", *fieldIt);
}
// resistanceHell
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseEnumList(monster.resistanceHell, ParseMonsterResistance); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "resistanceHell", *fieldIt);
}
// selectionType
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.selectionType); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "selectionType", *fieldIt);
}
// treasure
// TODO: Replace this hack with proper parsing once unique monsters have been migrated.
advance();
{
const std::string_view value = (*fieldIt).value();
if (value.empty()) {
monster.treasure = 0;
} else if (value == "None") {
monster.treasure = T_NODROP;
} else if (value == "Uniq(SKCROWN)") {
monster.treasure = Uniq(UITEM_SKCROWN);
} else if (value == "Uniq(CLEAVER)") {
monster.treasure = Uniq(UITEM_CLEAVER);
} else {
DataFile::reportFatalFieldError(DataFileField::Error::InvalidValue, filename, "treasure", *fieldIt, "NOTE: Parser is incomplete");
}
}
// exp
advance();
if (tl::expected<void, DataFileField::Error> result = (*fieldIt).parseInt(monster.exp); !result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename, "exp", *fieldIt);
}
}
}
size_t GetNumMonsterSprites()
{
return MonsterSpritePaths.size();
}
/** Contains the data related to each unique monster ID. */
const UniqueMonsterData UniqueMonstersData[] = {
// clang-format off

83
Source/monstdat.h

@ -87,73 +87,11 @@ enum class MonsterAvailability : uint8_t {
Retail,
};
enum class MonsterSpriteId : uint8_t {
Zombie = 0, // "zombie\\zombie"
FallenSpear, // "falspear\\phall"
FallenSword, // "falsword\\fall"
SkeletonAxe, // "skelaxe\\sklax"
SkeletonBow, // "skelbow\\sklbw"
SkeletonCaptain, // "skelsd\\sklsr"
SkeletonDemon, // "demskel\\demskl"
SkeletonKing, // "sking\\sking"
Scavenger, // "scav\\scav"
InvisibleLord, // "tsneak\\tsneak"
Hidden, // "sneak\\sneak"
GoatMace, // "goatmace\\goat"
GoatBow, // "goatbow\\goatb"
GoatLord, // "goatlord\\goatl"
Bat, // "bat\\bat"
AcidBeast, // "acid\\acid"
Overlord, // "fat\\fat"
Butcher, // "fatc\\fatc"
Wyrm, // "worm\\worm"
MagmaDemon, // "magma\\magma"
HornedDemon, // "rhino\\rhino"
StormRider, // "thin\\thin"
Incinerator, // "fireman\\firem"
DevilKinBrute, // "bigfall\\fallg"
Gargoyle, // "gargoyle\\gargo"
Slayer, // "mega\\mega"
Viper, // "snake\\snake"
BlackKnight, // "black\\black"
Shredded, // "unrav\\unrav"
Succubus, // "succ\\scbs"
Counselor, // "mage\\mage"
Golem, // "golem\\golem"
Diablo, // "diablo\\diablo"
ArchLitch, // "darkmage\\dmage"
Hellboar, // "fork\\fork"
Stinger, // "scorp\\scorp"
Psychorb, // "eye\\eye"
Arachnon, // "spider\\spider"
HorkSpawn, // "spawn\\spawn"
Venomtail, // "wscorp\\wscorp"
Necromorb, // "eye2\\eye2"
SpiderLord, // "bspidr\\bspidr"
Lashworm, // "clasp\\clasp"
Torchant, // "antworm\\worm"
HorkDemon, // "horkd\\horkd"
HellBug, // "hellbug\\hellbg"
Gravedigger, // "gravdg\\gravdg"
Rat, // "rat\\rat"
Firebat, // "hellbat\\helbat"
Lich, // "lich\\lich"
CryptDemon, // "bubba\\bubba"
Hellbat, // "hellbat2\\bhelbt"
ArchLich, // "lich2\\lich2"
Biclops, // "byclps\\byclps"
FleshThing, // "flesh\\flesh"
Reaper, // "reaper\\reap"
NaKrul, // "nkr\\nkr"
FIRST = Zombie,
LAST = NaKrul
};
struct MonsterData {
const char *name;
const char *soundSuffix;
const char *trnFile;
MonsterSpriteId spriteId;
std::string name;
std::string soundSuffix;
std::string trnFile;
uint16_t spriteId;
MonsterAvailability availability;
uint16_t width;
uint16_t image;
@ -196,7 +134,7 @@ struct MonsterData {
[[nodiscard]] const char *soundPath() const
{
return soundSuffix != nullptr ? soundSuffix : spritePath();
return !soundSuffix.empty() ? soundSuffix.c_str() : spritePath();
}
[[nodiscard]] bool hasAnim(size_t index) const
@ -388,8 +326,17 @@ struct UniqueMonsterData {
_speech_id mtalkmsg;
};
extern const MonsterData MonstersData[];
extern std::vector<MonsterData> MonstersData;
extern const _monster_id MonstConvTbl[];
extern const UniqueMonsterData UniqueMonstersData[];
void LoadMonsterData();
/**
* @brief Returns the number of the monster sprite files.
*
* Different monsters can use the same sprite with different TRNs, these count as 1.
*/
size_t GetNumMonsterSprites();
} // namespace devilution

4
Source/monster.cpp

@ -3425,7 +3425,7 @@ void InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData)
++j;
}
if (monsterData.trnFile != nullptr) {
if (!monsterData.trnFile.empty()) {
InitMonsterTRN(monsterType);
}
@ -3478,7 +3478,7 @@ void InitAllMonsterGFX()
return;
using LevelMonsterTypeIndices = StaticVector<uint8_t, 8>;
std::array<LevelMonsterTypeIndices, enum_size<MonsterSpriteId>::value> monstersBySprite;
std::vector<LevelMonsterTypeIndices> monstersBySprite(GetNumMonsterSprites());
for (size_t i = 0; i < LevelMonsterTypeCount; ++i) {
monstersBySprite[static_cast<size_t>(LevelMonsterTypes[i].data().spriteId)].emplace_back(i);
}

146
Source/translation_dummy.cpp

@ -0,0 +1,146 @@
/**
* @file translation_dummy.cpp
*
* Do not edit this file manually, it is automatically generated
* and updated by the extract_translation_data.py script.
*/
#include "utils/language.h
const char *MT_NZOMBIE_NAME = P_("monster", "Zombie");
const char *MT_BZOMBIE_NAME = P_("monster", "Ghoul");
const char *MT_GZOMBIE_NAME = P_("monster", "Rotting Carcass");
const char *MT_YZOMBIE_NAME = P_("monster", "Black Death");
const char *MT_RFALLSP_NAME = P_("monster", "Fallen One");
const char *MT_DFALLSP_NAME = P_("monster", "Carver");
const char *MT_YFALLSP_NAME = P_("monster", "Devil Kin");
const char *MT_BFALLSP_NAME = P_("monster", "Dark One");
const char *MT_WSKELAX_NAME = P_("monster", "Skeleton");
const char *MT_TSKELAX_NAME = P_("monster", "Corpse Axe");
const char *MT_RSKELAX_NAME = P_("monster", "Burning Dead");
const char *MT_XSKELAX_NAME = P_("monster", "Horror");
const char *MT_RFALLSD_NAME = P_("monster", "Fallen One");
const char *MT_DFALLSD_NAME = P_("monster", "Carver");
const char *MT_YFALLSD_NAME = P_("monster", "Devil Kin");
const char *MT_BFALLSD_NAME = P_("monster", "Dark One");
const char *MT_NSCAV_NAME = P_("monster", "Scavenger");
const char *MT_BSCAV_NAME = P_("monster", "Plague Eater");
const char *MT_WSCAV_NAME = P_("monster", "Shadow Beast");
const char *MT_YSCAV_NAME = P_("monster", "Bone Gasher");
const char *MT_WSKELBW_NAME = P_("monster", "Skeleton");
const char *MT_TSKELBW_NAME = P_("monster", "Corpse Bow");
const char *MT_RSKELBW_NAME = P_("monster", "Burning Dead");
const char *MT_XSKELBW_NAME = P_("monster", "Horror");
const char *MT_WSKELSD_NAME = P_("monster", "Skeleton Captain");
const char *MT_TSKELSD_NAME = P_("monster", "Corpse Captain");
const char *MT_RSKELSD_NAME = P_("monster", "Burning Dead Captain");
const char *MT_XSKELSD_NAME = P_("monster", "Horror Captain");
const char *MT_INVILORD_NAME = P_("monster", "Invisible Lord");
const char *MT_SNEAK_NAME = P_("monster", "Hidden");
const char *MT_STALKER_NAME = P_("monster", "Stalker");
const char *MT_UNSEEN_NAME = P_("monster", "Unseen");
const char *MT_ILLWEAV_NAME = P_("monster", "Illusion Weaver");
const char *MT_LRDSAYTR_NAME = P_("monster", "Satyr Lord");
const char *MT_NGOATMC_NAME = P_("monster", "Flesh Clan");
const char *MT_BGOATMC_NAME = P_("monster", "Stone Clan");
const char *MT_RGOATMC_NAME = P_("monster", "Fire Clan");
const char *MT_GGOATMC_NAME = P_("monster", "Night Clan");
const char *MT_FIEND_NAME = P_("monster", "Fiend");
const char *MT_BLINK_NAME = P_("monster", "Blink");
const char *MT_GLOOM_NAME = P_("monster", "Gloom");
const char *MT_FAMILIAR_NAME = P_("monster", "Familiar");
const char *MT_NGOATBW_NAME = P_("monster", "Flesh Clan");
const char *MT_BGOATBW_NAME = P_("monster", "Stone Clan");
const char *MT_RGOATBW_NAME = P_("monster", "Fire Clan");
const char *MT_GGOATBW_NAME = P_("monster", "Night Clan");
const char *MT_NACID_NAME = P_("monster", "Acid Beast");
const char *MT_RACID_NAME = P_("monster", "Poison Spitter");
const char *MT_BACID_NAME = P_("monster", "Pit Beast");
const char *MT_XACID_NAME = P_("monster", "Lava Maw");
const char *MT_SKING_NAME = P_("monster", "Skeleton King");
const char *MT_CLEAVER_NAME = P_("monster", "The Butcher");
const char *MT_FAT_NAME = P_("monster", "Overlord");
const char *MT_MUDMAN_NAME = P_("monster", "Mud Man");
const char *MT_TOAD_NAME = P_("monster", "Toad Demon");
const char *MT_FLAYED_NAME = P_("monster", "Flayed One");
const char *MT_WYRM_NAME = P_("monster", "Wyrm");
const char *MT_CAVSLUG_NAME = P_("monster", "Cave Slug");
const char *MT_DVLWYRM_NAME = P_("monster", "Devil Wyrm");
const char *MT_DEVOUR_NAME = P_("monster", "Devourer");
const char *MT_NMAGMA_NAME = P_("monster", "Magma Demon");
const char *MT_YMAGMA_NAME = P_("monster", "Blood Stone");
const char *MT_BMAGMA_NAME = P_("monster", "Hell Stone");
const char *MT_WMAGMA_NAME = P_("monster", "Lava Lord");
const char *MT_HORNED_NAME = P_("monster", "Horned Demon");
const char *MT_MUDRUN_NAME = P_("monster", "Mud Runner");
const char *MT_FROSTC_NAME = P_("monster", "Frost Charger");
const char *MT_OBLORD_NAME = P_("monster", "Obsidian Lord");
const char *MT_BONEDMN_NAME = P_("monster", "oldboned");
const char *MT_REDDTH_NAME = P_("monster", "Red Death");
const char *MT_LTCHDMN_NAME = P_("monster", "Litch Demon");
const char *MT_UDEDBLRG_NAME = P_("monster", "Undead Balrog");
const char *MT_INCIN_NAME = P_("monster", "Incinerator");
const char *MT_FLAMLRD_NAME = P_("monster", "Flame Lord");
const char *MT_DOOMFIRE_NAME = P_("monster", "Doom Fire");
const char *MT_HELLBURN_NAME = P_("monster", "Hell Burner");
const char *MT_STORM_NAME = P_("monster", "Red Storm");
const char *MT_RSTORM_NAME = P_("monster", "Storm Rider");
const char *MT_STORML_NAME = P_("monster", "Storm Lord");
const char *MT_MAEL_NAME = P_("monster", "Maelstrom");
const char *MT_BIGFALL_NAME = P_("monster", "Devil Kin Brute");
const char *MT_WINGED_NAME = P_("monster", "Winged-Demon");
const char *MT_GARGOYLE_NAME = P_("monster", "Gargoyle");
const char *MT_BLOODCLW_NAME = P_("monster", "Blood Claw");
const char *MT_DEATHW_NAME = P_("monster", "Death Wing");
const char *MT_MEGA_NAME = P_("monster", "Slayer");
const char *MT_GUARD_NAME = P_("monster", "Guardian");
const char *MT_VTEXLRD_NAME = P_("monster", "Vortex Lord");
const char *MT_BALROG_NAME = P_("monster", "Balrog");
const char *MT_NSNAKE_NAME = P_("monster", "Cave Viper");
const char *MT_RSNAKE_NAME = P_("monster", "Fire Drake");
const char *MT_BSNAKE_NAME = P_("monster", "Gold Viper");
const char *MT_GSNAKE_NAME = P_("monster", "Azure Drake");
const char *MT_NBLACK_NAME = P_("monster", "Black Knight");
const char *MT_RTBLACK_NAME = P_("monster", "Doom Guard");
const char *MT_BTBLACK_NAME = P_("monster", "Steel Lord");
const char *MT_RBLACK_NAME = P_("monster", "Blood Knight");
const char *MT_UNRAV_NAME = P_("monster", "The Shredded");
const char *MT_HOLOWONE_NAME = P_("monster", "Hollow One");
const char *MT_PAINMSTR_NAME = P_("monster", "Pain Master");
const char *MT_REALWEAV_NAME = P_("monster", "Reality Weaver");
const char *MT_SUCCUBUS_NAME = P_("monster", "Succubus");
const char *MT_SNOWWICH_NAME = P_("monster", "Snow Witch");
const char *MT_HLSPWN_NAME = P_("monster", "Hell Spawn");
const char *MT_SOLBRNR_NAME = P_("monster", "Soul Burner");
const char *MT_COUNSLR_NAME = P_("monster", "Counselor");
const char *MT_MAGISTR_NAME = P_("monster", "Magistrate");
const char *MT_CABALIST_NAME = P_("monster", "Cabalist");
const char *MT_ADVOCATE_NAME = P_("monster", "Advocate");
const char *MT_GOLEM_NAME = P_("monster", "Golem");
const char *MT_DIABLO_NAME = P_("monster", "The Dark Lord");
const char *MT_DARKMAGE_NAME = P_("monster", "The Arch-Litch Malignus");
const char *MT_HELLBOAR_NAME = P_("monster", "Hellboar");
const char *MT_STINGER_NAME = P_("monster", "Stinger");
const char *MT_PSYCHORB_NAME = P_("monster", "Psychorb");
const char *MT_ARACHNON_NAME = P_("monster", "Arachnon");
const char *MT_FELLTWIN_NAME = P_("monster", "Felltwin");
const char *MT_HORKSPWN_NAME = P_("monster", "Hork Spawn");
const char *MT_VENMTAIL_NAME = P_("monster", "Venomtail");
const char *MT_NECRMORB_NAME = P_("monster", "Necromorb");
const char *MT_SPIDLORD_NAME = P_("monster", "Spider Lord");
const char *MT_LASHWORM_NAME = P_("monster", "Lashworm");
const char *MT_TORCHANT_NAME = P_("monster", "Torchant");
const char *MT_HORKDMN_NAME = P_("monster", "Hork Demon");
const char *MT_DEFILER_NAME = P_("monster", "Hell Bug");
const char *MT_GRAVEDIG_NAME = P_("monster", "Gravedigger");
const char *MT_TOMBRAT_NAME = P_("monster", "Tomb Rat");
const char *MT_FIREBAT_NAME = P_("monster", "Firebat");
const char *MT_SKLWING_NAME = P_("monster", "Skullwing");
const char *MT_LICH_NAME = P_("monster", "Lich");
const char *MT_CRYPTDMN_NAME = P_("monster", "Crypt Demon");
const char *MT_HELLBAT_NAME = P_("monster", "Hellbat");
const char *MT_BONEDEMN_NAME = P_("monster", "Bone Demon");
const char *MT_ARCHLICH_NAME = P_("monster", "Arch Lich");
const char *MT_BICLOPS_NAME = P_("monster", "Biclops");
const char *MT_FLESTHNG_NAME = P_("monster", "Flesh Thing");
const char *MT_REAPER_NAME = P_("monster", "Reaper");
const char *MT_NAKRUL_NAME = P_("monster", "Na-Krul");

2
test/pack_test.cpp

@ -2,6 +2,7 @@
#include <gtest/gtest.h>
#include "monstdat.h"
#include "pack.h"
#include "playerdat.hpp"
#include "utils/paths.h"
@ -943,6 +944,7 @@ public:
SwapLE(testPack);
LoadPlayerDataFiles();
LoadMonsterData();
UnPackPlayer(testPack, *MyPlayer);
}
};

2
test/timedemo_test.cpp

@ -5,6 +5,7 @@
#include "diablo.h"
#include "engine/demomode.h"
#include "lua/lua.hpp"
#include "monstdat.h"
#include "options.h"
#include "pfile.h"
#include "playerdat.hpp"
@ -52,6 +53,7 @@ void RunTimedemo(std::string timedemoFolderName)
demo::InitPlayBack(demoNumber, true);
LoadPlayerDataFiles();
LoadMonsterData();
pfile_ui_set_hero_infos(Dummy_GetHeroInfo);
gbLoadGame = true;

23
tools/extract_translation_data.py

@ -0,0 +1,23 @@
#!/usr/bin/env python
import csv
import pathlib
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")
with open(translation_dummy_path, 'w') as temp_source:
temp_source.write(f'/**\n')
temp_source.write(f' * @file translation_dummy.cpp\n')
temp_source.write(f' *\n')
temp_source.write(f' * Do not edit this file manually, it is automatically generated\n')
temp_source.write(f' * and updated by the extract_translation_data.py script.\n')
temp_source.write(f' */\n')
temp_source.write(f'#include "utils/language.h\n')
temp_source.write(f'\n')
with open(monstdat_path, 'r') as tsv:
reader = csv.DictReader(tsv, delimiter='\t')
for row in reader:
translation_key = row['_monster_id'] + "_NAME"
name = row['name'];
temp_source.write(f'const char *' + translation_key + ' = P_("monster", "' + name + '");\n')
Loading…
Cancel
Save