From 9f6055a4a1e76cbefa245190fc0d622e965e492f Mon Sep 17 00:00:00 2001 From: Eric Robinson <68359262+kphoenix137@users.noreply.github.com> Date: Fri, 19 Apr 2024 22:25:05 -0400 Subject: [PATCH] Clean up CalcPlrItemVals() (#4052) --- Source/items.cpp | 515 ++++++++++++++++++++++++++--------------------- Source/player.h | 9 + 2 files changed, 294 insertions(+), 230 deletions(-) diff --git a/Source/items.cpp b/Source/items.cpp index 93aa72016..126127d8a 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -2559,135 +2559,66 @@ void InitItems() initItemGetRecords(); } -void CalcPlrItemVals(Player &player, bool loadgfx) +int GetBonusAC(const Item &item) { - int mind = 0; // min damage - int maxd = 0; // max damage - int tac = 0; // accuracy - - int bdam = 0; // bonus damage - int btohit = 0; // bonus chance to hit - int bac = 0; // bonus accuracy - - ItemSpecialEffect iflgs = ItemSpecialEffect::None; // item_special_effect flags - - ItemSpecialEffectHf pDamAcFlags = ItemSpecialEffectHf::None; - - int sadd = 0; // added strength - int madd = 0; // added magic - int dadd = 0; // added dexterity - int vadd = 0; // added vitality - - uint64_t spl = 0; // bitarray for all enabled/active spells - - int fr = 0; // fire resistance - int lr = 0; // lightning resistance - int mr = 0; // magic resistance - - int dmod = 0; // bonus damage mod? - int ghit = 0; // increased damage from enemies - - int lrad = 10; // light radius - - int ihp = 0; // increased HP - int imana = 0; // increased mana - - int spllvladd = 0; // increased spell level - int enac = 0; // enhanced accuracy - - int fmin = 0; // minimum fire damage - int fmax = 0; // maximum fire damage - int lmin = 0; // minimum lightning damage - int lmax = 0; // maximum lightning damage - - for (auto &item : player.InvBody) { - if (!item.isEmpty() && item._iStatFlag) { - - mind += item._iMinDam; - maxd += item._iMaxDam; - tac += item._iAC; - - if (IsValidSpell(item._iSpell)) { - spl |= GetSpellBitmask(item._iSpell); - } - - if (item._iMagical == ITEM_QUALITY_NORMAL || item._iIdentified) { - bdam += item._iPLDam; - btohit += item._iPLToHit; - if (item._iPLAC != 0) { - int tmpac = item._iAC; - tmpac *= item._iPLAC; - tmpac /= 100; - if (tmpac == 0) - tmpac = math::Sign(item._iPLAC); - bac += tmpac; - } - iflgs |= item._iFlags; - pDamAcFlags |= item._iDamAcFlags; - sadd += item._iPLStr; - madd += item._iPLMag; - dadd += item._iPLDex; - vadd += item._iPLVit; - fr += item._iPLFR; - lr += item._iPLLR; - mr += item._iPLMR; - dmod += item._iPLDamMod; - ghit += item._iPLGetHit; - lrad += item._iPLLight; - ihp += item._iPLHP; - imana += item._iPLMana; - spllvladd += item._iSplLvlAdd; - enac += item._iPLEnAc; - fmin += item._iFMinDam; - fmax += item._iFMaxDam; - lmin += item._iLMinDam; - lmax += item._iLMaxDam; - } - } + if (item._iPLAC != 0) { + int tempAc = item._iAC; + tempAc *= item._iPLAC; + tempAc /= 100; + if (tempAc == 0) + tempAc = math::Sign(item._iPLAC); + return tempAc; } - const uint8_t playerLevel = player.getCharacterLevel(); + return 0; +} - if (mind == 0 && maxd == 0) { - mind = 1; - maxd = 1; +void CalcPlrDamage(Player &player, int minDamage, int maxDamage) +{ + const uint8_t playerLevel = player.getCharacterLevel(); - if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Shield && player.InvBody[INVLOC_HAND_LEFT]._iStatFlag) { - maxd = 3; - } + if (minDamage == 0 && maxDamage == 0) { + minDamage = 1; + maxDamage = 1; - if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield && player.InvBody[INVLOC_HAND_RIGHT]._iStatFlag) { - maxd = 3; + if (player.isHoldingItem(ItemType::Shield)) { + maxDamage = 3; } if (player._pClass == HeroClass::Monk) { - mind = std::max(mind, playerLevel / 2); - maxd = std::max(maxd, playerLevel); + minDamage = std::max(minDamage, playerLevel / 2); + maxDamage = std::max(maxDamage, playerLevel); } } + player._pIMinDam = minDamage; + player._pIMaxDam = maxDamage; +} + +void CalcPlrPrimaryStats(Player &player, int strength, int &magic, int dexterity, int &vitality) +{ + const uint8_t playerLevel = player.getCharacterLevel(); + if (HasAnyOf(player._pSpellFlags, SpellFlag::RageActive)) { - sadd += 2 * playerLevel; - dadd += playerLevel + playerLevel / 2; - vadd += 2 * playerLevel; + strength += 2 * playerLevel; + dexterity += playerLevel + playerLevel / 2; + vitality += 2 * playerLevel; } if (HasAnyOf(player._pSpellFlags, SpellFlag::RageCooldown)) { - sadd -= 2 * playerLevel; - dadd -= playerLevel + playerLevel / 2; - vadd -= 2 * playerLevel; - } - - player._pIMinDam = mind; - player._pIMaxDam = maxd; - player._pIAC = tac; - player._pIBonusDam = bdam; - player._pIBonusToHit = btohit; - player._pIBonusAC = bac; - player._pIFlags = iflgs; - player.pDamAcFlags = pDamAcFlags; - player._pIBonusDamMod = dmod; - player._pIGetHit = ghit; + strength -= 2 * playerLevel; + dexterity -= playerLevel + playerLevel / 2; + vitality -= 2 * playerLevel; + } + player._pStrength = std::max(0, strength + player._pBaseStr); + player._pMagic = std::max(0, magic + player._pBaseMag); + player._pDexterity = std::max(0, dexterity + player._pBaseDex); + player._pVitality = std::max(0, vitality + player._pBaseVit); +} + +void CalcPlrLightRadius(Player &player, int lrad) + +{ lrad = std::clamp(lrad, 2, 15); if (player._pLightRad != lrad) { @@ -2695,182 +2626,194 @@ void CalcPlrItemVals(Player &player, bool loadgfx) ChangeVisionRadius(player.getId(), lrad); player._pLightRad = lrad; } +} - player._pStrength = std::max(0, sadd + player._pBaseStr); - player._pMagic = std::max(0, madd + player._pBaseMag); - player._pDexterity = std::max(0, dadd + player._pBaseDex); - player._pVitality = std::max(0, vadd + player._pBaseVit); - - if (player._pClass == HeroClass::Rogue) { - player._pDamageMod = playerLevel * (player._pStrength + player._pDexterity) / 200; - } else if (player._pClass == HeroClass::Monk) { - player._pDamageMod = playerLevel * (player._pStrength + player._pDexterity) / 150; - if ((!player.InvBody[INVLOC_HAND_LEFT].isEmpty() && player.InvBody[INVLOC_HAND_LEFT]._itype != ItemType::Staff) || (!player.InvBody[INVLOC_HAND_RIGHT].isEmpty() && player.InvBody[INVLOC_HAND_RIGHT]._itype != ItemType::Staff)) - player._pDamageMod /= 2; // Monks get half the normal damage bonus if they're holding a non-staff weapon - } else if (player._pClass == HeroClass::Bard) { - if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Sword || player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Sword) - player._pDamageMod = playerLevel * (player._pStrength + player._pDexterity) / 150; - else if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Bow || player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Bow) { - player._pDamageMod = playerLevel * (player._pStrength + player._pDexterity) / 250; +void CalcPlrDamageMod(Player &player) +{ + const uint8_t playerLevel = player.getCharacterLevel(); + const Item &leftHandItem = player.InvBody[INVLOC_HAND_LEFT]; + const Item &rightHandItem = player.InvBody[INVLOC_HAND_RIGHT]; + const int strMod = playerLevel * player._pStrength; + const int strDexMod = playerLevel * (player._pStrength + player._pDexterity); + + switch (player._pClass) { + case HeroClass::Rogue: + player._pDamageMod = strDexMod / 200; + return; + case HeroClass::Monk: + if (player.isHoldingItem(ItemType::Staff) || (leftHandItem.isEmpty() && rightHandItem.isEmpty())) { + player._pDamageMod = strDexMod / 150; } else { - player._pDamageMod = playerLevel * player._pStrength / 100; + player._pDamageMod = strDexMod / 300; } - } else if (player._pClass == HeroClass::Barbarian) { - - if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Axe || player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Axe) { - player._pDamageMod = playerLevel * player._pStrength / 75; - } else if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Mace || player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Mace) { - player._pDamageMod = playerLevel * player._pStrength / 75; - } else if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Bow || player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Bow) { - player._pDamageMod = playerLevel * player._pStrength / 300; + return; + case HeroClass::Bard: + if (player.isHoldingItem(ItemType::Sword)) { + player._pDamageMod = strDexMod / 150; + } else if (player.isHoldingItem(ItemType::Bow)) { + player._pDamageMod = strDexMod / 250; } else { - player._pDamageMod = playerLevel * player._pStrength / 100; + player._pDamageMod = strMod / 100; } - - if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Shield || player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) { - if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Shield) - player._pIAC -= player.InvBody[INVLOC_HAND_LEFT]._iAC / 2; - else if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) - player._pIAC -= player.InvBody[INVLOC_HAND_RIGHT]._iAC / 2; - } else if (IsNoneOf(player.InvBody[INVLOC_HAND_LEFT]._itype, ItemType::Staff, ItemType::Bow) && IsNoneOf(player.InvBody[INVLOC_HAND_RIGHT]._itype, ItemType::Staff, ItemType::Bow)) { + return; + case HeroClass::Barbarian: + if (player.isHoldingItem(ItemType::Axe) || player.isHoldingItem(ItemType::Mace)) { + player._pDamageMod = strMod / 75; + } else if (player.isHoldingItem(ItemType::Bow)) { + player._pDamageMod = strMod / 300; + } else { + player._pDamageMod = strMod / 100; + } + if (player.isHoldingItem(ItemType::Shield)) { + if (leftHandItem._itype == ItemType::Shield) + player._pIAC -= leftHandItem._iAC / 2; + else if (rightHandItem._itype == ItemType::Shield) + player._pIAC -= rightHandItem._iAC / 2; + } else if (!player.isHoldingItem(ItemType::Staff) && !player.isHoldingItem(ItemType::Bow)) { player._pDamageMod += playerLevel * player._pVitality / 100; } player._pIAC += playerLevel / 4; - } else { - player._pDamageMod = playerLevel * player._pStrength / 100; + return; + default: + player._pDamageMod = strMod / 100; + return; } +} - player._pISpells = spl; - - EnsureValidReadiedSpell(player); - - player._pISplLvlAdd = spllvladd; - player._pIEnAc = enac; +void CalcPlrResistances(Player &player, ItemSpecialEffect iflgs, int fire, int lightning, int magic) +{ + const uint8_t playerLevel = player.getCharacterLevel(); if (player._pClass == HeroClass::Barbarian) { - mr += playerLevel; - fr += playerLevel; - lr += playerLevel; + magic += playerLevel; + fire += playerLevel; + lightning += playerLevel; } if (HasAnyOf(player._pSpellFlags, SpellFlag::RageCooldown)) { - mr -= playerLevel; - fr -= playerLevel; - lr -= playerLevel; + magic -= playerLevel; + fire -= playerLevel; + lightning -= playerLevel; } if (HasAnyOf(iflgs, ItemSpecialEffect::ZeroResistance)) { // reset resistances to zero if the respective special effect is active - mr = 0; - fr = 0; - lr = 0; + magic = 0; + fire = 0; + lightning = 0; } - player._pMagResist = std::clamp(mr, 0, MaxResistance); - player._pFireResist = std::clamp(fr, 0, MaxResistance); - player._pLghtResist = std::clamp(lr, 0, MaxResistance); + player._pMagResist = std::clamp(magic, 0, MaxResistance); + player._pFireResist = std::clamp(fire, 0, MaxResistance); + player._pLghtResist = std::clamp(lightning, 0, MaxResistance); +} +void CalcPlrLifeMana(Player &player, int vitality, int magic, int life, int mana) +{ const ClassAttributes &playerClassAttributes = player.getClassAttributes(); - vadd = (vadd * playerClassAttributes.itmLife) >> 6; - ihp += (vadd << 6); // BUGFIX: blood boil can cause negative shifts here (see line 757) + vitality = (vitality * playerClassAttributes.itmLife) >> 6; + life += (vitality << 6); - madd = (madd * playerClassAttributes.itmMana) >> 6; - imana += (madd << 6); + magic = (magic * playerClassAttributes.itmMana) >> 6; + mana += (magic << 6); - player._pMaxHP = ihp + player._pMaxHPBase; - player._pHitPoints = std::min(ihp + player._pHPBase, player._pMaxHP); + player._pMaxHP = life + player._pMaxHPBase; + player._pHitPoints = std::min(life + player._pHPBase, player._pMaxHP); if (&player == MyPlayer && (player._pHitPoints >> 6) <= 0) { SetPlayerHitPoints(player, 0); } - player._pMaxMana = imana + player._pMaxManaBase; - player._pMana = std::min(imana + player._pManaBase, player._pMaxMana); + player._pMaxMana = mana + player._pMaxManaBase; + player._pMana = std::min(mana + player._pManaBase, player._pMaxMana); +} - player._pIFMinDam = fmin; - player._pIFMaxDam = fmax; - player._pILMinDam = lmin; - player._pILMaxDam = lmax; +void CalcPlrBlockFlag(Player &player) +{ + const auto &leftHandItem = player.InvBody[INVLOC_HAND_LEFT]; + const auto &rightHandItem = player.InvBody[INVLOC_HAND_RIGHT]; player._pBlockFlag = false; + if (player._pClass == HeroClass::Monk) { - if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Staff && player.InvBody[INVLOC_HAND_LEFT]._iStatFlag) { + if (player.isHoldingItem(ItemType::Staff)) { player._pBlockFlag = true; player._pIFlags |= ItemSpecialEffect::FastBlock; - } - if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Staff && player.InvBody[INVLOC_HAND_RIGHT]._iStatFlag) { + } else if ((leftHandItem.isEmpty() && rightHandItem.isEmpty()) || (leftHandItem._iClass == ICLASS_WEAPON && leftHandItem._iLoc != ILOC_TWOHAND && rightHandItem.isEmpty()) || (rightHandItem._iClass == ICLASS_WEAPON && rightHandItem._iLoc != ILOC_TWOHAND && leftHandItem.isEmpty())) { player._pBlockFlag = true; - player._pIFlags |= ItemSpecialEffect::FastBlock; } - if (player.InvBody[INVLOC_HAND_LEFT].isEmpty() && player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) - player._pBlockFlag = true; - if (player.InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON && player.GetItemLocation(player.InvBody[INVLOC_HAND_LEFT]) != ILOC_TWOHAND && player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) - player._pBlockFlag = true; - if (player.InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON && player.GetItemLocation(player.InvBody[INVLOC_HAND_RIGHT]) != ILOC_TWOHAND && player.InvBody[INVLOC_HAND_LEFT].isEmpty()) - player._pBlockFlag = true; } + player._pBlockFlag = player._pBlockFlag || player.isHoldingItem(ItemType::Shield); +} + +PlayerWeaponGraphic GetPlrAnimWeaponId(const Player &player) +{ + const Item &leftHandItem = player.InvBody[INVLOC_HAND_LEFT]; + const Item &rightHandItem = player.InvBody[INVLOC_HAND_RIGHT]; + bool holdsShield = player.isHoldingItem(ItemType::Shield); + bool leftHandUsable = player.CanUseItem(leftHandItem); + bool rightHandUsable = player.CanUseItem(rightHandItem); ItemType weaponItemType = ItemType::None; - bool holdsShield = false; - if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty() - && player.InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON - && player.InvBody[INVLOC_HAND_LEFT]._iStatFlag) { - weaponItemType = player.InvBody[INVLOC_HAND_LEFT]._itype; - } - if (!player.InvBody[INVLOC_HAND_RIGHT].isEmpty() - && player.InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON - && player.InvBody[INVLOC_HAND_RIGHT]._iStatFlag) { - weaponItemType = player.InvBody[INVLOC_HAND_RIGHT]._itype; + if (!leftHandItem.isEmpty() && leftHandItem._iClass == ICLASS_WEAPON && leftHandUsable) { + weaponItemType = leftHandItem._itype; } - if (player.InvBody[INVLOC_HAND_LEFT]._itype == ItemType::Shield && player.InvBody[INVLOC_HAND_LEFT]._iStatFlag) { - player._pBlockFlag = true; - holdsShield = true; - } - if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield && player.InvBody[INVLOC_HAND_RIGHT]._iStatFlag) { - player._pBlockFlag = true; - holdsShield = true; + if (!rightHandItem.isEmpty() && rightHandItem._iClass == ICLASS_WEAPON && rightHandUsable) { + weaponItemType = rightHandItem._itype; } - PlayerWeaponGraphic animWeaponId = holdsShield ? PlayerWeaponGraphic::UnarmedShield : PlayerWeaponGraphic::Unarmed; switch (weaponItemType) { case ItemType::Sword: - animWeaponId = holdsShield ? PlayerWeaponGraphic::SwordShield : PlayerWeaponGraphic::Sword; - break; + return holdsShield ? PlayerWeaponGraphic::SwordShield : PlayerWeaponGraphic::Sword; case ItemType::Axe: - animWeaponId = PlayerWeaponGraphic::Axe; - break; + return PlayerWeaponGraphic::Axe; case ItemType::Bow: - animWeaponId = PlayerWeaponGraphic::Bow; - break; + return PlayerWeaponGraphic::Bow; case ItemType::Mace: - animWeaponId = holdsShield ? PlayerWeaponGraphic::MaceShield : PlayerWeaponGraphic::Mace; - break; + return holdsShield ? PlayerWeaponGraphic::MaceShield : PlayerWeaponGraphic::Mace; case ItemType::Staff: - animWeaponId = PlayerWeaponGraphic::Staff; - break; + return PlayerWeaponGraphic::Staff; default: - break; + return holdsShield ? PlayerWeaponGraphic::UnarmedShield : PlayerWeaponGraphic::Unarmed; } +} - PlayerArmorGraphic animArmorId = PlayerArmorGraphic::Light; - if (player.InvBody[INVLOC_CHEST]._itype == ItemType::HeavyArmor && player.InvBody[INVLOC_CHEST]._iStatFlag) { - if (player._pClass == HeroClass::Monk && player.InvBody[INVLOC_CHEST]._iMagical == ITEM_QUALITY_UNIQUE) - player._pIAC += playerLevel / 2; - animArmorId = PlayerArmorGraphic::Heavy; - } else if (player.InvBody[INVLOC_CHEST]._itype == ItemType::MediumArmor && player.InvBody[INVLOC_CHEST]._iStatFlag) { - if (player._pClass == HeroClass::Monk) { - if (player.InvBody[INVLOC_CHEST]._iMagical == ITEM_QUALITY_UNIQUE) +PlayerArmorGraphic GetPlrAnimArmorId(Player &player) +{ + const Item &chestItem = player.InvBody[INVLOC_CHEST]; + bool chestUsable = player.CanUseItem(chestItem); + const uint8_t playerLevel = player.getCharacterLevel(); + + if (chestUsable) { + switch (chestItem._itype) { + case ItemType::HeavyArmor: + if (player._pClass == HeroClass::Monk) { + if (chestItem._iMagical == ITEM_QUALITY_UNIQUE) + player._pIAC += playerLevel / 2; + } + return PlayerArmorGraphic::Heavy; + case ItemType::MediumArmor: + if (player._pClass == HeroClass::Monk) { + if (chestItem._iMagical == ITEM_QUALITY_UNIQUE) + player._pIAC += playerLevel * 2; + else + player._pIAC += playerLevel / 2; + } + return PlayerArmorGraphic::Medium; + default: + if (player._pClass == HeroClass::Monk) player._pIAC += playerLevel * 2; - else - player._pIAC += playerLevel / 2; + return PlayerArmorGraphic::Light; } - animArmorId = PlayerArmorGraphic::Medium; - } else if (player._pClass == HeroClass::Monk) { - player._pIAC += playerLevel * 2; } + return PlayerArmorGraphic::Light; +} + +void CalcPlrGraphics(Player &player, PlayerWeaponGraphic animWeaponId, PlayerArmorGraphic animArmorId, bool loadgfx) +{ const uint8_t gfxNum = static_cast(animWeaponId) | static_cast(animArmorId); if (player._pgfxnum != gfxNum && loadgfx) { player._pgfxnum = gfxNum; @@ -2889,7 +2832,11 @@ void CalcPlrItemVals(Player &player, bool loadgfx) } else { player._pgfxnum = gfxNum; } +} +void CalcPlrAuricBonus(Player &player) + +{ if (&player == MyPlayer) { if (player.InvBody[INVLOC_AMULET].isEmpty() || player.InvBody[INVLOC_AMULET].IDidx != IDI_AURIC) { int half = MaxGold; @@ -2901,7 +2848,115 @@ void CalcPlrItemVals(Player &player, bool loadgfx) MaxGold = GOLD_MAX_LIMIT * 2; } } +} + +void CalcPlrItemVals(Player &player, bool loadgfx) +{ + int minDamage = 0; + int maxDamage = 0; + int ac = 0; + + int dam = 0; + int toHit = 0; + int bonusAc = 0; + + ItemSpecialEffect flags = ItemSpecialEffect::None; + ItemSpecialEffectHf damAcFlags = ItemSpecialEffectHf::None; + + int strength = 0; + int magic = 0; + int dexterity = 0; + int vitality = 0; + + uint64_t spells = 0; + + int fireRes = 0; + int lightRes = 0; + int magicRes = 0; + + int damMod = 0; + int getHit = 0; + + int lightRadius = 10; + + int life = 0; + int mana = 0; + + int8_t splLvlAdd = 0; + int targetAc = 0; + + int minFireDam = 0; + int maxFireDam = 0; + int minLightDam = 0; + int maxLightDam = 0; + + for (const Item &item : player.InvBody) { + if (!item.isEmpty() && item._iStatFlag) { + + minDamage += item._iMinDam; + maxDamage += item._iMaxDam; + ac += item._iAC; + + if (IsValidSpell(item._iSpell)) { + spells |= GetSpellBitmask(item._iSpell); + } + + if (item._iMagical == ITEM_QUALITY_NORMAL || item._iIdentified) { + dam += item._iPLDam; + toHit += item._iPLToHit; + bonusAc += GetBonusAC(item); + flags |= item._iFlags; + damAcFlags |= item._iDamAcFlags; + strength += item._iPLStr; + magic += item._iPLMag; + dexterity += item._iPLDex; + vitality += item._iPLVit; + fireRes += item._iPLFR; + lightRes += item._iPLLR; + magicRes += item._iPLMR; + damMod += item._iPLDamMod; + getHit += item._iPLGetHit; + lightRadius += item._iPLLight; + life += item._iPLHP; + mana += item._iPLMana; + splLvlAdd += item._iSplLvlAdd; + targetAc += item._iPLEnAc; + minFireDam += item._iFMinDam; + maxFireDam += item._iFMaxDam; + minLightDam += item._iLMinDam; + maxLightDam += item._iLMaxDam; + } + } + } + + CalcPlrDamage(player, minDamage, maxDamage); + CalcPlrPrimaryStats(player, strength, magic, dexterity, vitality); + player._pIAC = ac; + player._pIBonusDam = dam; + player._pIBonusToHit = toHit; + player._pIBonusAC = bonusAc; + player._pIFlags = flags; + player.pDamAcFlags = damAcFlags; + player._pIBonusDamMod = damMod; + player._pIGetHit = getHit; + CalcPlrLightRadius(player, lightRadius); + CalcPlrDamageMod(player); + player._pISpells = spells; + EnsureValidReadiedSpell(player); + player._pISplLvlAdd = splLvlAdd; + player._pIEnAc = targetAc; + CalcPlrResistances(player, flags, fireRes, lightRes, magicRes); + CalcPlrLifeMana(player, vitality, magic, life, mana); + player._pIFMinDam = minFireDam; + player._pIFMaxDam = maxFireDam; + player._pILMinDam = minLightDam; + player._pILMaxDam = maxLightDam; + + CalcPlrBlockFlag(player); + + CalcPlrGraphics(player, GetPlrAnimWeaponId(player), GetPlrAnimArmorId(player), loadgfx); + CalcPlrAuricBonus(player); RedrawComponent(PanelDrawComponent::Mana); RedrawComponent(PanelDrawComponent::Health); } diff --git a/Source/player.h b/Source/player.h index 86631078f..a6c392c54 100644 --- a/Source/player.h +++ b/Source/player.h @@ -894,6 +894,15 @@ public: /** @brief Checks if the player level is owned by local client. */ bool isLevelOwnedByLocalClient() const; + + /** @brief Checks if the player is holding an item of the provided type, and is usable. */ + bool isHoldingItem(const ItemType type) const + { + const Item &leftHandItem = InvBody[INVLOC_HAND_LEFT]; + const Item &rightHandItem = InvBody[INVLOC_HAND_RIGHT]; + + return (type == leftHandItem._itype && leftHandItem._iStatFlag) || (type == rightHandItem._itype && rightHandItem._iStatFlag); + } }; extern DVL_API_FOR_TEST uint8_t MyPlayerId;