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.