diff --git a/Source/monster.cpp b/Source/monster.cpp index 4bcb4ee08..605a16d8e 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -1194,41 +1194,35 @@ bool MonsterWalk(Monster &monster, MonsterMode variant) return isAnimationEnd; } -void MonsterAttackMonster(int i, int mid, int hper, int mind, int maxd) +void MonsterAttackMonster(Monster &attacker, Monster &target, int hper, int mind, int maxd) { - assert(static_cast(mid) < MaxMonsters); - auto &monster = Monsters[mid]; - Monster &attackingMonster = Monsters[i]; - - if (!monster.isPossibleToHit()) + if (!target.isPossibleToHit()) return; int hit = GenerateRnd(100); - if (monster.mode == MonsterMode::Petrified) + if (target.mode == MonsterMode::Petrified) hit = 0; - if (monster.tryLiftGargoyle()) + if (target.tryLiftGargoyle()) return; if (hit >= hper) return; int dam = (mind + GenerateRnd(maxd - mind + 1)) << 6; - monster.hitPoints -= dam; - if (monster.hitPoints >> 6 <= 0) { - StartDeathFromMonster(attackingMonster, monster); + target.hitPoints -= dam; + if (target.hitPoints >> 6 <= 0) { + StartDeathFromMonster(attacker, target); } else { - MonsterHitMonster(attackingMonster, monster, dam); + MonsterHitMonster(attacker, target, dam); } - if (monster.activeForTicks == 0) { - monster.activeForTicks = UINT8_MAX; - monster.position.last = attackingMonster.position.tile; + if (target.activeForTicks == 0) { + target.activeForTicks = UINT8_MAX; + target.position.last = attacker.position.tile; } } -void CheckReflect(Monster &monster, int pnum, int dam) +void CheckReflect(Monster &monster, Player &player, int dam) { - Player &player = Players[pnum]; - player.wReflections--; if (player.wReflections <= 0) NetSendCmdParam1(true, CMD_SETREFLECT, 0); @@ -1242,18 +1236,8 @@ void CheckReflect(Monster &monster, int pnum, int dam) M_StartHit(monster, player, mdam); } -void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDam) +void MonsterAttackPlayer(Monster &monster, Player &player, int hit, int minDam, int maxDam) { - assert(static_cast(monsterId) < MaxMonsters); - auto &monster = Monsters[monsterId]; - - if ((monster.flags & MFLAG_TARGETS_MONSTER) != 0) { - MonsterAttackMonster(monsterId, pnum, hit, minDam, maxDam); - return; - } - - Player &player = Players[pnum]; - if (player._pHitPoints >> 6 <= 0 || player._pInvincible || HasAnyOf(player._pSpellFlags, SpellFlag::Etherealize)) return; if (monster.position.tile.WalkingDistance(player.position.tile) >= 2) @@ -1294,7 +1278,7 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa if (&player == MyPlayer && player.wReflections > 0) { int dam = GenerateRnd(((maxDam - minDam) << 6) + 1) + (minDam << 6); dam = std::max(dam + (player._pIGetHit << 6), 64); - CheckReflect(monster, pnum, dam); + CheckReflect(monster, player, dam); } return; } @@ -1316,7 +1300,7 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa dam = std::max(dam + (player._pIGetHit << 6), 64); if (&player == MyPlayer) { if (player.wReflections > 0) - CheckReflect(monster, pnum, dam); + CheckReflect(monster, player, dam); ApplyPlrDamage(player, 0, 0, dam); } @@ -1347,28 +1331,35 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa player.position.tile = newPosition; FixPlayerLocation(player, player._pdir); FixPlrWalkTags(player); - dPlayer[newPosition.x][newPosition.y] = pnum + 1; + dPlayer[newPosition.x][newPosition.y] = player.getId() + 1; SetPlayerOld(player); } } } -bool MonsterAttack(int monsterId) +void MonsterAttackEnemy(Monster &monster, int hit, int minDam, int maxDam) { - assert(static_cast(monsterId) < MaxMonsters); - auto &monster = Monsters[monsterId]; + if ((monster.flags & MFLAG_TARGETS_MONSTER) != 0) + MonsterAttackMonster(monster, Monsters[monster.enemy], monster.toHit, monster.minDamage, monster.maxDamage); + else + MonsterAttackPlayer(monster, Players[monster.enemy], monster.toHit, monster.minDamage, monster.maxDamage); +} +bool MonsterAttack(Monster &monster) +{ if (monster.animInfo.currentFrame == monster.data().animFrameNum - 1) { - MonsterAttackPlayer(monsterId, monster.enemy, monster.toHit, monster.minDamage, monster.maxDamage); + MonsterAttackEnemy(monster, 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.toHit + 10, monster.minDamage - 2, monster.maxDamage - 2); + MonsterAttackEnemy(monster, 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.toHit - 20, monster.minDamage + 4, monster.maxDamage + 4); + MonsterAttackEnemy(monster, monster.toHit - 20, monster.minDamage + 4, monster.maxDamage + 4); + PlayEffect(monster, 0); } if (monster.ai == AI_SNAKE && monster.animInfo.currentFrame == 0) @@ -1412,11 +1403,8 @@ bool MonsterRangedAttack(Monster &monster) return false; } -bool MonsterRangedSpecialAttack(int monsterId) +bool MonsterRangedSpecialAttack(Monster &monster) { - assert(static_cast(monsterId) < MaxMonsters); - auto &monster = Monsters[monsterId]; - if (monster.animInfo.currentFrame == monster.data().animFrameNumSpecial - 1 && monster.animInfo.tickCounterOfCurrentFrame == 0 && (monster.ai != AI_MEGA || monster.var2 == 0)) { if (AddMissile( monster.position.tile, @@ -1424,7 +1412,7 @@ bool MonsterRangedSpecialAttack(int monsterId) monster.direction, static_cast(monster.var1), TARGET_PLAYERS, - monsterId, + monster.getId(), monster.var3, 0) != nullptr) { @@ -1448,13 +1436,11 @@ bool MonsterRangedSpecialAttack(int monsterId) return false; } -bool MonsterSpecialAttack(int monsterId) +bool MonsterSpecialAttack(Monster &monster) { - assert(static_cast(monsterId) < MaxMonsters); - auto &monster = Monsters[monsterId]; - - if (monster.animInfo.currentFrame == monster.data().animFrameNumSpecial - 1) - MonsterAttackPlayer(monsterId, monster.enemy, monster.toHitSpecial, monster.minDamageSpecial, monster.maxDamageSpecial); + if (monster.animInfo.currentFrame == monster.data().animFrameNumSpecial - 1) { + MonsterAttackEnemy(monster, monster.toHitSpecial, monster.minDamageSpecial, monster.maxDamageSpecial); + } if (monster.animInfo.currentFrame == monster.animInfo.numberOfFrames - 1) { M_StartStand(monster, monster.direction); @@ -3253,10 +3239,8 @@ bool IsMonsterAvalible(const MonsterData &monsterData) return currlevel >= monsterData.minDunLvl && currlevel <= monsterData.maxDunLvl; } -bool UpdateModeStance(int monsterId) +bool UpdateModeStance(Monster &monster) { - Monster &monster = Monsters[monsterId]; - switch (monster.mode) { case MonsterMode::Stand: MonsterIdle(monster); @@ -3266,14 +3250,14 @@ bool UpdateModeStance(int monsterId) case MonsterMode::MoveSideways: return MonsterWalk(monster, monster.mode); case MonsterMode::MeleeAttack: - return MonsterAttack(monsterId); + return MonsterAttack(monster); case MonsterMode::HitRecovery: return MonsterGotHit(monster); case MonsterMode::Death: MonsterDeath(monster); return false; case MonsterMode::SpecialMeleeAttack: - return MonsterSpecialAttack(monsterId); + return MonsterSpecialAttack(monster); case MonsterMode::FadeIn: return MonsterFadein(monster); case MonsterMode::FadeOut: @@ -3283,7 +3267,7 @@ bool UpdateModeStance(int monsterId) case MonsterMode::SpecialStand: return MonsterSpecialStand(monster); case MonsterMode::SpecialRangedAttack: - return MonsterRangedSpecialAttack(monsterId); + return MonsterRangedSpecialAttack(monster); case MonsterMode::Delay: return MonsterDelay(monster); case MonsterMode::Petrified: @@ -4203,7 +4187,7 @@ void ProcessMonsters() AiProc[monster.ai](monsterId); } - if (!UpdateModeStance(monsterId)) + if (!UpdateModeStance(monster)) break; GroupUnity(monster); @@ -4558,12 +4542,12 @@ void MissToMonst(Missile &missile, Point position) return; int pnum = dPlayer[oldPosition.x][oldPosition.y] - 1; - MonsterAttackPlayer(monsterId, pnum, 500, monster.minDamageSpecial, monster.maxDamageSpecial); + Player &player = Players[pnum]; + MonsterAttackPlayer(monster, player, 500, monster.minDamageSpecial, monster.maxDamageSpecial); if (IsAnyOf(monster.type().type, MT_NSNAKE, MT_RSNAKE, MT_BSNAKE, MT_GSNAKE)) return; - Player &player = Players[pnum]; if (player._pmode != PM_GOTHIT && player._pmode != PM_DEATH) StartPlrHit(player, 0, true); Point newPosition = oldPosition + monster.direction; @@ -4580,14 +4564,14 @@ void MissToMonst(Missile &missile, Point position) if (dMonster[oldPosition.x][oldPosition.y] <= 0) return; - int mid = dMonster[oldPosition.x][oldPosition.y] - 1; - MonsterAttackMonster(monsterId, mid, 500, monster.minDamageSpecial, monster.maxDamageSpecial); + Monster &target = *MonsterAtPosition(oldPosition); + MonsterAttackMonster(monster, target, 500, monster.minDamageSpecial, monster.maxDamageSpecial); if (IsAnyOf(monster.type().type, MT_NSNAKE, MT_RSNAKE, MT_BSNAKE, MT_GSNAKE)) return; Point newPosition = oldPosition + monster.direction; - if (IsTileAvailable(Monsters[mid], newPosition)) { + if (IsTileAvailable(target, newPosition)) { monsterId = dMonster[oldPosition.x][oldPosition.y]; dMonster[newPosition.x][newPosition.y] = monsterId; dMonster[oldPosition.x][oldPosition.y] = 0;