Skip to content

Commit

Permalink
feat(Core/Unit): New helper HasActivePowerType and script hook OnPlay…
Browse files Browse the repository at this point in the history
…erHasActivePowerType (azerothcore#18293)

* Create HasActivePower for script intercept

* Replace relevant player-related getPowerType() comparators with HasActivePowerType

* Change OnPlayerHasActivePowerType to regular bool instead of optional

---------

Co-authored-by: NathanHandley <[email protected]>
  • Loading branch information
NathanHandley and NathanHandley authored Feb 9, 2024
1 parent ed53ac2 commit 425a490
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 38 deletions.
41 changes: 24 additions & 17 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,8 @@ class Player : public Unit, public GridObject<Player>

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; }
Expand Down
12 changes: 6 additions & 6 deletions src/server/game/Entities/Unit/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Entities/Unit/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,7 @@ class Unit : public WorldObject

[[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<uint16>(UNIT_FIELD_POWER1) + power); }
[[nodiscard]] uint32 GetMaxPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power); }
void SetPower(Powers power, uint32 val, bool withPowerUpdate = true, bool fromRegenerate = false);
Expand Down
15 changes: 15 additions & 0 deletions src/server/game/Scripting/ScriptDefines/PlayerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>([&](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>([&](PlayerScript* script)
{
Expand Down
2 changes: 2 additions & 0 deletions src/server/game/Scripting/ScriptDefines/PlayerScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ class PlayerScript : public ScriptObject

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.
*
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Scripting/ScriptMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ class ScriptMgr
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);
Expand Down
8 changes: 4 additions & 4 deletions src/server/game/Spells/Auras/SpellAuraEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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()))
Expand Down
4 changes: 2 additions & 2 deletions src/server/game/Spells/Spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions src/server/game/Spells/SpellEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/server/scripts/Spells/spell_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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%
Expand Down
4 changes: 2 additions & 2 deletions src/server/scripts/Spells/spell_paladin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*/)
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/server/scripts/Spells/spell_shaman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand All @@ -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
Expand Down

0 comments on commit 425a490

Please sign in to comment.