Skip to content

Commit

Permalink
Spell: Revert usage of SPELL_ATTR_EX3_TREAT_AS_PERIODIC as proc indic…
Browse files Browse the repository at this point in the history
…ator

Blizzard and some other spells break for procs based on templates
  • Loading branch information
killerwife committed Sep 12, 2024
1 parent 3092e1d commit 65e8c0c
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/game/Entities/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -2227,7 +2227,7 @@ class Unit : public WorldObject
SPELL_PROC_TRIGGER_OK = 2,
};

SpellProcEventTriggerCheck IsTriggeredAtSpellProcEvent(ProcExecutionData& data, SpellAuraHolder* holder, SpellProcEventEntry const*& spellProcEvent);
SpellProcEventTriggerCheck IsTriggeredAtSpellProcEvent(ProcExecutionData& data, SpellAuraHolder* holder, SpellProcEventEntry const*& spellProcEvent, bool (&canProc)[MAX_EFFECT_INDEX]);
// only to be used in proc handlers - basepoints is expected to be a MAX_EFFECT_INDEX sized array
SpellAuraProcResult TriggerProccedSpell(Unit* target, std::array<int32, MAX_EFFECT_INDEX>& basepoints, uint32 triggeredSpellId, Item* castItem, Aura* triggeredByAura, uint32 cooldown, ObjectGuid originalCaster);
SpellAuraProcResult TriggerProccedSpell(Unit* target, std::array<int32, MAX_EFFECT_INDEX>& basepoints, SpellEntry const* spellInfo, Item* castItem, Aura* triggeredByAura, uint32 cooldown, ObjectGuid originalCaster);
Expand Down
6 changes: 0 additions & 6 deletions src/game/Spells/Spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,12 +871,6 @@ void Spell::PrepareMasksForProcSystem(uint8 effectMask, uint32& procAttacker, ui
procVictim |= PROC_FLAG_TAKE_MELEE_SWING;
}

if (m_spellInfo->HasAttribute(SPELL_ATTR_EX3_TREAT_AS_PERIODIC))
{
procAttacker = PROC_FLAG_DEAL_HARMFUL_PERIODIC;
procVictim = PROC_FLAG_TAKE_HARMFUL_PERIODIC;
}

if (m_spellInfo->HasAttribute(SPELL_ATTR_EX3_SUPPRESS_CASTER_PROCS))
procAttacker = 0;

Expand Down
101 changes: 66 additions & 35 deletions src/game/Spells/UnitAuraProcHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ struct ProcTriggeredData
{}
SpellProcEventEntry const* spellProcEvent;
SpellAuraHolder* triggeredByHolder;
bool canProc[MAX_EFFECT_INDEX];
};

typedef std::list< ProcTriggeredData > ProcTriggeredList;
Expand Down Expand Up @@ -503,25 +504,26 @@ void Unit::ProcDamageAndSpellFor(ProcSystemArguments& argData, bool isVictim)
if (holder->GetState() != SPELLAURAHOLDER_STATE_READY || holder->IsDeleted())
continue;

SpellProcEventEntry const* spellProcEvent = nullptr;
SpellProcEventTriggerCheck result = IsTriggeredAtSpellProcEvent(execData, holder, spellProcEvent);
ProcTriggeredData procTriggeredData(nullptr, itr->second);

SpellProcEventTriggerCheck result = IsTriggeredAtSpellProcEvent(execData, holder, procTriggeredData.spellProcEvent, procTriggeredData.canProc);
if (holder->GetSpellProto()->HasAttribute(SPELL_ATTR_PROC_FAILURE_BURNS_CHARGE) &&
result == SpellProcEventTriggerCheck::SPELL_PROC_TRIGGER_ROLL_FAILED && holder->GetAuraCharges() > 0)
holdersForDeletion.push_back(holder);

if (holder->GetSpellProto()->HasAttribute(SPELL_ATTR_EX2_PROC_COOLDOWN_ON_FAILURE) && result == SpellProcEventTriggerCheck::SPELL_PROC_TRIGGER_ROLL_FAILED)
{
uint32 cooldown = 0;
if (spellProcEvent && spellProcEvent->cooldown)
cooldown = spellProcEvent->cooldown;
if (procTriggeredData.spellProcEvent && procTriggeredData.spellProcEvent->cooldown)
cooldown = procTriggeredData.spellProcEvent->cooldown;
if (cooldown)
holder->SetProcCooldown(std::chrono::seconds(cooldown), GetMap()->GetCurrentClockTime());
}

if (result != SpellProcEventTriggerCheck::SPELL_PROC_TRIGGER_OK)
continue;

procTriggered.push_back(ProcTriggeredData(spellProcEvent, itr->second));
procTriggered.emplace_back(procTriggeredData);
}

for (SpellAuraHolder* holder : holdersForDeletion)
Expand Down Expand Up @@ -556,33 +558,8 @@ void Unit::ProcDamageAndSpellFor(ProcSystemArguments& argData, bool isVictim)
continue;

Modifier* auraModifier = execData.triggeredByAura->GetModifier();

if (execData.spellInfo)
{
if (spellProcEvent)
{
if (spellProcEvent->spellFamilyMask[i])
{
if (!execData.spellInfo->IsFitToFamilyMask(spellProcEvent->spellFamilyMask[i]))
continue;

// don't allow proc from cast end for non modifier spells
// unless they have proc ex defined for that
if (IsCastEndProcModifierAura(triggeredByHolder->GetSpellProto(), SpellEffectIndex(i), execData.spellInfo))
{
if (useCharges && execData.procExtra != PROC_EX_CAST_END && spellProcEvent->procEx == PROC_EX_NONE)
continue;
}
else if (spellProcEvent->procEx == PROC_EX_NONE && execData.procExtra == PROC_EX_CAST_END)
continue;
}
// don't check dbc FamilyFlags if schoolMask exists
else if (!execData.triggeredByAura->CanProcFrom(execData.spellInfo, spellProcEvent->procEx, execData.procExtra, execData.damage != 0, execData.absorb != 0, !spellProcEvent->schoolMask))
continue;
}
else if (!execData.triggeredByAura->CanProcFrom(execData.spellInfo, PROC_EX_NONE, execData.procExtra, execData.damage != 0, execData.absorb != 0, true))
continue;
}
if (itr->canProc[i] == false)
continue;

execData.triggeredSpellId = 0;
execData.basepoints = { 0, 0, 0 };
Expand Down Expand Up @@ -619,7 +596,7 @@ void Unit::ProcDamageAndSpellFor(ProcSystemArguments& argData, bool isVictim)
}
}

Unit::SpellProcEventTriggerCheck Unit::IsTriggeredAtSpellProcEvent(ProcExecutionData& data, SpellAuraHolder* holder, SpellProcEventEntry const*& spellProcEvent)
Unit::SpellProcEventTriggerCheck Unit::IsTriggeredAtSpellProcEvent(ProcExecutionData& data, SpellAuraHolder* holder, SpellProcEventEntry const*& spellProcEvent, bool (&canProc)[MAX_EFFECT_INDEX])
{
SpellEntry const* spellProto = holder->GetSpellProto();

Expand Down Expand Up @@ -732,13 +709,67 @@ Unit::SpellProcEventTriggerCheck Unit::IsTriggeredAtSpellProcEvent(ProcExecution
for (uint8 i = 0; i < MAX_EFFECT_INDEX; ++i)
if (Aura* aura = holder->m_auras[i])
if (data.spell->IsAuraProcced(aura))
return SpellProcEventTriggerCheck::SPELL_PROC_TRIGGER_FAILED;
canProc[i] = false;
}

for (uint8 i = 0; i < MAX_EFFECT_INDEX; ++i)
if (Aura* aura = holder->m_auras[i])
if (!aura->OnCheckProc(data))
return SpellProcEventTriggerCheck::SPELL_PROC_TRIGGER_FAILED;
canProc[i] = false;

if (data.spellInfo)
{
bool useCharges = holder->GetAuraCharges() > 0;
for (uint8 i = 0; i < MAX_EFFECT_INDEX; ++i)
{
if (Aura* aura = holder->m_auras[i])
{
if (spellProcEvent)
{
if (spellProcEvent->spellFamilyMask[i])
{
if (!data.spellInfo->IsFitToFamilyMask(spellProcEvent->spellFamilyMask[i]))
{
canProc[i] = false;
continue;
}

// don't allow proc from cast end for non modifier spells
// unless they have proc ex defined for that
if (IsCastEndProcModifierAura(holder->GetSpellProto(), SpellEffectIndex(i), data.spellInfo))
{
if (useCharges && data.procExtra != PROC_EX_CAST_END && spellProcEvent->procEx == PROC_EX_NONE)
{
canProc[i] = false;
continue;
}
}
else if (spellProcEvent->procEx == PROC_EX_NONE && data.procExtra == PROC_EX_CAST_END)
{
canProc[i] = false;
continue;
}
}
// don't check dbc FamilyFlags if schoolMask exists
else if (!aura->CanProcFrom(data.spellInfo, spellProcEvent->procEx, data.procExtra, data.damage != 0, data.absorb != 0, !spellProcEvent->schoolMask))
{
canProc[i] = false;
continue;
}
}
else if (!aura->CanProcFrom(data.spellInfo, PROC_EX_NONE, data.procExtra, data.damage != 0, data.absorb != 0, true))
{
canProc[i] = false;
continue;
}
}
else
canProc[i] = false;
}
}

if (!canProc[EFFECT_INDEX_0] || !canProc[EFFECT_INDEX_1] || !canProc[EFFECT_INDEX_2])
return SpellProcEventTriggerCheck::SPELL_PROC_TRIGGER_FAILED;

if (roll_chance_f(chance))
return SpellProcEventTriggerCheck::SPELL_PROC_TRIGGER_OK;
Expand Down

0 comments on commit 65e8c0c

Please sign in to comment.