Browse Source

Refactor PlaceGroup (#2425)

* Rename MonstPlace -> CanPlaceMonster
* Refactor custom hitpoints and armorclass out of mUnqAttr
* Introduce enum UniqueMonsterPack
pull/2425/merge
obligaron 5 years ago committed by GitHub
parent
commit
d63fcded76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 204
      Source/monstdat.cpp
  2. 28
      Source/monstdat.h
  3. 40
      Source/monster.cpp

204
Source/monstdat.cpp

@ -467,110 +467,110 @@ const char MonstAvailTbl[] = {
/** Contains the data related to each unique monster ID. */
const UniqMonstStruct UniqMonst[] = {
// clang-format off
// mtype, mName, mTrnName, mlevel, mmaxhp, mAi, mint, mMinDamage, mMaxDamage, mMagicRes, mUnqAttr, mUnqVar1, mUnqVar2, mtalkmsg
// mtype, mName, mTrnName, mlevel, mmaxhp, mAi, mint, mMinDamage, mMaxDamage, mMagicRes, monsterPack, customHitpoints, customArmorClass, mtalkmsg
// TRANSLATORS: Unique Monster Block start
{ MT_NGOATMC, N_("Gharbad the Weak"), "BSDB", 4, 120, AI_GARBUD, 3, 8, 16, IMMUNE_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_GARBUD1 },
{ MT_SKING, N_("Skeleton King"), "GENRL", 0, 240, AI_SKELKING, 3, 6, 16, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 1, 0, 0, TEXT_NONE },
{ MT_COUNSLR, N_("Zhar the Mad"), "GENERAL", 8, 360, AI_ZHAR, 3, 16, 40, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , 0, 0, 0, TEXT_ZHAR1 },
{ MT_BFALLSP, N_("Snotspill"), "BNG", 4, 220, AI_SNOTSPIL, 3, 10, 18, RESIST_LIGHTNING , 0, 0, 0, TEXT_BANNER10 },
{ MT_ADVOCATE, N_("Arch-Bishop Lazarus"), "GENERAL", 0, 600, AI_LAZARUS, 3, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_VILE13 },
{ MT_HLSPWN, N_("Red Vex"), "REDV", 0, 400, AI_LAZHELP, 3, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, 0, 0, 0, TEXT_VILE13 },
{ MT_HLSPWN, N_("Black Jade"), "BLKJD", 0, 400, AI_LAZHELP, 3, 30, 50, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_VILE13 },
{ MT_RBLACK, "Lachdanan", "BHKA", 14, 500, AI_LACHDAN, 3, 0, 0, 0 , 0, 0, 0, TEXT_VEIL9 },
{ MT_BTBLACK, N_("Warlord of Blood"), "GENERAL", 13, 850, AI_WARLORD, 3, 35, 50, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_WARLRD9 },
{ MT_CLEAVER, N_("The Butcher"), "GENRL", 0, 220, AI_CLEAVER, 3, 6, 12, RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_HORKDMN, N_("Hork Demon"), "GENRL", 19, 300, AI_HORKDMN, 3, 20, 35, RESIST_LIGHTNING , 0, 0, 0, TEXT_NONE },
{ MT_DEFILER, N_("The Defiler"), "GENRL", 20, 480, AI_SKELSD, 3, 30, 40, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING , 0, 0, 0, TEXT_NONE },
{ MT_NAKRUL, "Na-Krul", "GENRL", 0, 1332, AI_SKELSD, 3, 40, 50, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_TSKELAX, N_("Bonehead Keenaxe"), "BHKA", 2, 91, AI_SKELSD, 2, 4, 10, IMMUNE_MAGIC | IMMUNE_NULL_40, 7, 100, 0, TEXT_NONE },
{ MT_RFALLSD, N_("Bladeskin the Slasher"), "BSTS", 2, 51, AI_FALLEN, 0, 6, 18, RESIST_FIRE , 11, 45, 0, TEXT_NONE },
{ MT_NZOMBIE, N_("Soulpus"), "GENERAL", 2, 133, AI_ZOMBIE, 0, 4, 8, RESIST_FIRE | RESIST_LIGHTNING , 0, 0, 0, TEXT_NONE },
{ MT_RFALLSP, N_("Pukerat the Unclean"), "PTU", 2, 77, AI_FALLEN, 3, 1, 5, RESIST_FIRE , 0, 0, 0, TEXT_NONE },
{ MT_WSKELAX, N_("Boneripper"), "BR", 2, 54, AI_BAT, 0, 6, 15, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_NZOMBIE, N_("Rotfeast the Hungry"), "ETH", 2, 85, AI_SKELSD, 3, 4, 12, IMMUNE_MAGIC | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_DFALLSD, N_("Gutshank the Quick"), "GTQ", 3, 66, AI_BAT, 2, 6, 16, RESIST_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_TSKELSD, N_("Brokenhead Bangshield"), "BHBS", 3, 108, AI_SKELSD, 3, 12, 20, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_YFALLSP, "Bongo", "BNG", 3, 178, AI_FALLEN, 3, 9, 21, 0 , 3, 0, 0, TEXT_NONE },
{ MT_BZOMBIE, N_("Rotcarnage"), "RCRN", 3, 102, AI_ZOMBIE, 3, 9, 24, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, 11, 45, 0, TEXT_NONE },
{ MT_NSCAV, N_("Shadowbite"), "SHBT", 2, 60, AI_SKELSD, 3, 3, 20, IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_WSKELBW, N_("Deadeye"), "DE", 2, 49, AI_GOATBOW, 0, 6, 9, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_RSKELAX, N_("Madeye the Dead"), "MTD", 4, 75, AI_BAT, 0, 9, 21, IMMUNE_MAGIC | IMMUNE_FIRE , 11, 30, 0, TEXT_NONE },
{ MT_BSCAV, "El Chupacabras", "GENERAL", 3, 120, AI_GOATMC, 0, 10, 18, RESIST_FIRE , 3, 30, 0, TEXT_NONE },
{ MT_TSKELBW, N_("Skullfire"), "SKFR", 3, 125, AI_GOATBOW, 1, 6, 10, IMMUNE_FIRE , 0, 100, 0, TEXT_NONE },
{ MT_SNEAK, N_("Warpskull"), "TSPO", 3, 117, AI_SNEAK, 2, 6, 18, RESIST_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_GZOMBIE, N_("Goretongue"), "PMR", 3, 156, AI_SKELSD, 1, 15, 30, IMMUNE_MAGIC | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_WSCAV, N_("Pulsecrawler"), "BHKA", 4, 150, AI_SCAV, 0, 16, 20, IMMUNE_FIRE | RESIST_LIGHTNING , 11, 45, 0, TEXT_NONE },
{ MT_BLINK, N_("Moonbender"), "GENERAL", 4, 135, AI_BAT, 0, 9, 27, IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_BLINK, N_("Wrathraven"), "GENERAL", 5, 135, AI_BAT, 2, 9, 22, IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_YSCAV, N_("Spineeater"), "GENERAL", 4, 180, AI_SCAV, 1, 18, 25, IMMUNE_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_RSKELBW, N_("Blackash the Burning"), "BASHTB", 4, 120, AI_GOATBOW, 0, 6, 16, IMMUNE_MAGIC | IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_BFALLSD, N_("Shadowcrow"), "GENERAL", 5, 270, AI_SNEAK, 2, 12, 25, 0 , 3, 0, 0, TEXT_NONE },
{ MT_LRDSAYTR, N_("Blightstone the Weak"), "BHKA", 4, 360, AI_SKELSD, 0, 4, 12, IMMUNE_MAGIC | RESIST_LIGHTNING , 7, 70, 0, TEXT_NONE },
{ MT_FAT, N_("Bilefroth the Pit Master"), "BFTP", 6, 210, AI_BAT, 1, 16, 23, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_NGOATBW, N_("Bloodskin Darkbow"), "BSDB", 5, 207, AI_GOATBOW, 0, 3, 16, RESIST_FIRE | RESIST_LIGHTNING , 11, 55, 0, TEXT_NONE },
{ MT_GLOOM, N_("Foulwing"), "DB", 5, 246, AI_RHINO, 3, 12, 28, RESIST_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_XSKELSD, N_("Shadowdrinker"), "SHDR", 5, 300, AI_SNEAK, 1, 18, 26, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 8, 45, 0, TEXT_NONE },
{ MT_UNSEEN, N_("Hazeshifter"), "BHKA", 5, 285, AI_SNEAK, 3, 18, 30, IMMUNE_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_NACID, N_("Deathspit"), "BFDS", 6, 303, AI_ACIDUNIQ, 0, 12, 32, RESIST_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_RGOATMC, N_("Bloodgutter"), "BGBL", 6, 315, AI_BAT, 1, 24, 34, IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_BGOATMC, N_("Deathshade Fleshmaul"), "DSFM", 6, 276, AI_RHINO, 0, 12, 24, IMMUNE_MAGIC | RESIST_FIRE , 8, 65, 0, TEXT_NONE },
{ MT_WYRM, N_("Warmaggot the Mad"), "GENERAL", 6, 246, AI_BAT, 3, 15, 30, RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_STORM, N_("Glasskull the Jagged"), "BHKA", 7, 354, AI_STORM, 0, 18, 30, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_RGOATBW, N_("Blightfire"), "BLF", 7, 321, AI_SUCC, 2, 13, 21, IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_GARGOYLE, N_("Nightwing the Cold"), "GENERAL", 7, 342, AI_BAT, 1, 18, 26, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_GGOATBW, N_("Gorestone"), "GENERAL", 7, 303, AI_GOATBOW, 1, 15, 28, RESIST_LIGHTNING | IMMUNE_NULL_40, 7, 70, 0, TEXT_NONE },
{ MT_BMAGMA, N_("Bronzefist Firestone"), "GENERAL", 8, 360, AI_MAGMA, 0, 30, 36, IMMUNE_MAGIC | RESIST_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_INCIN, N_("Wrathfire the Doomed"), "WFTD", 8, 270, AI_SKELSD, 2, 20, 30, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_NMAGMA, N_("Firewound the Grim"), "BHKA", 8, 303, AI_MAGMA, 0, 18, 22, IMMUNE_MAGIC | RESIST_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_MUDMAN, N_("Baron Sludge"), "BSM", 8, 315, AI_SNEAK, 3, 25, 34, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 11, 75, 0, TEXT_NONE },
{ MT_GGOATMC, N_("Blighthorn Steelmace"), "BHSM", 7, 250, AI_RHINO, 0, 20, 28, RESIST_LIGHTNING , 11, 45, 0, TEXT_NONE },
{ MT_RACID, N_("Chaoshowler"), "GENERAL", 8, 240, AI_ACIDUNIQ, 0, 12, 20, 0 , 3, 0, 0, TEXT_NONE },
{ MT_REDDTH, N_("Doomgrin the Rotting"), "GENERAL", 8, 405, AI_STORM, 3, 25, 50, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_FLAMLRD, N_("Madburner"), "GENERAL", 9, 270, AI_STORM, 0, 20, 40, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_LTCHDMN, N_("Bonesaw the Litch"), "GENERAL", 9, 495, AI_STORM, 2, 30, 55, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_MUDRUN, N_("Breakspine"), "GENERAL", 9, 351, AI_RHINO, 0, 25, 34, RESIST_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_REDDTH, N_("Devilskull Sharpbone"), "GENERAL", 9, 444, AI_STORM, 1, 25, 40, IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_STORM, N_("Brokenstorm"), "GENERAL", 9, 411, AI_STORM, 2, 25, 36, IMMUNE_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_RSTORM, N_("Stormbane"), "GENERAL", 9, 555, AI_STORM, 3, 30, 30, IMMUNE_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_TOAD, N_("Oozedrool"), "GENERAL", 9, 483, AI_FAT, 3, 25, 30, RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_BLOODCLW, N_("Goldblight of the Flame"), "GENERAL", 10, 405, AI_GARG, 0, 15, 35, IMMUNE_MAGIC | IMMUNE_FIRE , 11, 80, 0, TEXT_NONE },
{ MT_OBLORD, N_("Blackstorm"), "GENERAL", 10, 525, AI_RHINO, 3, 20, 40, IMMUNE_MAGIC | IMMUNE_LIGHTNING , 11, 90, 0, TEXT_NONE },
{ MT_RACID, N_("Plaguewrath"), "GENERAL", 10, 450, AI_ACIDUNIQ, 2, 20, 30, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_RSTORM, N_("The Flayer"), "GENERAL", 10, 501, AI_STORM, 1, 20, 35, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_FROSTC, N_("Bluehorn"), "GENERAL", 11, 477, AI_RHINO, 1, 25, 30, IMMUNE_MAGIC | RESIST_FIRE , 11, 90, 0, TEXT_NONE },
{ MT_HELLBURN, N_("Warpfire Hellspawn"), "GENERAL", 11, 525, AI_FIREMAN, 3, 10, 40, RESIST_MAGIC | IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_NSNAKE, N_("Fangspeir"), "GENERAL", 11, 444, AI_SKELSD, 1, 15, 32, IMMUNE_FIRE | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_UDEDBLRG, N_("Festerskull"), "GENERAL", 11, 600, AI_STORM, 2, 15, 30, IMMUNE_MAGIC | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_NBLACK, N_("Lionskull the Bent"), "GENERAL", 12, 525, AI_SKELSD, 2, 25, 25, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_COUNSLR, N_("Blacktongue"), "GENERAL", 12, 360, AI_COUNSLR, 3, 15, 30, RESIST_FIRE | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_DEATHW, N_("Viletouch"), "GENERAL", 12, 525, AI_GARG, 3, 20, 40, IMMUNE_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_RSNAKE, N_("Viperflame"), "GENERAL", 12, 570, AI_SKELSD, 1, 25, 35, IMMUNE_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_BSNAKE, N_("Fangskin"), "BHKA", 14, 681, AI_SKELSD, 2, 15, 50, IMMUNE_MAGIC | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_SUCCUBUS, N_("Witchfire the Unholy"), "GENERAL", 12, 444, AI_SUCC, 3, 10, 20, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_BALROG, N_("Blackskull"), "BHKA", 13, 750, AI_SKELSD, 3, 25, 40, IMMUNE_MAGIC | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_UNRAV, N_("Soulslash"), "GENERAL", 12, 450, AI_SKELSD, 0, 25, 25, IMMUNE_MAGIC | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_VTEXLRD, N_("Windspawn"), "GENERAL", 12, 711, AI_SKELSD, 1, 35, 40, IMMUNE_MAGIC | IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_GSNAKE, N_("Lord of the Pit"), "GENERAL", 13, 762, AI_SKELSD, 2, 25, 42, RESIST_FIRE | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_RTBLACK, N_("Rustweaver"), "GENERAL", 13, 400, AI_SKELSD, 3, 1, 60, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_HOLOWONE, N_("Howlingire the Shade"), "GENERAL", 13, 450, AI_SKELSD, 2, 40, 75, RESIST_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_MAEL, N_("Doomcloud"), "GENERAL", 13, 612, AI_STORM, 1, 1, 60, RESIST_FIRE | IMMUNE_LIGHTNING , 0, 0, 0, TEXT_NONE },
{ MT_PAINMSTR, N_("Bloodmoon Soulfire"), "GENERAL", 13, 684, AI_SKELSD, 1, 15, 40, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_SNOWWICH, N_("Witchmoon"), "GENERAL", 13, 310, AI_SUCC, 3, 30, 40, RESIST_LIGHTNING , 0, 0, 0, TEXT_NONE },
{ MT_VTEXLRD, N_("Gorefeast"), "GENERAL", 13, 771, AI_SKELSD, 3, 20, 55, RESIST_FIRE | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_RTBLACK, N_("Graywar the Slayer"), "GENERAL", 14, 672, AI_SKELSD, 1, 30, 50, RESIST_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_MAGISTR, N_("Dreadjudge"), "GENERAL", 14, 540, AI_COUNSLR, 1, 30, 40, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , 3, 0, 0, TEXT_NONE },
{ MT_HLSPWN, N_("Stareye the Witch"), "GENERAL", 14, 726, AI_SUCC, 2, 30, 50, IMMUNE_FIRE , 0, 0, 0, TEXT_NONE },
{ MT_BTBLACK, N_("Steelskull the Hunter"), "GENERAL", 14, 831, AI_SKELSD, 3, 40, 50, RESIST_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_RBLACK, N_("Sir Gorash"), "GENERAL", 16, 1050, AI_SKELSD, 1, 20, 60, IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_CABALIST, N_("The Vizier"), "GENERAL", 15, 850, AI_COUNSLR, 2, 25, 40, IMMUNE_FIRE , 3, 0, 0, TEXT_NONE },
{ MT_REALWEAV, "Zamphir", "GENERAL", 15, 891, AI_SKELSD, 2, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_HLSPWN, N_("Bloodlust"), "GENERAL", 15, 825, AI_SUCC, 1, 20, 55, IMMUNE_MAGIC | IMMUNE_LIGHTNING | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_HLSPWN, "Webwidow", "GENERAL", 16, 774, AI_SUCC, 1, 20, 50, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_SOLBRNR, N_("Fleshdancer"), "GENERAL", 16, 999, AI_SUCC, 3, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, 0, 0, 0, TEXT_NONE },
{ MT_OBLORD, N_("Grimspike"), "GENERAL", 19, 534, AI_SNEAK, 1, 25, 40, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_NGOATMC, N_("Gharbad the Weak"), "BSDB", 4, 120, AI_GARBUD, 3, 8, 16, IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_GARBUD1 },
{ MT_SKING, N_("Skeleton King"), "GENRL", 0, 240, AI_SKELKING, 3, 6, 16, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Independent, 0, 0, TEXT_NONE },
{ MT_COUNSLR, N_("Zhar the Mad"), "GENERAL", 8, 360, AI_ZHAR, 3, 16, 40, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::None, 0, 0, TEXT_ZHAR1 },
{ MT_BFALLSP, N_("Snotspill"), "BNG", 4, 220, AI_SNOTSPIL, 3, 10, 18, RESIST_LIGHTNING , UniqueMonsterPack::None, 0, 0, TEXT_BANNER10 },
{ MT_ADVOCATE, N_("Arch-Bishop Lazarus"), "GENERAL", 0, 600, AI_LAZARUS, 3, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_VILE13 },
{ MT_HLSPWN, N_("Red Vex"), "REDV", 0, 400, AI_LAZHELP, 3, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_VILE13 },
{ MT_HLSPWN, N_("Black Jade"), "BLKJD", 0, 400, AI_LAZHELP, 3, 30, 50, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_VILE13 },
{ MT_RBLACK, "Lachdanan", "BHKA", 14, 500, AI_LACHDAN, 3, 0, 0, 0 , UniqueMonsterPack::None, 0, 0, TEXT_VEIL9 },
{ MT_BTBLACK, N_("Warlord of Blood"), "GENERAL", 13, 850, AI_WARLORD, 3, 35, 50, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_WARLRD9 },
{ MT_CLEAVER, N_("The Butcher"), "GENRL", 0, 220, AI_CLEAVER, 3, 6, 12, RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_HORKDMN, N_("Hork Demon"), "GENRL", 19, 300, AI_HORKDMN, 3, 20, 35, RESIST_LIGHTNING , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_DEFILER, N_("The Defiler"), "GENRL", 20, 480, AI_SKELSD, 3, 30, 40, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_NAKRUL, "Na-Krul", "GENRL", 0, 1332, AI_SKELSD, 3, 40, 50, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_TSKELAX, N_("Bonehead Keenaxe"), "BHKA", 2, 91, AI_SKELSD, 2, 4, 10, IMMUNE_MAGIC | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 100, 0, TEXT_NONE },
{ MT_RFALLSD, N_("Bladeskin the Slasher"), "BSTS", 2, 51, AI_FALLEN, 0, 6, 18, RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 45, TEXT_NONE },
{ MT_NZOMBIE, N_("Soulpus"), "GENERAL", 2, 133, AI_ZOMBIE, 0, 4, 8, RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_RFALLSP, N_("Pukerat the Unclean"), "PTU", 2, 77, AI_FALLEN, 3, 1, 5, RESIST_FIRE , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_WSKELAX, N_("Boneripper"), "BR", 2, 54, AI_BAT, 0, 6, 15, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_NZOMBIE, N_("Rotfeast the Hungry"), "ETH", 2, 85, AI_SKELSD, 3, 4, 12, IMMUNE_MAGIC | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_DFALLSD, N_("Gutshank the Quick"), "GTQ", 3, 66, AI_BAT, 2, 6, 16, RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_TSKELSD, N_("Brokenhead Bangshield"), "BHBS", 3, 108, AI_SKELSD, 3, 12, 20, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_YFALLSP, "Bongo", "BNG", 3, 178, AI_FALLEN, 3, 9, 21, 0 , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_BZOMBIE, N_("Rotcarnage"), "RCRN", 3, 102, AI_ZOMBIE, 3, 9, 24, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 45, TEXT_NONE },
{ MT_NSCAV, N_("Shadowbite"), "SHBT", 2, 60, AI_SKELSD, 3, 3, 20, IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_WSKELBW, N_("Deadeye"), "DE", 2, 49, AI_GOATBOW, 0, 6, 9, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_RSKELAX, N_("Madeye the Dead"), "MTD", 4, 75, AI_BAT, 0, 9, 21, IMMUNE_MAGIC | IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 30, TEXT_NONE },
{ MT_BSCAV, "El Chupacabras", "GENERAL", 3, 120, AI_GOATMC, 0, 10, 18, RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_TSKELBW, N_("Skullfire"), "SKFR", 3, 125, AI_GOATBOW, 1, 6, 10, IMMUNE_FIRE , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_SNEAK, N_("Warpskull"), "TSPO", 3, 117, AI_SNEAK, 2, 6, 18, RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_GZOMBIE, N_("Goretongue"), "PMR", 3, 156, AI_SKELSD, 1, 15, 30, IMMUNE_MAGIC | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_WSCAV, N_("Pulsecrawler"), "BHKA", 4, 150, AI_SCAV, 0, 16, 20, IMMUNE_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 45, TEXT_NONE },
{ MT_BLINK, N_("Moonbender"), "GENERAL", 4, 135, AI_BAT, 0, 9, 27, IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_BLINK, N_("Wrathraven"), "GENERAL", 5, 135, AI_BAT, 2, 9, 22, IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_YSCAV, N_("Spineeater"), "GENERAL", 4, 180, AI_SCAV, 1, 18, 25, IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_RSKELBW, N_("Blackash the Burning"), "BASHTB", 4, 120, AI_GOATBOW, 0, 6, 16, IMMUNE_MAGIC | IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_BFALLSD, N_("Shadowcrow"), "GENERAL", 5, 270, AI_SNEAK, 2, 12, 25, 0 , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_LRDSAYTR, N_("Blightstone the Weak"), "BHKA", 4, 360, AI_SKELSD, 0, 4, 12, IMMUNE_MAGIC | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 70, 0, TEXT_NONE },
{ MT_FAT, N_("Bilefroth the Pit Master"), "BFTP", 6, 210, AI_BAT, 1, 16, 23, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_NGOATBW, N_("Bloodskin Darkbow"), "BSDB", 5, 207, AI_GOATBOW, 0, 3, 16, RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 55, TEXT_NONE },
{ MT_GLOOM, N_("Foulwing"), "DB", 5, 246, AI_RHINO, 3, 12, 28, RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_XSKELSD, N_("Shadowdrinker"), "SHDR", 5, 300, AI_SNEAK, 1, 18, 26, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 45, TEXT_NONE },
{ MT_UNSEEN, N_("Hazeshifter"), "BHKA", 5, 285, AI_SNEAK, 3, 18, 30, IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_NACID, N_("Deathspit"), "BFDS", 6, 303, AI_ACIDUNIQ, 0, 12, 32, RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_RGOATMC, N_("Bloodgutter"), "BGBL", 6, 315, AI_BAT, 1, 24, 34, IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_BGOATMC, N_("Deathshade Fleshmaul"), "DSFM", 6, 276, AI_RHINO, 0, 12, 24, IMMUNE_MAGIC | RESIST_FIRE , UniqueMonsterPack::None, 0, 65, TEXT_NONE },
{ MT_WYRM, N_("Warmaggot the Mad"), "GENERAL", 6, 246, AI_BAT, 3, 15, 30, RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_STORM, N_("Glasskull the Jagged"), "BHKA", 7, 354, AI_STORM, 0, 18, 30, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_RGOATBW, N_("Blightfire"), "BLF", 7, 321, AI_SUCC, 2, 13, 21, IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_GARGOYLE, N_("Nightwing the Cold"), "GENERAL", 7, 342, AI_BAT, 1, 18, 26, IMMUNE_MAGIC | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_GGOATBW, N_("Gorestone"), "GENERAL", 7, 303, AI_GOATBOW, 1, 15, 28, RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 70, 0, TEXT_NONE },
{ MT_BMAGMA, N_("Bronzefist Firestone"), "GENERAL", 8, 360, AI_MAGMA, 0, 30, 36, IMMUNE_MAGIC | RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_INCIN, N_("Wrathfire the Doomed"), "WFTD", 8, 270, AI_SKELSD, 2, 20, 30, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_NMAGMA, N_("Firewound the Grim"), "BHKA", 8, 303, AI_MAGMA, 0, 18, 22, IMMUNE_MAGIC | RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_MUDMAN, N_("Baron Sludge"), "BSM", 8, 315, AI_SNEAK, 3, 25, 34, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 75, TEXT_NONE },
{ MT_GGOATMC, N_("Blighthorn Steelmace"), "BHSM", 7, 250, AI_RHINO, 0, 20, 28, RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 45, TEXT_NONE },
{ MT_RACID, N_("Chaoshowler"), "GENERAL", 8, 240, AI_ACIDUNIQ, 0, 12, 20, 0 , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_REDDTH, N_("Doomgrin the Rotting"), "GENERAL", 8, 405, AI_STORM, 3, 25, 50, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_FLAMLRD, N_("Madburner"), "GENERAL", 9, 270, AI_STORM, 0, 20, 40, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_LTCHDMN, N_("Bonesaw the Litch"), "GENERAL", 9, 495, AI_STORM, 2, 30, 55, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_MUDRUN, N_("Breakspine"), "GENERAL", 9, 351, AI_RHINO, 0, 25, 34, RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_REDDTH, N_("Devilskull Sharpbone"), "GENERAL", 9, 444, AI_STORM, 1, 25, 40, IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_STORM, N_("Brokenstorm"), "GENERAL", 9, 411, AI_STORM, 2, 25, 36, IMMUNE_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_RSTORM, N_("Stormbane"), "GENERAL", 9, 555, AI_STORM, 3, 30, 30, IMMUNE_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_TOAD, N_("Oozedrool"), "GENERAL", 9, 483, AI_FAT, 3, 25, 30, RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_BLOODCLW, N_("Goldblight of the Flame"), "GENERAL", 10, 405, AI_GARG, 0, 15, 35, IMMUNE_MAGIC | IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 80, TEXT_NONE },
{ MT_OBLORD, N_("Blackstorm"), "GENERAL", 10, 525, AI_RHINO, 3, 20, 40, IMMUNE_MAGIC | IMMUNE_LIGHTNING , UniqueMonsterPack::Leashed, 0, 90, TEXT_NONE },
{ MT_RACID, N_("Plaguewrath"), "GENERAL", 10, 450, AI_ACIDUNIQ, 2, 20, 30, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_RSTORM, N_("The Flayer"), "GENERAL", 10, 501, AI_STORM, 1, 20, 35, RESIST_MAGIC | RESIST_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_FROSTC, N_("Bluehorn"), "GENERAL", 11, 477, AI_RHINO, 1, 25, 30, IMMUNE_MAGIC | RESIST_FIRE , UniqueMonsterPack::Leashed, 0, 90, TEXT_NONE },
{ MT_HELLBURN, N_("Warpfire Hellspawn"), "GENERAL", 11, 525, AI_FIREMAN, 3, 10, 40, RESIST_MAGIC | IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_NSNAKE, N_("Fangspeir"), "GENERAL", 11, 444, AI_SKELSD, 1, 15, 32, IMMUNE_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_UDEDBLRG, N_("Festerskull"), "GENERAL", 11, 600, AI_STORM, 2, 15, 30, IMMUNE_MAGIC | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_NBLACK, N_("Lionskull the Bent"), "GENERAL", 12, 525, AI_SKELSD, 2, 25, 25, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_COUNSLR, N_("Blacktongue"), "GENERAL", 12, 360, AI_COUNSLR, 3, 15, 30, RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_DEATHW, N_("Viletouch"), "GENERAL", 12, 525, AI_GARG, 3, 20, 40, IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_RSNAKE, N_("Viperflame"), "GENERAL", 12, 570, AI_SKELSD, 1, 25, 35, IMMUNE_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_BSNAKE, N_("Fangskin"), "BHKA", 14, 681, AI_SKELSD, 2, 15, 50, IMMUNE_MAGIC | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_SUCCUBUS, N_("Witchfire the Unholy"), "GENERAL", 12, 444, AI_SUCC, 3, 10, 20, IMMUNE_MAGIC | IMMUNE_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_BALROG, N_("Blackskull"), "BHKA", 13, 750, AI_SKELSD, 3, 25, 40, IMMUNE_MAGIC | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_UNRAV, N_("Soulslash"), "GENERAL", 12, 450, AI_SKELSD, 0, 25, 25, IMMUNE_MAGIC | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_VTEXLRD, N_("Windspawn"), "GENERAL", 12, 711, AI_SKELSD, 1, 35, 40, IMMUNE_MAGIC | IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_GSNAKE, N_("Lord of the Pit"), "GENERAL", 13, 762, AI_SKELSD, 2, 25, 42, RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_RTBLACK, N_("Rustweaver"), "GENERAL", 13, 400, AI_SKELSD, 3, 1, 60, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_HOLOWONE, N_("Howlingire the Shade"), "GENERAL", 13, 450, AI_SKELSD, 2, 40, 75, RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_MAEL, N_("Doomcloud"), "GENERAL", 13, 612, AI_STORM, 1, 1, 60, RESIST_FIRE | IMMUNE_LIGHTNING , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_PAINMSTR, N_("Bloodmoon Soulfire"), "GENERAL", 13, 684, AI_SKELSD, 1, 15, 40, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_SNOWWICH, N_("Witchmoon"), "GENERAL", 13, 310, AI_SUCC, 3, 30, 40, RESIST_LIGHTNING , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_VTEXLRD, N_("Gorefeast"), "GENERAL", 13, 771, AI_SKELSD, 3, 20, 55, RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_RTBLACK, N_("Graywar the Slayer"), "GENERAL", 14, 672, AI_SKELSD, 1, 30, 50, RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_MAGISTR, N_("Dreadjudge"), "GENERAL", 14, 540, AI_COUNSLR, 1, 30, 40, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_HLSPWN, N_("Stareye the Witch"), "GENERAL", 14, 726, AI_SUCC, 2, 30, 50, IMMUNE_FIRE , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_BTBLACK, N_("Steelskull the Hunter"), "GENERAL", 14, 831, AI_SKELSD, 3, 40, 50, RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_RBLACK, N_("Sir Gorash"), "GENERAL", 16, 1050, AI_SKELSD, 1, 20, 60, IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_CABALIST, N_("The Vizier"), "GENERAL", 15, 850, AI_COUNSLR, 2, 25, 40, IMMUNE_FIRE , UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_REALWEAV, "Zamphir", "GENERAL", 15, 891, AI_SKELSD, 2, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_HLSPWN, N_("Bloodlust"), "GENERAL", 15, 825, AI_SUCC, 1, 20, 55, IMMUNE_MAGIC | IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_HLSPWN, "Webwidow", "GENERAL", 16, 774, AI_SUCC, 1, 20, 50, IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_SOLBRNR, N_("Fleshdancer"), "GENERAL", 16, 999, AI_SUCC, 3, 30, 50, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_NONE },
{ MT_OBLORD, N_("Grimspike"), "GENERAL", 19, 534, AI_SNEAK, 1, 25, 40, IMMUNE_MAGIC | RESIST_FIRE | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
// TRANSLATORS: Unique Monster Block end
{ MT_STORML, N_("Doomlock"), "GENERAL", 28, 534, AI_SNEAK, 1, 35, 55, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, 3, 0, 0, TEXT_NONE },
{ MT_INVALID, nullptr, nullptr, 0, 0, AI_INVALID, 0, 0, 0, 0 , 0, 0, 0, TEXT_NONE },
{ MT_STORML, N_("Doomlock"), "GENERAL", 28, 534, AI_SNEAK, 1, 35, 55, IMMUNE_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::Leashed, 0, 0, TEXT_NONE },
{ MT_INVALID, nullptr, nullptr, 0, 0, AI_INVALID, 0, 0, 0, 0 , UniqueMonsterPack::None, 0, 0, TEXT_NONE },
// clang-format on
};

28
Source/monstdat.h

@ -263,6 +263,24 @@ enum _monster_availability : uint8_t {
MAT_RETAIL,
};
/**
* @brief Defines if and how a group of monsters should be spawned with the unique monster
*/
enum class UniqueMonsterPack {
/**
* @brief Don't spawn a group of monsters with the unique monster
*/
None,
/**
* @brief Spawn a group of monsters that are independent from the unique monster
*/
Independent,
/**
* @brief Spawn a group of monsters that are leashed to the unique monster
*/
Leashed,
};
struct UniqMonstStruct {
_monster_id mtype;
const char *mName;
@ -275,9 +293,13 @@ struct UniqMonstStruct {
uint8_t mMaxDamage;
/** Using monster_resistance as bitflags */
uint16_t mMagicRes;
uint16_t mUnqAttr; // TODO create enum
uint8_t mUnqVar1;
uint8_t mUnqVar2;
/**
* @brief Defines if and how a group of monsters should be spawned with the unique monster
*/
UniqueMonsterPack monsterPack;
uint8_t customHitpoints;
uint8_t customArmorClass;
_speech_id mtalkmsg;
};

40
Source/monster.cpp

@ -267,7 +267,7 @@ void InitMonster(MonsterStruct &monster, Direction rd, int mtype, Point position
}
}
bool MonstPlace(int xp, int yp)
bool CanPlaceMonster(int xp, int yp)
{
char f;
@ -309,7 +309,7 @@ void PlaceMonster(int i, int mtype, int x, int y)
InitMonster(Monsters[i], rd, mtype, { x, y });
}
void PlaceGroup(int mtype, int num, int leaderAttributes, int leaderId)
void PlaceGroup(int mtype, int num, UniqueMonsterPack uniqueMonsterPack, int leaderId)
{
int placed = 0;
@ -325,7 +325,7 @@ void PlaceGroup(int mtype, int num, int leaderAttributes, int leaderId)
int xp;
int yp;
if ((leaderAttributes & 1) != 0) {
if (uniqueMonsterPack != UniqueMonsterPack::None) {
int offset = GenerateRnd(8);
auto position = leader.position.tile + static_cast<Direction>(offset);
xp = position.x;
@ -334,7 +334,7 @@ void PlaceGroup(int mtype, int num, int leaderAttributes, int leaderId)
do {
xp = GenerateRnd(80) + 16;
yp = GenerateRnd(80) + 16;
} while (!MonstPlace(xp, yp));
} while (!CanPlaceMonster(xp, yp));
}
int x1 = xp;
int y1 = yp;
@ -345,21 +345,21 @@ void PlaceGroup(int mtype, int num, int leaderAttributes, int leaderId)
int j = 0;
for (int try2 = 0; j < num && try2 < 100; xp += Displacement::fromDirection(static_cast<Direction>(GenerateRnd(8))).deltaX, yp += Displacement::fromDirection(static_cast<Direction>(GenerateRnd(8))).deltaX) { /// BUGFIX: `yp += Point.y`
if (!MonstPlace(xp, yp)
if (!CanPlaceMonster(xp, yp)
|| (dTransVal[xp][yp] != dTransVal[x1][y1])
|| ((leaderAttributes & 2) != 0 && (abs(xp - x1) >= 4 || abs(yp - y1) >= 4))) {
|| (uniqueMonsterPack == UniqueMonsterPack::Leashed && (abs(xp - x1) >= 4 || abs(yp - y1) >= 4))) {
try2++;
continue;
}
PlaceMonster(ActiveMonsterCount, mtype, xp, yp);
if ((leaderAttributes & 1) != 0) {
if (uniqueMonsterPack != UniqueMonsterPack::None) {
auto &minion = Monsters[ActiveMonsterCount];
minion._mmaxhp *= 2;
minion._mhitpoints = minion._mmaxhp;
minion._mint = leader._mint;
if ((leaderAttributes & 2) != 0) {
if (uniqueMonsterPack == UniqueMonsterPack::Leashed) {
minion.leader = leaderId;
minion.leaderRelation = LeaderRelation::Leashed;
minion._mAi = leader._mAi;
@ -382,7 +382,7 @@ void PlaceGroup(int mtype, int num, int leaderAttributes, int leaderId)
}
}
if ((leaderAttributes & 2) != 0) {
if (uniqueMonsterPack == UniqueMonsterPack::Leashed) {
leader.packsize = placed;
}
}
@ -412,7 +412,7 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
int count2 = 0;
for (int x = xp - 3; x < xp + 3; x++) {
for (int y = yp - 3; y < yp + 3; y++) {
if (y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX && MonstPlace(x, y)) {
if (y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX && CanPlaceMonster(x, y)) {
count2++;
}
}
@ -425,7 +425,7 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
}
}
if (MonstPlace(xp, yp)) {
if (CanPlaceMonster(xp, yp)) {
break;
}
}
@ -576,9 +576,9 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
monster._uniqtrans = uniquetrans++;
if ((uniqueData.mUnqAttr & 4) != 0) {
monster.mHit = uniqueData.mUnqVar1;
monster.mHit2 = uniqueData.mUnqVar1;
if (uniqueData.customHitpoints != 0) {
monster.mHit = uniqueData.customHitpoints;
monster.mHit2 = uniqueData.customHitpoints;
if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
monster.mHit += NIGHTMARE_TO_HIT_BONUS;
@ -588,8 +588,8 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
monster.mHit2 += HELL_TO_HIT_BONUS;
}
}
if ((uniqueData.mUnqAttr & 8) != 0) {
monster.mArmorClass = uniqueData.mUnqVar1;
if (uniqueData.customArmorClass != 0) {
monster.mArmorClass = uniqueData.customArmorClass;
if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
monster.mArmorClass += NIGHTMARE_AC_BONUS;
@ -600,8 +600,8 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
ActiveMonsterCount++;
if ((uniqueData.mUnqAttr & 1) != 0) {
PlaceGroup(miniontype, bosspacksize, uniqueData.mUnqAttr, ActiveMonsterCount - 1);
if (uniqueData.monsterPack != UniqueMonsterPack::None) {
PlaceGroup(miniontype, bosspacksize, uniqueData.monsterPack, ActiveMonsterCount - 1);
}
if (monster._mAi != AI_GARG) {
@ -3987,7 +3987,7 @@ void InitMonsters()
na = GenerateRnd(2) + 2;
else
na = GenerateRnd(3) + 3;
PlaceGroup(mtype, na, 0, 0);
PlaceGroup(mtype, na, UniqueMonsterPack::None, 0);
}
}
for (int i = 0; i < nt; i++) {
@ -4570,7 +4570,7 @@ bool DirOK(int i, Direction mdir)
if (monster.leaderRelation == LeaderRelation::Leashed) {
return futurePosition.WalkingDistance(Monsters[monster.leader].position.future) < 4;
}
if (monster._uniqtype == 0 || (UniqMonst[monster._uniqtype - 1].mUnqAttr & 2) == 0)
if (monster._uniqtype == 0 || UniqMonst[monster._uniqtype - 1].monsterPack == UniqueMonsterPack::Leashed)
return true;
int mcount = 0;
for (int x = futurePosition.x - 3; x <= futurePosition.x + 3; x++) {

Loading…
Cancel
Save