Created
August 21, 2011 13:19
-
-
Save rsa/1160600 to your computer and use it in GitHub Desktop.
attackers per map storage V4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/src/game/Group.cpp b/src/game/Group.cpp | |
| index a46b329..4af034b 100644 | |
| --- a/src/game/Group.cpp | |
| +++ b/src/game/Group.cpp | |
| @@ -1733,7 +1733,7 @@ bool Group::InCombatToInstance(uint32 instanceId) | |
| for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) | |
| { | |
| Player *pPlayer = itr->getSource(); | |
| - if(pPlayer->getAttackers().size() && pPlayer->GetInstanceId() == instanceId) | |
| + if(pPlayer->GetMap() && pPlayer->GetInstanceId() == instanceId && pPlayer->IsInCombat()) | |
| return true; | |
| } | |
| return false; | |
| diff --git a/src/game/Map.cpp b/src/game/Map.cpp | |
| index 15f4071..e80c87a 100644 | |
| --- a/src/game/Map.cpp | |
| +++ b/src/game/Map.cpp | |
| @@ -285,6 +285,7 @@ bool Map::Add(Player *player) | |
| { | |
| player->GetMapRef().link(this, player); | |
| player->SetMap(this); | |
| + CreateAttackersStorageFor(player->GetObjectGuid()); | |
| // update player state for other player and visa-versa | |
| CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); | |
| @@ -319,6 +320,8 @@ Map::Add(T *obj) | |
| } | |
| obj->SetMap(this); | |
| + if (obj->GetTypeId() == TYPEID_UNIT) | |
| + CreateAttackersStorageFor(obj->GetObjectGuid()); | |
| Cell cell(p); | |
| if(obj->isActiveObject()) | |
| @@ -573,6 +576,7 @@ void Map::Remove(Player *player, bool remove) | |
| else | |
| player->RemoveFromWorld(); | |
| + RemoveAttackersStorageFor(player->GetObjectGuid()); | |
| // this may be called during Map::Update | |
| // after decrement+unlink, ++m_mapRefIter will continue correctly | |
| // when the first element of the list is being removed | |
| @@ -647,6 +651,9 @@ Map::Remove(T *obj, bool remove) | |
| UpdateObjectVisibility(obj,cell,p); // i think will be better to call this function while object still in grid, this changes nothing but logically is better(as for me) | |
| RemoveFromGrid(obj,grid,cell); | |
| + if (obj->GetTypeId() == TYPEID_UNIT) | |
| + RemoveAttackersStorageFor(obj->GetObjectGuid()); | |
| + | |
| obj->ResetMap(); | |
| if( remove ) | |
| { | |
| @@ -3262,3 +3269,92 @@ void Map::PlayDirectSoundToMap(uint32 soundId) | |
| for (PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) | |
| itr->getSource()->SendDirectMessage(&data); | |
| } | |
| + | |
| +/** | |
| + * Function to operations with attackers per-map storage | |
| + * | |
| + * @param targetGuid (attackerGuid) | |
| + */ | |
| + | |
| +void Map::AddAttackerFor(ObjectGuid targetGuid, ObjectGuid attackerGuid) | |
| +{ | |
| + if (targetGuid.IsEmpty() || attackerGuid.IsEmpty()) | |
| + return; | |
| + | |
| + WriteGuard Guard(GetLock()); | |
| + AttackersMap::iterator itr = m_attackersMap.find(targetGuid); | |
| + if (itr != m_attackersMap.end()) | |
| + { | |
| + itr->second.insert(attackerGuid); | |
| + } | |
| + else | |
| + { | |
| + CreateAttackersStorageFor(targetGuid); | |
| + m_attackersMap[targetGuid].insert(attackerGuid); | |
| + } | |
| +} | |
| + | |
| +void Map::RemoveAttackerFor(ObjectGuid targetGuid, ObjectGuid attackerGuid) | |
| +{ | |
| + if (targetGuid.IsEmpty() || attackerGuid.IsEmpty()) | |
| + return; | |
| + | |
| + WriteGuard Guard(GetLock()); | |
| + AttackersMap::iterator itr = m_attackersMap.find(targetGuid); | |
| + if (itr != m_attackersMap.end()) | |
| + { | |
| + itr->second.erase(attackerGuid); | |
| + } | |
| +} | |
| + | |
| +void Map::RemoveAllAttackersFor(ObjectGuid targetGuid) | |
| +{ | |
| + if (targetGuid.IsEmpty()) | |
| + return; | |
| + | |
| + WriteGuard Guard(GetLock()); | |
| + AttackersMap::iterator itr = m_attackersMap.find(targetGuid); | |
| + if (itr != m_attackersMap.end()) | |
| + { | |
| + itr->second.clear(); | |
| + } | |
| +} | |
| + | |
| +ObjectGuidSet Map::GetAttackersFor(ObjectGuid targetGuid) | |
| +{ | |
| + if (!targetGuid.IsEmpty()) | |
| + { | |
| + ReadGuard Guard(GetLock()); | |
| + AttackersMap::const_iterator itr = m_attackersMap.find(targetGuid); | |
| + if (itr != m_attackersMap.end()) | |
| + return itr->second; | |
| + } | |
| + | |
| + return ObjectGuidSet(); | |
| +} | |
| + | |
| +void Map::CreateAttackersStorageFor(ObjectGuid targetGuid) | |
| +{ | |
| + if (targetGuid.IsEmpty()) | |
| + return; | |
| + | |
| + AttackersMap::iterator itr = m_attackersMap.find(targetGuid); | |
| + if (itr == m_attackersMap.end()) | |
| + { | |
| + m_attackersMap.insert(std::make_pair(targetGuid,ObjectGuidSet())); | |
| + } | |
| + | |
| +} | |
| + | |
| +void Map::RemoveAttackersStorageFor(ObjectGuid targetGuid) | |
| +{ | |
| + if (targetGuid.IsEmpty()) | |
| + return; | |
| + | |
| + WriteGuard Guard(GetLock()); | |
| + AttackersMap::iterator itr = m_attackersMap.find(targetGuid); | |
| + if (itr != m_attackersMap.end()) | |
| + { | |
| + m_attackersMap.erase(itr); | |
| + } | |
| +} | |
| diff --git a/src/game/Map.h b/src/game/Map.h | |
| index 024d2be..7616339 100644 | |
| --- a/src/game/Map.h | |
| +++ b/src/game/Map.h | |
| @@ -29,6 +29,7 @@ | |
| #include "GridDefines.h" | |
| #include "Cell.h" | |
| #include "Object.h" | |
| +#include "ObjectGuid.h" | |
| #include "Timer.h" | |
| #include "SharedDefines.h" | |
| #include "GridMap.h" | |
| @@ -90,6 +91,8 @@ enum LevelRequirementVsMode | |
| #define MIN_UNLOAD_DELAY 1 // immediate unload | |
| +typedef std::map<ObjectGuid,ObjectGuidSet> AttackersMap; | |
| + | |
| class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType> | |
| { | |
| friend class MapReference; | |
| @@ -259,6 +262,20 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType> | |
| void MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid = 0); | |
| void PlayDirectSoundToMap(uint32 soundId); | |
| + // Attacker per-map storage operations | |
| + void AddAttackerFor(ObjectGuid targetGuid, ObjectGuid attackerGuid); | |
| + void RemoveAttackerFor(ObjectGuid targetGuid, ObjectGuid attackerGuid); | |
| + void RemoveAllAttackersFor(ObjectGuid targetGuid); | |
| + ObjectGuidSet GetAttackersFor(ObjectGuid targetGuid); | |
| + void CreateAttackersStorageFor(ObjectGuid targetGuid); | |
| + void RemoveAttackersStorageFor(ObjectGuid targetGuid); | |
| + | |
| + // multithread locking | |
| + typedef ACE_RW_Thread_Mutex LockType; | |
| + typedef ACE_Read_Guard<LockType> ReadGuard; | |
| + typedef ACE_Write_Guard<LockType> WriteGuard; | |
| + LockType& GetLock() { return i_lock; } | |
| + | |
| private: | |
| void LoadMapAndVMap(int gx, int gy); | |
| @@ -347,6 +364,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType> | |
| template<class T> | |
| void RemoveFromGrid(T*, NGridType *, Cell const&); | |
| + | |
| + LockType i_lock; | |
| + AttackersMap m_attackersMap; | |
| + | |
| }; | |
| class MANGOS_DLL_SPEC WorldMap : public Map | |
| diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp | |
| index 0db0704..3583923 100644 | |
| --- a/src/game/SpellEffects.cpp | |
| +++ b/src/game/SpellEffects.cpp | |
| @@ -3568,7 +3568,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) | |
| } | |
| // non-standard cast requirement check | |
| - if (!friendTarget || friendTarget->getAttackers().empty()) | |
| + if (!friendTarget || !friendTarget->IsInCombat()) | |
| { | |
| ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id,true); | |
| SendCastResult(SPELL_FAILED_TARGET_AFFECTING_COMBAT); | |
| @@ -3581,16 +3581,18 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) | |
| ihit->effectMask &= ~(1<<1); | |
| // not empty (checked), copy | |
| - Unit::AttackerSet attackers = friendTarget->getAttackers(); | |
| - | |
| - // selected from list 3 | |
| - for(uint32 i = 0; i < std::min(size_t(3), attackers.size()); ++i) | |
| + ObjectGuidSet attackers = friendTarget->GetMap()->GetAttackersFor(friendTarget->GetObjectGuid()); | |
| + if (!attackers.empty()) | |
| { | |
| - Unit::AttackerSet::iterator aItr = attackers.begin(); | |
| - std::advance(aItr, rand() % attackers.size()); | |
| - if (Unit* nTarget = friendTarget->GetMap()->GetUnit(*aItr)) | |
| - AddUnitTarget(nTarget, EFFECT_INDEX_1); | |
| - attackers.erase(aItr); | |
| + // selected from list 3 | |
| + for(uint32 i = 0; i < std::min(size_t(3), attackers.size()); ++i) | |
| + { | |
| + ObjectGuidSet::iterator aItr = attackers.begin(); | |
| + std::advance(aItr, rand() % attackers.size()); | |
| + if (Unit* nTarget = friendTarget->GetMap()->GetUnit(*aItr)) | |
| + AddUnitTarget(nTarget, EFFECT_INDEX_1); | |
| + attackers.erase(aItr); | |
| + } | |
| } | |
| // now let next effect cast spell at each target. | |
| diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp | |
| index abc2249..2a91cb1 100644 | |
| --- a/src/game/Unit.cpp | |
| +++ b/src/game/Unit.cpp | |
| @@ -257,7 +257,7 @@ Unit::Unit() : | |
| for (int i = 0; i < MAX_STATS; ++i) | |
| m_createStats[i] = 0.0f; | |
| - m_attacking = NULL; | |
| + m_attackingGuid.Clear(); | |
| m_modMeleeHitChance = 0.0f; | |
| m_modRangedHitChance = 0.0f; | |
| m_modSpellHitChance = 0.0f; | |
| @@ -6048,14 +6048,18 @@ Unit* Unit::getAttackerForHelper() | |
| if (getVictim()) | |
| return getVictim(); | |
| - if (!m_attackers.empty()) | |
| + if (!IsInCombat()) | |
| + return NULL; | |
| + | |
| + ObjectGuidSet attackers = GetMap()->GetAttackersFor(GetObjectGuid()); | |
| + if (!attackers.empty()) | |
| { | |
| - for(AttackerSet::iterator i = m_attackers.begin(); i != m_attackers.end();) | |
| + for(ObjectGuidSet::const_iterator itr = attackers.begin(); itr != attackers.end();) | |
| { | |
| - ObjectGuid guid = *i; | |
| + ObjectGuid guid = *itr++; | |
| Unit* attacker = GetMap()->GetUnit(guid); | |
| if (!attacker || !attacker->isAlive()) | |
| - m_attackers.erase(guid); | |
| + GetMap()->RemoveAttackerFor(GetObjectGuid(),guid); | |
| else | |
| return attacker; | |
| } | |
| @@ -6095,9 +6099,9 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) | |
| RemoveSpellsCausingAura(SPELL_AURA_MOD_UNATTACKABLE); | |
| // in fighting already | |
| - if (m_attacking) | |
| + if (m_attackingGuid) | |
| { | |
| - if (m_attacking == victim) | |
| + if (m_attackingGuid == victim->GetObjectGuid()) | |
| { | |
| // switch to melee attack from ranged/magic | |
| if ( meleeAttack && !hasUnitState(UNIT_STAT_MELEE_ATTACKING) ) | |
| @@ -6126,8 +6130,9 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) | |
| if (meleeAttack) | |
| addUnitState(UNIT_STAT_MELEE_ATTACKING); | |
| - m_attacking = victim; | |
| - m_attacking->_addAttacker(GetObjectGuid()); | |
| + m_attackingGuid = victim->GetObjectGuid(); | |
| + | |
| + GetMap()->AddAttackerFor(m_attackingGuid,GetObjectGuid()); | |
| if (GetTypeId() == TYPEID_UNIT) | |
| { | |
| @@ -6166,13 +6171,12 @@ void Unit::AttackedBy(Unit *attacker) | |
| bool Unit::AttackStop(bool targetSwitch /*=false*/) | |
| { | |
| - if (!m_attacking) | |
| + if (!m_attackingGuid || !GetMap()) | |
| return false; | |
| - Unit* victim = m_attacking; | |
| - | |
| - m_attacking->_removeAttacker(GetObjectGuid()); | |
| - m_attacking = NULL; | |
| + Unit* victim = GetMap()->GetUnit(m_attackingGuid); | |
| + GetMap()->RemoveAttackerFor(m_attackingGuid,GetObjectGuid()); | |
| + m_attackingGuid.Clear(); | |
| // Clear our target | |
| SetTargetGuid(ObjectGuid()); | |
| @@ -6249,17 +6253,18 @@ void Unit::RemoveAllAttackers() | |
| if (!GetMap()) | |
| return; | |
| - while (!m_attackers.empty()) | |
| + ObjectGuidSet attackers = GetMap()->GetAttackersFor(GetObjectGuid()); | |
| + | |
| + for (ObjectGuidSet::const_iterator itr = attackers.begin(); itr != attackers.end(); ++itr) | |
| { | |
| - AttackerSet::iterator iter = m_attackers.begin(); | |
| - ObjectGuid guid = *iter; | |
| - Unit* attacker = GetMap()->GetUnit(guid); | |
| + Unit* attacker = GetMap()->GetUnit(*itr); | |
| if(!attacker || !attacker->AttackStop()) | |
| { | |
| sLog.outError("WORLD: Unit has an attacker that isn't attacking it!"); | |
| - m_attackers.erase(guid); | |
| + GetMap()->RemoveAttackerFor(GetObjectGuid(),*itr); | |
| } | |
| } | |
| + GetMap()->RemoveAllAttackersFor(GetObjectGuid()); | |
| } | |
| bool Unit::HasAuraStateForCaster(AuraState flag, ObjectGuid casterGuid) const | |
| @@ -8811,7 +8816,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo | |
| // Special cases | |
| // If is attacked then stealth is lost, some creature can use stealth too | |
| - if ( !getAttackers().empty() ) | |
| + if (IsInCombat()) | |
| return true; | |
| // If there is collision rogue is seen regardless of level difference | |
| @@ -9424,7 +9429,9 @@ bool Unit::SelectHostileTarget() | |
| // Note: creature not have targeted movement generator but have attacker in this case | |
| if (GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) | |
| { | |
| - for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr) | |
| + ObjectGuidSet attackers = GetMap()->GetAttackersFor(GetObjectGuid()); | |
| + | |
| + for (ObjectGuidSet::const_iterator itr = attackers.begin(); itr != attackers.end(); ++itr) | |
| { | |
| Unit* attacker = GetMap()->GetUnit(*itr); | |
| if (attacker && attacker->IsInMap(this) && attacker->isTargetableForAttack() && attacker->isInAccessablePlaceFor((Creature*)this)) | |
| @@ -11979,6 +11986,9 @@ struct StopAttackFactionHelper | |
| void Unit::StopAttackFaction(uint32 faction_id) | |
| { | |
| + if (!GetMap()) | |
| + return; | |
| + | |
| if (Unit* victim = getVictim()) | |
| { | |
| if (victim->getFactionTemplateEntry()->faction==faction_id) | |
| @@ -11993,17 +12003,19 @@ void Unit::StopAttackFaction(uint32 faction_id) | |
| } | |
| } | |
| - AttackerSet const& attackers = getAttackers(); | |
| - for(AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();) | |
| + ObjectGuidSet attackers = GetMap()->GetAttackersFor(GetObjectGuid()); | |
| + | |
| + for (ObjectGuidSet::iterator itr = attackers.begin(); itr != attackers.end(); ++itr) | |
| { | |
| Unit* attacker = GetMap()->GetUnit(*itr); | |
| - if (attacker && attacker->getFactionTemplateEntry()->faction==faction_id) | |
| + | |
| + if (attacker) | |
| { | |
| - attacker->AttackStop(); | |
| - itr = attackers.begin(); | |
| + if (attacker->getFactionTemplateEntry()->faction == faction_id) | |
| + attacker->AttackStop(); | |
| } | |
| else | |
| - ++itr; | |
| + GetMap()->RemoveAttackerFor(GetObjectGuid(),*itr); | |
| } | |
| getHostileRefManager().deleteReferencesForFaction(faction_id); | |
| diff --git a/src/game/Unit.h b/src/game/Unit.h | |
| index a03b7cf..eb07253 100644 | |
| --- a/src/game/Unit.h | |
| +++ b/src/game/Unit.h | |
| @@ -1152,7 +1152,6 @@ class VehicleKit; | |
| class MANGOS_DLL_SPEC Unit : public WorldObject | |
| { | |
| public: | |
| - typedef std::set<ObjectGuid> AttackerSet; | |
| typedef std::multimap< uint32, SpellAuraHolder*> SpellAuraHolderMap; | |
| typedef std::pair<SpellAuraHolderMap::iterator, SpellAuraHolderMap::iterator> SpellAuraHolderBounds; | |
| typedef std::pair<SpellAuraHolderMap::const_iterator, SpellAuraHolderMap::const_iterator> SpellAuraHolderConstBounds; | |
| @@ -1208,31 +1207,16 @@ class MANGOS_DLL_SPEC Unit : public WorldObject | |
| bool CanReachWithMeleeAttack(Unit* pVictim, float flat_mod = 0.0f) const; | |
| uint32 m_extraAttacks; | |
| - void _addAttacker(ObjectGuid attackerGuid) // must be called only from Unit::Attack(Unit*) | |
| - { | |
| - if (attackerGuid.IsEmpty()) | |
| - return; | |
| - | |
| - if (m_attackers.find(attackerGuid) == m_attackers.end()) | |
| - m_attackers.insert(attackerGuid); | |
| - } | |
| - void _removeAttacker(ObjectGuid attackerGuid) // must be called only from Unit::AttackStop() | |
| - { | |
| - if (attackerGuid.IsEmpty()) | |
| - return; | |
| - | |
| - if (m_attackers.find(attackerGuid) != m_attackers.end()) | |
| - m_attackers.erase(attackerGuid); | |
| - } | |
| + ObjectGuidSet const& getAttackers() const { return GetMap() ? GetMap()->GetAttackersFor(GetObjectGuid()) : ObjectGuidSet(); } | |
| + bool const IsInCombat() const { return GetMap() ? bool(GetMap()->GetAttackersFor(GetObjectGuid()).size() > 0) : false; } | |
| Unit* getAttackerForHelper(); // If someone wants to help, who to give them | |
| bool Attack(Unit *victim, bool meleeAttack); | |
| void AttackedBy(Unit *attacker); | |
| void CastStop(uint32 except_spellid = 0); | |
| bool AttackStop(bool targetSwitch = false); | |
| void RemoveAllAttackers(); | |
| - AttackerSet const& getAttackers() const { return m_attackers; } | |
| bool isAttackingPlayer() const; | |
| - Unit* getVictim() const { return m_attacking; } | |
| + Unit* getVictim() const { return GetMap() ? GetMap()->GetUnit(m_attackingGuid) : NULL; } | |
| void CombatStop(bool includingCast = false); | |
| void CombatStopWithPets(bool includingCast = false); | |
| void StopAttackFaction(uint32 faction_id); | |
| @@ -2090,8 +2074,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject | |
| float m_createStats[MAX_STATS]; | |
| - AttackerSet m_attackers; | |
| - Unit* m_attacking; | |
| + ObjectGuid m_attackingGuid; | |
| DeathState m_deathState; | |
| diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp | |
| index 10a759d..ea9bd18 100644 | |
| --- a/src/game/WorldSession.cpp | |
| +++ b/src/game/WorldSession.cpp | |
| @@ -397,25 +397,27 @@ void WorldSession::LogoutPlayer(bool Save) | |
| ///- If the player just died before logging out, make him appear as a ghost | |
| //FIXME: logout must be delayed in case lost connection with client in time of combat | |
| - if (_player->GetDeathTimer()) | |
| + if (GetPlayer()->GetDeathTimer()) | |
| { | |
| - _player->getHostileRefManager().deleteReferences(); | |
| - _player->BuildPlayerRepop(); | |
| - _player->RepopAtGraveyard(); | |
| + GetPlayer()->getHostileRefManager().deleteReferences(); | |
| + GetPlayer()->BuildPlayerRepop(); | |
| + GetPlayer()->RepopAtGraveyard(); | |
| } | |
| - else if (!_player->getAttackers().empty()) | |
| + else if (GetPlayer()->IsInCombat() && GetPlayer()->GetMap()) | |
| { | |
| - _player->CombatStop(); | |
| - _player->getHostileRefManager().setOnlineOfflineState(false); | |
| - _player->RemoveAllAurasOnDeath(); | |
| + GetPlayer()->CombatStop(); | |
| + GetPlayer()->getHostileRefManager().setOnlineOfflineState(false); | |
| + GetPlayer()->RemoveAllAurasOnDeath(); | |
| // build set of player who attack _player or who have pet attacking of _player | |
| std::set<Player*> aset; | |
| - for(Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr) | |
| + ObjectGuidSet attackers = GetPlayer()->GetMap()->GetAttackersFor(GetPlayer()->GetObjectGuid()); | |
| + | |
| + for (ObjectGuidSet::const_iterator itr = attackers.begin(); itr != attackers.end();) | |
| { | |
| - Unit* attacker = _player->GetMap()->GetUnit(*itr); | |
| - if (!attacker) | |
| - continue; | |
| + Unit* attacker = GetPlayer()->GetMap()->GetUnit(*itr++); | |
| + if (!attacker) | |
| + continue; | |
| Unit* owner = attacker->GetOwner(); // including player controlled case | |
| if(owner) | |
| @@ -428,59 +430,59 @@ void WorldSession::LogoutPlayer(bool Save) | |
| aset.insert((Player*)(attacker)); | |
| } | |
| - _player->SetPvPDeath(!aset.empty()); | |
| - _player->KillPlayer(); | |
| - _player->BuildPlayerRepop(); | |
| - _player->RepopAtGraveyard(); | |
| + GetPlayer()->SetPvPDeath(!aset.empty()); | |
| + GetPlayer()->KillPlayer(); | |
| + GetPlayer()->BuildPlayerRepop(); | |
| + GetPlayer()->RepopAtGraveyard(); | |
| // give honor to all attackers from set like group case | |
| for(std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) | |
| - (*itr)->RewardHonor(_player,aset.size()); | |
| + (*itr)->RewardHonor(GetPlayer(),aset.size()); | |
| // give bg rewards and update counters like kill by first from attackers | |
| // this can't be called for all attackers. | |
| if(!aset.empty()) | |
| - if(BattleGround *bg = _player->GetBattleGround()) | |
| - bg->HandleKillPlayer(_player,*aset.begin()); | |
| + if(BattleGround *bg = GetPlayer()->GetBattleGround()) | |
| + bg->HandleKillPlayer(GetPlayer(),*aset.begin()); | |
| } | |
| - else if(_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) | |
| + else if(GetPlayer()->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) | |
| { | |
| // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION | |
| - _player->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); | |
| - //_player->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time | |
| - _player->KillPlayer(); | |
| - _player->BuildPlayerRepop(); | |
| - _player->RepopAtGraveyard(); | |
| + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); | |
| + //GetPlayer()->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time | |
| + GetPlayer()->KillPlayer(); | |
| + GetPlayer()->BuildPlayerRepop(); | |
| + GetPlayer()->RepopAtGraveyard(); | |
| } | |
| - else if (_player->HasPendingBind()) | |
| + else if (GetPlayer()->HasPendingBind()) | |
| { | |
| - _player->RepopAtGraveyard(); | |
| - _player->SetPendingBind(NULL, 0); | |
| + GetPlayer()->RepopAtGraveyard(); | |
| + GetPlayer()->SetPendingBind(NULL, 0); | |
| } | |
| //drop a flag if player is carrying it | |
| - if(BattleGround *bg = _player->GetBattleGround()) | |
| - bg->EventPlayerLoggedOut(_player); | |
| + if(BattleGround *bg = GetPlayer()->GetBattleGround()) | |
| + bg->EventPlayerLoggedOut(GetPlayer()); | |
| ///- Teleport to home if the player is in an invalid instance | |
| - if(!_player->m_InstanceValid && !_player->isGameMaster()) | |
| + if(!GetPlayer()->m_InstanceValid && !GetPlayer()->isGameMaster()) | |
| { | |
| - _player->TeleportToHomebind(); | |
| + GetPlayer()->TeleportToHomebind(); | |
| //this is a bad place to call for far teleport because we need player to be in world for successful logout | |
| //maybe we should implement delayed far teleport logout? | |
| } | |
| // FG: finish pending transfers after starting the logout | |
| // this should fix players beeing able to logout and login back with full hp at death position | |
| - while(_player->IsBeingTeleportedFar()) | |
| + while(GetPlayer()->IsBeingTeleportedFar()) | |
| HandleMoveWorldportAckOpcode(); | |
| for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) | |
| { | |
| - if(BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i)) | |
| + if(BattleGroundQueueTypeId bgQueueTypeId = GetPlayer()->GetBattleGroundQueueTypeId(i)) | |
| { | |
| - _player->RemoveBattleGroundQueueId(bgQueueTypeId); | |
| - sBattleGroundMgr.m_BattleGroundQueues[ bgQueueTypeId ].RemovePlayer(_player->GetObjectGuid(), true); | |
| + GetPlayer()->RemoveBattleGroundQueueId(bgQueueTypeId); | |
| + sBattleGroundMgr.m_BattleGroundQueues[ bgQueueTypeId ].RemovePlayer(GetPlayer()->GetObjectGuid(), true); | |
| } | |
| } | |
| @@ -496,48 +498,48 @@ void WorldSession::LogoutPlayer(bool Save) | |
| } | |
| ///- If the player is in a guild, update the guild roster and broadcast a logout message to other guild members | |
| - if (Guild* guild = sGuildMgr.GetGuildById(_player->GetGuildId())) | |
| + if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId())) | |
| { | |
| - if (MemberSlot* slot = guild->GetMemberSlot(_player->GetObjectGuid())) | |
| + if (MemberSlot* slot = guild->GetMemberSlot(GetPlayer()->GetObjectGuid())) | |
| { | |
| - slot->SetMemberStats(_player); | |
| + slot->SetMemberStats(GetPlayer()); | |
| slot->UpdateLogoutTime(); | |
| } | |
| - guild->BroadcastEvent(GE_SIGNED_OFF, _player->GetObjectGuid(), _player->GetName()); | |
| + guild->BroadcastEvent(GE_SIGNED_OFF, GetPlayer()->GetObjectGuid(), GetPlayer()->GetName()); | |
| } | |
| ///- Remove pet | |
| - _player->RemovePet(PET_SAVE_AS_CURRENT); | |
| + GetPlayer()->RemovePet(PET_SAVE_AS_CURRENT); | |
| - _player->InterruptNonMeleeSpells(true); | |
| + GetPlayer()->InterruptNonMeleeSpells(true); | |
| ///- empty buyback items and save the player in the database | |
| // some save parts only correctly work in case player present in map/player_lists (pets, etc) | |
| if(Save) | |
| - _player->SaveToDB(); | |
| + GetPlayer()->SaveToDB(); | |
| ///- Leave all channels before player delete... | |
| - _player->CleanupChannels(); | |
| + GetPlayer()->CleanupChannels(); | |
| // LFG cleanup | |
| - sLFGMgr.Leave(_player); | |
| + sLFGMgr.Leave(GetPlayer()); | |
| ///- If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group. | |
| - _player->UninviteFromGroup(); | |
| + GetPlayer()->UninviteFromGroup(); | |
| // remove player from the group if he is: | |
| // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) | |
| - if(_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket) | |
| - _player->RemoveFromGroup(); | |
| + if(GetPlayer()->GetGroup() && !GetPlayer()->GetGroup()->isRaidGroup() && m_Socket) | |
| + GetPlayer()->RemoveFromGroup(); | |
| ///- Send update to group | |
| - if(_player->GetGroup()) | |
| - _player->GetGroup()->SendUpdate(); | |
| + if(GetPlayer()->GetGroup()) | |
| + GetPlayer()->GetGroup()->SendUpdate(); | |
| ///- Broadcast a logout message to the player's friends | |
| - sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetObjectGuid(), true); | |
| - sSocialMgr.RemovePlayerSocial (_player->GetGUIDLow ()); | |
| + sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_OFFLINE, GetPlayer()->GetObjectGuid(), true); | |
| + sSocialMgr.RemovePlayerSocial (GetPlayer()->GetGUIDLow ()); | |
| // Playerbot - remember player GUID for update SQL below | |
| uint32 guid = GetPlayer()->GetGUIDLow(); | |
| @@ -546,15 +548,15 @@ void WorldSession::LogoutPlayer(bool Save) | |
| // the player may not be in the world when logging out | |
| // e.g if he got disconnected during a transfer to another map | |
| // calls to GetMap in this case may cause crashes | |
| - if (_player->IsInWorld()) | |
| + if (GetPlayer()->IsInWorld()) | |
| { | |
| - Map* _map = _player->GetMap(); | |
| - _map->Remove(_player, true); | |
| + Map* _map = GetPlayer()->GetMap(); | |
| + _map->Remove(GetPlayer(), true); | |
| } | |
| else | |
| { | |
| - _player->CleanupsBeforeDelete(); | |
| - Map::DeleteFromWorld(_player); | |
| + GetPlayer()->CleanupsBeforeDelete(); | |
| + Map::DeleteFromWorld(GetPlayer()); | |
| } | |
| SetPlayer(NULL); // deleted in Remove/DeleteFromWorld call |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment