diff options
author | Shauren <shauren.trinity@gmail.com> | 2015-02-25 00:13:14 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2015-04-28 21:19:46 +0200 |
commit | ca83e14f8b141fab0a13e08f48fca6c1ace0c4c7 (patch) | |
tree | 68487de0cd291b6aba9131a4eade228433f05d99 /src/server/game/Maps/Map.cpp | |
parent | 455ef1a64af14ee249e270b451f67f552ba3605a (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.cpp | 135 |
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()); |