TrinityCore
ObjectGridLoader.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ObjectGridLoader.h"
19#include "AreaTrigger.h"
21#include "CellImpl.h"
22#include "Conversation.h"
23#include "Corpse.h"
24#include "Creature.h"
25#include "CreatureAI.h"
26#include "DynamicObject.h"
27#include "GameObject.h"
28#include "GameTime.h"
29#include "Log.h"
30#include "ObjectAccessor.h"
31#include "ObjectMgr.h"
32#include "PhasingHandler.h"
33#include "SceneObject.h"
34
36{
37 // creature in unloading grid can have respawn point in another grid
38 // if it will be unloaded then it will not respawn in original grid until unload/load original grid
39 // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
40 for (CreatureMapType::iterator iter = m.begin(); iter != m.end();)
41 {
42 Creature* c = iter->GetSource();
43 ++iter;
44
45 ASSERT(!c->IsPet() && "ObjectGridRespawnMover must not be called for pets");
46 c->GetMap()->CreatureRespawnRelocation(c, true);
47 }
48}
49
51{
52 // gameobject in unloading grid can have respawn point in another grid
53 // if it will be unloaded then it will not respawn in original grid until unload/load original grid
54 // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
55 for (GameObjectMapType::iterator iter = m.begin(); iter != m.end();)
56 {
57 GameObject* go = iter->GetSource();
58 ++iter;
59
60 go->GetMap()->GameObjectRespawnRelocation(go, true);
61 }
62}
63
64// for loading world object at grid loading (Corpses)
67{
68 public:
70 : i_cell(gloader.i_cell), i_map(gloader.i_map), i_grid(gloader.i_grid), i_corpses(gloader.i_corpses)
71 { }
72
73 void Visit(CorpseMapType &m);
74
75 template<class T> void Visit(GridRefManager<T>&) { }
76
77 private:
81 public:
83};
84
86{
87 Cell cell(cellCoord);
88 obj->SetCurrentCell(cell);
89}
90
91template <class T>
92void AddObjectHelper(CellCoord &cell, GridRefManager<T> &m, uint32 &count, Map* map, T *obj)
93{
94 obj->AddToGrid(m);
96 obj->AddToWorld();
97 if (obj->isActiveObject())
98 map->AddToActive(obj);
99
100 ++count;
101}
102
103template <class T>
104void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefManager<T>& m, uint32& count, Map* map, uint32 phaseId = 0, Optional<ObjectGuid> phaseOwner = {})
105{
106 for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
107 {
108 // Don't spawn at all if there's a respawn timer
109 ObjectGuid::LowType guid = *i_guid;
110 if (!map->ShouldBeSpawnedOnGridLoad<T>(guid))
111 continue;
112
113 T* obj = new T;
114 //TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: {} for (guid: {}) Loading", table, guid);
115 if (!obj->LoadFromDB(guid, map, false, phaseOwner.has_value() /*allowDuplicate*/))
116 {
117 delete obj;
118 continue;
119 }
120
121 if (phaseOwner)
122 {
123 PhasingHandler::InitDbPersonalOwnership(obj->GetPhaseShift(), *phaseOwner);
124 map->GetMultiPersonalPhaseTracker().RegisterTrackedObject(phaseId, *phaseOwner, obj);
125 }
126
127 AddObjectHelper(cell, m, count, map, obj);
128 }
129}
130
132{
133 CellCoord cellCoord = i_cell.GetCellCoord();
134 if (CellObjectGuids const* cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetDifficultyID(), cellCoord.GetId()))
135 LoadHelper(cell_guids->gameobjects, cellCoord, m, i_gameObjects, i_map);
136}
137
139{
140 CellCoord cellCoord = i_cell.GetCellCoord();
141 if (CellObjectGuids const* cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetDifficultyID(), cellCoord.GetId()))
142 LoadHelper(cell_guids->creatures, cellCoord, m, i_creatures, i_map);
143}
144
146{
147 CellCoord cellCoord = i_cell.GetCellCoord();
148 if (CellGuidSet const* areaTriggers = sAreaTriggerDataStore->GetAreaTriggersForMapAndCell(i_map->GetId(), i_map->GetDifficultyID(), cellCoord.GetId()))
149 LoadHelper(*areaTriggers, cellCoord, m, i_areaTriggers, i_map);
150}
151
153{
154 CellCoord cellCoord = i_cell.GetCellCoord();
155 if (std::unordered_set<Corpse*> const* corpses = i_map->GetCorpsesInCell(cellCoord.GetId()))
156 {
157 for (Corpse* corpse : *corpses)
158 {
159 corpse->AddToWorld();
161 if (corpse->IsStoredInWorldObjectGridContainer())
162 cell.AddWorldObject(corpse);
163 else
164 cell.AddGridObject(corpse);
165
166 ++i_corpses;
167 }
168 }
169}
170
172{
173 i_gameObjects = 0; i_creatures = 0; i_corpses = 0;
175 for (uint32 x = 0; x < MAX_NUMBER_OF_CELLS; ++x)
176 {
178 for (uint32 y = 0; y < MAX_NUMBER_OF_CELLS; ++y)
179 {
181
182 //Load creatures and game objects
183 {
185 i_grid.VisitGrid(x, y, visitor);
186 }
187
188 //Load corpses (not bones)
189 {
190 ObjectWorldLoader worker(*this);
192 i_grid.VisitGrid(x, y, visitor);
193 }
194 }
195 }
196 TC_LOG_DEBUG("maps", "{} GameObjects, {} Creatures, {} AreaTrriggers, and {} Corpses/Bones loaded for grid {} on map {}",
198}
199
201{
202 CellCoord cellCoord = i_cell.GetCellCoord();
203 if (CellObjectGuids const* cell_guids = sObjectMgr->GetCellPersonalObjectGuids(i_map->GetId(), i_map->GetDifficultyID(), _phaseId, cellCoord.GetId()))
204 LoadHelper(cell_guids->gameobjects, cellCoord, m, i_gameObjects, i_map, _phaseId, _phaseOwner);
205}
206
208{
209 CellCoord cellCoord = i_cell.GetCellCoord();
210 if (CellObjectGuids const* cell_guids = sObjectMgr->GetCellPersonalObjectGuids(i_map->GetId(), i_map->GetDifficultyID(), _phaseId, cellCoord.GetId()))
211 LoadHelper(cell_guids->creatures, cellCoord, m, i_creatures, i_map, _phaseId, _phaseOwner);
212}
213
215{
216 _phaseId = phaseId;
218 for (uint32 x = 0; x < MAX_NUMBER_OF_CELLS; ++x)
219 {
221 for (uint32 y = 0; y < MAX_NUMBER_OF_CELLS; ++y)
222 {
224
225 //Load creatures and game objects
227 i_grid.VisitGrid(x, y, visitor);
228 }
229 }
230}
231
232template<class T>
234{
235 while (!m.isEmpty())
236 {
237 T *obj = m.getFirst()->GetSource();
238 //Some creatures may summon other temp summons in CleanupsBeforeDelete()
239 //So we need this even after cleaner (maybe we can remove cleaner)
240 //Example: Flame Leviathan Turret 33139 is summoned when a creature is deleted
242 obj->CleanupsBeforeDelete();
244 delete obj;
245 }
246}
247
249{
250 // stop any fights at grid de-activation and remove dynobjects/areatriggers created at cast by creatures
251 for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
252 {
253 iter->GetSource()->RemoveAllDynObjects();
254 iter->GetSource()->RemoveAllAreaTriggers();
255 if (iter->GetSource()->IsInCombat())
256 iter->GetSource()->CombatStop();
257 }
258}
259
260template<class T>
262{
263 for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
264 {
265 iter->GetSource()->SetDestroyedObject(true);
266 iter->GetSource()->CleanupsBeforeDelete();
267 }
268}
269
276
278template void ObjectGridCleaner::Visit<GameObject>(GameObjectMapType &);
279template void ObjectGridCleaner::Visit<DynamicObject>(DynamicObjectMapType &);
280template void ObjectGridCleaner::Visit<Corpse>(CorpseMapType &);
281template void ObjectGridCleaner::Visit<AreaTrigger>(AreaTriggerMapType &);
282template void ObjectGridCleaner::Visit<SceneObject>(SceneObjectMapType &);
283template void ObjectGridCleaner::Visit<Conversation>(ConversationMapType &);
#define sAreaTriggerDataStore
uint32_t uint32
Definition: Define.h:142
#define ASSERT
Definition: Errors.h:68
#define MAX_NUMBER_OF_CELLS
Definition: GridDefines.h:36
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
void AddObjectHelper(CellCoord &cell, GridRefManager< T > &m, uint32 &count, Map *map, T *obj)
void LoadHelper(CellGuidSet const &guid_set, CellCoord &cell, GridRefManager< T > &m, uint32 &count, Map *map, uint32 phaseId=0, Optional< ObjectGuid > phaseOwner={})
std::set< ObjectGuid::LowType > CellGuidSet
Definition: ObjectMgr.h:479
#define sObjectMgr
Definition: ObjectMgr.h:1946
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
Definition: Corpse.h:53
iterator end()
GridReference< OBJECT > * getFirst()
iterator begin()
Definition: Grid.h:46
void AddWorldObject(SPECIFIC_OBJECT *obj)
Definition: Grid.h:58
void AddGridObject(SPECIFIC_OBJECT *obj)
Definition: Grid.h:111
bool isEmpty() const
Definition: LinkedList.h:110
void SetCurrentCell(Cell const &cell)
Definition: MapObject.h:49
Definition: Map.h:189
std::unordered_set< Corpse * > const * GetCorpsesInCell(uint32 cellId) const
Definition: Map.h:436
bool GameObjectRespawnRelocation(GameObject *go, bool diffGridOnly)
Definition: Map.cpp:1573
MultiPersonalPhaseTracker & GetMultiPersonalPhaseTracker()
Definition: Map.h:814
Difficulty GetDifficultyID() const
Definition: Map.h:324
uint32 GetId() const
Definition: Map.cpp:3228
void AddToActive(WorldObject *obj)
Definition: Map.cpp:2733
bool CreatureRespawnRelocation(Creature *c, bool diffGridOnly)
Definition: Map.cpp:1542
bool ShouldBeSpawnedOnGridLoad(SpawnObjectType type, ObjectGuid::LowType spawnId) const
Definition: Map.cpp:2319
Definition: NGrid.h:70
uint32 GetGridId(void) const
Definition: NGrid.h:90
GridType & GetGridType(const uint32 x, const uint32 y)
Definition: NGrid.h:78
void VisitGrid(const uint32 x, const uint32 y, TypeContainerVisitor< T, TypeMapContainer< TT > > &visitor)
Definition: NGrid.h:145
void Visit(GridRefManager< T > &)
void Visit(CreatureMapType &m)
static void SetObjectCell(MapObject *obj, CellCoord const &cellCoord)
void Visit(GameObjectMapType &m)
void Visit(CreatureMapType &m)
void Visit(CorpseMapType &)
uint64 LowType
Definition: ObjectGuid.h:278
ObjectWorldLoader(ObjectGridLoader &gloader)
void Visit(CorpseMapType &m)
void Visit(GridRefManager< T > &)
ObjectGuid const & _phaseOwner
void Load(uint32 phaseId)
void Visit(GameObjectMapType &m)
static void InitDbPersonalOwnership(PhaseShift &phaseShift, ObjectGuid const &personalGuid)
FROM * GetSource() const
Definition: Reference.h:96
bool IsPet() const
Definition: Unit.h:740
Map * GetMap() const
Definition: Object.h:624
Definition: wmo.h:163
Definition: Cell.h:47
CellCoord GetCellCoord() const
Definition: Cell.h:78
union Cell::@313 data
unsigned cell_y
Definition: Cell.h:99
unsigned cell_x
Definition: Cell.h:98
uint32 CellX() const
Definition: Cell.h:71
uint32 CellY() const
Definition: Cell.h:72
struct Cell::@313::@314 Part
uint32 GetId() const
Definition: GridDefines.h:166
void RegisterTrackedObject(uint32 phaseId, ObjectGuid const &phaseOwner, WorldObject *object)