From 9da76e0003c9a954a45df8333829dbd4cff27be2 Mon Sep 17 00:00:00 2001 From: ephphatha Date: Sat, 31 Dec 2022 23:34:35 +1100 Subject: [PATCH] Update CheckReflect to return applied damage Instead of modifying the damage value by reference --- Source/engine/random.hpp | 24 ++++++++++++++++++++++++ Source/monster.cpp | 13 ++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Source/engine/random.hpp b/Source/engine/random.hpp index 5a629a527..34c01c60f 100644 --- a/Source/engine/random.hpp +++ b/Source/engine/random.hpp @@ -84,4 +84,28 @@ const T PickRandomlyAmong(const std::initializer_list &values) return *(values.begin() + index); } +/** + * @brief Generates a random non-negative integer + * + * Effectively the same as GenerateRnd but will never return a negative value + * @param v upper limit for the return value + * @return a value between 0 and v-1 inclusive, i.e. the range [0, v) + */ +inline int32_t RandomIntLessThan(int32_t v) +{ + return std::max(GenerateRnd(v), 0); +} + +/** + * @brief Randomly chooses a value somewhere within the given range + * @param min lower limit, minumum possible value + * @param max upper limit, either the maximum possible value for a closed range (the default behaviour) or one greater than the maximum value for a half-open range + * @param halfOpen whether to use the limits as a half-open range or not + * @return a randomly selected integer + */ +inline int32_t RandomIntBetween(int32_t min, int32_t max, bool halfOpen = false) +{ + return RandomIntLessThan(max - min + (halfOpen ? 0 : 1)) + min; +} + } // namespace devilution diff --git a/Source/monster.cpp b/Source/monster.cpp index f85c1ba39..8395c5c95 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -1106,19 +1106,20 @@ void MonsterAttackMonster(Monster &attacker, Monster &target, int hper, int mind } } -void CheckReflect(Monster &monster, Player &player, int &dam) +int CheckReflect(Monster &monster, Player &player, int dam) { player.wReflections--; if (player.wReflections <= 0) NetSendCmdParam1(true, CMD_SETREFLECT, 0); // reflects 20-30% damage - int mdam = dam * (GenerateRnd(10) + 20L) / 100; + int mdam = dam * RandomIntBetween(20, 30, true) / 100; ApplyMonsterDamage(monster, mdam); - dam = std::max(dam - mdam, 0); if (monster.hitPoints >> 6 <= 0) M_StartKill(monster, player); else M_StartHit(monster, player, mdam); + + return mdam; } int GetMinHit() @@ -1192,8 +1193,10 @@ void MonsterAttackPlayer(Monster &monster, Player &player, int hit, int minDam, int dam = (minDam << 6) + GenerateRnd(((maxDam - minDam) << 6) + 1); dam = std::max(dam + (player._pIGetHit << 6), 64); if (&player == MyPlayer) { - if (player.wReflections > 0) - CheckReflect(monster, player, dam); + if (player.wReflections > 0) { + int reflectedDamage = CheckReflect(monster, player, dam); + dam = std::max(dam - reflectedDamage, 0); + } ApplyPlrDamage(player, 0, 0, dam); }