Browse Source

Rename MonsterData members (#5000)

pull/5001/head
Mikołaj Piróg 4 years ago committed by GitHub
parent
commit
262fa9ac2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      Source/cursor.cpp
  2. 2
      Source/debug.cpp
  3. 4
      Source/effects.cpp
  4. 14
      Source/items.cpp
  5. 24
      Source/loadsave.cpp
  6. 14
      Source/missiles.cpp
  7. 6
      Source/monstdat.cpp
  8. 69
      Source/monstdat.h
  9. 166
      Source/monster.cpp
  10. 14
      Source/monster.h
  11. 2
      Source/player.cpp
  12. 6
      Source/qol/monhealthbar.cpp

28
Source/cursor.cpp

@ -405,49 +405,49 @@ void CheckCursMove()
if (pcurstemp != -1) {
if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 })) {
int mi = abs(dMonster[mx + 2][my + 1]) - 1;
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 4) != 0) {
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) {
cursPosition = Point { mx, my } + Displacement { 2, 1 };
pcursmonst = mi;
}
}
if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && IsTileLit({ mx + 1, my + 2 })) {
int mi = abs(dMonster[mx + 1][my + 2]) - 1;
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 4) != 0) {
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) {
cursPosition = Point { mx, my } + Displacement { 1, 2 };
pcursmonst = mi;
}
}
if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && IsTileLit({ mx + 2, my + 2 })) {
int mi = abs(dMonster[mx + 2][my + 2]) - 1;
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 4) != 0) {
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) {
cursPosition = Point { mx, my } + Displacement { 2, 2 };
pcursmonst = mi;
}
}
if (mx + 1 < MAXDUNX && !flipflag && dMonster[mx + 1][my] != 0 && IsTileLit({ mx + 1, my })) {
int mi = abs(dMonster[mx + 1][my]) - 1;
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 2) != 0) {
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) {
cursPosition = Point { mx, my } + Displacement { 1, 0 };
pcursmonst = mi;
}
}
if (my + 1 < MAXDUNY && flipflag && dMonster[mx][my + 1] != 0 && IsTileLit({ mx, my + 1 })) {
int mi = abs(dMonster[mx][my + 1]) - 1;
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 2) != 0) {
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) {
cursPosition = Point { mx, my } + Displacement { 0, 1 };
pcursmonst = mi;
}
}
if (dMonster[mx][my] != 0 && IsTileLit({ mx, my })) {
int mi = abs(dMonster[mx][my]) - 1;
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 1) != 0) {
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 1) != 0) {
cursPosition = { mx, my };
pcursmonst = mi;
}
}
if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && IsTileLit({ mx + 1, my + 1 })) {
int mi = abs(dMonster[mx + 1][my + 1]) - 1;
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 2) != 0) {
if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) {
cursPosition = Point { mx, my } + Displacement { 1, 1 };
pcursmonst = mi;
}
@ -465,49 +465,49 @@ void CheckCursMove()
}
if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 })) {
int mi = abs(dMonster[mx + 2][my + 1]) - 1;
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 4) != 0) {
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) {
cursPosition = Point { mx, my } + Displacement { 2, 1 };
pcursmonst = mi;
}
}
if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && IsTileLit({ mx + 1, my + 2 })) {
int mi = abs(dMonster[mx + 1][my + 2]) - 1;
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 4) != 0) {
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) {
cursPosition = Point { mx, my } + Displacement { 1, 2 };
pcursmonst = mi;
}
}
if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && IsTileLit({ mx + 2, my + 2 })) {
int mi = abs(dMonster[mx + 2][my + 2]) - 1;
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 4) != 0) {
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) {
cursPosition = Point { mx, my } + Displacement { 2, 2 };
pcursmonst = mi;
}
}
if (!flipflag && mx + 1 < MAXDUNX && dMonster[mx + 1][my] != 0 && IsTileLit({ mx + 1, my })) {
int mi = abs(dMonster[mx + 1][my]) - 1;
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 2) != 0) {
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) {
cursPosition = Point { mx, my } + Displacement { 1, 0 };
pcursmonst = mi;
}
}
if (flipflag && my + 1 < MAXDUNY && dMonster[mx][my + 1] != 0 && IsTileLit({ mx, my + 1 })) {
int mi = abs(dMonster[mx][my + 1]) - 1;
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 2) != 0) {
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) {
cursPosition = Point { mx, my } + Displacement { 0, 1 };
pcursmonst = mi;
}
}
if (dMonster[mx][my] != 0 && IsTileLit({ mx, my })) {
int mi = abs(dMonster[mx][my]) - 1;
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 1) != 0) {
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 1) != 0) {
cursPosition = { mx, my };
pcursmonst = mi;
}
}
if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && IsTileLit({ mx + 1, my + 1 })) {
int mi = abs(dMonster[mx + 1][my + 1]) - 1;
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().mSelFlag & 2) != 0) {
if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) {
cursPosition = Point { mx, my } + Displacement { 1, 1 };
pcursmonst = mi;
}

2
Source/debug.cpp

@ -767,7 +767,7 @@ std::string DebugCmdSpawnMonster(const string_view parameter)
for (int i = 0; i < NUM_MTYPES; i++) {
auto mondata = MonstersData[i];
std::string monsterName(mondata.mName);
std::string monsterName(mondata.name);
std::transform(monsterName.begin(), monsterName.end(), monsterName.begin(), [](unsigned char c) { return std::tolower(c); });
if (monsterName.find(name) == std::string::npos)
continue;

4
Source/effects.cpp

@ -1220,10 +1220,10 @@ void InitMonsterSND(size_t monst)
const int mtype = LevelMonsterTypes[monst].type;
const MonsterData &data = MonstersData[mtype];
for (int i = 0; i < 4; i++) {
if (MonstSndChar[i] != 's' || data.snd_special) {
if (MonstSndChar[i] != 's' || data.hasSpecialSound) {
for (int j = 0; j < 2; j++) {
char path[MAX_PATH];
const char *sndfile = data.sndfile != nullptr ? data.sndfile : data.GraphicType;
const char *sndfile = data.soundSuffix != nullptr ? data.soundSuffix : data.assetsSuffix;
*BufCopy(path, "Monsters\\", sndfile, string_view(&MonstSndChar[i], 1), j + 1, ".WAV") = '\0';
LevelMonsterTypes[monst].sounds[i][j] = sound_file_load(path);
}

14
Source/items.cpp

@ -1333,8 +1333,8 @@ void GetItemBonus(Item &item, int minlvl, int maxlvl, bool onlygood, bool allows
int RndUItem(Monster *monster)
{
if (monster != nullptr && (monster->data().mTreasure & T_UNIQ) != 0 && !gbIsMultiplayer)
return -((monster->data().mTreasure & T_MASK) + 1);
if (monster != nullptr && (monster->data().treasure & T_UNIQ) != 0 && !gbIsMultiplayer)
return -((monster->data().treasure & T_MASK) + 1);
int ril[512];
@ -3011,10 +3011,10 @@ void SetupItem(Item &item)
int RndItem(const Monster &monster)
{
if ((monster.data().mTreasure & T_UNIQ) != 0)
return -((monster.data().mTreasure & T_MASK) + 1);
if ((monster.data().treasure & T_UNIQ) != 0)
return -((monster.data().treasure & T_MASK) + 1);
if ((monster.data().mTreasure & T_NODROP) != 0)
if ((monster.data().treasure & T_NODROP) != 0)
return 0;
if (GenerateRnd(100) > 40)
@ -3074,7 +3074,7 @@ void SpawnItem(Monster &monster, Point position, bool sendmsg)
int idx;
bool onlygood = true;
if (monster.isUnique() || ((monster.data().mTreasure & T_UNIQ) != 0 && gbIsMultiplayer)) {
if (monster.isUnique() || ((monster.data().treasure & T_UNIQ) != 0 && gbIsMultiplayer)) {
idx = RndUItem(&monster);
if (idx < 0) {
SpawnUnique((_unique_items) - (idx + 1), position);
@ -3105,7 +3105,7 @@ void SpawnItem(Monster &monster, Point position, bool sendmsg)
GetSuperItemSpace(position, ii);
int uper = monster.isUnique() ? 15 : 1;
int8_t mLevel = monster.data().mLevel;
int8_t mLevel = monster.data().level;
if (!gbIsHellfire && monster.type().type == MT_DIABLO)
mLevel -= 15;

24
Source/loadsave.cpp

@ -642,17 +642,17 @@ void LoadMonster(LoadHelper *file, Monster &monster)
monster.exp = file->NextLE<uint16_t>();
if ((monster.flags & MFLAG_GOLEM) != 0) // Don't skip for golems
monster.hit = file->NextLE<uint8_t>();
monster.toHit = file->NextLE<uint8_t>();
else
file->Skip(1); // Skip hit as it's already initialized
monster.minDamage = file->NextLE<uint8_t>();
monster.maxDamage = file->NextLE<uint8_t>();
file->Skip(1); // Skip hit2 as it's already initialized
monster.minDamage2 = file->NextLE<uint8_t>();
monster.maxDamage2 = file->NextLE<uint8_t>();
file->Skip(1); // Skip toHitSpecial as it's already initialized
monster.minDamageSpecial = file->NextLE<uint8_t>();
monster.maxDamageSpecial = file->NextLE<uint8_t>();
monster.armorClass = file->NextLE<uint8_t>();
file->Skip(1); // Alignment
monster.magicResistance = file->NextLE<uint16_t>();
monster.resistance = file->NextLE<uint16_t>();
file->Skip(2); // Alignment
monster.talkMsg = static_cast<_speech_id>(file->NextLE<int32_t>());
@ -667,7 +667,7 @@ void LoadMonster(LoadHelper *file, Monster &monster)
if (monster.lightId == 0)
monster.lightId = NO_LIGHT; // Correct incorect values in old saves
// Omit pointer mName;
// Omit pointer name;
if (gbSkipSync)
return;
@ -1391,15 +1391,15 @@ void SaveMonster(SaveHelper *file, Monster &monster)
file->Skip(1); // Alignment
file->WriteLE<uint16_t>(monster.exp);
file->WriteLE<uint8_t>(static_cast<uint8_t>(std::min<uint16_t>(monster.hit, std::numeric_limits<uint8_t>::max()))); // For backwards compatibility
file->WriteLE<uint8_t>(static_cast<uint8_t>(std::min<uint16_t>(monster.toHit, std::numeric_limits<uint8_t>::max()))); // For backwards compatibility
file->WriteLE<uint8_t>(monster.minDamage);
file->WriteLE<uint8_t>(monster.maxDamage);
file->WriteLE<uint8_t>(static_cast<uint8_t>(std::min<uint16_t>(monster.hit2, std::numeric_limits<uint8_t>::max()))); // For backwards compatibility
file->WriteLE<uint8_t>(monster.minDamage2);
file->WriteLE<uint8_t>(monster.maxDamage2);
file->WriteLE<uint8_t>(static_cast<uint8_t>(std::min<uint16_t>(monster.toHitSpecial, std::numeric_limits<uint8_t>::max()))); // For backwards compatibility
file->WriteLE<uint8_t>(monster.minDamageSpecial);
file->WriteLE<uint8_t>(monster.maxDamageSpecial);
file->WriteLE<uint8_t>(monster.armorClass);
file->Skip(1); // Alignment
file->WriteLE<uint16_t>(monster.magicResistance);
file->WriteLE<uint16_t>(monster.resistance);
file->Skip(2); // Alignment
file->WriteLE<int32_t>(monster.talkMsg == TEXT_NONE ? 0 : monster.talkMsg); // Replicate original bad mapping of none for monsters
@ -1412,7 +1412,7 @@ void SaveMonster(SaveHelper *file, Monster &monster)
else
file->WriteLE<int8_t>(monster.lightId);
// Omit pointer mName;
// Omit pointer name;
}
void SaveMissile(SaveHelper *file, const Missile &missile)

14
Source/missiles.cpp

@ -229,7 +229,7 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, miss
dam += player._pDamageMod;
else
dam += player._pDamageMod / 2;
if (monster.data().mMonstClass == MonsterClass::Demon && HasAnyOf(player._pIFlags, ItemSpecialEffect::TripleDemonDamage))
if (monster.data().monsterClass == MonsterClass::Demon && HasAnyOf(player._pIFlags, ItemSpecialEffect::TripleDemonDamage))
dam *= 3;
}
bool resist = monster.isResistant(t);
@ -910,7 +910,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, missil
if (MissilesData[mtype].mType == 0) {
int tac = player.GetArmor();
if (monster != nullptr) {
hper = monster->hit
hper = monster->toHit
+ ((monster->level - player._pLevel) * 2)
+ 30
- (dist * 2) - tac;
@ -1147,9 +1147,9 @@ void AddBerserk(Missile &missile, const AddMissileParameter &parameter)
return false;
if (IsAnyOf(monster.mode, MonsterMode::FadeIn, MonsterMode::FadeOut, MonsterMode::Charge))
return false;
if ((monster.magicResistance & IMMUNE_MAGIC) != 0)
if ((monster.resistance & IMMUNE_MAGIC) != 0)
return false;
if ((monster.magicResistance & RESIST_MAGIC) != 0 && ((monster.magicResistance & RESIST_MAGIC) != 1 || !FlipCoin()))
if ((monster.resistance & RESIST_MAGIC) != 0 && ((monster.resistance & RESIST_MAGIC) != 1 || !FlipCoin()))
return false;
return true;
@ -1163,8 +1163,8 @@ void AddBerserk(Missile &missile, const AddMissileParameter &parameter)
monster.flags |= MFLAG_BERSERK | MFLAG_GOLEM;
monster.minDamage = (GenerateRnd(10) + 120) * monster.minDamage / 100 + slvl;
monster.maxDamage = (GenerateRnd(10) + 120) * monster.maxDamage / 100 + slvl;
monster.minDamage2 = (GenerateRnd(10) + 120) * monster.minDamage2 / 100 + slvl;
monster.maxDamage2 = (GenerateRnd(10) + 120) * monster.maxDamage2 / 100 + slvl;
monster.minDamageSpecial = (GenerateRnd(10) + 120) * monster.minDamageSpecial / 100 + slvl;
monster.maxDamageSpecial = (GenerateRnd(10) + 120) * monster.maxDamageSpecial / 100 + slvl;
int lightRadius = leveltype == DTYPE_NEST ? 9 : 3;
monster.lightId = AddLight(monster.position.tile, lightRadius);
UseMana(player, SPL_BERSERK);
@ -3459,7 +3459,7 @@ void MI_Acidsplat(Missile &missile)
if (missile._mirange == 0) {
missile._miDelFlag = true;
int monst = missile._misource;
int dam = (Monsters[monst].data().mLevel >= 2 ? 2 : 1);
int dam = (Monsters[monst].data().level >= 2 ? 2 : 1);
AddMissile(missile.position.tile, { 0, 0 }, Direction::South, MIS_ACIDPUD, TARGET_PLAYERS, monst, dam, missile._mispllvl);
} else {
PutMissile(missile);

6
Source/monstdat.cpp

@ -14,7 +14,7 @@ namespace devilution {
namespace {
// Returns an `mTreasure` value for the given item.
// Returns a `treasure` value for the given item.
constexpr uint16_t Uniq(_unique_items item)
{
return static_cast<uint16_t>(T_UNIQ) + item;
@ -25,7 +25,7 @@ constexpr uint16_t Uniq(_unique_items item)
/** Contains the data related to each monster ID. */
const MonsterData MonstersData[] = {
// clang-format off
// _monster_id name, GraphicType, sndfile, TransFile, availability, width, mImage, has_special, snd_special, Frames[6], rate[6], mMinDLvl, mMaxDLvl, level, mMinHP, mMaxHP, mAi, mFlags , mInt, hit, mAFNum, minDamage, maxDamage, hit2, mAFNum2, minDamage2, maxDamage2, armorClass, mMonstClass , magicResistance , mMagicRes2 , mSelFlag, mTreasure, exp
// _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
// 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, AI_ZOMBIE, 0 , 0, 10, 8, 2, 5, 0, 0, 0, 0, 5, MonsterClass::Undead, IMMUNE_MAGIC | IMMUNE_NULL_40 , IMMUNE_MAGIC | IMMUNE_NULL_40 , 3, 0, 54 },
@ -336,7 +336,7 @@ const _monster_id MonstConvTbl[] = {
/** Contains the data related to each unique monster ID. */
const UniqueMonsterData UniqueMonstersData[] = {
// clang-format off
// type, name, mTrnName, mlevel, mmaxhp, mAi, mint, minDamage, maxDamage, magicResistance, monsterPack, customToHit, customArmorClass, talkMsg
// type, name, mTrnName, mlevel, mmaxhp, ai, mint, minDamage, maxDamage, resistance, monsterPack, customToHit, customArmorClass, talkMsg
// TRANSLATORS: Unique Monster Block start
{ MT_NGOATMC, P_("monster", "Gharbad the Weak"), "BSDB", 4, 120, AI_GARBUD, 3, 8, 16, IMMUNE_LIGHTNING | IMMUNE_NULL_40, UniqueMonsterPack::None, 0, 0, TEXT_GARBUD1 },
{ MT_SKING, P_("monster", "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 },

69
Source/monstdat.h

@ -89,44 +89,47 @@ enum class MonsterAvailability : uint8_t {
};
struct MonsterData {
const char *mName;
const char *GraphicType;
const char *sndfile;
const char *TransFile;
const char *name;
const char *assetsSuffix;
const char *soundSuffix;
const char *trnFile;
MonsterAvailability availability;
uint16_t width;
uint16_t mImage;
bool has_special;
bool snd_special;
int8_t Frames[6];
int8_t Rate[6];
int8_t mMinDLvl;
int8_t mMaxDLvl;
int8_t mLevel;
uint16_t mMinHP;
uint16_t mMaxHP;
_mai_id mAi;
/** Usign monster_flag as bitflags */
uint16_t mFlags;
uint8_t mInt;
uint8_t mHit;
int8_t mAFNum;
uint8_t mMinDamage;
uint8_t mMaxDamage;
uint8_t mHit2;
int8_t mAFNum2;
uint8_t mMinDamage2;
uint8_t mMaxDamage2;
uint8_t mArmorClass;
MonsterClass mMonstClass;
uint16_t image;
bool hasSpecial;
bool hasSpecialSound;
int8_t frames[6];
int8_t rate[6];
int8_t minDunLvl;
int8_t maxDunLvl;
int8_t level;
uint16_t hitPointsMinimum;
uint16_t hitPointsMaximum;
_mai_id ai;
/**
* @brief Denotes monster's abilities defined in @p monster_flag as bitflags
* For usage, see @p MonstersData in monstdat.cpp
*/
uint16_t abilityFlags;
uint8_t intelligence;
uint8_t toHit;
int8_t animFrameNum;
uint8_t minDamage;
uint8_t maxDamage;
uint8_t toHitSpecial;
int8_t animFrameNumSpecial;
uint8_t minDamageSpecial;
uint8_t maxDamageSpecial;
uint8_t armorClass;
MonsterClass monsterClass;
/** Using monster_resistance as bitflags */
uint8_t mMagicRes;
uint8_t resistance;
/** Using monster_resistance as bitflags */
uint8_t mMagicRes2;
int8_t mSelFlag; // TODO Create enum
uint8_t resistanceHell;
int8_t selectionType; // TODO Create enum
/** Using monster_treasure */
uint16_t mTreasure;
uint16_t mExp;
uint16_t treasure;
uint16_t exp;
};
enum _monster_id : int16_t {

166
Source/monster.cpp

@ -154,7 +154,7 @@ constexpr char Animletter[7] = "nwahds";
size_t GetNumAnims(const MonsterData &monsterData)
{
return monsterData.has_special ? 6 : 5;
return monsterData.hasSpecial ? 6 : 5;
}
bool IsDirectionalAnim(const CMonster &monster, size_t animIndex)
@ -166,7 +166,7 @@ void InitMonsterTRN(CMonster &monst)
{
char path[MAX_PATH];
std::array<uint8_t, 256> colorTranslations;
*BufCopy(path, "Monsters\\", monst.data->TransFile, ".TRN") = '\0';
*BufCopy(path, "Monsters\\", monst.data->trnFile, ".TRN") = '\0';
LoadFileInMem(path, colorTranslations);
std::replace(colorTranslations.begin(), colorTranslations.end(), 255, 0);
@ -205,8 +205,8 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
monster.animInfo.tickCounterOfCurrentFrame = GenerateRnd(monster.animInfo.ticksPerFrame - 1);
monster.animInfo.currentFrame = GenerateRnd(monster.animInfo.numberOfFrames - 1);
monster.level = monster.data().mLevel;
int maxhp = monster.data().mMinHP + GenerateRnd(monster.data().mMaxHP - monster.data().mMinHP + 1);
monster.level = monster.data().level;
int maxhp = monster.data().hitPointsMinimum + GenerateRnd(monster.data().hitPointsMaximum - monster.data().hitPointsMinimum + 1);
if (monster.type().type == MT_DIABLO && !gbIsHellfire) {
maxhp /= 2;
monster.level -= 15;
@ -217,8 +217,8 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
monster.maxHitPoints = std::max(monster.maxHitPoints / 2, 64);
monster.hitPoints = monster.maxHitPoints;
monster.ai = monster.data().mAi;
monster.intelligence = monster.data().mInt;
monster.ai = monster.data().ai;
monster.intelligence = monster.data().intelligence;
monster.goal = MonsterGoal::Normal;
monster.goalVar1 = 0;
monster.goalVar2 = 0;
@ -231,18 +231,18 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
monster.rndItemSeed = AdvanceRndSeed();
monster.aiSeed = AdvanceRndSeed();
monster.whoHit = 0;
monster.exp = monster.data().mExp;
monster.hit = monster.data().mHit;
monster.minDamage = monster.data().mMinDamage;
monster.maxDamage = monster.data().mMaxDamage;
monster.hit2 = monster.data().mHit2;
monster.minDamage2 = monster.data().mMinDamage2;
monster.maxDamage2 = monster.data().mMaxDamage2;
monster.armorClass = monster.data().mArmorClass;
monster.magicResistance = monster.data().mMagicRes;
monster.exp = monster.data().exp;
monster.toHit = monster.data().toHit;
monster.minDamage = monster.data().minDamage;
monster.maxDamage = monster.data().maxDamage;
monster.toHitSpecial = monster.data().toHitSpecial;
monster.minDamageSpecial = monster.data().minDamageSpecial;
monster.maxDamageSpecial = monster.data().maxDamageSpecial;
monster.armorClass = monster.data().armorClass;
monster.resistance = monster.data().resistance;
monster.leader = Monster::NoLeader;
monster.leaderRelation = LeaderRelation::None;
monster.flags = monster.data().mFlags;
monster.flags = monster.data().abilityFlags;
monster.talkMsg = TEXT_NONE;
if (monster.ai == AI_GARG) {
@ -261,12 +261,12 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
monster.hitPoints = monster.maxHitPoints;
monster.level += 15;
monster.exp = 2 * (monster.exp + 1000);
monster.hit += NightmareToHitBonus;
monster.toHit += NightmareToHitBonus;
monster.minDamage = 2 * (monster.minDamage + 2);
monster.maxDamage = 2 * (monster.maxDamage + 2);
monster.hit2 += NightmareToHitBonus;
monster.minDamage2 = 2 * (monster.minDamage2 + 2);
monster.maxDamage2 = 2 * (monster.maxDamage2 + 2);
monster.toHitSpecial += NightmareToHitBonus;
monster.minDamageSpecial = 2 * (monster.minDamageSpecial + 2);
monster.maxDamageSpecial = 2 * (monster.maxDamageSpecial + 2);
monster.armorClass += NightmareAcBonus;
} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
monster.maxHitPoints = 4 * monster.maxHitPoints;
@ -277,14 +277,14 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
monster.hitPoints = monster.maxHitPoints;
monster.level += 30;
monster.exp = 4 * (monster.exp + 1000);
monster.hit += HellToHitBonus;
monster.toHit += HellToHitBonus;
monster.minDamage = 4 * monster.minDamage + 6;
monster.maxDamage = 4 * monster.maxDamage + 6;
monster.hit2 += HellToHitBonus;
monster.minDamage2 = 4 * monster.minDamage2 + 6;
monster.maxDamage2 = 4 * monster.maxDamage2 + 6;
monster.toHitSpecial += HellToHitBonus;
monster.minDamageSpecial = 4 * monster.minDamageSpecial + 6;
monster.maxDamageSpecial = 4 * monster.maxDamageSpecial + 6;
monster.armorClass += HellAcBonus;
monster.magicResistance = monster.data().mMagicRes2;
monster.resistance = monster.data().resistanceHell;
}
}
@ -499,7 +499,7 @@ size_t AddMonsterType(_monster_id type, placeflag placeflag)
if (typeIndex == LevelMonsterTypeCount) {
LevelMonsterTypeCount++;
LevelMonsterTypes[typeIndex].type = type;
monstimgtot += MonstersData[type].mImage;
monstimgtot += MonstersData[type].image;
InitMonsterGFX(typeIndex);
InitMonsterSND(typeIndex);
}
@ -910,7 +910,7 @@ void StartRangedSpecialAttack(Monster &monster, missile_id missileType, int dam)
Direction md = GetMonsterDirection(monster);
int8_t distributeFramesBeforeFrame = 0;
if (monster.ai == AI_MEGA)
distributeFramesBeforeFrame = monster.data().mAFNum2;
distributeFramesBeforeFrame = monster.data().animFrameNumSpecial;
NewMonsterAnim(monster, MonsterGraphic::Special, md, AnimationDistributionFlags::ProcessAnimationPending, 0, distributeFramesBeforeFrame);
monster.mode = MonsterMode::SpecialRangedAttack;
monster.var1 = missileType;
@ -1326,9 +1326,9 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa
hper = 1000;
#endif
int ac = player.GetArmor();
if (HasAnyOf(player.pDamAcFlags, ItemSpecialEffectHf::ACAgainstDemons) && monster.data().mMonstClass == MonsterClass::Demon)
if (HasAnyOf(player.pDamAcFlags, ItemSpecialEffectHf::ACAgainstDemons) && monster.data().monsterClass == MonsterClass::Demon)
ac += 40;
if (HasAnyOf(player.pDamAcFlags, ItemSpecialEffectHf::ACAgainstUndead) && monster.data().mMonstClass == MonsterClass::Undead)
if (HasAnyOf(player.pDamAcFlags, ItemSpecialEffectHf::ACAgainstUndead) && monster.data().monsterClass == MonsterClass::Undead)
ac += 20;
hit += 2 * (monster.level - player._pLevel)
+ 30
@ -1419,17 +1419,17 @@ bool MonsterAttack(int monsterId)
assert(static_cast<size_t>(monsterId) < MaxMonsters);
auto &monster = Monsters[monsterId];
if (monster.animInfo.currentFrame == monster.data().mAFNum - 1) {
MonsterAttackPlayer(monsterId, monster.enemy, monster.hit, monster.minDamage, monster.maxDamage);
if (monster.animInfo.currentFrame == monster.data().animFrameNum - 1) {
MonsterAttackPlayer(monsterId, monster.enemy, monster.toHit, monster.minDamage, monster.maxDamage);
if (monster.ai != AI_SNAKE)
PlayEffect(monster, 0);
}
if (IsAnyOf(monster.type().type, MT_NMAGMA, MT_YMAGMA, MT_BMAGMA, MT_WMAGMA) && monster.animInfo.currentFrame == 8) {
MonsterAttackPlayer(monsterId, monster.enemy, monster.hit + 10, monster.minDamage - 2, monster.maxDamage - 2);
MonsterAttackPlayer(monsterId, monster.enemy, monster.toHit + 10, monster.minDamage - 2, monster.maxDamage - 2);
PlayEffect(monster, 0);
}
if (IsAnyOf(monster.type().type, MT_STORM, MT_RSTORM, MT_STORML, MT_MAEL) && monster.animInfo.currentFrame == 12) {
MonsterAttackPlayer(monsterId, monster.enemy, monster.hit - 20, monster.minDamage + 4, monster.maxDamage + 4);
MonsterAttackPlayer(monsterId, monster.enemy, monster.toHit - 20, monster.minDamage + 4, monster.maxDamage + 4);
PlayEffect(monster, 0);
}
if (monster.ai == AI_SNAKE && monster.animInfo.currentFrame == 0)
@ -1444,7 +1444,7 @@ bool MonsterAttack(int monsterId)
bool MonsterRangedAttack(Monster &monster)
{
if (monster.animInfo.currentFrame == monster.data().mAFNum - 1) {
if (monster.animInfo.currentFrame == monster.data().animFrameNum - 1) {
const auto &missileType = static_cast<missile_id>(monster.var1);
if (missileType != MIS_NULL) {
int multimissiles = 1;
@ -1478,7 +1478,7 @@ bool MonsterRangedSpecialAttack(int monsterId)
assert(static_cast<size_t>(monsterId) < MaxMonsters);
auto &monster = Monsters[monsterId];
if (monster.animInfo.currentFrame == monster.data().mAFNum2 - 1 && monster.animInfo.tickCounterOfCurrentFrame == 0 && (monster.ai != AI_MEGA || monster.var2 == 0)) {
if (monster.animInfo.currentFrame == monster.data().animFrameNumSpecial - 1 && monster.animInfo.tickCounterOfCurrentFrame == 0 && (monster.ai != AI_MEGA || monster.var2 == 0)) {
if (AddMissile(
monster.position.tile,
monster.enemyPosition,
@ -1493,7 +1493,7 @@ bool MonsterRangedSpecialAttack(int monsterId)
}
}
if (monster.ai == AI_MEGA && monster.animInfo.currentFrame == monster.data().mAFNum2 - 1) {
if (monster.ai == AI_MEGA && monster.animInfo.currentFrame == monster.data().animFrameNumSpecial - 1) {
if (monster.var2++ == 0) {
monster.flags |= MFLAG_ALLOW_SPECIAL;
} else if (monster.var2 == 15) {
@ -1514,8 +1514,8 @@ bool MonsterSpecialAttack(int monsterId)
assert(static_cast<size_t>(monsterId) < MaxMonsters);
auto &monster = Monsters[monsterId];
if (monster.animInfo.currentFrame == monster.data().mAFNum2 - 1)
MonsterAttackPlayer(monsterId, monster.enemy, monster.hit2, monster.minDamage2, monster.maxDamage2);
if (monster.animInfo.currentFrame == monster.data().animFrameNumSpecial - 1)
MonsterAttackPlayer(monsterId, monster.enemy, monster.toHitSpecial, monster.minDamageSpecial, monster.maxDamageSpecial);
if (monster.animInfo.currentFrame == monster.animInfo.numberOfFrames - 1) {
M_StartStand(monster, monster.direction);
@ -1704,7 +1704,7 @@ void MonsterDeath(Monster &monster)
bool MonsterSpecialStand(Monster &monster)
{
if (monster.animInfo.currentFrame == monster.data().mAFNum2 - 1)
if (monster.animInfo.currentFrame == monster.data().animFrameNumSpecial - 1)
PlayEffect(monster, 3);
if (monster.animInfo.currentFrame == monster.animInfo.numberOfFrames - 1) {
@ -1877,8 +1877,8 @@ bool IsTileSafe(const Monster &monster, Point position)
return true;
}
bool fearsFire = (monster.magicResistance & IMMUNE_FIRE) == 0 || monster.type().type == MT_DIABLO;
bool fearsLightning = (monster.magicResistance & IMMUNE_LIGHTNING) == 0 || monster.type().type == MT_DIABLO;
bool fearsFire = (monster.resistance & IMMUNE_FIRE) == 0 || monster.type().type == MT_DIABLO;
bool fearsLightning = (monster.resistance & IMMUNE_LIGHTNING) == 0 || monster.type().type == MT_DIABLO;
for (auto &missile : Missiles) {
if (missile.position.tile == position) {
@ -2358,7 +2358,7 @@ void ScavengerAi(int monsterId)
StartEating(monster);
if ((monster.flags & MFLAG_NOHEAL) == 0) {
if (gbIsHellfire) {
int mMaxHP = monster.maxHitPoints; // BUGFIX use maxHitPoints or we loose health when difficulty isn't normal (fixed)
int mMaxHP = monster.maxHitPoints; // BUGFIX use hitPointsMaximum or we loose health when difficulty isn't normal (fixed)
monster.hitPoints += mMaxHP / 8;
if (monster.hitPoints > monster.maxHitPoints)
monster.hitPoints = monster.maxHitPoints;
@ -2432,7 +2432,7 @@ void RhinoAi(int monsterId)
&& v < 2 * monster.intelligence + 43
&& LineClear([&monster](Point position) { return IsTileAvailable(monster, position); }, monster.position.tile, monster.enemyPosition)) {
if (AddMissile(monster.position.tile, monster.enemyPosition, md, MIS_RHINO, TARGET_PLAYERS, monsterId, 0, 0) != nullptr) {
if (monster.data().snd_special)
if (monster.data().hasSpecialSound)
PlayEffect(monster, 3);
dMonster[monster.position.tile.x][monster.position.tile.y] = -(monsterId + 1);
monster.mode = MonsterMode::Charge;
@ -3231,7 +3231,7 @@ void HorkDemonAi(int monsterId)
string_view GetMonsterTypeText(const MonsterData &monsterData)
{
switch (monsterData.mMonstClass) {
switch (monsterData.monsterClass) {
case MonsterClass::Animal:
return _("Animal");
case MonsterClass::Demon:
@ -3240,7 +3240,7 @@ string_view GetMonsterTypeText(const MonsterData &monsterData)
return _("Undead");
}
app_fatal(StrCat("Unknown mMonstClass ", static_cast<int>(monsterData.mMonstClass)));
app_fatal(StrCat("Unknown monsterClass ", static_cast<int>(monsterData.monsterClass)));
}
void ActivateSpawn(Monster &monster, Point position, Direction dir)
@ -3324,7 +3324,7 @@ bool IsMonsterAvalible(const MonsterData &monsterData)
if (gbIsSpawn && monsterData.availability == MonsterAvailability::Retail)
return false;
return currlevel >= monsterData.mMinDLvl && currlevel <= monsterData.mMaxDLvl;
return currlevel >= monsterData.minDunLvl && currlevel <= monsterData.maxDunLvl;
}
bool UpdateModeStance(int monsterId)
@ -3390,7 +3390,7 @@ void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, int min
if (uniqueMonsterData.mlevel != 0) {
monster.level = 2 * uniqueMonsterData.mlevel;
} else {
monster.level = monster.data().mLevel + 5;
monster.level = monster.data().level + 5;
}
monster.exp *= 2;
@ -3404,9 +3404,9 @@ void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, int min
monster.intelligence = uniqueMonsterData.mint;
monster.minDamage = uniqueMonsterData.mMinDamage;
monster.maxDamage = uniqueMonsterData.mMaxDamage;
monster.minDamage2 = uniqueMonsterData.mMinDamage;
monster.maxDamage2 = uniqueMonsterData.mMaxDamage;
monster.magicResistance = uniqueMonsterData.mMagicRes;
monster.minDamageSpecial = uniqueMonsterData.mMinDamage;
monster.maxDamageSpecial = uniqueMonsterData.mMaxDamage;
monster.resistance = uniqueMonsterData.mMagicRes;
monster.talkMsg = uniqueMonsterData.mtalkmsg;
if (monsterType == UniqueMonsterType::HorkDemon)
monster.lightId = NO_LIGHT; // BUGFIX monsters initial light id should be -1 (fixed)
@ -3436,8 +3436,8 @@ void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, int min
monster.exp = 2 * (monster.exp + 1000);
monster.minDamage = 2 * (monster.minDamage + 2);
monster.maxDamage = 2 * (monster.maxDamage + 2);
monster.minDamage2 = 2 * (monster.minDamage2 + 2);
monster.maxDamage2 = 2 * (monster.maxDamage2 + 2);
monster.minDamageSpecial = 2 * (monster.minDamageSpecial + 2);
monster.maxDamageSpecial = 2 * (monster.maxDamageSpecial + 2);
} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
monster.maxHitPoints = 4 * monster.maxHitPoints;
if (gbIsHellfire)
@ -3449,23 +3449,23 @@ void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, int min
monster.exp = 4 * (monster.exp + 1000);
monster.minDamage = 4 * monster.minDamage + 6;
monster.maxDamage = 4 * monster.maxDamage + 6;
monster.minDamage2 = 4 * monster.minDamage2 + 6;
monster.maxDamage2 = 4 * monster.maxDamage2 + 6;
monster.minDamageSpecial = 4 * monster.minDamageSpecial + 6;
monster.maxDamageSpecial = 4 * monster.maxDamageSpecial + 6;
}
InitTRNForUniqueMonster(monster);
monster.uniqTrans = uniquetrans++;
if (uniqueMonsterData.customToHit != 0) {
monster.hit = uniqueMonsterData.customToHit;
monster.hit2 = uniqueMonsterData.customToHit;
monster.toHit = uniqueMonsterData.customToHit;
monster.toHitSpecial = uniqueMonsterData.customToHit;
if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
monster.hit += NightmareToHitBonus;
monster.hit2 += NightmareToHitBonus;
monster.toHit += NightmareToHitBonus;
monster.toHitSpecial += NightmareToHitBonus;
} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
monster.hit += HellToHitBonus;
monster.hit2 += HellToHitBonus;
monster.toHit += HellToHitBonus;
monster.toHitSpecial += HellToHitBonus;
}
}
if (uniqueMonsterData.customArmorClass != 0) {
@ -3574,7 +3574,7 @@ void GetLevelMTypes()
while (nt > 0 && LevelMonsterTypeCount < MaxLvlMTypes && monstimgtot < 4000) {
for (int i = 0; i < nt;) {
if (MonstersData[typelist[i]].mImage > 4000 - monstimgtot) {
if (MonstersData[typelist[i]].image > 4000 - monstimgtot) {
typelist[i] = typelist[--nt];
continue;
}
@ -3605,14 +3605,14 @@ void InitMonsterGFX(size_t monsterTypeIndex)
const size_t numAnims = GetNumAnims(monsterData);
const auto hasAnim = [&monsterData](size_t i) {
return monsterData.Frames[i] != 0;
return monsterData.frames[i] != 0;
};
std::array<uint32_t, MaxAnims> animOffsets;
if (!HeadlessMode) {
monster.animData = MultiFileLoader<MaxAnims> {}(
numAnims,
FileNameWithCharAffixGenerator({ "Monsters\\", monsterData.GraphicType }, ".CL2", Animletter),
FileNameWithCharAffixGenerator({ "Monsters\\", monsterData.assetsSuffix }, ".CL2", Animletter),
animOffsets.data(),
hasAnim);
}
@ -3625,8 +3625,8 @@ void InitMonsterGFX(size_t monsterTypeIndex)
continue;
}
anim.frames = monsterData.Frames[animIndex];
anim.rate = monsterData.Rate[animIndex];
anim.frames = monsterData.frames[animIndex];
anim.rate = monsterData.rate[animIndex];
anim.width = width;
if (HeadlessMode)
@ -3647,7 +3647,7 @@ void InitMonsterGFX(size_t monsterTypeIndex)
if (HeadlessMode)
return;
if (monsterData.TransFile != nullptr) {
if (monsterData.trnFile != nullptr) {
InitMonsterTRN(monster);
}
@ -3704,7 +3704,7 @@ void WeakenNaKrul()
Quests[Q_NAKRUL]._qlog = false;
monster.armorClass -= 50;
int hp = monster.maxHitPoints / 2;
monster.magicResistance = 0;
monster.resistance = 0;
monster.hitPoints = hp;
monster.maxHitPoints = hp;
}
@ -4421,7 +4421,7 @@ void M_FallenFear(Point position)
if (monster.ai != AI_FALLEN || monster.hitPoints >> 6 <= 0)
continue;
int runDistance = std::max((8 - monster.data().mLevel), 2);
int runDistance = std::max((8 - monster.data().level), 2);
monster.goal = MonsterGoal::Retreat;
monster.goalVar1 = runDistance;
monster.goalVar2 = static_cast<int>(GetDirection(position, monster.position.tile));
@ -4437,8 +4437,8 @@ void PrintMonstHistory(int mt)
}
if (MonsterKillCounts[mt] >= 30) {
int minHP = MonstersData[mt].mMinHP;
int maxHP = MonstersData[mt].mMaxHP;
int minHP = MonstersData[mt].hitPointsMinimum;
int maxHP = MonstersData[mt].hitPointsMaximum;
if (!gbIsHellfire && mt == MT_DIABLO) {
minHP /= 2;
maxHP /= 2;
@ -4468,7 +4468,7 @@ void PrintMonstHistory(int mt)
AddPanelString(fmt::format(fmt::runtime(_("Hit Points: {:d}-{:d}")), minHP, maxHP));
}
if (MonsterKillCounts[mt] >= 15) {
int res = (sgGameInitInfo.nDifficulty != DIFF_HELL) ? MonstersData[mt].mMagicRes : MonstersData[mt].mMagicRes2;
int res = (sgGameInitInfo.nDifficulty != DIFF_HELL) ? MonstersData[mt].resistance : MonstersData[mt].resistanceHell;
if ((res & (RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING)) == 0) {
AddPanelString(_("No magic resistance"));
} else {
@ -4503,7 +4503,7 @@ void PrintUniqueHistory()
AddPanelString(fmt::format(fmt::runtime(_("Type: {:s}")), GetMonsterTypeText(monster.data())));
}
int res = monster.magicResistance & (RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING);
int res = monster.resistance & (RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING);
if (res == 0) {
AddPanelString(_("No resistances"));
AddPanelString(_("No Immunities"));
@ -4570,7 +4570,7 @@ void MissToMonst(Missile &missile, Point position)
return;
int pnum = dPlayer[oldPosition.x][oldPosition.y] - 1;
MonsterAttackPlayer(monsterId, pnum, 500, monster.minDamage2, monster.maxDamage2);
MonsterAttackPlayer(monsterId, pnum, 500, monster.minDamageSpecial, monster.maxDamageSpecial);
if (IsAnyOf(monster.type().type, MT_NSNAKE, MT_RSNAKE, MT_BSNAKE, MT_GSNAKE))
return;
@ -4593,7 +4593,7 @@ void MissToMonst(Missile &missile, Point position)
return;
int mid = dMonster[oldPosition.x][oldPosition.y] - 1;
MonsterAttackMonster(monsterId, mid, 500, monster.minDamage2, monster.maxDamage2);
MonsterAttackMonster(monsterId, mid, 500, monster.minDamageSpecial, monster.maxDamageSpecial);
if (IsAnyOf(monster.type().type, MT_NSNAKE, MT_RSNAKE, MT_BSNAKE, MT_GSNAKE))
return;
@ -4743,7 +4743,7 @@ void SpawnGolem(int id, Point position, Missile &missile)
golem.maxHitPoints = 2 * (320 * missile._mispllvl + player._pMaxMana / 3);
golem.hitPoints = golem.maxHitPoints;
golem.armorClass = 25;
golem.hit = 5 * (missile._mispllvl + 8) + 2 * player._pLevel;
golem.toHit = 5 * (missile._mispllvl + 8) + 2 * player._pLevel;
golem.minDamage = 2 * (missile._mispllvl + 4);
golem.maxDamage = 2 * (missile._mispllvl + 8);
golem.flags |= MFLAG_GOLEM;
@ -4852,12 +4852,12 @@ bool Monster::isImmune(missile_id missileType) const
{
missile_resistance missileElement = MissilesData[missileType].mResist;
if (((magicResistance & IMMUNE_MAGIC) != 0 && missileElement == MISR_MAGIC)
|| ((magicResistance & IMMUNE_FIRE) != 0 && missileElement == MISR_FIRE)
|| ((magicResistance & IMMUNE_LIGHTNING) != 0 && missileElement == MISR_LIGHTNING)
|| ((magicResistance & IMMUNE_ACID) != 0 && missileElement == MISR_ACID))
if (((resistance & IMMUNE_MAGIC) != 0 && missileElement == MISR_MAGIC)
|| ((resistance & IMMUNE_FIRE) != 0 && missileElement == MISR_FIRE)
|| ((resistance & IMMUNE_LIGHTNING) != 0 && missileElement == MISR_LIGHTNING)
|| ((resistance & IMMUNE_ACID) != 0 && missileElement == MISR_ACID))
return true;
if (missileType == MIS_HBOLT && type().type != MT_DIABLO && data().mMonstClass != MonsterClass::Undead)
if (missileType == MIS_HBOLT && type().type != MT_DIABLO && data().monsterClass != MonsterClass::Undead)
return true;
return false;
}
@ -4866,9 +4866,9 @@ bool Monster::isResistant(missile_id missileType) const
{
missile_resistance missileElement = MissilesData[missileType].mResist;
if (((magicResistance & RESIST_MAGIC) != 0 && missileElement == MISR_MAGIC)
|| ((magicResistance & RESIST_FIRE) != 0 && missileElement == MISR_FIRE)
|| ((magicResistance & RESIST_LIGHTNING) != 0 && missileElement == MISR_LIGHTNING))
if (((resistance & RESIST_MAGIC) != 0 && missileElement == MISR_MAGIC)
|| ((resistance & RESIST_FIRE) != 0 && missileElement == MISR_FIRE)
|| ((resistance & RESIST_LIGHTNING) != 0 && missileElement == MISR_LIGHTNING))
return true;
if (gbIsHellfire && missileType == MIS_HBOLT && IsAnyOf(type().type, MT_DIABLO, MT_BONEDEMN))
return true;

14
Source/monster.h

@ -200,9 +200,9 @@ struct Monster { // note: missing field _mAFNum
/** Seed used to determine AI behaviour/sync sounds in multiplayer games? */
uint32_t aiSeed;
uint16_t exp;
uint16_t hit;
uint16_t hit2;
uint16_t magicResistance;
uint16_t toHit;
uint16_t toHitSpecial;
uint16_t resistance;
_speech_id talkMsg;
ActorPosition position;
@ -232,8 +232,8 @@ struct Monster { // note: missing field _mAFNum
int8_t level;
uint8_t minDamage;
uint8_t maxDamage;
uint8_t minDamage2;
uint8_t maxDamage2;
uint8_t minDamageSpecial;
uint8_t maxDamageSpecial;
uint8_t armorClass;
uint8_t leader;
LeaderRelation leaderRelation;
@ -251,7 +251,7 @@ struct Monster { // note: missing field _mAFNum
{
auto &animationData = type().getAnimData(graphic);
// Passing the Frames and rate properties here is only relevant when initialising a monster, but doesn't cause any harm when switching animations.
// Passing the frames and rate properties here is only relevant when initialising a monster, but doesn't cause any harm when switching animations.
this->animInfo.changeAnimationData(animationData.getCelSpritesForDirection(desiredDirection), animationData.frames, animationData.rate);
}
@ -295,7 +295,7 @@ struct Monster { // note: missing field _mAFNum
if (uniqueType != UniqueMonsterType::None)
return pgettext("monster", UniqueMonstersData[static_cast<int8_t>(uniqueType)].mName);
return pgettext("monster", data().mName);
return pgettext("monster", data().name);
}
/**

2
Source/player.cpp

@ -849,7 +849,7 @@ bool PlrHitMonst(int pnum, size_t monsterId, bool adjacentDamage = false)
phanditype = ItemType::Mace;
}
switch (monster.data().mMonstClass) {
switch (monster.data().monsterClass) {
case MonsterClass::Undead:
if (phanditype == ItemType::Sword) {
dam -= dam / 2;

6
Source/qol/monhealthbar.cpp

@ -123,7 +123,7 @@ void DrawMonsterHealthBar(const Surface &out)
};
if (*sgOptions.Gameplay.showMonsterType) {
Uint8 borderColor = getBorderColor(monster.data().mMonstClass);
Uint8 borderColor = getBorderColor(monster.data().monsterClass);
int borderWidth = width - (border * 2);
UnsafeDrawHorizontalLine(out, { position.x + border, position.y + border }, borderWidth, borderColor);
UnsafeDrawHorizontalLine(out, { position.x + border, position.y + height - border - 1 }, borderWidth, borderColor);
@ -150,10 +150,10 @@ void DrawMonsterHealthBar(const Surface &out)
int resOffset = 5;
for (int i = 0; i < 3; i++) {
if ((monster.magicResistance & immunes[i]) != 0) {
if ((monster.resistance & immunes[i]) != 0) {
DrawArt(out, position + Displacement { resOffset, height - 6 }, &resistance, i * 2 + 1);
resOffset += resistance.w() + 2;
} else if ((monster.magicResistance & resists[i]) != 0) {
} else if ((monster.resistance & resists[i]) != 0) {
DrawArt(out, position + Displacement { resOffset, height - 6 }, &resistance, i * 2);
resOffset += resistance.w() + 2;
}

Loading…
Cancel
Save