Core/Spells: Implement SPELL_ATTR4_PROC_ONLY_ON_CASTER properly. Closes #5204
This commit is contained in:
@@ -411,7 +411,7 @@ enum SpellAttr3
|
||||
enum SpellAttr4
|
||||
{
|
||||
SPELL_ATTR4_UNK0 = 0x00000001, // 0
|
||||
SPELL_ATTR4_PROC_ONLY_ON_DUMMY = 0x00000002, // 1 proc only on SPELL_EFFECT_DUMMY?
|
||||
SPELL_ATTR4_PROC_ONLY_ON_CASTER = 0x00000002, // 1 proc only on effects with TARGET_UNIT_CASTER?
|
||||
SPELL_ATTR4_UNK2 = 0x00000004, // 2
|
||||
SPELL_ATTR4_UNK3 = 0x00000008, // 3
|
||||
SPELL_ATTR4_UNK4 = 0x00000010, // 4 This will no longer cause guards to attack on use??
|
||||
|
||||
@@ -2745,18 +2745,18 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask)
|
||||
if (!m_hitTriggerSpells.empty())
|
||||
{
|
||||
int _duration = 0;
|
||||
for (HitTriggerSpells::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
|
||||
for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
|
||||
{
|
||||
if (CanExecuteTriggersOnHit(effMask, i->first) && roll_chance_i(i->second))
|
||||
if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
|
||||
{
|
||||
m_caster->CastSpell(unit, i->first, true);
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->first->Id);
|
||||
m_caster->CastSpell(unit, i->triggeredSpell, true);
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
|
||||
|
||||
// SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
|
||||
// set duration of current aura to the triggered spell
|
||||
if (i->first->GetDuration() == -1)
|
||||
if (i->triggeredSpell->GetDuration() == -1)
|
||||
{
|
||||
if (Aura* triggeredAur = unit->GetAura(i->first->Id, m_caster->GetGUID()))
|
||||
if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
|
||||
{
|
||||
// get duration from aura-only once
|
||||
if (!_duration)
|
||||
@@ -7171,14 +7171,13 @@ void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTarget
|
||||
}
|
||||
}
|
||||
|
||||
bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* spellInfo) const
|
||||
bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura) const
|
||||
{
|
||||
bool only_on_dummy = (spellInfo && (spellInfo->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_DUMMY));
|
||||
// If triggered spell has SPELL_ATTR4_PROC_ONLY_ON_DUMMY then it can only proc on a casted spell with SPELL_EFFECT_DUMMY
|
||||
// If triggered spell doesn't have SPELL_ATTR4_PROC_ONLY_ON_DUMMY then it can NOT proc on SPELL_EFFECT_DUMMY (needs confirmation)
|
||||
bool only_on_caster = (triggeredByAura && (triggeredByAura->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_CASTER));
|
||||
// If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a casted spell with TARGET_UNIT_CASTER
|
||||
for (uint8 i = 0;i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if ((effMask & (1 << i)) && (only_on_dummy == (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DUMMY)))
|
||||
if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -7230,9 +7229,14 @@ void Spell::PrepareTriggersExecutedOnHit()
|
||||
// calculate the chance using spell base amount, because aura amount is not updated on combo-points change
|
||||
// this possibly needs fixing
|
||||
int32 auraBaseAmount = (*i)->GetBaseAmount();
|
||||
int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
|
||||
// proc chance is stored in effect amount
|
||||
m_hitTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetBase()->GetStackAmount()));
|
||||
int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
|
||||
// build trigger and add to the list
|
||||
HitTriggerSpell spellTriggerInfo;
|
||||
spellTriggerInfo.triggeredSpell = spellInfo;
|
||||
spellTriggerInfo.triggeredByAura = auraSpellInfo;
|
||||
spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
|
||||
m_hitTriggerSpells.push_back(spellTriggerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,10 +633,18 @@ class Spell
|
||||
void CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex);
|
||||
std::list<SpellScript*> m_loadedScripts;
|
||||
|
||||
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* spellInfo = NULL) const;
|
||||
struct HitTriggerSpell
|
||||
{
|
||||
SpellInfo const* triggeredSpell;
|
||||
SpellInfo const* triggeredByAura;
|
||||
// uint8 triggeredByEffIdx This might be needed at a later stage - No need known for now
|
||||
int32 chance;
|
||||
};
|
||||
|
||||
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura = NULL) const;
|
||||
void PrepareTriggersExecutedOnHit();
|
||||
typedef std::list< std::pair<SpellInfo const*, int32> > HitTriggerSpells;
|
||||
HitTriggerSpells m_hitTriggerSpells;
|
||||
typedef std::list<HitTriggerSpell> HitTriggerSpellList;
|
||||
HitTriggerSpellList m_hitTriggerSpells;
|
||||
|
||||
// effect helpers
|
||||
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numSummons);
|
||||
|
||||
Reference in New Issue
Block a user