aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none.none>2011-11-10 17:31:45 -0500
committermegamage <none@none.none>2011-11-10 17:31:45 -0500
commit31a88d4fe5d5dea87f4dad24e4d7c3c1d47fc48c (patch)
tree959c67bc2442019a69d37877fc7e7bcb33225ab6 /src
parent23b3f16f3a4a27b7b24081b725666c5897fdbbee (diff)
Fix the crash when removing object from an unloaded grid. Object should always be unlinked from grid no matter if the grid is loaded.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h8
-rwxr-xr-xsrc/server/game/Grids/Grid.h30
-rwxr-xr-xsrc/server/game/Grids/ObjectGridLoader.cpp2
-rwxr-xr-xsrc/server/game/Maps/Map.cpp58
-rwxr-xr-xsrc/server/game/Maps/Map.h3
-rwxr-xr-xsrc/server/shared/Dynamic/TypeContainerFunctions.h51
6 files changed, 54 insertions, 98 deletions
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index dfcf6a3cfa4..c579659623b 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -527,9 +527,11 @@ template<class T>
class GridObject
{
public:
- GridReference<T> &GetGridRef() { return m_gridRef; }
- protected:
- GridReference<T> m_gridRef;
+ bool IsInGrid() const { return _gridRef.isValid(); }
+ void AddToGrid(GridRefManager<T>& m) { ASSERT(!IsInGrid()); _gridRef.link(&m, (T*)this); }
+ void RemoveFromGrid() { ASSERT(IsInGrid()); _gridRef.unlink(); }
+ private:
+ GridReference<T> _gridRef;
};
template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, uint8 ARRAY_SIZE>
diff --git a/src/server/game/Grids/Grid.h b/src/server/game/Grids/Grid.h
index cf6eb2471da..448c4cb35fd 100755
--- a/src/server/game/Grids/Grid.h
+++ b/src/server/game/Grids/Grid.h
@@ -58,20 +58,19 @@ class Grid
*/
template<class SPECIFIC_OBJECT> void AddWorldObject(SPECIFIC_OBJECT *obj)
{
- ASSERT(!obj->GetGridRef().isValid());
i_objects.template insert<SPECIFIC_OBJECT>(obj);
- ASSERT(obj->GetGridRef().isValid());
+ ASSERT(obj->IsInGrid());
}
/** an object of interested exits the grid
*/
//Actually an unlink is enough, no need to go through the container
- template<class SPECIFIC_OBJECT> void RemoveWorldObject(SPECIFIC_OBJECT *obj)
- {
- ASSERT(obj->GetGridRef().isValid());
- i_objects.template remove<SPECIFIC_OBJECT>(obj);
- ASSERT(!obj->GetGridRef().isValid());
- }
+ //template<class SPECIFIC_OBJECT> void RemoveWorldObject(SPECIFIC_OBJECT *obj)
+ //{
+ // ASSERT(obj->GetGridRef().isValid());
+ // i_objects.template remove<SPECIFIC_OBJECT>(obj);
+ // ASSERT(!obj->GetGridRef().isValid());
+ //}
/** Refreshes/update the grid. This required for remote grids.
*/
@@ -107,19 +106,18 @@ class Grid
*/
template<class SPECIFIC_OBJECT> void AddGridObject(SPECIFIC_OBJECT *obj)
{
- ASSERT(!obj->GetGridRef().isValid());
i_container.template insert<SPECIFIC_OBJECT>(obj);
- ASSERT(obj->GetGridRef().isValid());
+ ASSERT(obj->IsInGrid());
}
/** Removes a containter type object from the grid
*/
- template<class SPECIFIC_OBJECT> void RemoveGridObject(SPECIFIC_OBJECT *obj)
- {
- ASSERT(obj->GetGridRef().isValid());
- i_container.template remove<SPECIFIC_OBJECT>(obj);
- ASSERT(!obj->GetGridRef().isValid());
- }
+ //template<class SPECIFIC_OBJECT> void RemoveGridObject(SPECIFIC_OBJECT *obj)
+ //{
+ // ASSERT(obj->GetGridRef().isValid());
+ // i_container.template remove<SPECIFIC_OBJECT>(obj);
+ // ASSERT(!obj->GetGridRef().isValid());
+ //}
/*bool NoWorldObjectInGrid() const
{
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index e38c74dd8e4..1f27aeb4742 100755
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -77,7 +77,7 @@ template<> void ObjectGridLoader::SetObjectCell(Creature* obj, CellCoord const&
template <class T>
void AddObjectHelper(CellCoord &cell, GridRefManager<T> &m, uint32 &count, Map* map, T *obj)
{
- obj->GetGridRef().link(&m, obj);
+ obj->AddToGrid(m);
ObjectGridLoader::SetObjectCell(obj, cell);
obj->AddToWorld();
if (obj->isActiveObject())
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 0c2a808f5c6..05abdd2a734 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -255,17 +255,6 @@ void Map::AddToGrid(Creature* obj, Cell const& cell)
obj->SetCurrentCell(cell);
}
-//TODO: cell is not needed. Just an unlink is enough.
-template<class T>
-void Map::RemoveFromGrid(T* obj, Cell const& cell)
-{
- NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
- if (obj->m_isWorldObject)
- grid->GetGridType(cell.CellX(), cell.CellY()).template RemoveWorldObject<T>(obj);
- else
- grid->GetGridType(cell.CellX(), cell.CellY()).template RemoveGridObject<T>(obj);
-}
-
template<class T>
void Map::SwitchGridContainers(T* obj, bool on)
{
@@ -286,16 +275,11 @@ void Map::SwitchGridContainers(T* obj, bool on)
GridType &grid = ngrid->GetGridType(cell.CellX(), cell.CellY());
+ obj->RemoveFromGrid(); //This step is not really necessary but we want to do ASSERT in remove/add
if (on)
- {
- grid.RemoveGridObject<T>(obj); //not really necessary if there were no ASSERT in remove/add
grid.AddWorldObject<T>(obj);
- }
else
- {
- grid.RemoveWorldObject<T>(obj); //not really necessary if there were no ASSERT in remove/add
grid.AddGridObject<T>(obj);
- }
obj->m_isWorldObject = on;
}
@@ -662,21 +646,8 @@ void Map::RemoveFromMap(Player* player, bool remove)
player->RemoveFromWorld();
SendRemoveTransports(player);
- CellCoord p = Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY());
- if (!p.IsCoordValid())
- sLog->outCrash("Map::Remove: Player is in invalid cell!");
- else
- {
- Cell cell(p);
- if (!getNGrid(cell.data.Part.grid_x, cell.data.Part.grid_y))
- sLog->outError("Map::Remove() i_grids was NULL x:%d, y:%d", cell.data.Part.grid_x, cell.data.Part.grid_y);
- else
- {
- sLog->outStaticDebug("Remove player %s from grid[%u, %u]", player->GetName(), cell.GridX(), cell.GridY());
- player->UpdateObjectVisibility(true);
- RemoveFromGrid(player, cell);
- }
- }
+ player->UpdateObjectVisibility(true);
+ player->RemoveFromGrid();
if (remove)
DeleteFromWorld(player);
@@ -692,19 +663,8 @@ Map::RemoveFromMap(T *obj, bool remove)
if (obj->isActiveObject())
RemoveFromActive(obj);
- CellCoord p = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
- if (!p.IsCoordValid())
- sLog->outError("Map::Remove: Object " UI64FMTD " has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
- else
- {
- Cell cell(p);
- if (IsGridLoaded(GridCoord(cell.data.Part.grid_x, cell.data.Part.grid_y)))
- {
- sLog->outStaticDebug("Remove object " UI64FMTD " from grid[%u, %u]", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y);
- obj->UpdateObjectVisibility(true);
- RemoveFromGrid(obj, cell);
- }
- }
+ obj->UpdateObjectVisibility(true);
+ obj->RemoveFromGrid();
obj->ResetMap();
@@ -731,7 +691,7 @@ Map::PlayerRelocation(Player* player, float x, float y, float z, float orientati
{
sLog->outStaticDebug("Player %s relocation grid[%u, %u]cell[%u, %u]->grid[%u, %u]cell[%u, %u]", player->GetName(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
- RemoveFromGrid(player, old_cell);
+ player->RemoveFromGrid();
if (old_cell.DiffGrid(new_cell))
EnsureGridLoadedForActiveObject(new_cell, player);
@@ -857,7 +817,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
sLog->outDebug(LOG_FILTER_MAPS, "Creature (GUID: %u Entry: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
#endif
- RemoveFromGrid(c, old_cell);
+ c->RemoveFromGrid();
AddToGrid(c, new_cell);
}
else
@@ -879,7 +839,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
sLog->outDebug(LOG_FILTER_MAPS, "Active creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
#endif
- RemoveFromGrid(c, old_cell);
+ c->RemoveFromGrid();
AddToGrid(c, new_cell);
return true;
@@ -892,7 +852,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
sLog->outDebug(LOG_FILTER_MAPS, "Creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
#endif
- RemoveFromGrid(c, old_cell);
+ c->RemoveFromGrid();
EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY()));
AddToGrid(c, new_cell);
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 053759a3ab3..9dfa75636cd 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -526,9 +526,6 @@ class Map : public GridRefManager<NGridType>
void AddToGrid(T* object, Cell const& cell);
template<class T>
- void RemoveFromGrid(T* object, Cell const& cell);
-
- template<class T>
void DeleteFromWorld(T*);
template<class T>
diff --git a/src/server/shared/Dynamic/TypeContainerFunctions.h b/src/server/shared/Dynamic/TypeContainerFunctions.h
index 981cd82197f..9bfbf47da93 100755
--- a/src/server/shared/Dynamic/TypeContainerFunctions.h
+++ b/src/server/shared/Dynamic/TypeContainerFunctions.h
@@ -62,7 +62,7 @@ namespace Trinity
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE *obj)
{
//elements._element[hdl] = obj;
- obj->GetGridRef().link(&elements._element, obj);
+ obj->AddToGrid(elements._element);
return obj;
};
@@ -84,31 +84,30 @@ namespace Trinity
return (t != NULL ? t : Insert(elements._TailElements, obj));
}
- // non-const remove method
- template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<SPECIFIC_TYPE> & /*elements*/, SPECIFIC_TYPE *obj)
- {
- obj->GetGridRef().unlink();
- return obj;
- }
-
- template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
- {
- return NULL;
- }
-
- // this is a missed
- template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
- {
- return NULL; // a missed
- }
-
- template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj)
- {
- // The head element is bad
- SPECIFIC_TYPE* t = Remove(elements._elements, obj);
- return ( t != NULL ? t : Remove(elements._TailElements, obj) );
- }
-
+ //// non-const remove method
+ //template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<SPECIFIC_TYPE> & /*elements*/, SPECIFIC_TYPE *obj)
+ //{
+ // obj->GetGridRef().unlink();
+ // return obj;
+ //}
+
+ //template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
+ //{
+ // return NULL;
+ //}
+
+ //// this is a missed
+ //template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
+ //{
+ // return NULL; // a missed
+ //}
+
+ //template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj)
+ //{
+ // // The head element is bad
+ // SPECIFIC_TYPE* t = Remove(elements._elements, obj);
+ // return ( t != NULL ? t : Remove(elements._TailElements, obj) );
+ //}
}
#endif