mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-09 08:17:56 +00:00
fix(Core/Spells): Ensures that procs triggered by another aura are proccessed in the first place. (#5075)
This commit is contained in:
@@ -15219,15 +15219,22 @@ bool Unit::isFrozen() const
|
|||||||
|
|
||||||
struct ProcTriggeredData
|
struct ProcTriggeredData
|
||||||
{
|
{
|
||||||
ProcTriggeredData(Aura* _aura)
|
ProcTriggeredData(Aura* _aura) : aura(_aura)
|
||||||
: aura(_aura)
|
|
||||||
{
|
{
|
||||||
effMask = 0;
|
effMask = 0;
|
||||||
spellProcEvent = nullptr;
|
spellProcEvent = nullptr;
|
||||||
|
triggerSpelId.fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellProcEventEntry const* spellProcEvent;
|
SpellProcEventEntry const* spellProcEvent;
|
||||||
Aura* aura;
|
Aura* aura;
|
||||||
uint32 effMask;
|
uint32 effMask;
|
||||||
|
std::array<uint32, EFFECT_ALL> triggerSpelId;
|
||||||
|
|
||||||
|
bool operator==(const uint32 spellId) const
|
||||||
|
{
|
||||||
|
return aura->GetId() == spellId;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list< ProcTriggeredData > ProcTriggeredList;
|
typedef std::list< ProcTriggeredData > ProcTriggeredList;
|
||||||
@@ -15571,24 +15578,74 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
|||||||
//bool triggered = !spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ?
|
//bool triggered = !spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ?
|
||||||
// (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false;
|
// (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false;
|
||||||
|
|
||||||
|
bool hasTriggeredProc = false;
|
||||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||||
{
|
{
|
||||||
if (itr->second->HasEffect(i))
|
if (itr->second->HasEffect(i))
|
||||||
{
|
{
|
||||||
AuraEffect* aurEff = itr->second->GetBase()->GetEffect(i);
|
AuraEffect* aurEff = itr->second->GetBase()->GetEffect(i);
|
||||||
|
|
||||||
// Skip this auras
|
// Skip this auras
|
||||||
if (isNonTriggerAura[aurEff->GetAuraType()])
|
if (isNonTriggerAura[aurEff->GetAuraType()])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If not trigger by default and spellProcEvent == nullptr - skip
|
// If not trigger by default and spellProcEvent == nullptr - skip
|
||||||
if (!isTriggerAura[aurEff->GetAuraType()] && triggerData.spellProcEvent == nullptr)
|
if (!isTriggerAura[aurEff->GetAuraType()] && triggerData.spellProcEvent == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
switch (aurEff->GetAuraType())
|
||||||
|
{
|
||||||
|
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
||||||
|
case SPELL_AURA_MANA_SHIELD:
|
||||||
|
case SPELL_AURA_DUMMY:
|
||||||
|
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
|
||||||
|
if (uint32 triggerSpellId = aurEff->GetSpellInfo()->Effects[i].TriggerSpell)
|
||||||
|
{
|
||||||
|
triggerData.triggerSpelId[i] = triggerSpellId;
|
||||||
|
hasTriggeredProc = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Some spells must always trigger
|
// Some spells must always trigger
|
||||||
//if (isAlwaysTriggeredAura[aurEff->GetAuraType()])
|
//if (isAlwaysTriggeredAura[aurEff->GetAuraType()])
|
||||||
triggerData.effMask |= 1 << i;
|
triggerData.effMask |= 1 << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (triggerData.effMask)
|
if (triggerData.effMask)
|
||||||
procTriggered.push_front(triggerData);
|
{
|
||||||
|
// If there is aura that triggers another proc aura, make sure that the triggered one is going to be proccessed on top of it
|
||||||
|
if (hasTriggeredProc)
|
||||||
|
{
|
||||||
|
bool proccessed = false;
|
||||||
|
for (uint8 i = 0; i < EFFECT_ALL; ++i)
|
||||||
|
{
|
||||||
|
if (uint32 triggeredSpellId = triggerData.triggerSpelId[i])
|
||||||
|
{
|
||||||
|
auto iter = std::find(procTriggered.begin(), procTriggered.end(), triggeredSpellId);
|
||||||
|
if (iter != procTriggered.end())
|
||||||
|
{
|
||||||
|
std::advance(iter, 1);
|
||||||
|
procTriggered.insert(iter, triggerData);
|
||||||
|
proccessed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proccessed)
|
||||||
|
{
|
||||||
|
procTriggered.push_front(triggerData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
procTriggered.push_front(triggerData);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing found
|
// Nothing found
|
||||||
|
|||||||
Reference in New Issue
Block a user