From c2a195af2df8b6b77ffda3263ab9995e47a0ebc7 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Mon, 8 Aug 2022 08:57:59 +0100 Subject: [PATCH] Slightly optimize loading same-sprite monsters For monsters with the same sprite, load the sprite from the file system only once. Example: ``` Loaded monster graphics: SkelAxe\SklAx 599 KiB x1 Loaded monster graphics: SkelBow\SklBw 623 KiB x1 Loaded monster graphics: Scav\Scav 328 KiB x2 Loaded monster graphics: Sneak\Sneak 765 KiB x1 Loaded monster graphics: Bat\Bat 287 KiB x1 Loaded monster graphics: Golem\Golem 765 KiB x1 Total monster graphics: 3369 KiB 3698 KiB ``` --- Source/levels/gendung.cpp | 1 + Source/monstdat.cpp | 343 ++++++++++++++++++++------------- Source/monstdat.h | 71 ++++++- Source/monster.cpp | 111 ++++++++--- Source/monster.h | 19 +- Source/pfile.cpp | 2 + Source/utils/static_vector.hpp | 5 + 7 files changed, 378 insertions(+), 174 deletions(-) diff --git a/Source/levels/gendung.cpp b/Source/levels/gendung.cpp index a899572b1d7f..6ed8e1c60a8e 100644 --- a/Source/levels/gendung.cpp +++ b/Source/levels/gendung.cpp @@ -569,6 +569,7 @@ void LoadDungeonBase(const char *path, Point spawn, int floorId, int dirtId) LoadTransparency(dunData.get()); SetMapMonsters(dunData.get(), Point(0, 0).megaToWorld()); + InitAllMonsterGFX(); SetMapObjects(dunData.get(), 0, 0); } diff --git a/Source/monstdat.cpp b/Source/monstdat.cpp index 74d89344dd04..f5bb2bff6e6f 100644 --- a/Source/monstdat.cpp +++ b/Source/monstdat.cpp @@ -22,153 +22,218 @@ constexpr uint16_t Uniq(_unique_items item) return static_cast(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 +}; + } // namespace +const char *MonsterData::spritePath() const +{ + return MonsterSpritePaths[static_cast(spriteId)]; +} + /** Contains the data related to each monster ID. */ const MonsterData MonstersData[] = { // clang-format off -// _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 +// _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"), "zombie\\zombie", nullptr, nullptr, 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"), "zombie\\zombie", nullptr, "zombie\\bluered", 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"), "zombie\\zombie", nullptr, "zombie\\grey", 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"), "zombie\\zombie", nullptr, "zombie\\yellow", 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"), "falspear\\phall", nullptr, "falspear\\fallent", 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"), "falspear\\phall", nullptr, "falspear\\dark", 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"), "falspear\\phall", nullptr, nullptr, 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"), "falspear\\phall", nullptr, "falspear\\blue", 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"), "skelaxe\\sklax", nullptr, "skelaxe\\white", 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"), "skelaxe\\sklax", nullptr, "skelaxe\\skelt", 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"), "skelaxe\\sklax", nullptr, nullptr, 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"), "skelaxe\\sklax", nullptr, "skelaxe\\black", 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"), "falsword\\fall", nullptr, "falsword\\fallent", 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"), "falsword\\fall", nullptr, "falsword\\dark", 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"), "falsword\\fall", nullptr, nullptr, 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"), "falsword\\fall", nullptr, "falsword\\blue", 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"), "scav\\scav", nullptr, nullptr, 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"), "scav\\scav", nullptr, "scav\\scavbr", 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"), "scav\\scav", nullptr, "scav\\scavbe", 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"), "scav\\scav", nullptr, "scav\\scavw", 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"), "skelbow\\sklbw", nullptr, "skelbow\\white", 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"), "skelbow\\sklbw", nullptr, "skelbow\\skelt", 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"), "skelbow\\sklbw", nullptr, nullptr, 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"), "skelbow\\sklbw", nullptr, "skelbow\\black", 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"), "skelsd\\sklsr", nullptr, "skelsd\\white", 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"), "skelsd\\sklsr", nullptr, "skelsd\\skelt", 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"), "skelsd\\sklsr", nullptr, nullptr, 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"), "skelsd\\sklsr", nullptr, "skelsd\\black", 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"), "tsneak\\tsneak", nullptr, nullptr, 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"), "sneak\\sneak", nullptr, nullptr, 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"), "sneak\\sneak", nullptr, "sneak\\sneakv2", 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"), "sneak\\sneak", nullptr, "sneak\\sneakv3", 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"), "sneak\\sneak", nullptr, "sneak\\sneakv1", 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"), "goatlord\\goatl", "newsfx\\satyr", nullptr, 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"), "goatmace\\goat", nullptr, nullptr, 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"), "goatmace\\goat", nullptr, "goatmace\\beige", 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"), "goatmace\\goat", nullptr, "goatmace\\red", 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"), "goatmace\\goat", nullptr, "goatmace\\gray", 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"), "bat\\bat", nullptr, "bat\\red", 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"), "bat\\bat", nullptr, nullptr, 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"), "bat\\bat", nullptr, "bat\\grey", 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"), "bat\\bat", nullptr, "bat\\orange", 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"), "goatbow\\goatb", nullptr, nullptr, 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"), "goatbow\\goatb", nullptr, "goatbow\\beige", 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"), "goatbow\\goatb", nullptr, "goatbow\\red", 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"), "goatbow\\goatb", nullptr, "goatbow\\gray", 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"), "acid\\acid", nullptr, nullptr, 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"), "acid\\acid", nullptr, "acid\\acidblk", 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"), "acid\\acid", nullptr, "acid\\acidb", 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"), "acid\\acid", nullptr, "acid\\acidr", 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"), "sking\\sking", nullptr, "skelaxe\\white", 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"), "fatc\\fatc", nullptr, nullptr, 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"), "fat\\fat", nullptr, nullptr, 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"), "fat\\fat", nullptr, "fat\\blue", 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"), "fat\\fat", nullptr, "fat\\fatb", 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"), "fat\\fat", nullptr, "fat\\fatf", 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"), "worm\\worm", nullptr, nullptr, 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"), "worm\\worm", nullptr, nullptr, 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"), "worm\\worm", nullptr, nullptr, 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"), "worm\\worm", nullptr, nullptr, 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"), "magma\\magma", nullptr, nullptr, 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"), "magma\\magma", nullptr, "magma\\yellow", 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"), "magma\\magma", nullptr, "magma\\blue", 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"), "magma\\magma", nullptr, "magma\\wierd", 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"), "rhino\\rhino", nullptr, nullptr, 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"), "rhino\\rhino", nullptr, "rhino\\orange", 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"), "rhino\\rhino", nullptr, "rhino\\blue", 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"), "rhino\\rhino", nullptr, "rhino\\rhinob", 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"), "demskel\\demskl", nullptr, nullptr, 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"), "thin\\thin", nullptr, "thin\\thinv3", 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"), "thin\\thin", nullptr, "thin\\thinv3", 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"), "thin\\thin", nullptr, "thin\\thinv3", 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"), "fireman\\firem", nullptr, nullptr, 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"), "fireman\\firem", nullptr, nullptr, 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"), "fireman\\firem", nullptr, nullptr, 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"), "fireman\\firem", nullptr, nullptr, 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"), "thin\\thin", nullptr, "thin\\thinv3", 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"), "thin\\thin", nullptr, nullptr, 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"), "thin\\thin", nullptr, "thin\\thinv2", 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"), "thin\\thin", nullptr, "thin\\thinv1", 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"), "bigfall\\fallg", "newsfx\\kbrute", nullptr, 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"), "gargoyle\\gargo", nullptr, nullptr, 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"), "gargoyle\\gargo", nullptr, "gargoyle\\gare", 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"), "gargoyle\\gargo", nullptr, "gargoyle\\gargbr", 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"), "gargoyle\\gargo", nullptr, "gargoyle\\gargb", 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"), "mega\\mega", nullptr, nullptr, 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"), "mega\\mega", nullptr, "mega\\guard", 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"), "mega\\mega", nullptr, "mega\\vtexl", 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"), "mega\\mega", nullptr, "mega\\balr", 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"), "snake\\snake", nullptr, nullptr, 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"), "snake\\snake", nullptr, "snake\\snakr", 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"), "snake\\snake", nullptr, "snake\\snakg", 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"), "snake\\snake", nullptr, "snake\\snakb", 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"), "black\\black", nullptr, nullptr, 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"), "black\\black", nullptr, "black\\blkkntrt", 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"), "black\\black", nullptr, "black\\blkkntbt", 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"), "black\\black", nullptr, "black\\blkkntbe", 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"), "unrav\\unrav", "newsfx\\shred", nullptr, 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"), "unrav\\unrav", "acid\\acid", nullptr, 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"), "unrav\\unrav", "acid\\acid", nullptr, 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"), "unrav\\unrav", "acid\\acid", nullptr, 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"), "succ\\scbs", nullptr, nullptr, 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"), "succ\\scbs", nullptr, "succ\\succb", 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"), "succ\\scbs", nullptr, "succ\\succrw", 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"), "succ\\scbs", nullptr, "succ\\succbw", 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"), "mage\\mage", nullptr, nullptr, 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"), "mage\\mage", nullptr, "mage\\cnselg", 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"), "mage\\mage", nullptr, "mage\\cnselgd", 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"), "mage\\mage", nullptr, "mage\\cnselbk", 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\\golem", "golem\\golm", nullptr, 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"), "diablo\\diablo", nullptr, nullptr, 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\\dmage", "darkmage\\dmag", nullptr, 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"), "fork\\fork", "newsfx\\hboar", nullptr, 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"), "scorp\\scorp", "newsfx\\stingr", nullptr, 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"), "eye\\eye", "newsfx\\psyco", nullptr, 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"), "spider\\spider", "newsfx\\slord", nullptr, 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"), "tsneak\\tsneak", "newsfx\\ftwin", nullptr, 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"), "spawn\\spawn", "newsfx\\hspawn", nullptr, 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"), "wscorp\\wscorp", "newsfx\\stingr", nullptr, 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"), "eye2\\eye2", "newsfx\\psyco", nullptr, 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"), "bspidr\\bspidr", "newsfx\\slord", nullptr, 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"), "clasp\\clasp", "newsfx\\lworm", nullptr, 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"), "antworm\\worm", "newsfx\\tchant", nullptr, 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"), "horkd\\horkd", "newsfx\\hdemon", nullptr, 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"), "hellbug\\hellbg", "newsfx\\defile", nullptr, 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"), "gravdg\\gravdg", "newsfx\\gdiggr", nullptr, 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"), "rat\\rat", "newsfx\\tmbrat", nullptr, 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"), "hellbat\\helbat", "newsfx\\helbat", nullptr, 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"), "demskel\\demskl", "newsfx\\swing", "skelaxe\\skelt", 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"), "lich\\lich", "newsfx\\lich", nullptr, 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"), "bubba\\bubba", "newsfx\\crypt", nullptr, 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"), "hellbat2\\bhelbt", "newsfx\\helbat", nullptr, 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"), "demskel\\demskl", "newsfx\\swing", nullptr, 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"), "lich2\\lich2", "newsfx\\lich", nullptr, 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"), "byclps\\byclps", "newsfx\\biclop", nullptr, 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"), "flesh\\flesh", "newsfx\\flesht", nullptr, 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"), "reaper\\reap", "newsfx\\reaper", nullptr, 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 }, +/* 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"), "nkr\\nkr", "newsfx\\nakrul", nullptr, 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 }, +/* 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 }; diff --git a/Source/monstdat.h b/Source/monstdat.h index 258744bc9499..acb5bba3910e 100644 --- a/Source/monstdat.h +++ b/Source/monstdat.h @@ -87,11 +87,73 @@ 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 *assetsSuffix; const char *soundSuffix; const char *trnFile; + MonsterSpriteId spriteId; MonsterAvailability availability; uint16_t width; uint16_t image; @@ -129,6 +191,13 @@ struct MonsterData { /** Using monster_treasure */ uint16_t treasure; uint16_t exp; + + [[nodiscard]] const char *spritePath() const; + + [[nodiscard]] const char *soundPath() const + { + return soundSuffix != nullptr ? soundSuffix : spritePath(); + } }; enum _monster_id : int16_t { diff --git a/Source/monster.cpp b/Source/monster.cpp index 521ca058ecec..947c6578e2ad 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -43,6 +43,8 @@ #include "utils/cl2_to_clx.hpp" #include "utils/file_name_generator.hpp" #include "utils/language.h" +#include "utils/log.hpp" +#include "utils/static_vector.hpp" #include "utils/str_cat.hpp" #include "utils/utf8.hpp" @@ -100,12 +102,12 @@ size_t GetNumAnims(const MonsterData &monsterData) void InitMonsterTRN(CMonster &monst) { char path[64]; - *BufCopy(path, "monsters\\", monst.data->trnFile, ".trn") = '\0'; + *BufCopy(path, "monsters\\", monst.data().trnFile, ".trn") = '\0'; std::array colorTranslations; LoadFileInMem(path, colorTranslations); std::replace(colorTranslations.begin(), colorTranslations.end(), 255, 0); - const size_t numAnims = GetNumAnims(*monst.data); + const size_t numAnims = GetNumAnims(monst.data()); for (size_t i = 0; i < numAnims; i++) { if (i == 1 && IsAnyOf(monst.type, MT_COUNSLR, MT_MAGISTR, MT_CABALIST, MT_ADVOCATE)) { continue; @@ -409,8 +411,19 @@ size_t AddMonsterType(_monster_id type, placeflag placeflag) if (typeIndex == LevelMonsterTypeCount) { LevelMonsterTypeCount++; monsterType.type = type; - monstimgtot += MonstersData[type].image; - InitMonsterGFX(monsterType); + const MonsterData &monsterData = MonstersData[type]; + monstimgtot += monsterData.image; + + const size_t numAnims = GetNumAnims(monsterData); + for (size_t i = 0; i < numAnims; ++i) { + AnimStruct &anim = monsterType.anims[i]; + anim.frames = monsterData.frames[i]; + if (monsterData.frames[i] != 0) { + anim.rate = monsterData.rate[i]; + anim.width = monsterData.width; + } + } + InitMonsterSND(monsterType); } @@ -3102,6 +3115,19 @@ bool UpdateModeStance(Monster &monster) } } +MonsterSpritesData LoadMonsterSpritesData(const MonsterData &monsterData) +{ + MonsterSpritesData result; + result.data = MultiFileLoader {}( + GetNumAnims(monsterData), + FileNameWithCharAffixGenerator({ "Monsters\\", monsterData.spritePath() }, ".CL2", Animletter), + result.offsets.data(), + [&monsterData](size_t index) { + return monsterData.frames[index] != 0; + }); + return result; +} + } // namespace void InitTRNForUniqueMonster(Monster &monster) @@ -3321,7 +3347,7 @@ void InitMonsterSND(CMonster &monsterType) }; const MonsterData &data = MonstersData[monsterType.type]; - std::string_view soundSuffix = data.soundSuffix != nullptr ? data.soundSuffix : data.assetsSuffix; + std::string_view soundSuffix = data.soundPath(); for (int i = 0; i < 4; i++) { std::string_view prefix = prefixes[i]; @@ -3336,7 +3362,7 @@ void InitMonsterSND(CMonster &monsterType) } } -void InitMonsterGFX(CMonster &monsterType) +void InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData) { const _monster_id mtype = monsterType.type; const MonsterData &monsterData = MonstersData[mtype]; @@ -3344,14 +3370,10 @@ void InitMonsterGFX(CMonster &monsterType) const auto hasAnim = [&monsterData](size_t index) { return monsterData.frames[index] != 0; }; - constexpr size_t MaxAnims = 6; - std::array animOffsets; if (!HeadlessMode) { - monsterType.animData = MultiFileLoader {}( - numAnims, - FileNameWithCharAffixGenerator({ "monsters\\", monsterData.assetsSuffix }, DEVILUTIONX_CL2_EXT, Animletter), - animOffsets.data(), - hasAnim); + if (spritesData.data == nullptr) + spritesData = LoadMonsterSpritesData(monsterData); + monsterType.animData = std::move(spritesData.data); } #ifndef UNPACKED_MPQS @@ -3362,36 +3384,34 @@ void InitMonsterGFX(CMonster &monsterType) for (size_t i = 0, j = 0; i < numAnims; ++i) { if (!hasAnim(i)) continue; - const uint32_t begin = animOffsets[j]; - const uint32_t end = animOffsets[j + 1]; + const uint32_t begin = spritesData.offsets[j]; + const uint32_t end = spritesData.offsets[j + 1]; clxData.emplace_back(); Cl2ToClx(reinterpret_cast(&monsterType.animData[begin]), end - begin, PointerOrValue { monsterData.width }, clxData.back()); - animOffsets[j] = accumulatedSize; + spritesData.offsets[j] = accumulatedSize; accumulatedSize += clxData.back().size(); ++j; } - animOffsets[clxData.size()] = accumulatedSize; + spritesData.offsets[clxData.size()] = accumulatedSize; monsterType.animData = nullptr; monsterType.animData = std::unique_ptr(new std::byte[accumulatedSize]); for (size_t i = 0; i < clxData.size(); ++i) { - memcpy(&monsterType.animData[animOffsets[i]], clxData[i].data(), clxData[i].size()); + memcpy(&monsterType.animData[spritesData.offsets[i]], clxData[i].data(), clxData[i].size()); } } #endif for (size_t i = 0, j = 0; i < numAnims; ++i) { - AnimStruct &anim = monsterType.anims[i]; - if (!hasAnim(i)) { - anim.frames = 0; + if (!hasAnim(i)) continue; - } + AnimStruct &anim = monsterType.anims[i]; anim.frames = monsterData.frames[i]; anim.rate = monsterData.rate[i]; anim.width = monsterData.width; if (!HeadlessMode) { - const uint32_t begin = animOffsets[j]; - const uint32_t end = animOffsets[j + 1]; + const uint32_t begin = spritesData.offsets[j]; + const uint32_t end = spritesData.offsets[j + 1]; auto spritesData = reinterpret_cast(&monsterType.animData[begin]); const uint16_t numLists = GetNumListsFromClxListOrSheetBuffer(spritesData, end - begin); anim.sprites = ClxSpriteListOrSheet { spritesData, numLists }; @@ -3399,11 +3419,6 @@ void InitMonsterGFX(CMonster &monsterType) ++j; } - monsterType.data = &monsterData; - - if (HeadlessMode) - return; - if (monsterData.trnFile != nullptr) { InitMonsterTRN(monsterType); } @@ -3451,6 +3466,39 @@ void InitMonsterGFX(CMonster &monsterType) GetMissileSpriteData(MissileGraphicID::DiabloApocalypseBoom).LoadGFX(); } +void InitAllMonsterGFX() +{ + if (HeadlessMode) + return; + + using LevelMonsterTypeIndices = StaticVector; + std::array::value> monstersBySprite; + for (size_t i = 0; i < LevelMonsterTypeCount; ++i) { + monstersBySprite[static_cast(LevelMonsterTypes[i].data().spriteId)].emplace_back(i); + } + uint32_t totalUniqueBytes = 0; + uint32_t totalBytes = 0; + for (const LevelMonsterTypeIndices &monsterTypes : monstersBySprite) { + if (monsterTypes.empty()) + continue; + CMonster &firstMonster = LevelMonsterTypes[monsterTypes[0]]; + if (firstMonster.animData != nullptr) + continue; + MonsterSpritesData spritesData = LoadMonsterSpritesData(firstMonster.data()); + const size_t spritesDataSize = spritesData.offsets[GetNumAnims(firstMonster.data())]; + for (size_t i = 1; i < monsterTypes.size(); ++i) { + MonsterSpritesData spritesDataCopy { std::unique_ptr { new std::byte[spritesDataSize] }, spritesData.offsets }; + memcpy(spritesDataCopy.data.get(), spritesData.data.get(), spritesDataSize); + InitMonsterGFX(LevelMonsterTypes[monsterTypes[i]], std::move(spritesDataCopy)); + } + LogVerbose("Loaded monster graphics: {:15s} {:>4d} KiB x{:d}", firstMonster.data().spritePath(), spritesDataSize / 1024, monsterTypes.size()); + totalUniqueBytes += spritesDataSize; + totalBytes += spritesDataSize * monsterTypes.size(); + InitMonsterGFX(firstMonster, std::move(spritesData)); + } + LogVerbose(" Total monster graphics: {:>4d} KiB {:>4d} KiB", totalUniqueBytes / 1024, totalBytes / 1024); +} + void WeakenNaKrul() { if (currlevel != 24 || static_cast(UberDiabloMonsterIndex) >= ActiveMonsterCount) @@ -3530,6 +3578,8 @@ void InitMonsters() DoUnVision(trigs[i].position + Displacement { s, t }, 15); } } + + InitAllMonsterGFX(); } void SetMapMonsters(const uint16_t *dunData, Point startPosition) @@ -4037,6 +4087,7 @@ void FreeMonsters() { for (CMonster &monsterType : LevelMonsterTypes) { monsterType.animData = nullptr; + monsterType.corpseId = 0; for (AnimStruct &animData : monsterType.anims) { animData.sprites = std::nullopt; } @@ -4166,7 +4217,7 @@ void SyncMonsterAnim(Monster &monster) #ifdef _DEBUG // fix for saves with debug monsters having type originally not on the level CMonster &monsterType = LevelMonsterTypes[monster.levelType]; - if (monsterType.data == nullptr) { + if (monsterType.corpseId == 0) { InitMonsterGFX(monsterType); monsterType.corpseId = 1; } diff --git a/Source/monster.h b/Source/monster.h index 1178e011ccf6..71aa358ea230 100644 --- a/Source/monster.h +++ b/Source/monster.h @@ -175,16 +175,26 @@ enum class MonsterSound : uint8_t { Special }; +struct MonsterSpritesData { + static constexpr size_t MaxAnims = 6; + std::unique_ptr data; + std::array offsets; +}; + struct CMonster { std::unique_ptr animData; AnimStruct anims[6]; std::unique_ptr sounds[4][2]; - const MonsterData *data; _monster_id type; /** placeflag enum as a flags*/ uint8_t placeFlags; - int8_t corpseId; + int8_t corpseId = 0; + + const MonsterData &data() const + { + return MonstersData[type]; + } /** * @brief Returns AnimStruct for specified graphic @@ -313,7 +323,7 @@ struct Monster { // note: missing field _mAFNum const MonsterData &data() const { - return *type().data; + return type().data(); } /** @@ -466,7 +476,8 @@ void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t void InitLevelMonsters(); void GetLevelMTypes(); void InitMonsterSND(CMonster &monsterType); -void InitMonsterGFX(CMonster &monsterType); +void InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData = {}); +void InitAllMonsterGFX(); void WeakenNaKrul(); void InitGolems(); void InitMonsters(); diff --git a/Source/pfile.cpp b/Source/pfile.cpp index 6ff84254702b..ebb0f814db5d 100644 --- a/Source/pfile.cpp +++ b/Source/pfile.cpp @@ -287,6 +287,8 @@ void CreateDetailDiffs(std::string_view prefix, std::string_view memoryMapFile, size_t readBytes = SDL_RWsize(handle); std::unique_ptr memoryMapFileData { new std::byte[readBytes] }; SDL_RWread(handle, memoryMapFileData.get(), readBytes, 1); + SDL_RWclose(handle); + const std::string_view buffer(reinterpret_cast(memoryMapFileData.get()), readBytes); std::unordered_map counter; diff --git a/Source/utils/static_vector.hpp b/Source/utils/static_vector.hpp index 58aa5e4f0714..bf89e5ba4116 100644 --- a/Source/utils/static_vector.hpp +++ b/Source/utils/static_vector.hpp @@ -43,6 +43,11 @@ class StaticVector { return size_; } + [[nodiscard]] bool empty() const + { + return size_ == 0; + } + [[nodiscard]] T &back() { return (*this)[size_ - 1];