refactor(Core/Spells): QAston proc system (#24233)

Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
Co-authored-by: QAston <qaston@gmail.com>
Co-authored-by: joschiwald <joschiwald@online.de>
Co-authored-by: ariel- <ariel-@users.noreply.github.com>
Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com>
Co-authored-by: blinkysc <your-github-email@example.com>
Co-authored-by: Tereneckla <Tereneckla@users.noreply.github.com>
Co-authored-by: Andrew <47818697+Nyeriah@users.noreply.github.com>
This commit is contained in:
blinkysc
2026-02-18 05:31:53 -06:00
committed by GitHub
parent 65a869ea27
commit 4599f26ae9
76 changed files with 22915 additions and 5181 deletions

View File

@@ -104,8 +104,8 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS] =
&AuraEffect::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
&AuraEffect::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
&AuraEffect::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
&AuraEffect::HandleNoImmediateEffect, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
&AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
&AuraEffect::HandleNoImmediateEffect, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Aura::TriggerProcOnEvent
&AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Aura::TriggerProcOnEvent
&AuraEffect::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
&AuraEffect::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
&AuraEffect::HandleNULL, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a)
@@ -700,8 +700,6 @@ void AuraEffect::CalculateSpellMod()
m_spellmod->type = SpellModType(GetAuraType()); // SpellModType value == spell aura types
m_spellmod->spellId = GetId();
m_spellmod->mask = GetSpellInfo()->Effects[GetEffIndex()].SpellClassMask;
m_spellmod->charges = GetBase()->GetCharges();
m_spellmod->priority = GetSpellInfo()->SpellPriority;
}
m_spellmod->value = GetAmount();
break;
@@ -1181,6 +1179,72 @@ void AuraEffect::PeriodicTick(AuraApplication* aurApp, Unit* caster) const
}
}
bool AuraEffect::CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) const
{
bool result = GetBase()->CallScriptCheckEffectProcHandlers(this, aurApp, eventInfo);
if (!result)
return false;
SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
switch (GetAuraType())
{
case SPELL_AURA_MOD_CONFUSE:
case SPELL_AURA_MOD_FEAR:
case SPELL_AURA_MOD_STUN:
case SPELL_AURA_MOD_ROOT:
case SPELL_AURA_TRANSFORM:
{
DamageInfo* damageInfo = eventInfo.GetDamageInfo();
if (!damageInfo || !damageInfo->GetDamage())
return false;
// Spell own damage at apply won't break CC
if (spellInfo && spellInfo == GetSpellInfo())
{
Aura* aura = GetBase();
// called from spellcast, should not have ticked yet
if (aura->GetDuration() == aura->GetMaxDuration())
return false;
}
break;
}
case SPELL_AURA_MECHANIC_IMMUNITY:
case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
// compare mechanic
if (!spellInfo || !(spellInfo->GetAllEffectsMechanicMask() & (1 << GetMiscValue())))
return false;
break;
case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
// skip melee hits and instant cast spells
if (!eventInfo.GetProcSpell() || !eventInfo.GetProcSpell()->GetCastTime())
return false;
break;
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
{
// Skip melee hits and spells with wrong school or zero cost
if (!spellInfo || !(spellInfo->GetSchoolMask() & GetMiscValue())
|| !spellInfo->ManaCost || !spellInfo->ManaCostPercentage)
return false;
break;
}
case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
// Skip melee hits and spells with wrong school
if (!spellInfo || !(spellInfo->GetSchoolMask() & GetMiscValue()))
return false;
break;
case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
// Compare casters
if (GetCasterGUID() != eventInfo.GetActor()->GetGUID())
return false;
break;
default:
break;
}
return result;
}
void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
{
bool prevented = GetBase()->CallScriptEffectProcHandlers(this, aurApp, eventInfo);
@@ -6200,31 +6264,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
{
switch (GetSpellInfo()->SpellFamilyName)
{
case SPELLFAMILY_DRUID:
{
switch (GetSpellInfo()->Id)
{
// Frenzied Regeneration
case 22842:
{
// 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->HasActivePowerType(POWER_RAGE))
break;
uint32 rage = target->GetPower(POWER_RAGE);
// Nothing todo
if (rage == 0)
break;
int32 mod = (rage < 100) ? rage : 100;
int32 points = target->CalculateSpellDamage(target, GetSpellInfo(), 1);
int32 regen = target->GetMaxHealth() * (mod * points / 10) / 1000;
target->CastCustomSpell(target, 22845, &regen, 0, 0, true, 0, this);
target->SetPower(POWER_RAGE, rage - mod);
break;
}
}
break;
}
case SPELLFAMILY_HUNTER:
{
// Explosive Shot
@@ -6251,15 +6290,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
}
break;
}
case SPELLFAMILY_SHAMAN:
if (GetId() == 52179) // Astral Shift
{
// Periodic need for remove visual on stun/fear/silence lost
if (!(target->GetUnitFlags() & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED)))
target->RemoveAurasDueToSpell(52179);
break;
}
break;
case SPELLFAMILY_DEATHKNIGHT:
switch (GetId())
{
@@ -6426,21 +6456,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
}
break;
}
case SPELLFAMILY_SHAMAN:
{
switch (auraId)
{
// Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
case 28820:
{
// Need remove self if Lightning Shield not active
if (!target->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0))
target->RemoveAurasDueToSpell(28820);
return;
}
}
break;
}
default:
break;
}
@@ -6450,10 +6465,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
// Spell exist but require custom code
switch (auraId)
{
// Mana Tide
case 16191:
target->CastCustomSpell(target, triggerSpellId, &m_amount, nullptr, nullptr, true, nullptr, this);
return;
// Poison (Grobbulus)
case 28158:
case 54362:
@@ -6670,18 +6681,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
damage = damageReductedArmor;
}
// Curse of Agony damage-per-tick calculation
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x400) && GetSpellInfo()->SpellIconID == 544)
{
uint32 totalTick = GetTotalTicks();
// 1..4 ticks, 1/2 from normal tick damage
if (m_tickNumber <= totalTick / 3)
damage = damage / 2;
// 9..12 ticks, 3/2 from normal tick damage
else if (m_tickNumber > totalTick * 2 / 3)
damage += (damage + 1) / 2; // +1 prevent 0.5 damage possible lost at 1..4 ticks
// 5..8 ticks have normal tick damage
}
}
// calculate crit chance
@@ -6748,7 +6747,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo);
Unit::ProcSkillsAndAuras(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo);
}
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
@@ -6842,7 +6841,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
new_damage = Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo);
Unit::ProcSkillsAndAuras(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo);
if (!caster || !caster->IsAlive())
return;
@@ -6955,22 +6954,6 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
}
else
{
// Wild Growth = amount + (6 - 2*doneTicks) * ticks* amount / 100
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellInfo()->SpellIconID == 2864)
{
uint32 tickNumber = GetTickNumber() - 1;
int32 tempAmount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, nullptr);
float drop = 2.0f;
// Item - Druid T10 Restoration 2P Bonus
if (caster)
if (AuraEffect* aurEff = caster->GetAuraEffect(70658, 0))
AddPct(drop, -aurEff->GetAmount());
damage += GetTotalTicks() * tempAmount * (6 - (drop * tickNumber)) * 0.01f;
}
if (GetBase()->GetType() == DYNOBJ_AURA_TYPE)
damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetEffIndex(), 0.0f, GetBase()->GetStackAmount());
damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
@@ -7039,7 +7022,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
Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, heal, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, nullptr, &healInfo);
Unit::ProcSkillsAndAuras(caster, target, caster ? procAttacker : 0, procVictim, procEx, heal, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, nullptr, &healInfo);
}
void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) const
@@ -7220,14 +7203,14 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE) | PROC_EX_INTERNAL_DOT;
if (damageInfo.damage)
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
caster->DealSpellDamage(&damageInfo, true);
DamageInfo dmgInfo(damageInfo, DOT);
Unit::ProcDamageAndSpell(caster, damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex(), nullptr, &dmgInfo);
DamageInfo dmgInfo(damageInfo, DOT, BASE_ATTACK, SPELL_MISS_NONE);
uint32 hitMask = dmgInfo.GetHitMask() | PROC_EX_INTERNAL_DOT;
Unit::ProcSkillsAndAuras(caster, damageInfo.target, procAttacker, procVictim, hitMask, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex(), nullptr, &dmgInfo);
}
void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)