From 8bf05571a10f702c7d4359505b88f91cf9ea56aa Mon Sep 17 00:00:00 2001 From: ephphatha Date: Sat, 8 Jan 2022 14:00:15 +1100 Subject: [PATCH] Dedupe code which determines how much life/mana to restore for potions This is very similar to the code used when casting heal other, except for how the amount to heal is chosen. Could potentially reuse it there as well with a bit of work. --- Source/items.cpp | 90 +++++++++++++++++------------------------------ Source/player.cpp | 26 ++++++++++++++ Source/player.h | 38 ++++++++++++++++++++ 3 files changed, 96 insertions(+), 58 deletions(-) diff --git a/Source/items.cpp b/Source/items.cpp index f27b3a722..9d68e3c78 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -4064,39 +4064,27 @@ void UseItem(int pnum, item_misc_id mid, spell_id spl) switch (mid) { case IMISC_HEAL: - case IMISC_FOOD: { - int j = player._pMaxHP >> 8; - int l = ((j / 2) + GenerateRnd(j)) << 6; - if (IsAnyOf(player._pClass, HeroClass::Warrior, HeroClass::Barbarian)) - l *= 2; - if (IsAnyOf(player._pClass, HeroClass::Rogue, HeroClass::Monk, HeroClass::Bard)) - l += l / 2; - player._pHitPoints = std::min(player._pHitPoints + l, player._pMaxHP); - player._pHPBase = std::min(player._pHPBase + l, player._pMaxHPBase); - drawhpflag = true; - } break; + case IMISC_FOOD: + player.RestorePartialLife(); + if (&player == MyPlayer) { + drawhpflag = true; + } + break; case IMISC_FULLHEAL: - player._pHitPoints = player._pMaxHP; - player._pHPBase = player._pMaxHPBase; - drawhpflag = true; + player.RestoreFullLife(); + if (&player == MyPlayer) { + drawhpflag = true; + } break; - case IMISC_MANA: { - int j = player._pMaxMana >> 8; - int l = ((j / 2) + GenerateRnd(j)) << 6; - if (player._pClass == HeroClass::Sorcerer) - l *= 2; - if (IsAnyOf(player._pClass, HeroClass::Rogue, HeroClass::Monk, HeroClass::Bard)) - l += l / 2; - if ((player._pIFlags & ISPL_NOMANA) == 0) { - player._pMana = std::min(player._pMana + l, player._pMaxMana); - player._pManaBase = std::min(player._pManaBase + l, player._pMaxManaBase); + case IMISC_MANA: + player.RestorePartialMana(); + if (&player == MyPlayer) { drawmanaflag = true; } - } break; + break; case IMISC_FULLMANA: - if ((player._pIFlags & ISPL_NOMANA) == 0) { - player._pMana = player._pMaxMana; - player._pManaBase = player._pMaxManaBase; + player.RestoreFullMana(); + if (&player == MyPlayer) { drawmanaflag = true; } break; @@ -4106,9 +4094,10 @@ void UseItem(int pnum, item_misc_id mid, spell_id spl) case IMISC_ELIXMAG: ModifyPlrMag(pnum, 1); if (gbIsHellfire) { - player._pMana = player._pMaxMana; - player._pManaBase = player._pMaxManaBase; - drawmanaflag = true; + player.RestoreFullMana(); + if (&player == MyPlayer) { + drawmanaflag = true; + } } break; case IMISC_ELIXDEX: @@ -4117,40 +4106,25 @@ void UseItem(int pnum, item_misc_id mid, spell_id spl) case IMISC_ELIXVIT: ModifyPlrVit(pnum, 1); if (gbIsHellfire) { - player._pHitPoints = player._pMaxHP; - player._pHPBase = player._pMaxHPBase; - drawhpflag = true; + player.RestoreFullLife(); + if (&player == MyPlayer) { + drawhpflag = true; + } } break; case IMISC_REJUV: { - int j = player._pMaxHP >> 8; - int l = ((j / 2) + GenerateRnd(j)) << 6; - if (IsAnyOf(player._pClass, HeroClass::Warrior, HeroClass::Barbarian)) - l *= 2; - if (player._pClass == HeroClass::Rogue) - l += l / 2; - player._pHitPoints = std::min(player._pHitPoints + l, player._pMaxHP); - player._pHPBase = std::min(player._pHPBase + l, player._pMaxHPBase); - drawhpflag = true; - j = player._pMaxMana >> 8; - l = ((j / 2) + GenerateRnd(j)) << 6; - if (player._pClass == HeroClass::Sorcerer) - l *= 2; - if (player._pClass == HeroClass::Rogue) - l += l / 2; - if ((player._pIFlags & ISPL_NOMANA) == 0) { - player._pMana = std::min(player._pMana + l, player._pMaxMana); - player._pManaBase = std::min(player._pManaBase + l, player._pMaxManaBase); + player.RestorePartialLife(); + player.RestorePartialMana(); + if (&player == MyPlayer) { + drawhpflag = true; drawmanaflag = true; } } break; case IMISC_FULLREJUV: - player._pHitPoints = player._pMaxHP; - player._pHPBase = player._pMaxHPBase; - drawhpflag = true; - if ((player._pIFlags & ISPL_NOMANA) == 0) { - player._pMana = player._pMaxMana; - player._pManaBase = player._pMaxManaBase; + player.RestoreFullLife(); + player.RestoreFullMana(); + if (&player == MyPlayer) { + drawhpflag = true; drawmanaflag = true; } break; diff --git a/Source/player.cpp b/Source/player.cpp index e8307608b..95b6bbd77 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -2100,6 +2100,32 @@ void Player::Reset() *this = std::move(*emptyPlayer); } +void Player::RestorePartialLife() +{ + int wholeHitpoints = _pMaxHP >> 6; + int l = ((wholeHitpoints / 8) + GenerateRnd(wholeHitpoints / 4)) << 6; + if (IsAnyOf(_pClass, HeroClass::Warrior, HeroClass::Barbarian)) + l *= 2; + if (IsAnyOf(_pClass, HeroClass::Rogue, HeroClass::Monk, HeroClass::Bard)) + l += l / 2; + _pHitPoints = std::min(_pHitPoints + l, _pMaxHP); + _pHPBase = std::min(_pHPBase + l, _pMaxHPBase); +} + +void Player::RestorePartialMana() +{ + int wholeManaPoints = _pMaxMana >> 6; + int l = ((wholeManaPoints / 8) + GenerateRnd(wholeManaPoints / 4)) << 6; + if (_pClass == HeroClass::Sorcerer) + l *= 2; + if (IsAnyOf(_pClass, HeroClass::Rogue, HeroClass::Monk, HeroClass::Bard)) + l += l / 2; + if ((_pIFlags & ISPL_NOMANA) == 0) { + _pMana = std::min(_pMana + l, _pMaxMana); + _pManaBase = std::min(_pManaBase + l, _pMaxManaBase); + } +} + void LoadPlrGFX(Player &player, player_graphic graphic) { char prefix[16]; diff --git a/Source/player.h b/Source/player.h index 19ec72183..0712cb206 100644 --- a/Source/player.h +++ b/Source/player.h @@ -577,6 +577,44 @@ struct Player { return _pManaPer; } + /** + * @brief Restores between 1/8 (inclusive) and 1/4 (exclusive) of the players max HP (further adjusted by class). + * + * This determines a random amount of non-fractional life points to restore then scales the value based on the + * player class. Warriors/barbarians get between 1/4 and 1/2 life restored per potion, rogue/monk/bard get 3/16 + * to 3/8, and sorcerers get the base amount. + */ + void RestorePartialLife(); + + /** + * @brief Resets hp to maxHp + */ + void RestoreFullLife() + { + _pHitPoints = _pMaxHP; + _pHPBase = _pMaxHPBase; + } + + /** + * @brief Restores between 1/8 (inclusive) and 1/4 (exclusive) of the players max Mana (further adjusted by class). + * + * This determines a random amount of non-fractional mana points to restore then scales the value based on the + * player class. Sorcerers get between 1/4 and 1/2 mana restored per potion, rogue/monk/bard get 3/16 to 3/8, + * and warrior/barbarian get the base amount. However if the player can't use magic due to an equipped item then + * they get nothing. + */ + void RestorePartialMana(); + + /** + * @brief Resets mana to maxMana (if the player can use magic) + */ + void RestoreFullMana() + { + if ((_pIFlags & ISPL_NOMANA) == 0) { + _pMana = _pMaxMana; + _pManaBase = _pMaxManaBase; + } + } /** * @brief Sets the readied spell to the spell in the specified equipment slot. Does nothing if the item does not have a valid spell. * @param bodyLocation - the body location whose item will be checked for the spell.