summaryrefslogtreecommitdiff
path: root/src/server/game/Grids/GridObjectLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Grids/GridObjectLoader.cpp')
-rw-r--r--src/server/game/Grids/GridObjectLoader.cpp138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/server/game/Grids/GridObjectLoader.cpp b/src/server/game/Grids/GridObjectLoader.cpp
new file mode 100644
index 0000000000..09550ab906
--- /dev/null
+++ b/src/server/game/Grids/GridObjectLoader.cpp
@@ -0,0 +1,138 @@
+/*
+ * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by the
+ * Free Software Foundation; either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "GridObjectLoader.h"
+#include "CellImpl.h"
+#include "Corpse.h"
+#include "Creature.h"
+#include "DynamicObject.h"
+#include "GameObject.h"
+#include "GridNotifiers.h"
+#include "Transport.h"
+
+template <class T>
+void GridObjectLoader::AddObjectHelper(Map* map, T* obj)
+{
+ CellCoord cellCoord = Acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
+ Cell cell(cellCoord);
+
+ map->AddToGrid(obj, cell);
+ obj->AddToWorld();
+ if (obj->isActiveObject())
+ map->AddToActive(obj);
+}
+
+void GridObjectLoader::LoadCreatures(CellGuidSet const& guid_set, Map* map)
+{
+ for (ObjectGuid::LowType const& guid : guid_set)
+ {
+ Creature* obj = new Creature();
+ if (!obj->LoadFromDB(guid, map))
+ {
+ delete obj;
+ continue;
+ }
+
+ AddObjectHelper<Creature>(map, obj);
+
+ if (!obj->IsMoveInLineOfSightDisabled() && obj->GetDefaultMovementType() == IDLE_MOTION_TYPE && !obj->isNeedNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION))
+ {
+ if (obj->IsAlive() && !obj->HasUnitState(UNIT_STATE_SIGHTLESS) && obj->HasReactState(REACT_AGGRESSIVE) && !obj->IsImmuneToNPC())
+ {
+ // call MoveInLineOfSight for nearby grid creatures
+ Acore::AIRelocationNotifier notifier(*obj);
+ Cell::VisitGridObjects(obj, notifier, 60.f);
+ }
+ }
+ }
+}
+
+void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map)
+{
+ for (ObjectGuid::LowType const& guid : guid_set)
+ {
+ GameObjectData const* data = sObjectMgr->GetGameObjectData(guid);
+ GameObject* obj = data && sObjectMgr->IsGameObjectStaticTransport(data->id) ? new StaticTransport() : new GameObject();
+
+ if (!obj->LoadFromDB(guid, map))
+ {
+ delete obj;
+ continue;
+ }
+
+ AddObjectHelper<GameObject>(map, obj);
+ }
+}
+
+void GridObjectLoader::LoadAllCellsInGrid()
+{
+ CellObjectGuids const& cell_guids = sObjectMgr->GetGridObjectGuids(_map->GetId(), _map->GetSpawnMode(), _grid.GetId());
+ LoadGameObjects(cell_guids.gameobjects, _map);
+ LoadCreatures(cell_guids.creatures, _map);
+
+ if (std::unordered_set<Corpse*> const* corpses = _map->GetCorpsesInCell(_grid.GetId()))
+ {
+ for (Corpse* corpse : *corpses)
+ {
+ if (corpse->IsInGrid())
+ continue;
+
+ CellCoord cellCoord = Acore::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
+ Cell cell(cellCoord);
+
+ if (corpse->IsWorldObject())
+ _grid.AddWorldObject(cell.CellX(), cell.CellY(), corpse);
+ else
+ _grid.AddGridObject(cell.CellX(), cell.CellY(), corpse);
+ }
+ }
+}
+
+template<class T>
+void GridObjectUnloader::Visit(GridRefMgr<T>& m)
+{
+ while (!m.IsEmpty())
+ {
+ T* obj = m.getFirst()->GetSource();
+ // if option set then object already saved at this moment
+ //if (!sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY))
+ // obj->SaveRespawnTime();
+ //Some creatures may summon other temp summons in CleanupsBeforeDelete()
+ //So we need this even after cleaner (maybe we can remove cleaner)
+ //Example: Flame Leviathan Turret 33139 is summoned when a creature is deleted
+ //TODO: Check if that script has the correct logic. Do we really need to summons something before deleting?
+ obj->CleanupsBeforeDelete();
+ ///- object will get delinked from the manager when deleted
+ delete obj;
+ }
+}
+
+template<class T>
+void GridObjectCleaner::Visit(GridRefMgr<T>& m)
+{
+ for (typename GridRefMgr<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
+ iter->GetSource()->CleanupsBeforeDelete();
+}
+
+template void GridObjectUnloader::Visit(CreatureMapType&);
+template void GridObjectUnloader::Visit(GameObjectMapType&);
+template void GridObjectUnloader::Visit(DynamicObjectMapType&);
+
+template void GridObjectCleaner::Visit(CreatureMapType&);
+template void GridObjectCleaner::Visit<GameObject>(GameObjectMapType&);
+template void GridObjectCleaner::Visit<DynamicObject>(DynamicObjectMapType&);
+template void GridObjectCleaner::Visit<Corpse>(CorpseMapType&);