Browse Source

Replace level member with a member function in monster (#5336)

pull/5354/head
Mikołaj Piróg 4 years ago committed by GitHub
parent
commit
5e340d3261
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      Source/items.cpp
  2. 4
      Source/loadsave.cpp
  3. 10
      Source/missiles.cpp
  4. 31
      Source/monster.cpp
  5. 33
      Source/monster.h

4
Source/items.cpp

@ -1323,7 +1323,7 @@ int RndUItem(Monster *monster)
if (AllItemsList[i].iRnd == IDROP_NEVER)
okflag = false;
if (monster != nullptr) {
if (monster->level < AllItemsList[i].iMinMLvl)
if (monster->level(sgGameInitInfo.nDifficulty) < AllItemsList[i].iMinMLvl)
okflag = false;
} else {
if (2 * curlv < AllItemsList[i].iMinMLvl)
@ -3026,7 +3026,7 @@ int RndItem(const Monster &monster)
if ((monsterTreasureFlags & T_NODROP) != 0)
return 0;
return RndItemForMonsterLevel(monster.level);
return RndItemForMonsterLevel(monster.level(sgGameInitInfo.nDifficulty));
}
void SpawnUnique(_unique_items uid, Point position)

4
Source/loadsave.cpp

@ -631,7 +631,7 @@ void LoadMonster(LoadHelper *file, Monster &monster)
monster.corpseId = file->NextLE<int8_t>();
monster.whoHit = file->NextLE<int8_t>();
monster.level = file->NextLE<int8_t>();
file->Skip(1); // Skip level - now calculated on the fly
file->Skip(1); // Alignment
file->Skip(2); // Skip exp - now calculated from monstdat when the monster dies
@ -1397,7 +1397,7 @@ void SaveMonster(SaveHelper *file, Monster &monster)
file->WriteLE<int8_t>(monster.corpseId);
file->WriteLE<int8_t>(monster.whoHit);
file->WriteLE<int8_t>(monster.level);
file->WriteLE<int8_t>(static_cast<int8_t>(monster.level(sgGameInitInfo.nDifficulty)));
file->Skip(1); // Alignment
file->WriteLE<uint16_t>(static_cast<uint16_t>(std::min<unsigned>(std::numeric_limits<uint16_t>::max(), monster.exp(sgGameInitInfo.nDifficulty))));

10
Source/missiles.cpp

@ -198,7 +198,7 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, miss
hper -= player.CalculateArmorPierce(monster.armorClass, false);
hper -= (dist * dist) / 2;
} else {
hper = player.GetMagicToHit() - (monster.level * 2) - dist;
hper = player.GetMagicToHit() - (monster.level(sgGameInitInfo.nDifficulty) * 2) - dist;
}
hper = clamp(hper, 5, 95);
@ -956,14 +956,14 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, missil
int tac = player.GetArmor();
if (monster != nullptr) {
hper = monster->toHit
+ ((monster->level - player._pLevel) * 2)
+ ((monster->level(sgGameInitInfo.nDifficulty) - player._pLevel) * 2)
+ 30
- (dist * 2) - tac;
} else {
hper = 100 - (tac / 2) - (dist * 2);
}
} else if (monster != nullptr) {
hper += (monster->level * 2) - (player._pLevel * 2) - (dist * 2);
hper += (monster->level(sgGameInitInfo.nDifficulty) * 2) - (player._pLevel * 2) - (dist * 2);
}
int minhit = 10;
@ -987,7 +987,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, missil
int blkper = player.GetBlockChance(false);
if (monster != nullptr)
blkper -= (monster->level - player._pLevel) * 2;
blkper -= (monster->level(sgGameInitInfo.nDifficulty) - player._pLevel) * 2;
blkper = clamp(blkper, 0, 100);
int8_t resper;
@ -1955,7 +1955,7 @@ void AddFlash(Missile &missile, const AddMissileParameter & /*parameter*/)
ConsumeSpell(player, SPL_FLASH);
} break;
case MissileSource::Monster:
missile._midam = missile.sourceMonster()->level * 2;
missile._midam = missile.sourceMonster()->level(sgGameInitInfo.nDifficulty) * 2;
break;
case MissileSource::Trap:
missile._midam = currlevel / 2;

31
Source/monster.cpp

@ -130,11 +130,9 @@ void InitMonster(Monster &monster, Direction rd, size_t typeIndex, Point positio
monster.animInfo.tickCounterOfCurrentFrame = GenerateRnd(monster.animInfo.ticksPerFrame - 1);
monster.animInfo.currentFrame = GenerateRnd(monster.animInfo.numberOfFrames - 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;
}
monster.maxHitPoints = maxhp << 6;
@ -183,7 +181,6 @@ void InitMonster(Monster &monster, Direction rd, size_t typeIndex, Point positio
else
monster.maxHitPoints += 64;
monster.hitPoints = monster.maxHitPoints;
monster.level += 15;
monster.toHit += NightmareToHitBonus;
monster.minDamage = 2 * (monster.minDamage + 2);
monster.maxDamage = 2 * (monster.maxDamage + 2);
@ -198,7 +195,6 @@ void InitMonster(Monster &monster, Direction rd, size_t typeIndex, Point positio
else
monster.maxHitPoints += 192;
monster.hitPoints = monster.maxHitPoints;
monster.level += 30;
monster.toHit += HellToHitBonus;
monster.minDamage = 4 * monster.minDamage + 6;
monster.maxDamage = 4 * monster.maxDamage + 6;
@ -943,7 +939,7 @@ void Teleport(Monster &monster)
void MonsterHitMonster(Monster &attacker, Monster &target, int dam)
{
if (IsAnyOf(target.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= target.level + 3) {
if (IsAnyOf(target.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= target.level(sgGameInitInfo.nDifficulty) + 3) {
target.direction = Opposite(attacker.direction);
}
@ -1130,7 +1126,7 @@ void MonsterAttackPlayer(Monster &monster, Player &player, int hit, int minDam,
ac += 40;
if (HasAnyOf(player.pDamAcFlags, ItemSpecialEffectHf::ACAgainstUndead) && monster.data().monsterClass == MonsterClass::Undead)
ac += 20;
hit += 2 * (monster.level - player._pLevel)
hit += 2 * (monster.level(sgGameInitInfo.nDifficulty) - player._pLevel)
+ 30
- ac;
int minhit = 15;
@ -1145,7 +1141,7 @@ void MonsterAttackPlayer(Monster &monster, Player &player, int hit, int minDam,
if ((player._pmode == PM_STAND || player._pmode == PM_ATTACK) && player._pBlockFlag) {
blkper = GenerateRnd(100);
}
int blk = player.GetBlockChance() - (monster.level * 2);
int blk = player.GetBlockChance() - (monster.level(sgGameInitInfo.nDifficulty) * 2);
blk = clamp(blk, 0, 100);
if (hper >= hit)
return;
@ -3098,13 +3094,6 @@ void InitTRNForUniqueMonster(Monster &monster)
void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t minionType, int bosspacksize, const UniqueMonsterData &uniqueMonsterData)
{
monster.uniqueType = monsterType;
if (uniqueMonsterData.mlevel != 0) {
monster.level = 2 * uniqueMonsterData.mlevel;
} else {
monster.level = monster.data().level + 5;
}
monster.maxHitPoints = uniqueMonsterData.mmaxhp << 6;
if (!gbIsMultiplayer)
@ -3142,7 +3131,6 @@ void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t
monster.maxHitPoints += (gbIsMultiplayer ? 100 : 50) << 6;
else
monster.maxHitPoints += 64;
monster.level += 15;
monster.hitPoints = monster.maxHitPoints;
monster.minDamage = 2 * (monster.minDamage + 2);
monster.maxDamage = 2 * (monster.maxDamage + 2);
@ -3154,7 +3142,6 @@ void PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t
monster.maxHitPoints += (gbIsMultiplayer ? 200 : 100) << 6;
else
monster.maxHitPoints += 192;
monster.level += 30;
monster.hitPoints = monster.maxHitPoints;
monster.minDamage = 4 * monster.minDamage + 6;
monster.maxDamage = 4 * monster.maxDamage + 6;
@ -3627,7 +3614,7 @@ void M_StartHit(Monster &monster, int dam)
{
PlayEffect(monster, MonsterSound::Hit);
if (IsAnyOf(monster.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= monster.level + 3) {
if (IsAnyOf(monster.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= monster.level(sgGameInitInfo.nDifficulty) + 3) {
if (monster.type().type == MT_BLINK) {
Teleport(monster);
} else if (IsAnyOf(monster.type().type, MT_NSCAV, MT_BSCAV, MT_WSCAV, MT_YSCAV, MT_GRAVEDIG)) {
@ -3644,7 +3631,7 @@ void M_StartHit(Monster &monster, int dam)
void M_StartHit(Monster &monster, const Player &player, int dam)
{
monster.tag(player);
if (IsAnyOf(monster.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= monster.level + 3) {
if (IsAnyOf(monster.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= monster.level(sgGameInitInfo.nDifficulty) + 3) {
monster.enemy = player.getId();
monster.enemyPosition = player.position.future;
monster.flags &= ~MFLAG_TARGETS_MONSTER;
@ -3657,7 +3644,7 @@ void M_StartHit(Monster &monster, const Player &player, int dam)
void MonsterDeath(Monster &monster, Direction md, bool sendmsg)
{
if (!monster.isPlayerMinion())
AddPlrMonstExper(monster.level, monster.exp(sgGameInitInfo.nDifficulty), monster.whoHit);
AddPlrMonstExper(monster.level(sgGameInitInfo.nDifficulty), monster.exp(sgGameInitInfo.nDifficulty), monster.whoHit);
MonsterKillCounts[monster.type().type]++;
monster.hitPoints = 0;
@ -3933,10 +3920,10 @@ void ProcessMonsters()
monster.aiSeed = AdvanceRndSeed();
}
if ((monster.flags & MFLAG_NOHEAL) == 0 && monster.hitPoints < monster.maxHitPoints && monster.hitPoints >> 6 > 0) {
if (monster.level > 1) {
monster.hitPoints += monster.level / 2;
if (monster.level(sgGameInitInfo.nDifficulty) > 1) {
monster.hitPoints += monster.level(sgGameInitInfo.nDifficulty) / 2;
} else {
monster.hitPoints += monster.level;
monster.hitPoints += monster.level(sgGameInitInfo.nDifficulty);
}
monster.hitPoints = std::min(monster.hitPoints, monster.maxHitPoints); // prevent going over max HP with part of a single regen tick
}

33
Source/monster.h

@ -18,6 +18,7 @@
#include "engine/point.hpp"
#include "engine/sound.h"
#include "engine/world_tile.hpp"
#include "init.h"
#include "monstdat.h"
#include "spelldat.h"
#include "textdat.h"
@ -248,7 +249,6 @@ struct Monster { // note: missing field _mAFNum
uint8_t uniqTrans;
int8_t corpseId;
int8_t whoHit;
int8_t level;
uint8_t minDamage;
uint8_t maxDamage;
uint8_t minDamageSpecial;
@ -340,6 +340,37 @@ struct Monster { // note: missing field _mAFNum
return monsterExp;
}
/**
* @brief Calculates monster's level.
* Fetches base level value from @p MonstersData array or @p UniqueMonstersData.
* @param difficulty - difficulty on which calculation is performed
* @return Monster's level, including bonuses from difficulty and monster being unique
*/
unsigned int level(_difficulty difficulty) const
{
unsigned int baseLevel = data().level;
if (isUnique()) {
baseLevel = UniqueMonstersData[static_cast<int8_t>(uniqueType)].mlevel;
if (baseLevel != 0) {
baseLevel *= 2;
} else {
baseLevel = data().level + 5;
}
}
if (type().type == MT_DIABLO && !gbIsHellfire) {
baseLevel -= 15;
}
if (difficulty == DIFF_NIGHTMARE) {
baseLevel += 15;
} else if (difficulty == DIFF_HELL) {
baseLevel += 30;
}
return baseLevel;
}
/**
* @brief Returns the network identifier for this monster
*

Loading…
Cancel
Save