diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 11f7178a3..d4736d5f7 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -587,13 +587,13 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo InitPrimaryProfessions(); // to max set before any spell added // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() - if (getPowerType() == POWER_MANA) + if (HasActivePowerType(POWER_MANA)) { UpdateMaxPower(POWER_MANA); // Update max Mana (for add bonus from intellect) SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); } - if (getPowerType() == POWER_RUNIC_POWER) + if (HasActivePowerType(POWER_RUNIC_POWER)) { SetPower(POWER_RUNE, 8); SetMaxPower(POWER_RUNE, 8); @@ -2019,22 +2019,21 @@ void Player::RegenerateHealth() void Player::ResetAllPowers() { SetHealth(GetMaxHealth()); - switch (getPowerType()) + if (HasActivePowerType(POWER_MANA)) { - case POWER_MANA: - SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); - break; - case POWER_RAGE: - SetPower(POWER_RAGE, 0); - break; - case POWER_ENERGY: - SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); - break; - case POWER_RUNIC_POWER: - SetPower(POWER_RUNIC_POWER, 0); - break; - default: - break; + SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); + } + if (HasActivePowerType(POWER_RAGE)) + { + SetPower(POWER_RAGE, 0); + } + if (HasActivePowerType(POWER_ENERGY)) + { + SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); + } + if (HasActivePowerType(POWER_RUNIC_POWER)) + { + SetPower(POWER_RUNIC_POWER, 0); } } @@ -2714,6 +2713,14 @@ void Player::InitStatsForLevel(bool reapplyMods) pet->SynchronizeLevelWithOwner(); } +bool Player::HasActivePowerType(Powers power) +{ + if (sScriptMgr->OnPlayerHasActivePowerType(this, power)) + return true; + else + return (getPowerType() == power); +} + void Player::SendInitialSpells() { uint32 curTime = GameTime::GetGameTimeMS().count(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 5d6494239..bb99778be 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1170,6 +1170,8 @@ public: void InitStatsForLevel(bool reapplyMods = false); + [[nodiscard]] bool HasActivePowerType(Powers power) override; + // .cheat command related [[nodiscard]] bool GetCommandStatus(uint32 command) const { return _activeCheats & command; } void SetCommandStatusOn(uint32 command) { _activeCheats |= command; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4b136f63c..b4c6812af 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -929,7 +929,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage } // Rage from Damage made (only from direct weapon damage) - if (attacker && cleanDamage && damagetype == DIRECT_DAMAGE && attacker != victim && attacker->getPowerType() == POWER_RAGE) + if (attacker && cleanDamage && damagetype == DIRECT_DAMAGE && attacker != victim && attacker->HasActivePowerType(POWER_RAGE)) { uint32 weaponSpeedHitFactor; @@ -957,10 +957,10 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage // Rage from absorbed damage if (cleanDamage && cleanDamage->absorbed_damage) { - if (victim->getPowerType() == POWER_RAGE) + if (victim->HasActivePowerType(POWER_RAGE)) victim->RewardRage(cleanDamage->absorbed_damage, 0, false); - if (attacker && attacker->getPowerType() == POWER_RAGE ) + if (attacker && attacker->HasActivePowerType(POWER_RAGE)) attacker->RewardRage(cleanDamage->absorbed_damage, 0, true); } @@ -1083,7 +1083,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage } // Rage from damage received - if (attacker != victim && victim->getPowerType() == POWER_RAGE) + if (attacker != victim && victim->HasActivePowerType(POWER_RAGE)) { uint32 rageDamage = damage + (cleanDamage ? cleanDamage->absorbed_damage : 0); victim->RewardRage(rageDamage, 0, false); @@ -6996,7 +6996,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Magic Absorption if (dummySpell->SpellIconID == 459) // only this spell has SpellIconID == 459 and dummy aura { - if (getPowerType() != POWER_MANA) + if (!HasActivePowerType(POWER_MANA)) return false; // mana reward @@ -7775,7 +7775,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Judgement of Wisdom case 20186: { - if (!victim || !victim->IsAlive() || victim->getPowerType() != POWER_MANA || victim->HasSpellCooldown(20268)) + if (!victim || !victim->IsAlive() || !victim->HasActivePowerType(POWER_MANA) || victim->HasSpellCooldown(20268)) return false; // 2% of base mana diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index bf70798d9..ad55d384c 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1472,6 +1472,7 @@ public: [[nodiscard]] Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); } void setPowerType(Powers power); + [[nodiscard]] virtual bool HasActivePowerType(Powers power) { return getPowerType() == power; } [[nodiscard]] uint32 GetPower(Powers power) const { return GetUInt32Value(static_cast(UNIT_FIELD_POWER1) + power); } [[nodiscard]] uint32 GetMaxPower(Powers power) const { return GetUInt32Value(static_cast(UNIT_FIELD_MAXPOWER1) + power); } void SetPower(Powers power, uint32 val, bool withPowerUpdate = true, bool fromRegenerate = false); diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index ed2465695..c9574106d 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -1046,6 +1046,21 @@ void ScriptMgr::OnGetMaxSkillValue(Player* player, uint32 skill, int32& result, }); } +bool ScriptMgr::OnPlayerHasActivePowerType(Player const* player, Powers power) +{ + auto ret = IsValidBoolScript([&](PlayerScript* script) + { + return script->OnPlayerHasActivePowerType(player, power); + }); + + if (ret && *ret) + { + return true; + } + + return false; +} + void ScriptMgr::OnUpdateGatheringSkill(Player *player, uint32 skillId, uint32 currentLevel, uint32 gray, uint32 green, uint32 yellow, uint32 &gain) { ExecuteScript([&](PlayerScript* script) { diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.h b/src/server/game/Scripting/ScriptDefines/PlayerScript.h index 788474390..68c67fa00 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.h +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.h @@ -324,6 +324,8 @@ public: virtual void OnGetMaxSkillValue(Player* /*player*/, uint32 /*skill*/, int32& /*result*/, bool /*IsPure*/) { } + [[nodiscard]] virtual bool OnPlayerHasActivePowerType(Player const* /*player*/, Powers /*power*/) { return false; } + /** * @brief This hook called before gathering skill gain is applied to the character. * diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index c39c10980..0df982ea4 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -402,6 +402,7 @@ public: /* PlayerScript */ void OnDeleteFromDB(CharacterDatabaseTransaction trans, uint32 guid); bool CanRepopAtGraveyard(Player* player); void OnGetMaxSkillValue(Player* player, uint32 skill, int32& result, bool IsPure); + bool OnPlayerHasActivePowerType(Player const* player, Powers power); void OnUpdateGatheringSkill(Player* player, uint32 skillId, uint32 currentLevel, uint32 gray, uint32 green, uint32 yellow, uint32& gain); void OnUpdateCraftingSkill(Player* player, SkillLineAbilityEntry const* skill, uint32 currentLevel, uint32& gain); bool OnUpdateFishingSkill(Player* player, int32 skill, int32 zone_skill, int32 chance, int32 roll); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index f8c8117af..130945722 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6244,7 +6244,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const { // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health. // Should be manauser - if (target->getPowerType() != POWER_RAGE) + if (!target->HasActivePowerType(POWER_RAGE)) break; uint32 rage = target->GetPower(POWER_RAGE); // Nothing todo @@ -7082,7 +7082,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con { Powers PowerType = Powers(GetMiscValue()); - if (!caster || !caster->IsAlive() || !target->IsAlive() || target->getPowerType() != PowerType) + if (!caster || !caster->IsAlive() || !target->IsAlive() || !target->HasActivePowerType(PowerType)) return; if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamageOrSchool(GetSpellInfo())) @@ -7189,7 +7189,7 @@ void AuraEffect::HandlePeriodicEnergizeAuraTick(Unit* target, Unit* caster) cons { Powers PowerType = Powers(GetMiscValue()); - if (target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() != PowerType && !m_spellInfo->HasAttribute(SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED)) + if (target->GetTypeId() == TYPEID_PLAYER && !target->HasActivePowerType(PowerType) && !m_spellInfo->HasAttribute(SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED)) return; if (!target->IsAlive() || !target->GetMaxPower(PowerType)) @@ -7223,7 +7223,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con { Powers PowerType = Powers(GetMiscValue()); - if (!caster || !target->IsAlive() || target->getPowerType() != PowerType) + if (!caster || !target->IsAlive() || !target->HasActivePowerType(PowerType)) return; if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamageOrSchool(GetSpellInfo())) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 0ea3ccb2c..75522d2dd 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6173,7 +6173,7 @@ SpellCastResult Spell::CheckCast(bool strict) // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects) if (m_caster->GetTypeId() == TYPEID_PLAYER) if (Unit* target = m_targets.GetUnitTarget()) - if (target != m_caster && target->getPowerType() != Powers(m_spellInfo->Effects[i].MiscValue)) + if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue))) return SPELL_FAILED_BAD_TARGETS; break; } @@ -6702,7 +6702,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (!m_targets.GetUnitTarget()) return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - if (m_targets.GetUnitTarget()->getPowerType() != POWER_MANA) + if (!m_targets.GetUnitTarget()->HasActivePowerType(POWER_MANA)) return SPELL_FAILED_BAD_TARGETS; break; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 98cd74e6c..aaeb85080 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1345,7 +1345,7 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex) Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != PowerType || damage < 0) + if (!unitTarget || !unitTarget->IsAlive() || !unitTarget->HasActivePowerType(PowerType) || damage < 0) return; // add spell damage bonus @@ -1424,7 +1424,7 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex) Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != PowerType || damage < 0) + if (!unitTarget || !unitTarget->IsAlive() || !unitTarget->HasActivePowerType(PowerType) || damage < 0) return; // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn) @@ -1877,7 +1877,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && m_spellInfo->SpellFamilyName != SPELLFAMILY_POTION + if (unitTarget->GetTypeId() == TYPEID_PLAYER && !unitTarget->HasActivePowerType(power) && m_spellInfo->SpellFamilyName != SPELLFAMILY_POTION && !m_spellInfo->HasAttribute(SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED)) return; @@ -1982,7 +1982,7 @@ void Spell::EffectEnergizePct(SpellEffIndex effIndex) Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !m_spellInfo->HasAttribute(SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED)) + if (unitTarget->GetTypeId() == TYPEID_PLAYER && !unitTarget->HasActivePowerType(power) && !m_spellInfo->HasAttribute(SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED)) return; uint32 maxPower = unitTarget->GetMaxPower(power); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 6feb5f6c3..da7c3e997 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -576,7 +576,7 @@ class spell_item_skull_of_impeding_doom : public AuraScript void CalculateManaLeechAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) { - if (!GetCaster() || GetCaster()->getPowerType() != POWER_MANA) + if (!GetCaster() || !GetCaster()->HasActivePowerType(POWER_MANA)) return; amount = GetCaster()->GetMaxPower(POWER_MANA) * 0.12f; // 5 ticks which reduce health by 60% diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 0cd83b638..4793489fe 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -483,7 +483,7 @@ class spell_pal_blessing_of_sanctuary : public AuraScript bool CheckProc(ProcEventInfo& /*eventInfo*/) { - return GetTarget()->getPowerType() == POWER_MANA; + return GetTarget()->HasActivePowerType(POWER_MANA); } void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) @@ -969,7 +969,7 @@ class spell_pal_lay_on_hands : public SpellScript // Xinef: Glyph of Divinity if (Unit* target = GetExplTargetUnit()) - if (target->getPowerType() == POWER_MANA) + if (target->HasActivePowerType(POWER_MANA)) _manaAmount = target->GetPower(POWER_MANA); return SPELL_CAST_OK; diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 9fd557adb..5ca5f32b2 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -992,7 +992,7 @@ class spell_sha_mana_spring_totem : public SpellScript int32 damage = GetEffectValue(); if (Unit* target = GetHitUnit()) if (Unit* caster = GetCaster()) - if (target->getPowerType() == POWER_MANA) + if (target->HasActivePowerType(POWER_MANA)) caster->CastCustomSpell(target, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); } @@ -1017,7 +1017,7 @@ class spell_sha_mana_tide_totem : public SpellScript if (Unit* caster = GetCaster()) if (Unit* unitTarget = GetHitUnit()) { - if (unitTarget->getPowerType() == POWER_MANA) + if (unitTarget->HasActivePowerType(POWER_MANA)) { int32 effValue = GetEffectValue(); // Glyph of Mana Tide