mirror of
https://github.com/mangosfour/server.git
synced 2025-12-29 07:37:05 +00:00
[11766] fix spell redirection and totem destruction on hit by redirected spell
This commit is contained in:
parent
61f31980cf
commit
c60425c6bd
11 changed files with 73 additions and 26 deletions
|
|
@ -392,6 +392,8 @@ Spell::Spell( Unit* caster, SpellEntry const *info, bool triggered, ObjectGuid o
|
|||
// determine reflection
|
||||
m_canReflect = false;
|
||||
|
||||
m_spellFlags = SPELL_FLAG_NORMAL;
|
||||
|
||||
if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED))
|
||||
{
|
||||
for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
|
||||
|
|
@ -804,6 +806,9 @@ void Spell::AddUnitTarget(Unit* pVictim, SpellEffectIndex effIndex)
|
|||
// Check for effect immune skip if immuned
|
||||
bool immuned = pVictim->IsImmuneToSpellEffect(m_spellInfo, effIndex);
|
||||
|
||||
if (pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsTotem() && (m_spellFlags & SPELL_FLAG_REDIRECTED))
|
||||
immuned = false;
|
||||
|
||||
ObjectGuid targetGUID = pVictim->GetObjectGuid();
|
||||
|
||||
// Lookup target in already in list
|
||||
|
|
@ -858,6 +863,8 @@ void Spell::AddUnitTarget(Unit* pVictim, SpellEffectIndex effIndex)
|
|||
|
||||
// Increase time interval for reflected spells by 1.5
|
||||
target.timeDelay += target.timeDelay >> 1;
|
||||
|
||||
m_spellFlags |= SPELL_FLAG_REFLECTED;
|
||||
}
|
||||
else
|
||||
target.reflectResult = SPELL_MISS_NONE;
|
||||
|
|
@ -1004,7 +1011,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
{
|
||||
if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
|
||||
{
|
||||
DoSpellHitOnUnit(m_caster, mask, true);
|
||||
DoSpellHitOnUnit(m_caster, mask);
|
||||
unitTarget = m_caster;
|
||||
}
|
||||
}
|
||||
|
|
@ -1147,7 +1154,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
((Creature*)m_caster)->AI()->SpellHitTarget(unit, m_spellInfo);
|
||||
}
|
||||
|
||||
void Spell::DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool isReflected)
|
||||
void Spell::DoSpellHitOnUnit(Unit *unit, uint32 effectMask)
|
||||
{
|
||||
if (!unit || !effectMask)
|
||||
return;
|
||||
|
|
@ -1298,7 +1305,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool isReflected)
|
|||
if (duration > 0)
|
||||
{
|
||||
int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, m_spellInfo);
|
||||
unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel, limitduration, isReflected);
|
||||
unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel, limitduration, m_spellFlags & SPELL_FLAG_REFLECTED);
|
||||
|
||||
// Fully diminished
|
||||
if (duration == 0)
|
||||
|
|
@ -1819,6 +1826,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
if(Unit* pUnitTarget = m_caster->SelectMagnetTarget(m_targets.getUnitTarget(), this, effIndex))
|
||||
{
|
||||
m_targets.setUnitTarget(pUnitTarget);
|
||||
m_spellFlags |= SPELL_FLAG_REDIRECTED;
|
||||
targetUnitMap.push_back(pUnitTarget);
|
||||
}
|
||||
}
|
||||
|
|
@ -2257,6 +2265,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
if(Unit* pUnitTarget = m_caster->SelectMagnetTarget(m_targets.getUnitTarget(), this, effIndex))
|
||||
{
|
||||
m_targets.setUnitTarget(pUnitTarget);
|
||||
m_spellFlags |= SPELL_FLAG_REDIRECTED;
|
||||
targetUnitMap.push_back(pUnitTarget);
|
||||
}
|
||||
}
|
||||
|
|
@ -2287,6 +2296,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
if(Unit* pUnitTarget = m_caster->SelectMagnetTarget(m_targets.getUnitTarget(), this, effIndex))
|
||||
{
|
||||
m_targets.setUnitTarget(pUnitTarget);
|
||||
m_spellFlags |= SPELL_FLAG_REDIRECTED;
|
||||
targetUnitMap.push_back(pUnitTarget);
|
||||
}
|
||||
break;
|
||||
|
|
@ -2902,13 +2912,18 @@ void Spell::cancel()
|
|||
|
||||
case SPELL_STATE_CASTING:
|
||||
{
|
||||
for(TargetList::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
for(TargetList::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
{
|
||||
if (ihit->missCondition == SPELL_MISS_NONE)
|
||||
{
|
||||
Unit* unit = m_caster->GetObjectGuid() == (*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
|
||||
if (unit && unit->isAlive())
|
||||
unit->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetObjectGuid());
|
||||
|
||||
// prevent other effects applying if spell is already interrupted
|
||||
// i.e. if effects have different targets and it was interrupted on one of them when
|
||||
// haven't yet applied to another
|
||||
ihit->processed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ enum SpellCastFlags
|
|||
CAST_FLAG_IMMUNITY = 0x04000000 // spell cast school imminity info
|
||||
};
|
||||
|
||||
enum SpellFlags
|
||||
{
|
||||
SPELL_FLAG_NORMAL = 0x00,
|
||||
SPELL_FLAG_REFLECTED = 0x01, // reflected spell
|
||||
SPELL_FLAG_REDIRECTED = 0x02 // redirected spell
|
||||
};
|
||||
|
||||
enum SpellNotifyPushType
|
||||
{
|
||||
PUSH_IN_FRONT,
|
||||
|
|
@ -514,6 +521,7 @@ class Spell
|
|||
int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare
|
||||
int32 m_duration;
|
||||
bool m_canReflect; // can reflect this spell?
|
||||
uint8 m_spellFlags; // for spells whose target was changed in cast i.e. due to reflect
|
||||
bool m_autoRepeat;
|
||||
uint8 m_runesState;
|
||||
|
||||
|
|
@ -615,7 +623,7 @@ class Spell
|
|||
void HandleDelayedSpellLaunch(TargetInfo *target);
|
||||
void InitializeDamageMultipliers();
|
||||
void ResetEffectDamageAndHeal();
|
||||
void DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool isReflected = false);
|
||||
void DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
|
||||
void DoAllEffectOnTarget(GOTargetInfo *target);
|
||||
void DoAllEffectOnTarget(ItemTargetInfo *target);
|
||||
bool IsAliveUnitPresentInTargetList();
|
||||
|
|
|
|||
|
|
@ -8383,9 +8383,9 @@ void Aura::HandleAuraModAllCritChance(bool apply, bool Real)
|
|||
((Player*)target)->UpdateAllSpellCritChances();
|
||||
}
|
||||
|
||||
void Aura::HandleAuraStopNaturalManaRegen(bool apply, bool real)
|
||||
void Aura::HandleAuraStopNaturalManaRegen(bool apply, bool Real)
|
||||
{
|
||||
if (!real)
|
||||
if (!Real)
|
||||
return;
|
||||
|
||||
GetTarget()->ApplyModFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER, !apply && !GetTarget()->IsUnderLastManaUseEffect());
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
void HandleAuraModAllCritChance(bool Apply, bool Real);
|
||||
void HandleAuraOpenStable(bool apply, bool Real);
|
||||
void HandleAuraAddMechanicAbilities(bool apply, bool Real);
|
||||
void HandleAuraStopNaturalManaRegen(bool apply, bool real);
|
||||
void HandleAuraStopNaturalManaRegen(bool apply, bool Real);
|
||||
|
||||
virtual ~Aura();
|
||||
|
||||
|
|
|
|||
|
|
@ -6042,7 +6042,7 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, Spell* spell, SpellEffectIndex eff)
|
|||
return NULL;
|
||||
|
||||
// Magic case
|
||||
if (spell && (spell->m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE || spell->m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC))
|
||||
if (spell && spell->m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
|
||||
{
|
||||
Unit::AuraList const& magnetAuras = victim->GetAurasByType(SPELL_AURA_SPELL_MAGNET);
|
||||
for(Unit::AuraList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
|
||||
|
|
@ -6050,12 +6050,7 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, Spell* spell, SpellEffectIndex eff)
|
|||
if (Unit* magnet = (*itr)->GetCaster())
|
||||
{
|
||||
if (magnet->isAlive() && magnet->IsWithinLOSInMap(this) && spell->CheckTarget(magnet, eff))
|
||||
{
|
||||
if (SpellAuraHolder *holder = (*itr)->GetHolder())
|
||||
if (holder->DropAuraCharge())
|
||||
victim->RemoveSpellAuraHolder(holder);
|
||||
return magnet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6070,12 +6065,7 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, Spell* spell, SpellEffectIndex eff)
|
|||
if (magnet->isAlive() && magnet->IsWithinLOSInMap(this) && (!spell || spell->CheckTarget(magnet, eff)))
|
||||
{
|
||||
if (roll_chance_i((*i)->GetModifier()->m_amount))
|
||||
{
|
||||
if (SpellAuraHolder *holder = (*i)->GetHolder())
|
||||
if (holder->DropAuraCharge())
|
||||
victim->RemoveSpellAuraHolder(holder);
|
||||
return magnet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9739,8 +9729,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
|
|||
if (!triggeredByAura)
|
||||
continue;
|
||||
|
||||
Modifier *auraModifier = triggeredByAura->GetModifier();
|
||||
|
||||
if (procSpell)
|
||||
{
|
||||
if (spellProcEvent)
|
||||
|
|
@ -9769,7 +9757,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
|
|||
continue;
|
||||
}
|
||||
|
||||
SpellAuraProcResult procResult = (*this.*AuraProcHandler[auraModifier->m_auraname])(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown);
|
||||
SpellAuraProcResult procResult = (*this.*AuraProcHandler[triggeredByHolder->GetSpellProto()->EffectApplyAuraName[i]])(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown);
|
||||
switch (procResult)
|
||||
{
|
||||
case SPELL_AURA_PROC_CANT_TRIGGER:
|
||||
|
|
|
|||
|
|
@ -1849,6 +1849,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
SpellAuraProcResult HandleAddPctModifierAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleModDamagePercentDoneAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleModRating(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleSpellMagnetAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleManaShieldAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleModResistanceAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleNULLProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* /*triggeredByAura*/, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/)
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ pAuraProcHandler AuraProcHandler[TOTAL_AURAS]=
|
|||
&Unit::HandleNULLProc, // 93 SPELL_AURA_MOD_UNATTACKABLE
|
||||
&Unit::HandleNULLProc, // 94 SPELL_AURA_INTERRUPT_REGEN
|
||||
&Unit::HandleNULLProc, // 95 SPELL_AURA_GHOST
|
||||
&Unit::HandleNULLProc, // 96 SPELL_AURA_SPELL_MAGNET
|
||||
&Unit::HandleSpellMagnetAuraProc, // 96 SPELL_AURA_SPELL_MAGNET
|
||||
&Unit::HandleManaShieldAuraProc, // 97 SPELL_AURA_MANA_SHIELD
|
||||
&Unit::HandleNULLProc, // 98 SPELL_AURA_MOD_SKILL_TALENT
|
||||
&Unit::HandleNULLProc, // 99 SPELL_AURA_MOD_ATTACK_POWER
|
||||
|
|
@ -3974,6 +3974,20 @@ SpellAuraProcResult Unit::HandleModRating(Unit* /*pVictim*/, uint32 /*damage*/,
|
|||
return SPELL_AURA_PROC_OK;
|
||||
}
|
||||
|
||||
SpellAuraProcResult Unit::HandleSpellMagnetAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
|
||||
{
|
||||
if (triggeredByAura->GetId() == 8178) // Grounding Totem Effect
|
||||
{
|
||||
// for spells that doesn't do damage but need to destroy totem anyway
|
||||
if ((!damage || damage < GetHealth()) && GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsTotem())
|
||||
{
|
||||
DealDamage(this, GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
return SPELL_AURA_PROC_OK;
|
||||
}
|
||||
}
|
||||
return SPELL_AURA_PROC_OK;
|
||||
}
|
||||
|
||||
SpellAuraProcResult Unit::HandleManaShieldAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
|
||||
{
|
||||
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue