aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp1
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp6
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp2
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp9
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp17
-rw-r--r--src/server/game/Entities/Corpse/Corpse.h1
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp4
-rw-r--r--src/server/game/Entities/Object/Object.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp74
-rw-r--r--src/server/game/Entities/Player/Player.h35
-rw-r--r--src/server/game/Globals/ObjectAccessor.cpp188
-rw-r--r--src/server/game/Globals/ObjectAccessor.h120
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp16
-rw-r--r--src/server/game/Globals/ObjectMgr.h5
-rw-r--r--src/server/game/Grids/ObjectGridLoader.cpp52
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp29
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp2
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp1
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp4
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp10
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp21
-rw-r--r--src/server/game/Maps/Map.cpp113
-rw-r--r--src/server/game/Maps/Map.h25
-rw-r--r--src/server/game/Maps/MapManager.cpp7
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp3
-rw-r--r--src/server/game/World/World.cpp15
-rw-r--r--src/server/game/World/World.h3
-rw-r--r--src/server/scripts/Commands/cs_instance.cpp4
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp8
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp1
-rw-r--r--src/server/scripts/Commands/cs_server.cpp2
-rw-r--r--src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp4
-rw-r--r--src/server/worldserver/Main.cpp1
35 files changed, 344 insertions, 444 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 940bee4e3a2..3f6543716f9 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -345,6 +345,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CORPSE_PHASES, "SELECT cp.OwnerGuid, cp.PhaseId FROM corpse_phases cp LEFT JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ? AND c.instanceId = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_CORPSE_PHASES, "INSERT INTO corpse_phases (OwnerGuid, PhaseId) VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE OwnerGuid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CORPSE_LOCATION, "SELECT mapId, posX, posY, posZ, orientation FROM corpse WHERE guid = ?", CONNECTION_ASYNC);
// Creature respawn
PrepareStatement(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index 2054bfa7ca5..f5f907c2bf1 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -285,6 +285,7 @@ enum CharacterDatabaseStatements
CHAR_SEL_CORPSE_PHASES,
CHAR_INS_CORPSE_PHASES,
CHAR_DEL_CORPSE_PHASES,
+ CHAR_SEL_CORPSE_LOCATION,
CHAR_SEL_CREATURE_RESPAWNS,
CHAR_REP_CREATURE_RESPAWN,
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index c6a16e1b2fd..d909713a204 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -208,7 +208,7 @@ void SmartAI::EndPath(bool fail)
if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
{
Player* player = (*targets->begin())->ToPlayer();
- if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse())
+ if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
player->GroupEventHappens(mEscortQuestID, me);
if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
@@ -220,7 +220,7 @@ void SmartAI::EndPath(bool fail)
{
Player* groupGuy = groupRef->GetSource();
- if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->GetCorpse())
+ if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->HasCorpse())
groupGuy->AreaExploredOrEventHappens(mEscortQuestID);
if (fail && groupGuy->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
groupGuy->FailQuest(mEscortQuestID);
@@ -233,7 +233,7 @@ void SmartAI::EndPath(bool fail)
if (GetScript()->IsPlayer((*iter)))
{
Player* player = (*iter)->ToPlayer();
- if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse())
+ if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
player->AreaExploredOrEventHappens(mEscortQuestID);
if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
player->FailQuest(mEscortQuestID);
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index fbd49acaf0b..dc1ecf7c1c3 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -711,7 +711,7 @@ void BfGraveyard::Resurrect()
player->CastSpell(player, 6962, true);
player->CastSpell(player, SPELL_SPIRIT_HEAL_MANA, true);
- sObjectAccessor->ConvertCorpseForPlayer(player->GetGUID());
+ player->SpawnCorpseBones(false);
}
m_ResurrectQueue.clear();
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 28205d493de..07c88486c50 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -396,7 +396,7 @@ inline void Battleground::_ProcessResurrect(uint32 diff)
player->ResurrectPlayer(1.0f);
player->CastSpell(player, 6962, true);
player->CastSpell(player, SPELL_SPIRIT_HEAL_MANA, true);
- sObjectAccessor->ConvertCorpseForPlayer(*itr);
+ player->SpawnCorpseBones(false);
}
m_ResurrectQueue.clear();
}
@@ -954,8 +954,11 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen
player->SpawnCorpseBones();
}
}
- else // try to resurrect the offline player. If he is alive nothing will happen
- sObjectAccessor->ConvertCorpseForPlayer(guid);
+ else
+ {
+ SQLTransaction trans(nullptr);
+ Player::OfflineResurrect(guid, trans);
+ }
RemovePlayer(player, guid, team); // BG subclass specific code
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 4745a4d4e1b..4122c3a61c2 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -149,13 +149,18 @@ void Corpse::DeleteBonesFromWorld()
void Corpse::DeleteFromDB(SQLTransaction& trans)
{
+ DeleteFromDB(GetOwnerGUID(), trans);
+}
+
+void Corpse::DeleteFromDB(ObjectGuid const& ownerGuid, SQLTransaction& trans)
+{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE);
- stmt->setUInt64(0, GetOwnerGUID().GetCounter());
- trans->Append(stmt);
+ stmt->setUInt64(0, ownerGuid.GetCounter());
+ CharacterDatabase.ExecuteOrAppend(trans, stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES);
- stmt->setUInt64(0, GetOwnerGUID().GetCounter());
- trans->Append(stmt);
+ stmt->setUInt64(0, ownerGuid.GetCounter());
+ CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
@@ -202,6 +207,10 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
bool Corpse::IsExpired(time_t t) const
{
+ // Deleted character
+ if (!sWorld->GetCharacterInfo(GetOwnerGUID()))
+ return true;
+
if (m_type == CORPSE_BONES)
return m_time < t - 60 * MINUTE;
else
diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h
index 29ae2a79d84..be2cb435ac9 100644
--- a/src/server/game/Entities/Corpse/Corpse.h
+++ b/src/server/game/Entities/Corpse/Corpse.h
@@ -63,6 +63,7 @@ class Corpse : public WorldObject, public GridObject<Corpse>
void DeleteBonesFromWorld();
void DeleteFromDB(SQLTransaction& trans);
+ static void DeleteFromDB(ObjectGuid const& ownerGuid, SQLTransaction& trans);
ObjectGuid GetOwnerGUID() const { return GetGuidValue(CORPSE_FIELD_OWNER); }
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index ec1e7050732..60747974a13 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -635,7 +635,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI
offer.QuestGiverGUID = npcGUID;
// Is there a better way? what about game objects?
- if (Creature const* creature = sObjectAccessor->GetCreature(*_session->GetPlayer(), npcGUID))
+ if (Creature const* creature = ObjectAccessor::GetCreature(*_session->GetPlayer(), npcGUID))
offer.QuestGiverCreatureID = creature->GetCreatureTemplate()->Entry;
offer.QuestID = quest->GetQuestId();
@@ -693,7 +693,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
packet.QuestGiverGUID = npcGUID;
// Is there a better way? what about game objects?
- if (Creature const* creature = sObjectAccessor->GetCreature(*_session->GetPlayer(), npcGUID))
+ if (Creature const* creature = ObjectAccessor::GetCreature(*_session->GetPlayer(), npcGUID))
packet.QuestGiverCreatureID = creature->GetCreatureTemplate()->Entry;
packet.QuestID = quest->GetQuestId();
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 15b40c36c4a..9a01eacbf7f 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2166,7 +2166,7 @@ void WorldObject::SendObjectDeSpawnAnim(ObjectGuid guid)
void WorldObject::SetMap(Map* map)
{
ASSERT(map);
- ASSERT(!IsInWorld() || GetTypeId() == TYPEID_CORPSE);
+ ASSERT(!IsInWorld());
if (m_currMap == map) // command add npc: first create, than loadfromdb
return;
if (m_currMap)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index b52172afcc8..85c2869e72a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4129,10 +4129,6 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
charDeleteMethod = CHAR_DELETE_REMOVE;
}
- // convert corpse to bones if exist (to prevent exiting Corpse in World without DB entry)
- // bones will be deleted by corpse/bones deleting thread shortly
- sObjectAccessor->ConvertCorpseForPlayer(playerguid);
-
if (ObjectGuid::LowType guildId = GetGuildIdFromDB(playerguid))
if (Guild* guild = sGuildMgr->GetGuildById(guildId))
guild->DeleteMember(playerguid, false, false, true);
@@ -4452,13 +4448,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid);
trans->Append(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE);
- stmt->setUInt64(0, guid);
- trans->Append(stmt);
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES);
- stmt->setUInt64(0, guid);
- trans->Append(stmt);
+ Corpse::DeleteFromDB(playerguid, trans);
Garrison::DeleteFromDB(guid, trans);
@@ -4544,18 +4534,17 @@ void Player::BuildPlayerRepop()
// there must be SMSG.FORCE_RUN_SPEED_CHANGE, SMSG.FORCE_SWIM_SPEED_CHANGE, SMSG.MOVE_SET_WATER_WALK
// there must be SMSG.STOP_MIRROR_TIMER
- // there we must send 888 opcode
- // the player cannot have a corpse already, only bones which are not returned by GetCorpse
- if (GetCorpse())
+ // the player cannot have a corpse already on current map, only bones which are not returned by GetCorpse
+ WorldLocation corpseLocation = GetCorpseLocation();
+ if (corpseLocation.GetMapId() == GetMapId())
{
TC_LOG_ERROR("entities.player", "BuildPlayerRepop: player %s (%s) already has a corpse", GetName().c_str(), GetGUID().ToString().c_str());
return;
}
// create a corpse and place it at the player's location
- CreateCorpse();
- Corpse* corpse = GetCorpse();
+ Corpse* corpse = CreateCorpse();
if (!corpse)
{
TC_LOG_ERROR("entities.player", "Error creating corpse for Player %s [%s]", GetName().c_str(), GetGUID().ToString().c_str());
@@ -4697,7 +4686,16 @@ void Player::KillPlayer()
UpdateObjectVisibility();
}
-void Player::CreateCorpse()
+void Player::OfflineResurrect(ObjectGuid const& guid, SQLTransaction& trans)
+{
+ Corpse::DeleteFromDB(guid, trans);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_RESURRECT));
+ stmt->setUInt64(1, guid.GetCounter());
+ CharacterDatabase.ExecuteOrAppend(trans, stmt);
+}
+
+Corpse* Player::CreateCorpse()
{
// prevent existence 2 corpse for player
SpawnCorpseBones();
@@ -4710,9 +4708,11 @@ void Player::CreateCorpse()
if (!corpse->Create(GetMap()->GenerateLowGuid<HighGuid::Corpse>(), this))
{
delete corpse;
- return;
+ return nullptr;
}
+ _corpseLocation.WorldRelocate(*this);
+
uint8 skin = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID);
uint8 face = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID);
uint8 hairstyle = GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID);
@@ -4756,19 +4756,21 @@ void Player::CreateCorpse()
corpse->SaveToDB();
// register for player, but not show
- sObjectAccessor->AddCorpse(corpse);
+ GetMap()->AddCorpse(corpse);
+ return corpse;
}
-void Player::SpawnCorpseBones()
+void Player::SpawnCorpseBones(bool triggerSave /*= true*/)
{
- if (sObjectAccessor->ConvertCorpseForPlayer(GetGUID()))
- if (!GetSession()->PlayerLogoutWithSave()) // at logout we will already store the player
- SaveToDB(); // prevent loading as ghost without corpse
+ _corpseLocation.WorldRelocate();
+ if (GetMap()->ConvertCorpseToBones(GetGUID()))
+ if (triggerSave && !GetSession()->PlayerLogoutWithSave()) // at logout we will already store the player
+ SaveToDB(); // prevent loading as ghost without corpse
}
Corpse* Player::GetCorpse() const
{
- return sObjectAccessor->GetCorpseForPlayerGUID(GetGUID());
+ return GetMap()->GetCorpseByPlayer(GetGUID());
}
void Player::DurabilityLossAll(double percent, bool inventory)
@@ -8315,9 +8317,11 @@ void Player::RemovedInsignia(Player* looterPlr)
RepopAtGraveyard();
}
+ _corpseLocation.WorldRelocate();
+
// We have to convert player corpse to bones, not to be able to resurrect there
// SpawnCorpseBones isn't handy, 'cos it saves player while he in BG
- Corpse* bones = sObjectAccessor->ConvertCorpseForPlayer(GetGUID(), true);
+ Corpse* bones = GetMap()->ConvertCorpseToBones(GetGUID(), true);
if (!bones)
return;
@@ -17438,18 +17442,24 @@ void Player::_LoadGlyphAuras()
}
}
-void Player::LoadCorpse()
+void Player::LoadCorpse(PreparedQueryResult result)
{
- if (IsAlive())
- sObjectAccessor->ConvertCorpseForPlayer(GetGUID());
- else
+ if (IsAlive() || HasAtLoginFlag(AT_LOGIN_RESURRECT))
+ SpawnCorpseBones(false);
+
+ if (!IsAlive())
{
- if (Corpse* corpse = GetCorpse())
- ApplyModFlag(PLAYER_FIELD_LOCAL_FLAGS, PLAYER_LOCAL_FLAG_RELEASE_TIMER, corpse && !sMapStore.LookupEntry(corpse->GetMapId())->Instanceable());
+ if (result && !HasAtLoginFlag(AT_LOGIN_RESURRECT))
+ {
+ Field* fields = result->Fetch();
+ _corpseLocation.WorldRelocate(fields[0].GetUInt16(), fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat());
+ ApplyModFlag(PLAYER_FIELD_LOCAL_FLAGS, PLAYER_LOCAL_FLAG_RELEASE_TIMER, !sMapStore.LookupEntry(_corpseLocation.GetMapId())->Instanceable());
+ }
else
- //Prevent Dead Player login without corpse
ResurrectPlayer(0.5f);
}
+
+ RemoveAtLoginFlag(AT_LOGIN_RESURRECT);
}
void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 05aa3d5bbf4..f139e8e3031 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -642,15 +642,16 @@ enum PlayerExtraFlags
// 2^n values
enum AtLoginFlags
{
- AT_LOGIN_NONE = 0x00,
- AT_LOGIN_RENAME = 0x01,
- AT_LOGIN_RESET_SPELLS = 0x02,
- AT_LOGIN_RESET_TALENTS = 0x04,
- AT_LOGIN_CUSTOMIZE = 0x08,
- AT_LOGIN_RESET_PET_TALENTS = 0x10,
- AT_LOGIN_FIRST = 0x20,
- AT_LOGIN_CHANGE_FACTION = 0x40,
- AT_LOGIN_CHANGE_RACE = 0x80
+ AT_LOGIN_NONE = 0x000,
+ AT_LOGIN_RENAME = 0x001,
+ AT_LOGIN_RESET_SPELLS = 0x002,
+ AT_LOGIN_RESET_TALENTS = 0x004,
+ AT_LOGIN_CUSTOMIZE = 0x008,
+ AT_LOGIN_RESET_PET_TALENTS = 0x010,
+ AT_LOGIN_FIRST = 0x020,
+ AT_LOGIN_CHANGE_FACTION = 0x040,
+ AT_LOGIN_CHANGE_RACE = 0x080,
+ AT_LOGIN_RESURRECT = 0x100,
};
typedef std::map<uint32, QuestStatusData> QuestStatusMap;
@@ -986,6 +987,7 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE,
PLAYER_LOGIN_QUERY_LOAD_CURRENCY,
PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES,
+ PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION,
PLAYER_LOGIN_QUERY_LOAD_GARRISON,
PLAYER_LOGIN_QUERY_LOAD_GARRISON_BLUEPRINTS,
PLAYER_LOGIN_QUERY_LOAD_GARRISON_BUILDINGS,
@@ -1546,7 +1548,7 @@ class Player : public Unit, public GridObject<Player>
void AddItemDurations(Item* item);
void RemoveItemDurations(Item* item);
void SendItemDurations();
- void LoadCorpse();
+ void LoadCorpse(PreparedQueryResult result);
void LoadPet();
bool AddItem(uint32 itemId, uint32 count);
@@ -2088,15 +2090,18 @@ class Player : public Unit, public GridObject<Player>
bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }
void UpdateUnderwaterState(Map* m, float x, float y, float z) override;
- void SendMessageToSet(WorldPacket const* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); }// overwrite Object::SendMessageToSet
- void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) override; // overwrite Object::SendMessageToSetInRange
+ void SendMessageToSet(WorldPacket const* data, bool self) override { SendMessageToSetInRange(data, GetVisibilityRange(), self); }
+ void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) override;
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only);
void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) override;
Corpse* GetCorpse() const;
- void SpawnCorpseBones();
- void CreateCorpse();
+ void SpawnCorpseBones(bool triggerSave = true);
+ Corpse* CreateCorpse();
void KillPlayer();
+ static void OfflineResurrect(ObjectGuid const& guid, SQLTransaction& trans);
+ bool HasCorpse() const { return _corpseLocation.GetMapId() != MAPID_INVALID; }
+ WorldLocation GetCorpseLocation() const { return _corpseLocation; }
uint32 GetResurrectionSpellId() const;
void ResurrectPlayer(float restore_percent, bool applySickness = false);
void BuildPlayerRepop();
@@ -2913,6 +2918,8 @@ class Player : public Unit, public GridObject<Player>
std::unique_ptr<Garrison> _garrison;
bool _advancedCombatLoggingEnabled;
+
+ WorldLocation _corpseLocation;
};
void AddItemsSetItem(Player* player, Item* item);
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index 733e61876ad..d08fe61b397 100644
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -34,10 +34,6 @@
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/locks.hpp>
-ObjectAccessor::ObjectAccessor() { }
-
-ObjectAccessor::~ObjectAccessor() { }
-
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid)
{
switch (guid.GetHigh())
@@ -217,6 +213,11 @@ Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name)
return NULL;
}
+HashMapHolder<Player>::MapType const& ObjectAccessor::GetPlayers()
+{
+ return HashMapHolder<Player>::GetContainer();
+}
+
void ObjectAccessor::SaveAllPlayers()
{
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
@@ -226,185 +227,6 @@ void ObjectAccessor::SaveAllPlayers()
itr->second->SaveToDB();
}
-Corpse* ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid const& guid)
-{
- boost::shared_lock<boost::shared_mutex> lock(_corpseLock);
-
- Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid);
- if (iter == i_player2corpse.end())
- return NULL;
-
- ASSERT(iter->second->GetType() != CORPSE_BONES);
-
- return iter->second;
-}
-
-void ObjectAccessor::RemoveCorpse(Corpse* corpse)
-{
- ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
-
- boost::upgrade_lock<boost::shared_mutex> lock(_corpseLock);
-
- /// @todo more works need to be done for corpse and other world object
- if (Map* map = corpse->FindMap())
- {
- corpse->DestroyForNearbyPlayers();
- if (corpse->IsInGrid())
- map->RemoveFromMap(corpse, false);
- else
- {
- corpse->RemoveFromWorld();
- corpse->ResetMap();
- }
- }
- else
- corpse->RemoveFromWorld();
-
- // Critical section
- {
- boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
-
- Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGUID());
- if (iter == i_player2corpse.end()) /// @todo Fix this
- return;
-
- // build mapid*cellid -> guid_set map
- CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
- sObjectMgr->DeleteCorpseCellData(corpse->GetMapId(), cellCoord.GetId(), corpse->GetOwnerGUID());
-
- i_player2corpse.erase(iter);
- }
-}
-
-void ObjectAccessor::AddCorpse(Corpse* corpse)
-{
- ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
-
- // Critical section
- {
- boost::unique_lock<boost::shared_mutex> lock(_corpseLock);
-
- ASSERT(i_player2corpse.find(corpse->GetOwnerGUID()) == i_player2corpse.end());
- i_player2corpse[corpse->GetOwnerGUID()] = corpse;
-
- // build mapid*cellid -> guid_set map
- CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
- sObjectMgr->AddCorpseCellData(corpse->GetMapId(), cellCoord.GetId(), corpse->GetOwnerGUID(), corpse->GetInstanceId());
- }
-}
-
-void ObjectAccessor::AddCorpsesToGrid(GridCoord const& gridpair, GridType& grid, Map* map)
-{
- boost::shared_lock<boost::shared_mutex> lock(_corpseLock);
-
- for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter)
- {
- // We need this check otherwise a corpose may be added to a grid twice
- if (iter->second->IsInGrid())
- continue;
-
- if (iter->second->GetGridCoord() == gridpair)
- {
- // verify, if the corpse in our instance (add only corpses which are)
- if (map->Instanceable())
- {
- if (iter->second->GetInstanceId() == map->GetInstanceId())
- grid.AddWorldObject(iter->second);
- }
- else
- grid.AddWorldObject(iter->second);
- }
- }
-}
-
-Corpse* ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid const& player_guid, bool insignia /*=false*/)
-{
- Corpse* corpse = GetCorpseForPlayerGUID(player_guid);
- if (!corpse)
- {
- //in fact this function is called from several places
- //even when player doesn't have a corpse, not an error
- return NULL;
- }
-
- TC_LOG_DEBUG("misc", "Deleting Corpse and spawned bones.");
-
- // Map can be NULL
- Map* map = corpse->FindMap();
-
- // remove corpse from player_guid -> corpse map and from current map
- RemoveCorpse(corpse);
-
- // remove corpse from DB
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
- corpse->DeleteFromDB(trans);
- CharacterDatabase.CommitTransaction(trans);
-
- Corpse* bones = NULL;
- // create the bones only if the map and the grid is loaded at the corpse's location
- // ignore bones creating option in case insignia
-
- if (map && (insignia ||
- (map->IsBattlegroundOrArena() ? sWorld->getBoolConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld->getBoolConfig(CONFIG_DEATH_BONES_WORLD))) &&
- !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
- {
- // Create bones, don't change Corpse
- bones = new Corpse;
- bones->Create(corpse->GetGUID().GetCounter(), map);
-
- for (uint8 i = OBJECT_FIELD_TYPE + 1; i < CORPSE_END; ++i) // don't overwrite guid and object type
- bones->SetUInt32Value(i, corpse->GetUInt32Value(i));
-
- bones->SetGridCoord(corpse->GetGridCoord());
- bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
-
- bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
- bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty);
- bones->SetGuidValue(OBJECT_FIELD_DATA, corpse->GetGuidValue(OBJECT_FIELD_DATA));
-
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
- {
- if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
- bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
- }
-
- bones->CopyPhaseFrom(corpse);
-
- // add bones in grid store if grid loaded where corpse placed
- map->AddToMap(bones);
- }
-
- // all references to the corpse should be removed at this point
- delete corpse;
-
- return bones;
-}
-
-void ObjectAccessor::RemoveOldCorpses()
-{
- time_t now = time(NULL);
- Player2CorpsesMapType::iterator next;
- for (Player2CorpsesMapType::iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); itr = next)
- {
- next = itr;
- ++next;
-
- if (!itr->second->IsExpired(now))
- continue;
-
- ConvertCorpseForPlayer(itr->first);
- }
-}
-
-void ObjectAccessor::UnloadAll()
-{
- for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr)
- {
- itr->second->RemoveFromWorld();
- delete itr->second;
- }
-}
-
/// Define the static members of HashMapHolder
template <class T> typename HashMapHolder<T>::MapType HashMapHolder<T>::_objectMap;
diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h
index e4c1ac3aa41..a91a094954c 100644
--- a/src/server/game/Globals/ObjectAccessor.h
+++ b/src/server/game/Globals/ObjectAccessor.h
@@ -85,86 +85,48 @@ class HashMapHolder
static MapType _objectMap;
};
-class ObjectAccessor
+namespace ObjectAccessor
{
- private:
- ObjectAccessor();
- ~ObjectAccessor();
- ObjectAccessor(const ObjectAccessor&);
- ObjectAccessor& operator=(const ObjectAccessor&);
-
- public:
- /// @todo: Override these template functions for each holder type and add assertions
-
- static ObjectAccessor* instance()
- {
- static ObjectAccessor instance;
- return &instance;
- }
-
- // these functions return objects only if in map of specified object
- static WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&);
- static Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask);
- static Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid);
- static GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid);
- static Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid);
- static DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid);
- static AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid);
- static Unit* GetUnit(WorldObject const&, ObjectGuid const& guid);
- static Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid);
- static Pet* GetPet(WorldObject const&, ObjectGuid const& guid);
- static Player* GetPlayer(Map const*, ObjectGuid const& guid);
- static Player* GetPlayer(WorldObject const&, ObjectGuid const& guid);
- static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&);
-
- // these functions return objects if found in whole world
- // ACCESS LIKE THAT IS NOT THREAD SAFE
- static Player* FindPlayer(ObjectGuid const&);
- static Player* FindPlayerByName(std::string const& name);
-
- // this returns Player even if he is not in world, for example teleporting
- static Player* FindConnectedPlayer(ObjectGuid const&);
- static Player* FindConnectedPlayerByName(std::string const& name);
-
- // when using this, you must use the hashmapholder's lock
- static HashMapHolder<Player>::MapType const& GetPlayers()
- {
- return HashMapHolder<Player>::GetContainer();
- }
-
- template<class T> static void AddObject(T* object)
- {
- HashMapHolder<T>::Insert(object);
- }
-
- template<class T> static void RemoveObject(T* object)
- {
- HashMapHolder<T>::Remove(object);
- }
-
- static void SaveAllPlayers();
-
- //non-static functions
-
- //Thread safe
- Corpse* GetCorpseForPlayerGUID(ObjectGuid const& guid);
- void RemoveCorpse(Corpse* corpse);
- void AddCorpse(Corpse* corpse);
- void AddCorpsesToGrid(GridCoord const& gridpair, GridType& grid, Map* map);
- Corpse* ConvertCorpseForPlayer(ObjectGuid const& player_guid, bool insignia = false);
-
- //Thread unsafe
- void RemoveOldCorpses();
- void UnloadAll();
-
- private:
- typedef std::unordered_map<ObjectGuid, Corpse*> Player2CorpsesMapType;
- typedef std::unordered_map<Player*, UpdateData>::value_type UpdateDataValueType;
-
- Player2CorpsesMapType i_player2corpse;
-
- boost::shared_mutex _corpseLock;
+ // these functions return objects only if in map of specified object
+ WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&);
+ Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask);
+ Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid);
+ GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid);
+ Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid);
+ DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid);
+ AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid);
+ Unit* GetUnit(WorldObject const&, ObjectGuid const& guid);
+ Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid);
+ Pet* GetPet(WorldObject const&, ObjectGuid const& guid);
+ Player* GetPlayer(Map const*, ObjectGuid const& guid);
+ Player* GetPlayer(WorldObject const&, ObjectGuid const& guid);
+ Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&);
+
+ // these functions return objects if found in whole world
+ // ACCESS LIKE THAT IS NOT THREAD SAFE
+ Player* FindPlayer(ObjectGuid const&);
+ Player* FindPlayerByName(std::string const& name);
+
+ // this returns Player even if he is not in world, for example teleporting
+ Player* FindConnectedPlayer(ObjectGuid const&);
+ Player* FindConnectedPlayerByName(std::string const& name);
+
+ // when using this, you must use the hashmapholder's lock
+ HashMapHolder<Player>::MapType const& GetPlayers();
+
+ template<class T>
+ void AddObject(T* object)
+ {
+ HashMapHolder<T>::Insert(object);
+ }
+
+ template<class T>
+ void RemoveObject(T* object)
+ {
+ HashMapHolder<T>::Remove(object);
+ }
+
+ void SaveAllPlayers();
};
-#define sObjectAccessor ObjectAccessor::instance()
#endif
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index b048afe16a6..61e84c6aabe 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -7270,20 +7270,6 @@ void ObjectMgr::DeleteGOData(ObjectGuid::LowType guid)
_gameObjectDataStore.erase(guid);
}
-void ObjectMgr::AddCorpseCellData(uint32 mapid, uint32 cellid, ObjectGuid player_guid, uint32 instance)
-{
- // corpses are always added to spawn mode 0 and they are spawned by their instance id
- CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(mapid, 0)][cellid];
- cell_guids.corpses[player_guid] = instance;
-}
-
-void ObjectMgr::DeleteCorpseCellData(uint32 mapid, uint32 cellid, ObjectGuid player_guid)
-{
- // corpses are always added to spawn mode 0 and they are spawned by their instance id
- CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(mapid, 0)][cellid];
- cell_guids.corpses.erase(player_guid);
-}
-
void ObjectMgr::LoadQuestRelationsHelper(QuestRelations& map, QuestRelationsReverse* reverseMap, std::string const& table, bool starter, bool go)
{
uint32 oldMSTime = getMSTime();
@@ -8537,7 +8523,7 @@ void ObjectMgr::LoadScriptNames()
do
{
- _scriptNamesStore.emplace_back((*result)[0].GetCString());
+ _scriptNamesStore.push_back((*result)[0].GetString());
}
while (result->NextRow());
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index c5f3fb908e7..62791734b72 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -401,12 +401,10 @@ struct AreaTriggerStruct
};
typedef std::set<ObjectGuid::LowType> CellGuidSet;
-typedef std::map<ObjectGuid/*player guid*/, uint32/*instance*/> CellCorpseSet;
struct CellObjectGuids
{
CellGuidSet creatures;
CellGuidSet gameobjects;
- CellCorpseSet corpses;
};
typedef std::unordered_map<uint32/*cell_id*/, CellObjectGuids> CellObjectGuidsMap;
typedef std::unordered_map<uint32/*(mapid, spawnMode) pair*/, CellObjectGuidsMap> MapObjectGuids;
@@ -1214,9 +1212,6 @@ class ObjectMgr
LocaleConstant GetDBCLocaleIndex() const { return DBCLocaleIndex; }
void SetDBCLocaleIndex(LocaleConstant locale) { DBCLocaleIndex = locale; }
- void AddCorpseCellData(uint32 mapid, uint32 cellid, ObjectGuid player_guid, uint32 instance);
- void DeleteCorpseCellData(uint32 mapid, uint32 cellid, ObjectGuid player_guid);
-
// grid objects
void AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const* data);
void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const* data);
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 365cfb63e08..27af37068c2 100644
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -63,7 +63,7 @@ class ObjectWorldLoader
{
public:
explicit ObjectWorldLoader(ObjectGridLoader& gloader)
- : i_cell(gloader.i_cell), i_map(gloader.i_map), i_corpses (0)
+ : i_cell(gloader.i_cell), i_map(gloader.i_map), i_grid(gloader.i_grid), i_corpses(gloader.i_corpses)
{ }
void Visit(CorpseMapType &m);
@@ -73,8 +73,9 @@ class ObjectWorldLoader
private:
Cell i_cell;
Map* i_map;
+ NGridType& i_grid;
public:
- uint32 i_corpses;
+ uint32& i_corpses;
};
template<class T> void ObjectGridLoader::SetObjectCell(T* /*obj*/, CellCoord const& /*cellCoord*/) { }
@@ -130,36 +131,6 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T>
}
}
-void LoadHelper(CellCorpseSet const& cell_corpses, CellCoord &cell, CorpseMapType &m, uint32 &count, Map* map)
-{
- if (cell_corpses.empty())
- return;
-
- for (CellCorpseSet::const_iterator itr = cell_corpses.begin(); itr != cell_corpses.end(); ++itr)
- {
- if (itr->second != map->GetInstanceId())
- continue;
-
- Corpse* obj = sObjectAccessor->GetCorpseForPlayerGUID(itr->first);
- if (!obj)
- continue;
-
- /// @todo this is a hack
- // corpse's map should be reset when the map is unloaded
- // but it may still exist when the grid is unloaded but map is not
- // in that case map == currMap
- obj->SetMap(map);
-
- if (obj->IsInGrid())
- {
- obj->AddToWorld();
- continue;
- }
-
- AddObjectHelper(cell, m, count, map, obj);
- }
-}
-
void ObjectGridLoader::Visit(GameObjectMapType &m)
{
CellCoord cellCoord = i_cell.GetCellCoord();
@@ -177,19 +148,25 @@ void ObjectGridLoader::Visit(CreatureMapType &m)
void ObjectWorldLoader::Visit(CorpseMapType &m)
{
CellCoord cellCoord = i_cell.GetCellCoord();
- // corpses are always added to spawn mode 0 and they are spawned by their instance id
- CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), 0, cellCoord.GetId());
- LoadHelper(cell_guids.corpses, cellCoord, m, i_corpses, i_map);
+ if (std::unordered_set<Corpse*> const* corpses = i_map->GetCorpsesInCell(cellCoord.GetId()))
+ {
+ for (Corpse* corpse : *corpses)
+ {
+ corpse->AddToWorld();
+ i_grid.GetGridType(i_cell.CellX(), i_cell.CellY()).AddWorldObject(corpse);
+ ++i_corpses;
+ }
+ }
}
void ObjectGridLoader::LoadN(void)
{
i_gameObjects = 0; i_creatures = 0; i_corpses = 0;
i_cell.data.Part.cell_y = 0;
- for (unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x)
+ for (uint32 x = 0; x < MAX_NUMBER_OF_CELLS; ++x)
{
i_cell.data.Part.cell_x = x;
- for (unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y)
+ for (uint32 y = 0; y < MAX_NUMBER_OF_CELLS; ++y)
{
i_cell.data.Part.cell_y = y;
@@ -204,7 +181,6 @@ void ObjectGridLoader::LoadN(void)
ObjectWorldLoader worker(*this);
TypeContainerVisitor<ObjectWorldLoader, WorldTypeMapContainer> visitor(worker);
i_grid.VisitGrid(x, y, visitor);
- i_corpses += worker.i_corpses;
}
}
}
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 3b0a8fc8913..4bf764dcdce 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -445,7 +445,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPackets::AuctionHouse::AuctionPlac
SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_OK);
// Not sure if we must send this now.
- Player* owner = sObjectAccessor->FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(auction->owner));
+ Player* owner = ObjectAccessor::FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(auction->owner));
Item* item = sAuctionMgr->GetAItem(auction->itemGUIDLow);
if (owner && item)
owner->GetSession()->SendAuctionOwnerBidNotification(auction, item);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index e2c1fe0a858..847574bf763 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -236,6 +236,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CURRENCY, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_LOCATION);
+ stmt->setUInt64(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION, stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GARRISON);
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_GARRISON, stmt);
@@ -1016,7 +1020,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation());
}
- sObjectAccessor->AddObject(pCurrChar);
+ ObjectAccessor::AddObject(pCurrChar);
//TC_LOG_DEBUG("Player %s added to Map.", pCurrChar->GetName().c_str());
if (pCurrChar->GetGuildId())
@@ -1055,7 +1059,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID(), true);
// Place character in world (and load zone) before some object loading
- pCurrChar->LoadCorpse();
+ pCurrChar->LoadCorpse(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION));
// setting Ghost+speed if dead
if (pCurrChar->m_deathState != ALIVE)
@@ -1844,23 +1848,22 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
return;
}
- /// All checks are fine, deal with race change now
-
+ // All checks are fine, deal with race change now
ObjectGuid::LowType lowGuid = factionChangeInfo->Guid.GetCounter();
- // resurrect the character in case he's dead
- sObjectAccessor->ConvertCorpseForPlayer(factionChangeInfo->Guid);
-
PreparedStatement* stmt = nullptr;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- /// Name Change and update atLogin flags
+ // resurrect the character in case he's dead
+ Player::OfflineResurrect(factionChangeInfo->Guid, trans);
+
+ // Name Change and update atLogin flags
{
CharacterDatabase.EscapeString(factionChangeInfo->Name);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
stmt->setString(0, factionChangeInfo->Name);
- stmt->setUInt16(1, uint16(atLoginFlags & ~usedLoginFlag));
+ stmt->setUInt16(1, uint16((atLoginFlags | AT_LOGIN_RESURRECT) & ~usedLoginFlag));
stmt->setUInt64(2, lowGuid);
trans->Append(stmt);
@@ -1871,7 +1874,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
trans->Append(stmt);
}
- /// Customize
+ // Customize
{
if (factionChangeInfo->SkinID)
{
@@ -1922,7 +1925,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
trans->Append(stmt);
}
- /// Race Change
+ // Race Change
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_RACE);
stmt->setUInt8(0, factionChangeInfo->RaceID);
@@ -1996,7 +1999,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
trans->Append(stmt);
}
- /// Team Conversation
+ // Team Conversion
if (factionChangeInfo->FactionChange)
{
// Delete all Flypaths
@@ -2024,7 +2027,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
trans->Append(stmt);
}
- /// @todo: make this part asynch
+ /// @todo: make this part async
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
{
// Reset guild
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index 49922edafd7..c200c0851b2 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -454,7 +454,7 @@ void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std:
if (!normalizePlayerName(target))
break;
- Player* receiver = sObjectAccessor->FindPlayerByName(target);
+ Player* receiver = ObjectAccessor::FindPlayerByName(target);
if (!receiver)
break;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 1d98b85a441..553f51d0461 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -418,7 +418,6 @@ void WorldSession::HandleReclaimCorpse(WorldPackets::Misc::ReclaimCorpse& /*pack
return;
Corpse* corpse = _player->GetCorpse();
-
if (!corpse)
return;
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 279345845a1..dad3d2f8a54 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -157,8 +157,8 @@ void WorldSession::HandleMoveWorldportAckOpcode()
}
// resurrect character at enter into instance where his corpse exist after add to map
- Corpse* corpse = GetPlayer()->GetCorpse();
- if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId())
+ Corpse* corpse = GetPlayer()->GetMap()->GetCorpseByPlayer(GetPlayer()->GetGUID());
+ if (corpse && corpse->GetType() != CORPSE_BONES)
{
if (mEntry->IsDungeon())
{
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index 2418bb84cac..a6e192521f4 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -409,10 +409,12 @@ void WorldSession::SendSpiritResurrect()
// get corpse nearest graveyard
WorldSafeLocsEntry const* corpseGrave = NULL;
- Corpse* corpse = _player->GetCorpse();
- if (corpse)
- corpseGrave = sObjectMgr->GetClosestGraveYard(
- corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetMapId(), _player->GetTeam());
+ WorldLocation corpseLocation = _player->GetCorpseLocation();
+ if (_player->HasCorpse())
+ {
+ corpseGrave = sObjectMgr->GetClosestGraveYard(corpseLocation.GetPositionX(), corpseLocation.GetPositionY(),
+ corpseLocation.GetPositionZ(), corpseLocation.GetMapId(), _player->GetTeam());
+ }
// now can spawn bones
_player->SpawnCorpseBones();
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index a9ab4ca841d..93611114b4e 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -169,9 +169,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObj
void WorldSession::HandleQueryCorpseLocation(WorldPackets::Query::QueryCorpseLocationFromClient& /*packet*/)
{
- Corpse* corpse = GetPlayer()->GetCorpse();
-
- if (!corpse)
+ if (!_player->HasCorpse())
{
WorldPackets::Query::CorpseLocation packet;
packet.Valid = false; // corpse not found
@@ -179,11 +177,12 @@ void WorldSession::HandleQueryCorpseLocation(WorldPackets::Query::QueryCorpseLoc
return;
}
- uint32 mapID = corpse->GetMapId();
- float x = corpse->GetPositionX();
- float y = corpse->GetPositionY();
- float z = corpse->GetPositionZ();
- uint32 corpseMapID = mapID;
+ WorldLocation corpseLocation = _player->GetCorpseLocation();
+ uint32 corpseMapID = corpseLocation.GetMapId();
+ uint32 mapID = corpseLocation.GetMapId();
+ float x = corpseLocation.GetPositionX();
+ float y = corpseLocation.GetPositionY();
+ float z = corpseLocation.GetPositionZ();
// if corpse at different map
if (mapID != _player->GetMapId())
@@ -210,7 +209,7 @@ void WorldSession::HandleQueryCorpseLocation(WorldPackets::Query::QueryCorpseLoc
packet.MapID = corpseMapID;
packet.ActualMapID = mapID;
packet.Position = G3D::Vector3(x, y, z);
- packet.Transport = corpse->GetTransGUID();
+ packet.Transport = ObjectGuid::Empty;
SendPacket(packet.Write());
}
@@ -280,12 +279,12 @@ void WorldSession::HandleQueryPageText(WorldPackets::Query::QueryPageText& packe
}
}
-void WorldSession::HandleQueryCorpseTransport(WorldPackets::Query::QueryCorpseTransport& packet)
+void WorldSession::HandleQueryCorpseTransport(WorldPackets::Query::QueryCorpseTransport& queryCorpseTransport)
{
Corpse* corpse = _player->GetCorpse();
WorldPackets::Query::CorpseTransportQuery response;
- if (!corpse || corpse->GetTransGUID().IsEmpty() || corpse->GetTransGUID() != packet.Transport)
+ if (!corpse || corpse->GetTransGUID().IsEmpty() || corpse->GetTransGUID() != queryCorpseTransport.Transport)
{
response.Position = G3D::Vector3(0.0f, 0.0f, 0.0f);
response.Facing = 0.0f;
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index ccfd3ce33f7..1e35722202c 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -57,9 +57,9 @@ ZoneDynamicInfo::ZoneDynamicInfo() : MusicId(0), WeatherId(WEATHER_STATE_FINE),
Map::~Map()
{
- sScriptMgr->OnDestroyMap(this);
+ // UnloadAll must be called before deleting the map
- UnloadAll();
+ sScriptMgr->OnDestroyMap(this);
while (!i_worldObjects.empty())
{
@@ -399,7 +399,7 @@ void Map::DeleteFromWorld(T* obj)
template<>
void Map::DeleteFromWorld(Player* player)
{
- sObjectAccessor->RemoveObject(player);
+ ObjectAccessor::RemoveObject(player);
RemoveUpdateObject(player); /// @todo I do not know why we need this, it should be removed in ~Object anyway
delete player;
}
@@ -466,8 +466,6 @@ bool Map::EnsureGridLoaded(const Cell &cell)
LoadGridObjects(grid, cell);
- // Add resurrectable corpses to world object list in grid
- sObjectAccessor->AddCorpsesToGrid(GridCoord(cell.GridX(), cell.GridY()), grid->GetGridType(cell.CellX(), cell.CellY()), this);
Balance();
return true;
}
@@ -516,6 +514,9 @@ bool Map::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)
player->UpdateObjectVisibility(false);
player->SendUpdatePhasing();
+ if (player->IsAlive())
+ ConvertCorpseToBones(player->GetGUID());
+
sScriptMgr->OnPlayerEnterMap(this, player);
return true;
}
@@ -3580,7 +3581,7 @@ time_t Map::GetLinkedRespawnTime(ObjectGuid guid) const
void Map::LoadCorpseData()
{
- std::unordered_map<uint64, std::unordered_set<uint32>> phases;
+ std::unordered_map<ObjectGuid::LowType, std::unordered_set<uint32>> phases;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_PHASES);
stmt->setUInt32(0, GetId());
@@ -3594,7 +3595,7 @@ void Map::LoadCorpseData()
do
{
Field* fields = phaseResult->Fetch();
- uint64 guid = fields[0].GetUInt64();
+ ObjectGuid::LowType guid = fields[0].GetUInt64();
uint32 phaseId = fields[1].GetUInt32();
phases[guid].insert(phaseId);
@@ -3612,7 +3613,6 @@ void Map::LoadCorpseData()
if (!result)
return;
- uint32 count = 0;
do
{
Field* fields = result->Fetch();
@@ -3634,8 +3634,8 @@ void Map::LoadCorpseData()
for (auto phaseId : phases[guid])
corpse->SetInPhase(phaseId, false, true);
- sObjectAccessor->AddCorpse(corpse);
- ++count;
+ AddCorpse(corpse);
+
} while (result->NextRow());
}
@@ -3648,6 +3648,99 @@ void Map::DeleteCorpseData()
CharacterDatabase.Execute(stmt);
}
+void Map::AddCorpse(Corpse* corpse)
+{
+ corpse->SetMap(this);
+
+ CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
+ _corpsesByCell[cellCoord.GetId()].insert(corpse);
+ _corpsesByPlayer[corpse->GetOwnerGUID()] = corpse;
+}
+
+void Map::RemoveCorpse(Corpse* corpse)
+{
+ ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
+
+ corpse->DestroyForNearbyPlayers();
+ if (corpse->IsInGrid())
+ RemoveFromMap(corpse, false);
+ else
+ {
+ corpse->RemoveFromWorld();
+ corpse->ResetMap();
+ }
+
+ CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
+ _corpsesByCell[cellCoord.GetId()].erase(corpse);
+ _corpsesByPlayer.erase(corpse->GetOwnerGUID());
+}
+
+Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= false*/)
+{
+ Corpse* corpse = GetCorpseByPlayer(ownerGuid);
+ if (!corpse)
+ return nullptr;
+
+ RemoveCorpse(corpse);
+
+ // remove corpse from DB
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ corpse->DeleteFromDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
+
+ Corpse* bones = NULL;
+
+ // create the bones only if the map and the grid is loaded at the corpse's location
+ // ignore bones creating option in case insignia
+ if ((insignia ||
+ (IsBattlegroundOrArena() ? sWorld->getBoolConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld->getBoolConfig(CONFIG_DEATH_BONES_WORLD))) &&
+ !IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
+ {
+ // Create bones, don't change Corpse
+ bones = new Corpse();
+ bones->Create(corpse->GetGUID().GetCounter(), this);
+
+ for (uint8 i = OBJECT_FIELD_GUID + 4; i < CORPSE_END; ++i) // don't overwrite guid
+ bones->SetUInt32Value(i, corpse->GetUInt32Value(i));
+
+ bones->SetGridCoord(corpse->GetGridCoord());
+ bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
+
+ bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
+ bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty);
+ bones->SetGuidValue(OBJECT_FIELD_DATA, corpse->GetGuidValue(OBJECT_FIELD_DATA));
+
+ for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
+ bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
+
+ bones->CopyPhaseFrom(corpse);
+
+ // add bones in grid store if grid loaded where corpse placed
+ AddToMap(bones);
+ }
+
+ // all references to the corpse should be removed at this point
+ delete corpse;
+
+ return bones;
+}
+
+void Map::RemoveOldCorpses()
+{
+ time_t now = time(nullptr);
+
+ std::vector<ObjectGuid> corpses;
+ corpses.reserve(_corpsesByPlayer.size());
+
+ for (auto const& p : _corpsesByPlayer)
+ if (p.second->IsExpired(now))
+ corpses.push_back(p.first);
+
+ for (ObjectGuid const& ownerGuid : corpses)
+ ConvertCorpseToBones(ownerGuid);
+}
+
void Map::SendZoneDynamicInfo(Player* player)
{
uint32 zoneId = GetZoneId(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 9331815bb39..596a753ad34 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -464,6 +464,24 @@ class Map : public GridRefManager<NGridType>
typedef std::unordered_multimap<ObjectGuid::LowType, GameObject*> GameObjectBySpawnIdContainer;
GameObjectBySpawnIdContainer& GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; }
+ std::unordered_set<Corpse*> const* GetCorpsesInCell(uint32 cellId) const
+ {
+ auto itr = _corpsesByCell.find(cellId);
+ if (itr != _corpsesByCell.end())
+ return &itr->second;
+
+ return nullptr;
+ }
+
+ Corpse* GetCorpseByPlayer(ObjectGuid const& ownerGuid) const
+ {
+ auto itr = _corpsesByPlayer.find(ownerGuid);
+ if (itr != _corpsesByPlayer.end())
+ return itr->second;
+
+ return nullptr;
+ }
+
MapInstanced* ToMapInstanced() { if (Instanceable()) return reinterpret_cast<MapInstanced*>(this); return NULL; }
MapInstanced const* ToMapInstanced() const { if (Instanceable()) return reinterpret_cast<MapInstanced const*>(this); return NULL; }
@@ -511,8 +529,13 @@ class Map : public GridRefManager<NGridType>
void RemoveGORespawnTime(ObjectGuid::LowType dbGuid);
void LoadRespawnTimes();
void DeleteRespawnTimes();
+
void LoadCorpseData();
void DeleteCorpseData();
+ void AddCorpse(Corpse* corpse);
+ void RemoveCorpse(Corpse* corpse);
+ Corpse* ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia = false);
+ void RemoveOldCorpses();
static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
@@ -708,6 +731,8 @@ class Map : public GridRefManager<NGridType>
MapStoredObjectTypesContainer _objectsStore;
CreatureBySpawnIdContainer _creatureBySpawnIdStore;
GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore;
+ std::unordered_map<uint32/*cellId*/, std::unordered_set<Corpse*>> _corpsesByCell;
+ std::unordered_map<ObjectGuid, Corpse*> _corpsesByPlayer;
std::unordered_set<Object*> _updateObjects;
};
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index 5cb3a2c26c5..bfaa9c588b9 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -163,10 +163,10 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
if (!player->IsAlive())
{
- if (Corpse* corpse = player->GetCorpse())
+ if (player->HasCorpse())
{
// let enter in ghost mode in instance that connected to inner instance with corpse
- uint32 corpseMap = corpse->GetMapId();
+ uint32 corpseMap = player->GetCorpseLocation().GetMapId();
do
{
if (corpseMap == mapid)
@@ -183,9 +183,8 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
TC_LOG_DEBUG("maps", "MAP: Player '%s' does not have a corpse in instance '%s' and cannot enter.", player->GetName().c_str(), mapName);
return false;
}
+
TC_LOG_DEBUG("maps", "MAP: Player '%s' has corpse in instance '%s' and can enter.", player->GetName().c_str(), mapName);
- player->ResurrectPlayer(0.5f, false);
- player->SpawnCorpseBones();
}
else
TC_LOG_DEBUG("maps", "Map::CanPlayerEnter - player '%s' is dead but does not have a corpse!", player->GetName().c_str());
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index afeb3e2a6b6..f491b3a6be5 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -52,6 +52,9 @@ WorldPackets::Character::EnumCharactersResult::CharacterInfo::CharacterInfo(Fiel
uint32 playerFlags = fields[14].GetUInt32();
uint32 atLoginFlags = fields[15].GetUInt16();
+ if (atLoginFlags & AT_LOGIN_RESURRECT)
+ playerFlags &= ~PLAYER_FLAGS_GHOST;
+
if (playerFlags & PLAYER_FLAGS_HIDE_HELM)
Flags |= CHARACTER_FLAG_HIDE_HELM;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 3acc8fb47f9..14c4d031cbd 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -2269,7 +2269,10 @@ void World::Update(uint32 diff)
if (m_timers[WUPDATE_CORPSES].Passed())
{
m_timers[WUPDATE_CORPSES].Reset();
- sObjectAccessor->RemoveOldCorpses();
+ sMapMgr->DoForAllMaps([](Map* map)
+ {
+ map->RemoveOldCorpses();
+ });
}
///- Process Game events when necessary
@@ -3431,11 +3434,6 @@ void World::UpdateCharacterInfoDeleted(ObjectGuid const& guid, bool deleted, std
itr->second.Name = *name;
}
-void World::UpdatePhaseDefinitions()
-{
-
-}
-
void World::ReloadRBAC()
{
// Passive reload, we mark the data as invalidated and next time a permission is checked it will be reloaded
@@ -3445,6 +3443,11 @@ void World::ReloadRBAC()
session->InvalidateRBACData();
}
+void World::RemoveOldCorpses()
+{
+ m_timers[WUPDATE_CORPSES].SetCurrent(m_timers[WUPDATE_CORPSES].GetInterval());
+}
+
uint32 GetVirtualRealmAddress()
{
return uint32(realmHandle.Region) << 24 | uint32(realmHandle.Battlegroup) << 16 | realmHandle.Index;
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index b72591e04fa..1ac4cb2af75 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -788,9 +788,10 @@ class World
void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; }
void ResetEventSeasonalQuests(uint16 event_id);
- void UpdatePhaseDefinitions();
void ReloadRBAC();
+ void RemoveOldCorpses();
+
protected:
void _UpdateGameTime();
// callback for UpdateRealmCharacters
diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp
index 6e82c4fbd1a..836d4caa22b 100644
--- a/src/server/scripts/Commands/cs_instance.cpp
+++ b/src/server/scripts/Commands/cs_instance.cpp
@@ -217,7 +217,7 @@ public:
{
playerName = param3;
if (normalizePlayerName(playerName))
- player = sObjectAccessor->FindPlayerByName(playerName);
+ player = ObjectAccessor::FindPlayerByName(playerName);
}
if (!player)
@@ -283,7 +283,7 @@ public:
{
playerName = param2;
if (normalizePlayerName(playerName))
- player = sObjectAccessor->FindPlayerByName(playerName);
+ player = ObjectAccessor::FindPlayerByName(playerName);
}
if (!player)
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 400ef88ff67..73fab358f38 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -620,8 +620,10 @@ public:
target->SaveToDB();
}
else
- // will resurrected at login without corpse
- sObjectAccessor->ConvertCorpseForPlayer(targetGuid);
+ {
+ SQLTransaction trans(nullptr);
+ Player::OfflineResurrect(targetGuid, trans);
+ }
return true;
}
@@ -842,7 +844,7 @@ public:
// Save all players in the world
static bool HandleSaveAllCommand(ChatHandler* handler, char const* /*args*/)
{
- sObjectAccessor->SaveAllPlayers();
+ ObjectAccessor::SaveAllPlayers();
handler->SendSysMessage(LANG_PLAYERS_SAVED);
return true;
}
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index c3ba942ef1f..be025ea7180 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -1117,7 +1117,6 @@ public:
{
TC_LOG_INFO("misc", "Reloading terrain_phase_info table...");
sObjectMgr->LoadTerrainPhaseInfo();
- sWorld->UpdatePhaseDefinitions();
handler->SendGlobalGMSysMessage("Terrain phase infos reloaded.");
return true;
}
diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp
index e65ac5f2105..15078e4cc78 100644
--- a/src/server/scripts/Commands/cs_server.cpp
+++ b/src/server/scripts/Commands/cs_server.cpp
@@ -100,7 +100,7 @@ public:
// Triggering corpses expire check in world
static bool HandleServerCorpsesCommand(ChatHandler* /*handler*/, char const* /*args*/)
{
- sObjectAccessor->RemoveOldCorpses();
+ sWorld->RemoveOldCorpses();
return true;
}
diff --git a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp
index 74686f23721..b831f83dc41 100644
--- a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp
+++ b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp
@@ -527,7 +527,7 @@ public:
case PHASE_PLANT_FIRST_DETONATE: // first explosives detonate finish
for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr)
{
- if (GameObject* explosive = sObjectAccessor->GetGameObject(*me, *itr))
+ if (GameObject* explosive = ObjectAccessor::GetGameObject(*me, *itr))
me->RemoveGameObject(explosive, true);
}
_explosivesGuids.clear();
@@ -624,7 +624,7 @@ public:
case PHASE_PLANT_SECOND_DETONATE: // second explosives detonate finish
for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr)
{
- if (GameObject* explosive = sObjectAccessor->GetGameObject(*me, *itr))
+ if (GameObject* explosive = ObjectAccessor::GetGameObject(*me, *itr))
me->RemoveGameObject(explosive, true);
}
_explosivesGuids.clear();
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 586697d3953..9c3c984b9b3 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -273,7 +273,6 @@ extern int main(int argc, char** argv)
sInstanceSaveMgr->Unload();
sOutdoorPvPMgr->Die(); // unload it before MapManager
sMapMgr->UnloadAll(); // unload all grids (including locked in memory)
- sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world
sScriptMgr->Unload();
// set server offline