[9347] Restore wild gameobject casting.

Most visible case: gameobject based teleports.
This commit is contained in:
VladimirMangos 2010-02-10 08:01:33 +03:00
parent 841cf86402
commit 003deed894
2 changed files with 25 additions and 22 deletions

View file

@ -941,9 +941,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
return;
// Get original caster (if exist) and calculate damage/healing from him data
Unit *caster = GetAffectiveCaster();
if (!caster)
return;
Unit *real_caster = GetAffectiveCaster();
// FIXME: in case wild GO heal/damage spells will be used target bonuses
Unit *caster = real_caster ? real_caster : m_caster;
SpellMissInfo missInfo = target->missCondition;
// Need init unitTarget by default unit (can changed in code on reflect)
@ -971,7 +971,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Do healing and triggers
if (m_healing)
{
bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
bool crit = real_caster && real_caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
uint32 addhealth = m_healing;
if (crit)
{
@ -983,10 +983,14 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
{
caster->ProcDamageAndSpell(unitTarget, real_caster ? procAttacker : PROC_FLAG_NONE, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
}
int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo, crit);
unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
if (real_caster)
unitTarget->getHostileRefManager().threatAssist(real_caster, float(gain) * 0.5f, m_spellInfo);
}
// Do damage and triggers
else if (m_damage)
@ -996,6 +1000,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Add bonuses and fill damageInfo struct
caster->CalculateSpellDamage(&damageInfo, m_damage, m_spellInfo, m_attackType);
caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
// Send log damage message to client
@ -1006,7 +1011,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
caster->ProcDamageAndSpell(unitTarget, real_caster ? procAttacker : PROC_FLAG_NONE, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
// Haunt (NOTE: for avoid use additional field damage stored in dummy value (replace unused 100%)
// apply before deal damage because aura can be removed at target kill
@ -1025,26 +1030,24 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
procEx = createProcExtendMask(&damageInfo, missInfo);
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo);
caster->ProcDamageAndSpell(unit, real_caster ? procAttacker : PROC_FLAG_NONE, procVictim, procEx, 0, m_attackType, m_spellInfo);
}
// Call scripted function for AI if this spell is casted upon a creature
if(unit->GetTypeId() == TYPEID_UNIT)
if (unit->GetTypeId() == TYPEID_UNIT)
{
// cast at creature (or GO) quest objectives update at successful cast finished (+channel finished)
// ignore pets or autorepeat/melee casts for speed (not exist quest for spells (hm... )
if( !((Creature*)unit)->isPet() && !IsAutoRepeat() && !IsNextMeleeSwingSpell() && !IsChannelActive() )
{
if ( Player* p = m_caster->GetCharmerOrOwnerPlayerOrPlayerItself() )
if (real_caster && !((Creature*)unit)->isPet() && !IsAutoRepeat() && !IsNextMeleeSwingSpell() && !IsChannelActive())
if (Player* p = real_caster->GetCharmerOrOwnerPlayerOrPlayerItself())
p->CastedCreatureOrGO(unit->GetEntry(), unit->GetGUID(), m_spellInfo->Id);
}
if(((Creature*)unit)->AI())
((Creature*)unit)->AI()->SpellHit(m_caster, m_spellInfo);
}
// Call scripted function for AI if this spell is casted by a creature
if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->AI())
if (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->AI())
((Creature*)m_caster)->AI()->SpellHitTarget(unit, m_spellInfo);
}
@ -1054,15 +1057,14 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
return;
Unit* realCaster = GetAffectiveCaster();
if (!realCaster)
return;
// Recheck immune (only for delayed spells)
if (m_spellInfo->speed && (
unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo)) ||
unit->IsImmunedToSpell(m_spellInfo)))
{
realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
if (realCaster)
realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
return;
}
@ -1072,10 +1074,10 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
}
if (realCaster->GetTypeId() == TYPEID_PLAYER)
if (realCaster && realCaster->GetTypeId() == TYPEID_PLAYER)
((Player*)realCaster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
if (realCaster != unit)
if (realCaster && realCaster != unit)
{
// Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
if (m_spellInfo->speed > 0.0f &&
@ -1167,8 +1169,9 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// Get multiplier
float multiplier = m_spellInfo->DmgMultiplier[effectNumber];
// Apply multiplier mods
if(Player* modOwner = realCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier, this);
if (realCaster)
if(Player* modOwner = realCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier, this);
m_damageMultipliers[effectNumber] *= multiplier;
}
}