aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Maps/Map.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-02-25 00:13:14 +0100
committerShauren <shauren.trinity@gmail.com>2015-04-28 21:19:46 +0200
commitca83e14f8b141fab0a13e08f48fca6c1ace0c4c7 (patch)
tree68487de0cd291b6aba9131a4eade228433f05d99 /src/server/game/Maps/Map.cpp
parent455ef1a64af14ee249e270b451f67f552ba3605a (diff)
Core/Entities: Reworked guid scopes
* Added ObjectGuid traits to easily access whether guid type can be generated globally (ObjectMgr) or not * This adds separate (per map) guid sequences depending on object type * Ported map object container from cmangos/mangos-wotlk@a2d396eb0bb195efc460944dd4e0fab2a858b300 * Added type container visitor for TypeUnorderedMapContainer * Implemented helper function to erase unique pairs from multimap containers * Moved object storage of all objects except players and transports to map level * Added containers linking database spawn id with creature/gameobject in world * Renamed DBTableGuid to spawnId * Added a separate spawn id sequence generator for creatures and gameobjects - this will be used in db tables * Moved building SMSG_UPDATE_OBJECT - updatefields changes broadcast to map update
Diffstat (limited to 'src/server/game/Maps/Map.cpp')
-rw-r--r--src/server/game/Maps/Map.cpp135
1 files changed, 121 insertions, 14 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index c2bec063223..ebfdaaf3b73 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -392,7 +392,7 @@ template<>
void Map::DeleteFromWorld(Player* player)
{
sObjectAccessor->RemoveObject(player);
- sObjectAccessor->RemoveUpdateObject(player); /// @todo I do not know why we need this, it should be removed in ~Object anyway
+ RemoveUpdateObject(player); /// @todo I do not know why we need this, it should be removed in ~Object anyway
delete player;
}
@@ -698,6 +698,8 @@ void Map::Update(const uint32 t_diff)
obj->Update(t_diff);
}
+ SendObjectUpdates();
+
///- Process necessary scripts
if (!m_scriptSchedule.empty())
{
@@ -2591,6 +2593,27 @@ inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y)
i_grids[x][y] = grid;
}
+void Map::SendObjectUpdates()
+{
+ UpdateDataMapType update_players;
+
+ while (!_updateObjects.empty())
+ {
+ Object* obj = *_updateObjects.begin();
+ ASSERT(obj && obj->IsInWorld());
+ _updateObjects.erase(_updateObjects.begin());
+ obj->BuildUpdate(update_players);
+ }
+
+ WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
+ for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
+ {
+ iter->second.BuildPacket(&packet);
+ iter->first->GetSession()->SendPacket(&packet);
+ packet.clear(); // clean the string
+ }
+}
+
void Map::DelayedUpdate(const uint32 t_diff)
{
RemoveAllObjectsInRemoveList();
@@ -2775,7 +2798,7 @@ void Map::AddToActive(Creature* c)
AddToActiveHelper(c);
// also not allow unloading spawn grid to prevent creating creature clone at load
- if (!c->IsPet() && c->GetDBTableGUIDLow())
+ if (!c->IsPet() && c->GetSpawnId())
{
float x, y, z;
c->GetRespawnPosition(x, y, z);
@@ -2806,7 +2829,7 @@ void Map::RemoveFromActive(Creature* c)
RemoveFromActiveHelper(c);
// also allow unloading spawn grid
- if (!c->IsPet() && c->GetDBTableGUIDLow())
+ if (!c->IsPet() && c->GetSpawnId())
{
float x, y, z;
c->GetRespawnPosition(x, y, z);
@@ -3188,8 +3211,11 @@ void InstanceMap::UnloadAll()
{
ASSERT(!HavePlayers());
- if (m_resetAfterUnload == true)
+ if (m_resetAfterUnload)
+ {
DeleteRespawnTimes();
+ DeleteCorpseData();
+ }
Map::UnloadAll();
}
@@ -3330,17 +3356,37 @@ void BattlegroundMap::RemoveAllPlayers()
player->TeleportTo(player->GetBattlegroundEntryPoint());
}
-Creature* Map::GetCreature(ObjectGuid guid)
+AreaTrigger* Map::GetAreaTrigger(ObjectGuid const& guid)
+{
+ return _objectsStore.Find<AreaTrigger>(guid);
+}
+
+Corpse* Map::GetCorpse(ObjectGuid const& guid)
{
- return ObjectAccessor::GetObjectInMap(guid, this, (Creature*)NULL);
+ return _objectsStore.Find<Corpse>(guid);
}
-GameObject* Map::GetGameObject(ObjectGuid guid)
+Creature* Map::GetCreature(ObjectGuid const& guid)
{
- return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)NULL);
+ return _objectsStore.Find<Creature>(guid);
}
-Transport* Map::GetTransport(ObjectGuid guid)
+DynamicObject* Map::GetDynamicObject(ObjectGuid const& guid)
+{
+ return _objectsStore.Find<DynamicObject>(guid);
+}
+
+GameObject* Map::GetGameObject(ObjectGuid const& guid)
+{
+ return _objectsStore.Find<GameObject>(guid);
+}
+
+Pet* Map::GetPet(ObjectGuid const& guid)
+{
+ return _objectsStore.Find<Pet>(guid);
+}
+
+Transport* Map::GetTransport(ObjectGuid const& guid)
{
if (!guid.IsMOTransport())
return NULL;
@@ -3349,11 +3395,6 @@ Transport* Map::GetTransport(ObjectGuid guid)
return go ? go->ToTransport() : NULL;
}
-DynamicObject* Map::GetDynamicObject(ObjectGuid guid)
-{
- return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)NULL);
-}
-
void Map::UpdateIteratorBack(Player* player)
{
if (m_mapRefIter == player->GetMapRef())
@@ -3490,6 +3531,72 @@ time_t Map::GetLinkedRespawnTime(ObjectGuid guid) const
return time_t(0);
}
+void Map::LoadCorpseData()
+{
+ std::unordered_map<uint64, std::unordered_set<uint32>> phases;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_PHASES);
+ stmt->setUInt32(0, GetId());
+
+ // 0 1
+ // SELECT OwnerGuid, PhaseId FROM corpse_phases cp LEFT JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ?
+ PreparedQueryResult phaseResult = CharacterDatabase.Query(stmt);
+ if (phaseResult)
+ {
+ do
+ {
+ Field* fields = phaseResult->Fetch();
+ uint64 guid = fields[0].GetUInt64();
+ uint32 phaseId = fields[1].GetUInt32();
+
+ phases[guid].insert(phaseId);
+
+ } while (phaseResult->NextRow());
+ }
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES);
+ stmt->setUInt32(0, GetId());
+
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+ // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ?
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
+ if (!result)
+ return;
+
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+ CorpseType type = CorpseType(fields[12].GetUInt8());
+ ObjectGuid::LowType guid = fields[14].GetUInt64();
+ if (type >= MAX_CORPSE_TYPE || type == CORPSE_BONES)
+ {
+ TC_LOG_ERROR("misc", "Corpse (guid: " UI64FMTD ") have wrong corpse type (%u), not loading.", guid, type);
+ continue;
+ }
+
+ Corpse* corpse = new Corpse(type);
+ if (!corpse->LoadCorpseFromDB(GenerateLowGuid<HighGuid::Corpse>(), fields))
+ {
+ delete corpse;
+ continue;
+ }
+
+ for (auto phaseId : phases[guid])
+ corpse->SetInPhase(phaseId, false, true);
+
+ sObjectAccessor->AddCorpse(corpse);
+ ++count;
+ } while (result->NextRow());
+}
+
+void Map::DeleteCorpseData()
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSES_FROM_MAP);
+ stmt->setUInt32(0, GetId());
+ CharacterDatabase.Execute(stmt);
+}
+
void Map::SendZoneDynamicInfo(Player* player)
{
uint32 zoneId = GetZoneId(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());