Core/Spells: Implement SPELL_ATTR4_PROC_ONLY_ON_CASTER properly. Closes #5204

This commit is contained in:
Liberate
2012-04-05 20:09:20 +02:00
parent 6759bcab16
commit 926f02f792
3 changed files with 29 additions and 17 deletions
@@ -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??
+17 -13
View File
@@ -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);
}
}
}
+11 -3
View File
@@ -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);