mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-25 14:46:24 +00:00
fix(Core/Spells): Master of Elements (#7102)
* Core/Spells: Master of Elements: Proc now also from arcane spells. Properly proc from periodic spells. Fixed #6035. * You shouldn't be there. * Buildfix. * missing sql.
This commit is contained in:
@@ -142,9 +142,9 @@ void DamageInfo::BlockDamage(uint32 amount)
|
||||
m_damage -= amount;
|
||||
}
|
||||
|
||||
ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* /*spell*/, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell)
|
||||
ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* /*spell*/, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell, int8 procAuraEffectIndex)
|
||||
: _actor(actor), _actionTarget(actionTarget), _procTarget(procTarget), _typeMask(typeMask), _spellTypeMask(spellTypeMask), _spellPhaseMask(spellPhaseMask),
|
||||
_hitMask(hitMask), _damageInfo(damageInfo), _healInfo(healInfo), _triggeredByAuraSpell(triggeredByAuraSpell)
|
||||
_hitMask(hitMask), _damageInfo(damageInfo), _healInfo(healInfo), _triggeredByAuraSpell(triggeredByAuraSpell), _procAuraEffectIndex(procAuraEffectIndex)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2041,7 +2041,7 @@ void Unit::CalcAbsorbResist(Unit* attacker, Unit* victim, SpellSchoolMask school
|
||||
|
||||
// create procs
|
||||
createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim);
|
||||
caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted, nullptr);
|
||||
caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted);
|
||||
|
||||
if (attacker)
|
||||
attacker->SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitted + splitted_absorb, schoolMask, splitted_absorb, 0, false, 0, false);
|
||||
@@ -2109,7 +2109,7 @@ void Unit::CalcAbsorbResist(Unit* attacker, Unit* victim, SpellSchoolMask school
|
||||
|
||||
// create procs
|
||||
createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim);
|
||||
caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted, nullptr);
|
||||
caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted);
|
||||
|
||||
if (attacker)
|
||||
attacker->SendSpellNonMeleeDamageLog(caster, splitSpellInfo->Id, splitted + splitted_absorb, splitSchoolMask, splitted_absorb, 0, false, 0, false);
|
||||
@@ -5835,15 +5835,15 @@ void Unit::SendSpellNonMeleeDamageLog(Unit* target, uint32 SpellID, uint32 Damag
|
||||
SendSpellNonMeleeDamageLog(&log);
|
||||
}
|
||||
|
||||
void Unit::ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpell, SpellInfo const* procAura)
|
||||
void Unit::ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpell, SpellInfo const* procAura, int8 procAuraEffectIndex)
|
||||
{
|
||||
// Not much to do if no flags are set.
|
||||
if (procAttacker)
|
||||
ProcDamageAndSpellFor(false, victim, procAttacker, procExtra, attType, procSpell, amount, procAura);
|
||||
ProcDamageAndSpellFor(false, victim, procAttacker, procExtra, attType, procSpell, amount, procAura, procAuraEffectIndex);
|
||||
// Now go on with a victim's events'n'auras
|
||||
// Not much to do if no flags are set or there is no victim
|
||||
if (victim && victim->IsAlive() && procVictim)
|
||||
victim->ProcDamageAndSpellFor(true, this, procVictim, procExtra, attType, procSpell, amount, procAura);
|
||||
victim->ProcDamageAndSpellFor(true, this, procVictim, procExtra, attType, procSpell, amount, procAura, procAuraEffectIndex);
|
||||
}
|
||||
|
||||
void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo)
|
||||
@@ -15495,7 +15495,7 @@ uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missC
|
||||
return procEx;
|
||||
}
|
||||
|
||||
void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpell, uint32 damage, SpellInfo const* procAura)
|
||||
void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpell, uint32 damage, SpellInfo const* procAura, int8 procAuraEffectIndex)
|
||||
{
|
||||
// Player is loaded now - do not allow passive spell casts to proc
|
||||
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetSession()->PlayerLoading())
|
||||
@@ -15592,7 +15592,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
|
||||
DamageInfo damageInfo = DamageInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE);
|
||||
HealInfo healInfo = HealInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, nullptr, &damageInfo, &healInfo, procAura);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, nullptr, &damageInfo, &healInfo, procAura, procAuraEffectIndex);
|
||||
|
||||
ProcTriggeredList procTriggered;
|
||||
// Fill procTriggered list
|
||||
@@ -15977,12 +15977,12 @@ void Unit::TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo)
|
||||
void Unit::TriggerAurasProcOnEvent(std::list<AuraApplication*>* myProcAuras, std::list<AuraApplication*>* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo)
|
||||
{
|
||||
// prepare data for self trigger
|
||||
ProcEventInfo myProcEventInfo = ProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo, nullptr);
|
||||
ProcEventInfo myProcEventInfo = ProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
|
||||
std::list<AuraApplication*> myAurasTriggeringProc;
|
||||
GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, myProcAuras, myProcEventInfo);
|
||||
|
||||
// prepare data for target trigger
|
||||
ProcEventInfo targetProcEventInfo = ProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo, nullptr);
|
||||
ProcEventInfo targetProcEventInfo = ProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
|
||||
std::list<AuraApplication*> targetAurasTriggeringProc;
|
||||
if (typeMaskActionTarget)
|
||||
GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, targetProcAuras, targetProcEventInfo);
|
||||
|
||||
@@ -958,8 +958,10 @@ private:
|
||||
DamageInfo* _damageInfo;
|
||||
HealInfo* _healInfo;
|
||||
SpellInfo const* const _triggeredByAuraSpell;
|
||||
int8 _procAuraEffectIndex;
|
||||
|
||||
public:
|
||||
explicit ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell);
|
||||
explicit ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell = nullptr, int8 procAuraEffectIndex = -1);
|
||||
Unit* GetActor() { return _actor; };
|
||||
[[nodiscard]] Unit* GetActionTarget() const { return _actionTarget; }
|
||||
[[nodiscard]] Unit* GetProcTarget() const { return _procTarget; }
|
||||
@@ -972,6 +974,7 @@ public:
|
||||
[[nodiscard]] DamageInfo* GetDamageInfo() const { return _damageInfo; }
|
||||
[[nodiscard]] HealInfo* GetHealInfo() const { return _healInfo; }
|
||||
[[nodiscard]] SpellInfo const* GetTriggerAuraSpell() const { return _triggeredByAuraSpell; }
|
||||
[[nodiscard]] int8 GetTriggerAuraEffectIndex() const { return _procAuraEffectIndex; }
|
||||
[[nodiscard]] uint32 GetProcCooldown() const { return _cooldown; }
|
||||
void SetProcCooldown(uint32 cooldown) { _cooldown = cooldown; }
|
||||
};
|
||||
@@ -1622,8 +1625,8 @@ public:
|
||||
static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr);
|
||||
static int32 DealHeal(Unit* healer, Unit* victim, uint32 addhealth);
|
||||
|
||||
void ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellInfo const* procSpell = nullptr, SpellInfo const* procAura = nullptr);
|
||||
void ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpell, uint32 damage, SpellInfo const* procAura = nullptr);
|
||||
void ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellInfo const* procSpell = nullptr, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1);
|
||||
void ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpell, uint32 damage, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1);
|
||||
|
||||
void GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTriggeringProc, std::list<AuraApplication*>* procAuras, ProcEventInfo eventInfo);
|
||||
void TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo);
|
||||
|
||||
@@ -6350,7 +6350,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
|
||||
|
||||
Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
|
||||
// allow null caster to call this function
|
||||
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo());
|
||||
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex());
|
||||
}
|
||||
|
||||
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
|
||||
@@ -6423,7 +6423,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
|
||||
|
||||
new_damage = Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
|
||||
// allow null caster to call this function
|
||||
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo());
|
||||
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex());
|
||||
|
||||
if (!caster || !caster->IsAlive())
|
||||
return;
|
||||
@@ -6603,7 +6603,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
|
||||
// ignore item heals
|
||||
if (!haveCastItem && GetAuraType() != SPELL_AURA_OBS_MOD_HEALTH) // xinef: dont allow obs_mod_health to proc spells, this is passive regeneration and not hot
|
||||
// xinef: allow null caster to proc
|
||||
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo());
|
||||
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex());
|
||||
}
|
||||
|
||||
void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) const
|
||||
@@ -6789,7 +6789,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
|
||||
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
|
||||
|
||||
caster->DealSpellDamage(&damageInfo, true);
|
||||
caster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto);
|
||||
caster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex());
|
||||
}
|
||||
|
||||
void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
|
||||
|
||||
@@ -626,6 +626,7 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags,
|
||||
m_glyphIndex = 0;
|
||||
m_preCastSpell = 0;
|
||||
m_triggeredByAuraSpell = nullptr;
|
||||
m_triggeredByAuraEffectIndex = -1;
|
||||
m_spellAura = nullptr;
|
||||
m_pathFinder = nullptr; // pussywizard
|
||||
_scriptsLoaded = false;
|
||||
@@ -2537,7 +2538,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
|
||||
|
||||
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
|
||||
if (canEffectTrigger)
|
||||
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
|
||||
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell, m_triggeredByAuraEffectIndex);
|
||||
}
|
||||
// Do damage and triggers
|
||||
else if (m_damage > 0)
|
||||
@@ -2611,7 +2612,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
|
||||
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
|
||||
if (canEffectTrigger)
|
||||
{
|
||||
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
|
||||
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell, m_triggeredByAuraEffectIndex);
|
||||
if (caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 &&
|
||||
m_spellInfo->HasAttribute(SPELL_ATTR4_SUPRESS_WEAPON_PROCS) == 0 && (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED))
|
||||
caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
|
||||
@@ -2628,7 +2629,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
|
||||
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
|
||||
if (canEffectTrigger)
|
||||
{
|
||||
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
|
||||
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell, m_triggeredByAuraEffectIndex);
|
||||
// Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
|
||||
// Xinef: ofc count only spells that HIT the target, little hack used to fool the system
|
||||
if ((procEx & PROC_EX_NORMAL_HIT || procEx & PROC_EX_CRITICAL_HIT) && caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 &&
|
||||
@@ -3198,6 +3199,7 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
|
||||
if (triggeredByAura)
|
||||
{
|
||||
m_triggeredByAuraSpell = triggeredByAura->GetSpellInfo();
|
||||
m_triggeredByAuraEffectIndex = triggeredByAura->GetEffIndex();
|
||||
}
|
||||
|
||||
// create and add update event for this spell
|
||||
|
||||
@@ -715,6 +715,7 @@ protected:
|
||||
// we can't store original aura link to prevent access to deleted auras
|
||||
// and in same time need aura data and after aura deleting.
|
||||
SpellInfo const* m_triggeredByAuraSpell;
|
||||
int8 m_triggeredByAuraEffectIndex;
|
||||
|
||||
bool m_skipCheck;
|
||||
uint8 m_auraScaleMask;
|
||||
|
||||
@@ -950,14 +950,43 @@ public:
|
||||
|
||||
bool CheckProc(ProcEventInfo& eventInfo)
|
||||
{
|
||||
return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo()
|
||||
_spellInfo = eventInfo.GetDamageInfo()->GetSpellInfo();
|
||||
if (!_spellInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool selectCaster = false;
|
||||
// Triggered spells cost no mana so we need triggering spellInfo
|
||||
if (SpellInfo const* triggeredByAuraSpellInfo = eventInfo.GetTriggerAuraSpell())
|
||||
{
|
||||
_spellInfo = triggeredByAuraSpellInfo;
|
||||
selectCaster = true;
|
||||
}
|
||||
|
||||
// If spell is periodic, mana amount is divided by tick number
|
||||
if (eventInfo.GetTriggerAuraEffectIndex() >= EFFECT_0)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
if (Unit* target = (selectCaster ? eventInfo.GetActor() : eventInfo.GetActionTarget()))
|
||||
{
|
||||
if (AuraEffect const* aurEff = target->GetAuraEffect(_spellInfo->Id, eventInfo.GetTriggerAuraEffectIndex(), caster->GetGUID()))
|
||||
{
|
||||
ticksModifier = aurEff->GetTotalTicks();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _spellInfo; // eventInfo.GetSpellInfo()
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
int32 mana = int32(eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask()));
|
||||
int32 mana = int32(_spellInfo->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask()) / ticksModifier);
|
||||
mana = CalculatePct(mana, aurEff->GetAmount());
|
||||
|
||||
if (mana > 0)
|
||||
@@ -969,6 +998,10 @@ public:
|
||||
DoCheckProc += AuraCheckProcFn(spell_mage_master_of_elements_AuraScript::CheckProc);
|
||||
OnEffectProc += AuraEffectProcFn(spell_mage_master_of_elements_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
}
|
||||
|
||||
private:
|
||||
SpellInfo const* _spellInfo = nullptr;
|
||||
uint8 ticksModifier = 1;
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
|
||||
Reference in New Issue
Block a user