diff --git a/Source/monster.cpp b/Source/monster.cpp index ad9b976e5..4c32f2293 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -934,9 +934,22 @@ void Teleport(Monster &monster) } } +bool IsHardHit(Monster &target, unsigned dam) +{ + switch (target.type().type) { + case MT_SNEAK: + case MT_STALKER: + case MT_UNSEEN: + case MT_ILLWEAV: + return true; + default: + return (dam >> 6) >= target.level(sgGameInitInfo.nDifficulty) + 3; + } +} + 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(sgGameInitInfo.nDifficulty) + 3) { + if (IsHardHit(target, dam)) { target.direction = Opposite(attacker.direction); } @@ -1820,7 +1833,7 @@ void AiAvoidance(Monster &monster) if (monster.goal == MonsterGoal::Normal) { if (distanceToEnemy >= 2) { if ((monster.var2 > 20 && v < 2 * monster.intelligence + 28) - || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) + || (IsMonsterModeMove(static_cast(monster.var1)) && monster.var2 == 0 && v < 2 * monster.intelligence + 78)) { RandomWalk(monster, md); @@ -1951,7 +1964,9 @@ void AiRangedAvoidance(Monster &monster) } else if (distanceToEnemy >= 2) { v = GenerateRnd(100); if (v < 1000 * (monster.intelligence + 5) - || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) && monster.var2 == 0 && v < 1000 * (monster.intelligence + 8))) { + || (IsMonsterModeMove(static_cast(monster.var1)) + && monster.var2 == 0 + && v < 1000 * (monster.intelligence + 8))) { RandomWalk(monster, md); } } else if (v < 1000 * (monster.intelligence + 6)) { @@ -2005,7 +2020,7 @@ void OverlordAi(Monster &monster) int v = GenerateRnd(100); if (monster.distanceToEnemy() >= 2) { if ((monster.var2 > 20 && v < 4 * monster.intelligence + 20) - || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) + || (IsMonsterModeMove(static_cast(monster.var1)) && monster.var2 == 0 && v < 4 * monster.intelligence + 70)) { RandomWalk(monster, md); @@ -2058,7 +2073,7 @@ void SkeletonBowAi(Monster &monster) if (monster.distanceToEnemy() < 4) { if ((monster.var2 > 20 && v < 2 * monster.intelligence + 13) - || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) + || (IsMonsterModeMove(static_cast(monster.var1)) && monster.var2 == 0 && v < 2 * monster.intelligence + 63)) { walking = Walk(monster, Opposite(md)); @@ -2362,7 +2377,7 @@ void BatAi(Monster &monster) } } else if (distanceToEnemy >= 2) { if ((monster.var2 > 20 && v < monster.intelligence + 13) - || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) + || (IsMonsterModeMove(static_cast(monster.var1)) && monster.var2 == 0 && v < monster.intelligence + 63)) { RandomWalk(monster, md); @@ -2464,7 +2479,10 @@ void SneakAi(Monster &monster) StartFadeout(monster, md, true); } else { if (monster.goal == MonsterGoal::Retreat - || (distanceToEnemy >= 2 && ((monster.var2 > 20 && v < 4 * monster.intelligence + 14) || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) && monster.var2 == 0 && v < 4 * monster.intelligence + 64)))) { + || (distanceToEnemy >= 2 + && ((monster.var2 > 20 && v < 4 * monster.intelligence + 14) + || (IsMonsterModeMove(static_cast(monster.var1)) + && monster.var2 == 0 && v < 4 * monster.intelligence + 64)))) { monster.goalVar1++; RandomWalk(monster, md); } @@ -2743,7 +2761,7 @@ void MegaAi(Monster &monster) } else if (distanceToEnemy >= 2) { v = GenerateRnd(100); if (v < 2 * (5 * monster.intelligence + 25) - || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) + || (IsMonsterModeMove(static_cast(monster.var1)) && monster.var2 == 0 && v < 2 * (5 * monster.intelligence + 40))) { RandomWalk(monster, md); @@ -2925,7 +2943,9 @@ void HorkDemonAi(Monster &monster) } else { v = GenerateRnd(100); if (v < 2 * monster.intelligence + 33 - || (IsAnyOf(static_cast(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) && monster.var2 == 0 && v < 2 * monster.intelligence + 83)) { + || (IsMonsterModeMove(static_cast(monster.var1)) + && monster.var2 == 0 + && v < 2 * monster.intelligence + 83)) { RandomWalk(monster, md); } else { AiDelay(monster, GenerateRnd(10) + 10); @@ -3608,7 +3628,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(sgGameInitInfo.nDifficulty) + 3) { + if (IsHardHit(monster, dam)) { if (monster.type().type == MT_BLINK) { Teleport(monster); } else if (IsAnyOf(monster.type().type, MT_NSCAV, MT_BSCAV, MT_WSCAV, MT_YSCAV, MT_GRAVEDIG)) { @@ -3625,7 +3645,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(sgGameInitInfo.nDifficulty) + 3) { + if (IsHardHit(monster, dam)) { monster.enemy = player.getId(); monster.enemyPosition = player.position.future; monster.flags &= ~MFLAG_TARGETS_MONSTER; diff --git a/Source/monster.h b/Source/monster.h index f9faac1fc..162b47913 100644 --- a/Source/monster.h +++ b/Source/monster.h @@ -92,6 +92,18 @@ enum class MonsterMode : uint8_t { Talk, }; +inline bool IsMonsterModeMove(MonsterMode mode) +{ + switch (mode) { + case MonsterMode::MoveNorthwards: + case MonsterMode::MoveSouthwards: + case MonsterMode::MoveSideways: + return true; + default: + return false; + } +} + enum class MonsterGraphic : uint8_t { Stand, Walk,