diff options
-rw-r--r-- | src/game/BattleGroundMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/Player.cpp | 16 | ||||
-rw-r--r-- | src/game/Player.h | 1 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 2 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 195 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 15 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/Unit.h | 2 |
8 files changed, 90 insertions, 145 deletions
diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index ce9eae6a5c8..53e466e9ca5 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -1178,7 +1178,7 @@ void BattleGroundMgr::Update(uint32 diff) // skip updating battleground template if( itr != m_BattleGrounds[i].end() ) ++itr; - for(itr = m_BattleGrounds[i].begin(); itr != m_BattleGrounds[i].end(); itr = next) + for(; itr != m_BattleGrounds[i].end(); itr = next) { next = itr; ++next; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 49ba06eb6db..53cfdeb054c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -19384,6 +19384,7 @@ void Player::SummonIfPossible(bool agree) } // drop flag at summon + // this code can be reached only when GM is summoning player who carries flag, because player should be immune to summoning spells when he carries flag if(BattleGround *bg = GetBattleGround()) bg->EventPlayerDroppedFlag(this); @@ -20129,6 +20130,7 @@ bool Player::CanUseBattleGroundObject() return ( //InBattleGround() && // in battleground - not need, check in other cases //!IsMounted() && - not correct, player is dismounted when he clicks on flag //i'm not sure if these two are correct, because invisible players should get visible when they click on flag + !isTotalImmune() && // not totally immune !HasStealthAura() && // not stealthed !HasInvisibilityAura() && // not invisible !HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup @@ -20285,6 +20287,20 @@ void Player::ExitVehicle(Vehicle *vehicle) CastSpell(this, 45472, true); // Parachute } +bool Player::isTotalImmune() +{ + AuraList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY); + + uint32 immuneMask = 0; + for(AuraList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr) + { + immuneMask |= (*itr)->GetModifier()->m_miscvalue; + if( immuneMask & SPELL_SCHOOL_MASK_ALL ) // total immunity + return true; + } + return false; +} + bool Player::HasTitle(uint32 bitIndex) { if (bitIndex > 128) diff --git a/src/game/Player.h b/src/game/Player.h index a6810e85c50..9af497aaa7b 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1920,6 +1920,7 @@ class TRINITY_DLL_SPEC Player : public Unit bool GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const; bool isTotalImmunity(); bool CanUseBattleGroundObject(); + bool isTotalImmune(); bool CanCaptureTowerPoint(); /*********************************************************/ diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index be289df52ba..f51a8764dd8 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -307,7 +307,7 @@ enum SpellCategory #define SPELL_ATTR_EX2_UNK18 0x00040000 // 18 Only Revive pet - possible req dead pet #define SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT 0x00080000 // 19 does not necessarly need shapeshift #define SPELL_ATTR_EX2_UNK20 0x00100000 // 20 -#define SPELL_ATTR_EX2_UNK21 0x00200000 // 21 +#define SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD 0x00200000 // 21 for ice blocks, pala immunity buffs, priest absorb shields, but used also for other spells -> not sure! #define SPELL_ATTR_EX2_UNK22 0x00400000 // 22 #define SPELL_ATTR_EX2_UNK23 0x00800000 // 23 Only mage Arcane Concentration have this flag #define SPELL_ATTR_EX2_UNK24 0x01000000 // 24 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 ) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index a6f003ac28d..8630f14baaa 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2483,6 +2483,8 @@ void Spell::EffectPowerDrain(uint32 i) void Spell::EffectSendEvent(uint32 EffectIndex) { + /* we do not drop a flag by sendevent system, OBSOLETE CODE: + this code caused crashes if (m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->InBattleGround()) { BattleGround* bg = ((Player *)m_caster)->GetBattleGround(); @@ -2491,25 +2493,22 @@ void Spell::EffectSendEvent(uint32 EffectIndex) switch(m_spellInfo->Id) { case 23333: // Pickup Horde Flag - /*do not uncomment . + /*do not uncomment if(bg->GetTypeID()==BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); sLog.outDebug("Send Event Horde Flag Picked Up"); break; - /* not used : case 23334: // Drop Horde Flag if(bg->GetTypeID()==BATTLEGROUND_WS) bg->EventPlayerDroppedFlag((Player*)m_caster); sLog.outDebug("Drop Horde Flag"); break; - */ case 23335: // Pickup Alliance Flag - /*do not uncomment ... (it will cause crash, because of null targetobject!) anyway this is a bad way to call that event, because it would cause recursion + /*do not uncomment - it will cause crash, because of null targetobject! if(bg->GetTypeID()==BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); sLog.outDebug("Send Event Alliance Flag Picked Up"); break; - /* not used : case 23336: // Drop Alliance Flag if(bg->GetTypeID()==BATTLEGROUND_WS) bg->EventPlayerDroppedFlag((Player*)m_caster); @@ -2524,19 +2523,17 @@ void Spell::EffectSendEvent(uint32 EffectIndex) if(bg->GetTypeID()==BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); sLog.outDebug("Horde Flag Returned"); - break;*/ + break; case 34976: - /* if(bg->GetTypeID()==BATTLEGROUND_EY) bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); - */ break; default: sLog.outDebug("Unknown spellid %u in BG event", m_spellInfo->Id); break; } } - } + }*/ sLog.outDebug("Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[EffectIndex], m_spellInfo->Id); sWorld.ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject); } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 10efa9a3aec..7a0c404d2e8 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -548,8 +548,6 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep) switch(spellId) { - case 23333: case 23335: case 34976: // BG spell - return true; case 28441: // not positive dummy spell case 37675: // Chaos Blast case 41519: // Mark of Stormrage diff --git a/src/game/Unit.h b/src/game/Unit.h index e91e0e4f55a..9bf55edd15a 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -79,7 +79,7 @@ enum SpellAuraInterruptFlags AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported - AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH = 0x00100000, // 20 removed when player on himself casts immunity spell or vanish? + AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to loose selection on you AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21 AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22 AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat |