diff options
Diffstat (limited to 'src/game/SpellAuras.cpp')
-rw-r--r-- | src/game/SpellAuras.cpp | 195 |
1 files changed, 64 insertions, 131 deletions
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c3d4b62a4a2..f9e44697ca4 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3338,7 +3338,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real) m_target->addUnitState(UNIT_STAT_DIED); m_target->CombatStop(); - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); // prevent interrupt message if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL]) @@ -3417,62 +3417,30 @@ void Aura::HandleAuraModDisarm(bool apply, bool Real) void Aura::HandleModStealth(bool apply, bool Real) { + if(!Real) + return; + if(apply) { - if(Real && m_target->GetTypeId()==TYPEID_PLAYER) - { - // drop flag at stealth in bg - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); - - // remove player from the objective's active player count at stealth - if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP()) - pvp->HandlePlayerActivityChanged((Player*)m_target); - } + // drop flag at stealth in bg + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); - // only at real aura add - if(Real) - { - m_target->SetStandFlags(UNIT_STAND_FLAGS_CREEP); - if(m_target->GetTypeId()==TYPEID_PLAYER) - m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000); + m_target->SetStandFlags(UNIT_STAND_FLAGS_CREEP); + if(m_target->GetTypeId()==TYPEID_PLAYER) + m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000); - // apply only if not in GM invisibility (and overwrite invisibility state) - if(m_target->GetVisibility()!=VISIBILITY_OFF) - { - //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); - //m_target->SetVisibility(VISIBILITY_OFF); - m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); - } - } + // apply only if not in GM invisibility (and overwrite invisibility state) + if(m_target->GetVisibility() != VISIBILITY_OFF) + m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); } - else + else if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH { - // only at real aura remove - if(Real) - { - // if last SPELL_AURA_MOD_STEALTH and no GM invisibility - if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF) - { - m_target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP); - if(m_target->GetTypeId()==TYPEID_PLAYER) - m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000); + m_target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP); + if(m_target->GetTypeId()==TYPEID_PLAYER) + m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000); - // restore invisibility if any - if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) - { - //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); - //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); - m_target->SetVisibility(VISIBILITY_ON); - } - else - { - m_target->SetVisibility(VISIBILITY_ON); - if(m_target->GetTypeId() == TYPEID_PLAYER) - if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP()) - pvp->HandlePlayerActivityChanged((Player*)m_target); - } - } - } + if(m_target->GetVisibility() != VISIBILITY_OFF) + m_target->SetVisibility(VISIBILITY_ON); } } @@ -3482,24 +3450,15 @@ void Aura::HandleInvisibility(bool apply, bool Real) { m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue); - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); - - if(Real && m_target->GetTypeId()==TYPEID_PLAYER) + if(Real) { + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); + // apply glow vision - m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); - // remove player from the objective's active player count at invisibility - if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP()) - pvp->HandlePlayerActivityChanged((Player*)m_target); - } + if(m_target->GetTypeId()==TYPEID_PLAYER) + m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); - // apply only if not in GM invisibility and not stealth - if(m_target->GetVisibility()==VISIBILITY_ON) - { - // Aura not added yet but visibility code expect temporary add aura - //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); - //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); - m_target->SetVisibility(VISIBILITY_ON); + m_target->SetToNotify(); } } else @@ -3511,24 +3470,13 @@ void Aura::HandleInvisibility(bool apply, bool Real) m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue); // only at real aura remove and if not have different invisibility auras. - if(Real && m_target->m_invisibilityMask==0) + if(Real) { // remove glow vision - if(m_target->GetTypeId() == TYPEID_PLAYER) + if(!m_target->m_invisibilityMask && m_target->GetTypeId() == TYPEID_PLAYER) m_target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); - // apply only if not in GM invisibility & not stealthed while invisible - if(m_target->GetVisibility()!=VISIBILITY_OFF) - { - // if have stealth aura then already have stealth visibility - if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) - { - m_target->SetVisibility(VISIBILITY_ON); - if(m_target->GetTypeId() == TYPEID_PLAYER) - if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP()) - pvp->HandlePlayerActivityChanged((Player*)m_target); - } - } + m_target->SetToNotify(); } } } @@ -3872,42 +3820,19 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real) } } +//this method is called whenever we add / remove aura which gives m_target some imunity to some spell effect void Aura::HandleAuraModEffectImmunity(bool apply, bool Real) { - if(!apply) + // when removing flag aura, handle flag drop + if( !apply && m_target->GetTypeId() == TYPEID_PLAYER + && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION) ) { if(m_target->GetTypeId() == TYPEID_PLAYER) { if(((Player*)m_target)->InBattleGround()) { - BattleGround *bg = ((Player*)m_target)->GetBattleGround(); - if(bg) - { - switch(bg->GetTypeID()) - { - case BATTLEGROUND_AV: - { - break; - } - case BATTLEGROUND_WS: - { - // Warsong Flag, horde // Silverwing Flag, alliance - if(GetId() == 23333 || GetId() == 23335) - bg->EventPlayerDroppedFlag(((Player*)m_target)); - break; - } - case BATTLEGROUND_AB: - { - break; - } - case BATTLEGROUND_EY: - { - if(GetId() == 34976) - bg->EventPlayerDroppedFlag(((Player*)m_target)); - break; - } - } - } + if( BattleGround *bg = ((Player*)m_target)->GetBattleGround() ) + bg->EventPlayerDroppedFlag(((Player*)m_target)); } else sOutdoorPvPMgr.HandleDropFlag((Player*)m_target,GetSpellProto()->Id); @@ -3940,32 +3865,37 @@ void Aura::HandleAuraModStateImmunity(bool apply, bool Real) void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real) { if(apply && m_modifier.m_miscvalue == SPELL_SCHOOL_MASK_NORMAL) - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply); - if(Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) + // remove all flag auras (they are positive, but they must be removed when you are immune) + if( this->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY + && this->GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD ) + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); + + // TODO: optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else + if( Real && apply + && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY + && IsPositiveSpell(GetId()) ) //Only positive immunity removes auras { - if(IsPositiveSpell(GetId())) //Only positive immunity removes auras + uint32 school_mask = m_modifier.m_miscvalue; + Unit::AuraMap& Auras = m_target->GetAuras(); + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) { - uint32 school_mask = m_modifier.m_miscvalue; - Unit::AuraMap& Auras = m_target->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + next = iter; + ++next; + SpellEntry const *spell = iter->second->GetSpellProto(); + if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask + && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability + && !iter->second->IsPositive() //Don't remove positive spells + && spell->Id != GetId() ) //Don't remove self { - next = iter; - ++next; - SpellEntry const *spell = iter->second->GetSpellProto(); - if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask - && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability - && !iter->second->IsPositive() //Don't remove positive spells - && spell->Id != GetId() ) //Don't remove self - { - m_target->RemoveAurasDueToSpell(spell->Id); - if(Auras.empty()) - break; - else - next = Auras.begin(); - } + m_target->RemoveAurasDueToSpell(spell->Id); + if(Auras.empty()) + break; + else + next = Auras.begin(); } } } @@ -5422,13 +5352,16 @@ void Aura::HandleAuraRetainComboPoints(bool apply, bool Real) void Aura::HandleModUnattackable( bool Apply, bool Real ) { - if(Real && Apply) + if(!Real) + return; + + if(Apply) { m_target->CombatStop(); - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } - m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply); + m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, Apply); } void Aura::HandleSpiritOfRedemption( bool apply, bool Real ) |