[7111] Fixes in Spell Effect immunes

Correct totem immunes for dot/leech/Fear/Transform auras (immune only to effect)
Correct log if all effects immuned by Effect Immune
Move check for IMMUNITY_STATE to Unit::IsImmunedToSpellEffect

Signed-off-by: DiSlord <dislord@nomail.com>
This commit is contained in:
DiSlord 2009-01-19 02:51:32 +03:00
parent c9ae3b8b5c
commit 17004d59d4
11 changed files with 61 additions and 53 deletions

View file

@ -1547,12 +1547,12 @@ bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo)
return Unit::IsImmunedToSpell(spellInfo); return Unit::IsImmunedToSpell(spellInfo);
} }
bool Creature::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{ {
if (GetCreatureInfo()->MechanicImmuneMask & (1 << (mechanic-1))) if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1)))
return true; return true;
return Unit::IsImmunedToSpellEffect(effect, mechanic); return Unit::IsImmunedToSpellEffect(spellInfo, index);
} }
SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)

View file

@ -433,7 +433,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
bool IsOutOfThreatArea(Unit* pVictim) const; bool IsOutOfThreatArea(Unit* pVictim) const;
bool IsImmunedToSpell(SpellEntry const* spellInfo); bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefine Unit::IsImmunedToSpell // redefine Unit::IsImmunedToSpell
bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const; bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefine Unit::IsImmunedToSpellEffect // redefine Unit::IsImmunedToSpellEffect
bool isElite() const bool isElite() const
{ {

View file

@ -170,7 +170,7 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target)
SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId()); SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
uint32 eff_index = i_dynobject.GetEffIndex(); uint32 eff_index = i_dynobject.GetEffIndex();
// Check target immune to spell or aura // Check target immune to spell or aura
if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo->Effect[eff_index], spellInfo->EffectMechanic[eff_index])) if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index))
return; return;
// Apply PersistentAreaAura on target // Apply PersistentAreaAura on target
PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster()); PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster());

View file

@ -757,8 +757,6 @@ void Spell::CleanupTargetList()
m_UniqueTargetInfo.clear(); m_UniqueTargetInfo.clear();
m_UniqueGOTargetInfo.clear(); m_UniqueGOTargetInfo.clear();
m_UniqueItemInfo.clear(); m_UniqueItemInfo.clear();
m_countOfHit = 0;
m_countOfMiss = 0;
m_delayMoment = 0; m_delayMoment = 0;
} }
@ -767,6 +765,9 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
if( m_spellInfo->Effect[effIndex]==0 ) if( m_spellInfo->Effect[effIndex]==0 )
return; return;
// Check for effect immune skip if immuned
bool immuned = pVictim->IsImmunedToSpellEffect(m_spellInfo, effIndex);
uint64 targetGUID = pVictim->GetGUID(); uint64 targetGUID = pVictim->GetGUID();
// Lookup target in already in list // Lookup target in already in list
@ -774,7 +775,8 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
{ {
if (targetGUID == ihit->targetGUID) // Found in list if (targetGUID == ihit->targetGUID) // Found in list
{ {
ihit->effectMask |= 1<<effIndex; // Add only effect mask if (!immuned)
ihit->effectMask |= 1<<effIndex; // Add only effect mask if not immuned
return; return;
} }
} }
@ -784,15 +786,11 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
// Get spell hit result on target // Get spell hit result on target
TargetInfo target; TargetInfo target;
target.targetGUID = targetGUID; // Store target GUID target.targetGUID = targetGUID; // Store target GUID
target.effectMask = 1<<effIndex; // Store index of effect target.effectMask = immuned ? 0 : 1<<effIndex; // Store index of effect if not immuned
target.processed = false; // Effects not apply on target target.processed = false; // Effects not apply on target
// Calculate hit result // Calculate hit result
target.missCondition = m_caster->SpellHitResult(pVictim, m_spellInfo, m_canReflect); target.missCondition = m_caster->SpellHitResult(pVictim, m_spellInfo, m_canReflect);
if (target.missCondition == SPELL_MISS_NONE)
++m_countOfHit;
else
++m_countOfMiss;
// Spell have speed - need calculate incoming time // Spell have speed - need calculate incoming time
if (m_spellInfo->speed > 0.0f) if (m_spellInfo->speed > 0.0f)
@ -872,8 +870,6 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
else else
target.timeDelay = 0LL; target.timeDelay = 0LL;
++m_countOfHit;
// Add target to list // Add target to list
m_UniqueGOTargetInfo.push_back(target); m_UniqueGOTargetInfo.push_back(target);
} }
@ -916,8 +912,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Get mask of effects for target // Get mask of effects for target
uint32 mask = target->effectMask; uint32 mask = target->effectMask;
if (mask == 0) // No effects
return;
Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID); Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID);
if (!unit) if (!unit)
@ -2985,7 +2979,23 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
void Spell::WriteSpellGoTargets( WorldPacket * data ) void Spell::WriteSpellGoTargets( WorldPacket * data )
{ {
*data << (uint8)m_countOfHit; uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO
uint32 miss = 0;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
{
// possibly SPELL_MISS_IMMUNE2 for this??
ihit->missCondition = SPELL_MISS_IMMUNE2;
miss++;
}
else if ((*ihit).missCondition == SPELL_MISS_NONE)
hit++;
else
miss++;
}
*data << (uint8)hit;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
*data << uint64(ihit->targetGUID); *data << uint64(ihit->targetGUID);
@ -2993,7 +3003,7 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit) for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit)
*data << uint64(ighit->targetGUID); // Always hits *data << uint64(ighit->targetGUID); // Always hits
*data << (uint8)m_countOfMiss; *data << (uint8)miss;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{ {
if( ihit->missCondition != SPELL_MISS_NONE ) // Add only miss if( ihit->missCondition != SPELL_MISS_NONE ) // Add only miss
@ -3501,16 +3511,11 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
gameObjTarget = pGOTarget; gameObjTarget = pGOTarget;
uint8 eff = m_spellInfo->Effect[i]; uint8 eff = m_spellInfo->Effect[i];
uint32 mechanic = m_spellInfo->EffectMechanic[i];
damage = int32(CalculateDamage((uint8)i,unitTarget)*DamageMultiplier); damage = int32(CalculateDamage((uint8)i,unitTarget)*DamageMultiplier);
sLog.outDebug( "Spell: Effect : %u", eff); sLog.outDebug( "Spell: Effect : %u", eff);
//Simply return. Do not display "immune" in red text on client
if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic))
return;
if(eff<TOTAL_SPELL_EFFECTS) if(eff<TOTAL_SPELL_EFFECTS)
{ {
//sLog.outDebug( "WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff); //sLog.outDebug( "WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff);

View file

@ -497,8 +497,6 @@ class Spell
// Spell target subsystem // Spell target subsystem
//***************************************** //*****************************************
// Targets store structures and data // Targets store structures and data
uint32 m_countOfHit;
uint32 m_countOfMiss;
struct TargetInfo struct TargetInfo
{ {
uint64 targetGUID; uint64 targetGUID;

View file

@ -2212,11 +2212,6 @@ void Spell::EffectApplyAura(uint32 i)
if(!unitTarget) if(!unitTarget)
return; return;
SpellImmuneList const& list = unitTarget->m_spellImmune[IMMUNITY_STATE];
for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
if(itr->type == m_spellInfo->EffectApplyAuraName[i])
return;
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 && if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 &&
(unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) ) (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
@ -5342,9 +5337,6 @@ void Spell::EffectSummonTotem(uint32 i)
if(m_caster->GetTypeId() == TYPEID_PLAYER) if(m_caster->GetTypeId() == TYPEID_PLAYER)
pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_MOD_FEAR,true);
pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_TRANSFORM,true);
pTotem->Summon(m_caster); pTotem->Summon(m_caster);
if(slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER) if(slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER)

View file

@ -159,18 +159,18 @@ void Totem::SetTypeBySummonSpell(SpellEntry const * spellProto)
m_type = TOTEM_STATUE; //Jewelery statue m_type = TOTEM_STATUE; //Jewelery statue
} }
bool Totem::IsImmunedToSpell(SpellEntry const* spellInfo) bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{ {
for (int i=0;i<3;i++) // TODO: possibly all negative auras immuned?
switch(spellInfo->EffectApplyAuraName[index])
{ {
switch(spellInfo->EffectApplyAuraName[i]) case SPELL_AURA_PERIODIC_DAMAGE:
{ case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_PERIODIC_DAMAGE: case SPELL_AURA_MOD_FEAR:
case SPELL_AURA_PERIODIC_LEECH: case SPELL_AURA_TRANSFORM:
return true; return true;
default: default:
continue; break;
}
} }
return Creature::IsImmunedToSpell(spellInfo); return Creature::IsImmunedToSpellEffect(spellInfo, index);
} }

View file

@ -53,7 +53,7 @@ class Totem : public Creature
void UpdateAttackPowerAndDamage(bool /*ranged*/ ) {} void UpdateAttackPowerAndDamage(bool /*ranged*/ ) {}
void UpdateDamagePhysical(WeaponAttackType /*attType*/) {} void UpdateDamagePhysical(WeaponAttackType /*attType*/) {}
bool IsImmunedToSpell(SpellEntry const* spellInfo); bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
protected: protected:
TotemType m_type; TotemType m_type;

View file

@ -8157,19 +8157,32 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
return false; return false;
} }
bool Unit::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{ {
//If m_immuneToEffect type contain this effect type, IMMUNE effect. //If m_immuneToEffect type contain this effect type, IMMUNE effect.
uint32 effect = spellInfo->Effect[index];
SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr) for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
if(itr->type == effect) if(itr->type == effect)
return true; return true;
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; uint32 mechanic = spellInfo->EffectMechanic[index];
for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) if (mechanic)
if(itr->type == mechanic) {
return true; SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
if(itr->type == mechanic)
return true;
}
uint32 aura = spellInfo->EffectApplyAuraName[index];
if (aura)
{
SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];
for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
if(itr->type == aura)
return true;
}
return false; return false;
} }

View file

@ -1319,7 +1319,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
virtual bool IsImmunedToSpell(SpellEntry const* spellInfo); virtual bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefined in Creature // redefined in Creature
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask); bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask);
virtual bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const; virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefined in Creature // redefined in Creature
uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage); uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7110" #define REVISION_NR "7111"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__