Skip to content

Instantly share code, notes, and snippets.

@rsa
Created August 20, 2011 13:05
Show Gist options
  • Select an option

  • Save rsa/1159083 to your computer and use it in GitHub Desktop.

Select an option

Save rsa/1159083 to your computer and use it in GitHub Desktop.
attacker per map storage v2
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..0cd494f 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())
@@ -610,6 +613,8 @@ void Map::Remove(Player *player, bool remove)
SendRemoveTransports(player);
UpdateObjectVisibility(player,cell,p);
+ RemoveAttackersStorageFor(player->GetObjectGuid());
+
if (!remove && !player->GetPlayerbotAI())
player->ResetMap();
@@ -647,6 +652,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 +3270,79 @@ 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)
+{
+ WriteGuard Guard(GetLock());
+ AttackersMap::iterator itr = m_attackersMap.find(targetGuid);
+ if (itr != m_attackersMap.end())
+ {
+ itr->second.insert(attackerGuid);
+ }
+}
+
+void Map::RemoveAttackerFor(ObjectGuid targetGuid, ObjectGuid attackerGuid)
+{
+ WriteGuard Guard(GetLock());
+ AttackersMap::iterator itr = m_attackersMap.find(targetGuid);
+ if (itr != m_attackersMap.end())
+ {
+ itr->second.erase(attackerGuid);
+ }
+}
+
+void Map::RemoveAllAttackerFor(ObjectGuid targetGuid)
+{
+ WriteGuard Guard(GetLock());
+ AttackersMap::iterator itr = m_attackersMap.find(targetGuid);
+ if (itr != m_attackersMap.end())
+ {
+ itr->second.clear();
+ }
+}
+
+ObjectGuidSet const& Map::GetAttackersFor(ObjectGuid targetGuid)
+{
+ if (targetGuid.IsEmpty())
+ return ObjectGuidSet();
+
+ ReadGuard Guard(GetLock());
+ AttackersMap::const_iterator itr = m_attackersMap.find(targetGuid);
+ if (itr != m_attackersMap.end())
+ return itr->second;
+ else
+ {
+ DEBUG_LOG("Map::GetAttackersFor - requested attackers list for target (guid %u), but his hot have it!", targetGuid.GetRawValue());
+ if (!targetGuid.IsEmpty())
+ {
+ CreateAttackersStorageFor(targetGuid);
+ return m_attackersMap[targetGuid];
+ }
+ }
+ return ObjectGuidSet();
+}
+
+void Map::CreateAttackersStorageFor(ObjectGuid targetGuid)
+{
+ 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)
+{
+ 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..8595ea3 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 RemoveAllAttackerFor(ObjectGuid targetGuid);
+ ObjectGuidSet const& 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 067d992..83566e1 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3581,14 +3581,15 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx)
ihit->effectMask &= ~(1<<1);
// not empty (checked), copy
- Unit::AttackerSet attackers = friendTarget->getAttackers();
+ ObjectGuidSet attackers = friendTarget->getAttackers();
// selected from list 3
- for(uint32 i = 0; i < std::min(size_t(3),attackers.size()); ++i)
+ for(uint32 i = 0; i < std::min(size_t(3), attackers.size()); ++i)
{
- Unit::AttackerSet::iterator aItr = attackers.begin();
+ ObjectGuidSet::iterator aItr = attackers.begin();
std::advance(aItr, rand() % attackers.size());
- AddUnitTarget((*aItr), EFFECT_INDEX_1);
+ if (Unit* nTarget = friendTarget->GetMap()->GetUnit(*aItr))
+ AddUnitTarget(nTarget, EFFECT_INDEX_1);
attackers.erase(aItr);
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index abc2249..18aa050 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,15 @@ Unit* Unit::getAttackerForHelper()
if (getVictim())
return getVictim();
- if (!m_attackers.empty())
+ ObjectGuidSet const& 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 +6096,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 +6127,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 +6168,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,15 +6250,20 @@ void Unit::RemoveAllAttackers()
if (!GetMap())
return;
- while (!m_attackers.empty())
+ ObjectGuidSet const& attackers = GetMap()->GetAttackersFor(GetObjectGuid());
+
+ for (ObjectGuidSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
{
- AttackerSet::iterator iter = m_attackers.begin();
- ObjectGuid guid = *iter;
+ ObjectGuid guid = *itr++;
Unit* attacker = GetMap()->GetUnit(guid);
if(!attacker || !attacker->AttackStop())
{
sLog.outError("WORLD: Unit has an attacker that isn't attacking it!");
- m_attackers.erase(guid);
+ GetMap()->RemoveAttackerFor(GetObjectGuid(),guid);
+ }
+ else
+ {
+ attacker->AttackStop();
}
}
}
@@ -8811,7 +8817,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 +9430,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 const& 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))
@@ -11993,10 +12001,11 @@ void Unit::StopAttackFaction(uint32 faction_id)
}
}
- AttackerSet const& attackers = getAttackers();
- for(AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
+ ObjectGuidSet const& attackers = GetMap()->GetAttackersFor(GetObjectGuid());
+ for(ObjectGuidSet::const_iterator itr = attackers.begin(); itr != attackers.end();)
{
Unit* attacker = GetMap()->GetUnit(*itr);
+
if (attacker && attacker->getFactionTemplateEntry()->faction==faction_id)
{
attacker->AttackStop();
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..b162e40 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 const& 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