aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/BattleGroundMgr.cpp2
-rw-r--r--src/game/Player.cpp16
-rw-r--r--src/game/Player.h1
-rw-r--r--src/game/SharedDefines.h2
-rw-r--r--src/game/SpellAuras.cpp195
-rw-r--r--src/game/SpellEffects.cpp15
-rw-r--r--src/game/SpellMgr.cpp2
-rw-r--r--src/game/Unit.h2
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