*Way more correct way of selecting caster and target for Periodic Trigger auras.

--HG--
branch : trunk
This commit is contained in:
QAston
2010-02-04 18:34:46 +01:00
parent 61cc641384
commit 3df5bb041c
4 changed files with 53 additions and 37 deletions

View File

@@ -1934,21 +1934,36 @@ void AuraEffect::PeriodicDummyTick(Unit * target, Unit * caster) const
Unit* AuraEffect::GetTriggerTarget(Unit * target) const
{
Unit * triggerTarget = NULL;
if (target->GetTypeId() == TYPEID_UNIT)
triggerTarget = ((Creature*)target)->AI()->GetAuraEffectTriggerTarget(GetId(), GetEffIndex());
return triggerTarget ? triggerTarget : ObjectAccessor::GetUnit(*target, target->GetUInt64Value(UNIT_FIELD_TARGET));
{
if (Unit * trigger = ((Creature*)target)->AI()->GetAuraEffectTriggerTarget(GetId(), GetEffIndex()))
return trigger;
}
return target;
}
Unit* AuraEffect::GetTriggerCaster(Unit * target, Unit * caster, SpellEntry const * triggeredSpell) const
{
for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS; ++i)
{
if (SpellTargetType[triggeredSpell->EffectImplicitTargetA[i]] == TARGET_TYPE_UNIT_TARGET
|| SpellTargetType[triggeredSpell->EffectImplicitTargetB[i]] == TARGET_TYPE_UNIT_TARGET
|| SpellTargetType[triggeredSpell->EffectImplicitTargetA[i]] == TARGET_TYPE_CHANNEL
|| SpellTargetType[triggeredSpell->EffectImplicitTargetB[i]] == TARGET_TYPE_CHANNEL
|| SpellTargetType[triggeredSpell->EffectImplicitTargetA[i]] == TARGET_TYPE_DEST_TARGET
|| SpellTargetType[triggeredSpell->EffectImplicitTargetB[i]] == TARGET_TYPE_DEST_TARGET)
return caster;
}
return target;
}
void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
{
Unit* triggerTarget = GetTriggerTarget(target);
if (!triggerTarget)
triggerTarget = target;
if(!caster || !target)
return;
Unit* triggerTarget = GetTriggerTarget(target);
// generic casting code with custom spells and target/caster customs
uint32 triggerSpellId = GetSpellProto()->EffectTriggerSpell[GetEffIndex()];
@@ -1971,9 +1986,10 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
break;
// Brood Affliction: Bronze
case 23170:
target->CastSpell(target, 23171, true, 0, this);
triggerSpellId = 23171;
return;
// Restoration
case 24379:
case 23493:
{
int32 heal = caster->GetMaxHealth() / 10;
@@ -2041,6 +2057,8 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
// Quake
case 30576: triggerSpellId = 30571; break;
// Doom
// TODO: effect trigger spell may be independant on spell targets, and executed in spell finish phase
// so instakill will be naturally done before trigger spell
case 31347:
{
target->CastSpell(target,31350,true, NULL, this);
@@ -2182,7 +2200,7 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
// Mana Tide
case 16191:
{
caster->CastCustomSpell(triggerTarget, triggerSpellId, &m_amount, NULL, NULL, true, NULL, this);
target->CastCustomSpell(triggerTarget, triggerSpellId, &m_amount, NULL, NULL, true, NULL, this);
return;
}
// Negative Energy Periodic
@@ -2194,45 +2212,38 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
case 54362:
target->CastCustomSpell(triggerSpellId, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000), NULL, true, NULL, this);
return;
// Mind Sear (target 76/16) if let target cast, will damage caster
case 48045:
case 53023:
// Curse of the Plaguebringer (22/15)
case 29213:
case 54835:
caster->CastSpell(target, triggerSpellId, true, NULL, this);
return;
// Ground Slam
case 33525:
target->CastSpell(triggerTarget, triggerSpellId, true);
return;
}
}
if(triggeredSpellInfo)
{
if(!caster->GetSpellMaxRangeForTarget(target,sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
triggerTarget = target; //for druid dispel poison
target->CastSpell(triggerTarget, triggeredSpellInfo, true, 0, this, GetCasterGUID());
Unit * triggerCaster = GetTriggerCaster(triggerTarget, caster, triggeredSpellInfo);
triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, 0, this, GetCasterGUID());
sLog.outDebug("AuraEffect::TriggerSpell: Spell %u Trigger %u",GetId(), triggeredSpellInfo->Id);
}
else if(target->GetTypeId()!=TYPEID_UNIT || !sScriptMgr.EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)target))
else if(target->GetTypeId()!=TYPEID_UNIT || !sScriptMgr.EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)triggerTarget))
sLog.outError("AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
}
void AuraEffect::TriggerSpellWithValue(Unit * target, Unit * caster) const
{
Unit* triggerTarget = GetTriggerTarget(target);
if (!triggerTarget)
triggerTarget = target;
if(!caster || !target)
return;
// generic casting code with custom spells and target/caster customs
uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
int32 basepoints0 = GetAmount();
Unit* triggerTarget = GetTriggerTarget(target);
caster->CastCustomSpell(triggerTarget, trigger_spell_id, &basepoints0, 0, 0, true, 0, this);
uint32 triggerSpellId = GetSpellProto()->EffectTriggerSpell[m_effIndex];
SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(triggerSpellId);
if(triggeredSpellInfo)
{
Unit * triggerCaster = GetTriggerCaster(triggerTarget, caster, triggeredSpellInfo);
// generic casting code with custom spells and target/caster customs
int32 basepoints0 = GetAmount();
triggerCaster->CastCustomSpell(triggerTarget, triggerSpellId, &basepoints0, 0, 0, true, 0, this);
}
else
sLog.outError("AuraEffect::TriggerSpellWithValue: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
}
bool AuraEffect::IsAffectedOnSpell(SpellEntry const *spell) const

View File

@@ -72,6 +72,7 @@ class TRINITY_DLL_SPEC AuraEffect
void PeriodicTick(Unit * target, Unit * caster) const;
void PeriodicDummyTick(Unit * target, Unit * caster) const;
Unit* GetTriggerTarget(Unit * target) const;
Unit* GetTriggerCaster(Unit * target, Unit * caster, SpellEntry const * triggeredSpell) const;
void TriggerSpell(Unit * target, Unit * caster) const;
void TriggerSpellWithValue(Unit * target, Unit * caster) const;

View File

@@ -3725,12 +3725,14 @@ void SpellMgr::LoadSpellCustomAttr()
break;
case 62374: // Pursued
spellInfo->MaxAffectedTargets = 1;
spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_AREA_ENTRY_SRC;
spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_AREA_ENTRY_SRC;
count++;
break;
case 13810: // Frost Trap Aura
spellInfo->Effect[1] = 0;
// target allys instead of enemies, target A is src_caster, spells with effect like that have ally target
// this is the only known exception, probably just wrong data
case SPELL_WRATH_OF_THE_PLAGUEBRINGER_29214: // Wrath of the Plaguebringer
case SPELL_WRATH_OF_THE_PLAGUEBRINGER_54836: // Wrath of the Plaguebringer
spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_AREA_ALLY_SRC;
spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_AREA_ALLY_SRC;
count++;
break;
default:

View File

@@ -922,6 +922,8 @@ class SpellMgr
{
spellid_1 = GetFirstSpellInChain(spellid_1);
spellid_2 = GetFirstSpellInChain(spellid_2);
if (spellid_1 == spellid_2)
return SPELL_GROUP_STACK_RULE_DEFAULT;
// find SpellGroups which are common for both spells
SpellSpellGroupMapBounds spellGroup1 = GetSpellSpellGroupMapBounds(spellid_1);
std::set<SpellGroup> groups;