OregonCore  revision 3611e8a-git
Your Favourite TBC server
ObjectGridLoader.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore 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 "ObjectAccessor.h"
20 #include "ObjectMgr.h"
21 #include "Creature.h"
22 #include "GameObject.h"
23 #include "DynamicObject.h"
24 #include "Corpse.h"
25 #include "World.h"
26 #include "CellImpl.h"
27 #include "CreatureAI.h"
28 
30 {
31  // creature in unloading grid can have respawn point in another grid
32  // if it will be unloaded then it will not respawn in original grid until unload/load original grid
33  // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
34  for (CreatureMapType::iterator iter = m.begin(); iter != m.end();)
35  {
36  Creature* c = iter->GetSource();
37  ++iter;
38 
39  ASSERT(!c->IsPet() && "ObjectGridRespawnMover don't must be called for pets");
40 
41  Cell const& cur_cell = c->GetCurrentCell();
42 
43  float resp_x, resp_y, resp_z;
44  c->GetRespawnPosition(resp_x, resp_y, resp_z);
45  CellCoord resp_val = Oregon::ComputeCellCoord(resp_x, resp_y);
46  Cell resp_cell(resp_val);
47 
48  if (cur_cell.DiffGrid(resp_cell))
49  {
51  // false result ignored: will be unload with other creatures at grid
52  }
53  }
54 }
55 
56 // for loading world object at grid loading (Corpses)
58 {
59  public:
61  : i_cell(gloader.i_cell), i_map(gloader.i_map), i_corpses (0)
62  {}
63 
64  void Visit(CorpseMapType& m);
65 
66  template<class T> void Visit(GridRefManager<T>&) { }
67 
68  private:
71  public:
73 };
74 
75 template<class T> void AddUnitState(T* /*obj*/, CellCoord const& /*cellCoord*/)
76 {
77 }
78 
79 template<> void AddUnitState(Creature* obj, CellCoord const& cellCoord)
80 {
81  Cell cell(cellCoord);
82 
83  obj->SetCurrentCell(cell);
84 }
85 
86 template <class T>
87 void AddObjectHelper(CellCoord& cell, GridRefManager<T>& m, uint32& count, Map* map, T* obj)
88 {
89  obj->AddToGrid(m);
90  AddUnitState(obj, cell);
91  obj->AddToWorld();
92  if (obj->isActiveObject())
93  map->AddToActive(obj);
94 
95  ++count;
96 }
97 
98 template <class T>
99 void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefManager<T>& m, uint32& count, Map* map)
100 {
101  for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
102  {
103  T* obj = new T;
104  uint32 guid = *i_guid;
105  //sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid);
106  if (!obj->LoadFromDB(guid, map))
107  {
108  delete obj;
109  continue;
110  }
111 
112  AddObjectHelper(cell, m, count, map, obj);
113  }
114 }
115 
116 void LoadHelper(CellCorpseSet const& cell_corpses, CellCoord& cell, CorpseMapType& m, uint32& count, Map* map)
117 {
118  if (cell_corpses.empty())
119  return;
120 
121  for (CellCorpseSet::const_iterator itr = cell_corpses.begin(); itr != cell_corpses.end(); ++itr)
122  {
123  if (itr->second != map->GetInstanceId())
124  continue;
125 
126  uint32 player_guid = itr->first;
127 
129  if (!obj)
130  continue;
131 
132  // @todo this is a hack
133  // corpse's map should be reset when the map is unloaded
134  // but it may still exist when the grid is unloaded but map is not
135  // in that case map == currMap
136  obj->SetMap(map);
137 
138  if (obj->IsInGrid())
139  {
140  obj->AddToWorld();
141  continue;
142  }
143 
144  AddObjectHelper(cell, m, count, map, obj);
145  }
146 }
147 
149 {
150  CellCoord cellCoord = i_cell.GetCellCoord();
151  CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
152  LoadHelper(cell_guids.gameobjects, cellCoord, m, i_gameObjects, i_map);
153 }
154 
156 {
157  CellCoord cellCoord = i_cell.GetCellCoord();
158  CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
159  LoadHelper(cell_guids.creatures, cellCoord, m, i_creatures, i_map);
160 }
161 
163 {
164  CellCoord cellCoord = i_cell.GetCellCoord();
165  // corpses are always added to spawn mode 0 and they are spawned by their instance id
166  CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), 0, cellCoord.GetId());
167  LoadHelper(cell_guids.corpses, cellCoord, m, i_corpses, i_map);
168 }
169 
171 {
172  i_gameObjects = 0;
173  i_creatures = 0;
174  i_corpses = 0;
175  i_cell.data.Part.cell_y = 0;
176  for (unsigned int x = 0; x < MAX_NUMBER_OF_CELLS; ++x)
177  {
178  i_cell.data.Part.cell_x = x;
179  for (unsigned int y = 0; y < MAX_NUMBER_OF_CELLS; ++y)
180  {
181  i_cell.data.Part.cell_y = y;
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  i_corpses += worker.i_corpses;
194  }
195  }
196  }
197  sLog.outDebug("%u GameObjects, %u Creatures, and %u Corpses/Bones loaded for grid %u on map %u", i_gameObjects, i_creatures, i_corpses, i_grid.GetGridId(), i_map->GetId());
198 }
199 
200 template<class T>
202 {
203  while (!m.isEmpty())
204  {
205  T* obj = m.getFirst()->GetSource();
206  // if option set then object already saved at this moment
208  obj->SaveRespawnTime();
209  //Some creatures may summon other temp summons in CleanupsBeforeDelete()
210  //So we need this even after cleaner (maybe we can remove cleaner)
211  obj->CleanupsBeforeDelete();
213  delete obj;
214  }
215 }
216 
218 {
219  // stop any fights at grid de-activation and remove dynobjects created at cast by creatures
220  for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
221  {
222  iter->GetSource()->RemoveAllDynObjects();
223  if (iter->GetSource()->IsInCombat() || !iter->GetSource()->getThreatManager().areThreatListsEmpty())
224  {
225  iter->GetSource()->CombatStop();
226  iter->GetSource()->DeleteThreatList();
227  if (iter->GetSource()->IsAIEnabled)
228  iter->GetSource()->AI()->EnterEvadeMode();
229  }
230  }
231 }
232 
233 template<class T>
235 {
236  for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
237  iter->GetSource()->CleanupsBeforeDelete();
238 }
239 
245 template void ObjectGridCleaner::Visit<GameObject>(GameObjectMapType&);
246 template void ObjectGridCleaner::Visit<DynamicObject>(DynamicObjectMapType&);
247 template void ObjectGridCleaner::Visit<Corpse>(CorpseMapType&);
248 
void Visit(GameObjectMapType &m)
Definition: Corpse.h:48
Map * GetMap() const
Definition: Object.h:829
std::set< uint32 > CellGuidSet
Definition: ObjectMgr.h:351
void LoadHelper(CellGuidSet const &guid_set, CellCoord &cell, GridRefManager< T > &m, uint32 &count, Map *map)
void Visit(CreatureMapType &m)
#define MAX_NUMBER_OF_CELLS
Definition: GridDefines.h:43
virtual void SetMap(Map *map)
Definition: Object.cpp:1951
void SetCurrentCell(Cell const &cell)
Definition: Creature.h:717
#define sLog
Log class singleton.
Definition: Log.h:187
void AddUnitState(T *, CellCoord const &)
void Visit(CreatureMapType &m)
std::map< uint32, uint32 > CellCorpseSet
Definition: ObjectMgr.h:352
#define sObjectMgr
Definition: ObjectMgr.h:1285
void Visit(GridRefManager< T > &m)
bool IsInGrid() const
Definition: Object.h:597
GridReference< OBJECT > * getFirst()
void AddObjectHelper(CellCoord &cell, GridRefManager< T > &m, uint32 &count, Map *map, T *obj)
CellCorpseSet corpses
Definition: ObjectMgr.h:357
void AddToWorld() override
Definition: Corpse.cpp:46
bool isEmpty() const
Definition: LinkedList.h:97
iterator end()
Definition: Map.h:266
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:167
Corpse * GetCorpseForPlayerGUID(uint64 guid)
ObjectWorldLoader(ObjectGridLoader &gloader)
bool IsPet() const
Definition: Unit.h:1020
Definition: Cell.h:46
Cell const & GetCurrentCell() const
Definition: Creature.h:713
void Visit(GridRefManager< T > &)
CellGuidSet creatures
Definition: ObjectMgr.h:355
FROM * GetSource() const
Definition: Reference.h:92
bool CreatureRespawnRelocation(Creature *c)
Definition: Map.cpp:873
void AddToActive(T *obj)
Definition: Map.h:502
iterator begin()
void Visit(CorpseMapType &m)
#define ASSERT
Definition: Errors.h:33
void Visit(GridRefManager< T > &)
CellGuidSet gameobjects
Definition: ObjectMgr.h:356
#define sWorld
Definition: World.h:860
ACE_UINT32 uint32
Definition: Define.h:71
void GetRespawnPosition(float &x, float &y, float &z, float *ori=NULL, float *dist=NULL) const
Definition: Creature.cpp:2307
uint32 GetInstanceId() const
Definition: Map.h:390
uint32 GetId() const
Definition: GridDefines.h:136