diff options
author | megamage <none@none.none> | 2011-11-10 17:31:45 -0500 |
---|---|---|
committer | megamage <none@none.none> | 2011-11-10 17:31:45 -0500 |
commit | 31a88d4fe5d5dea87f4dad24e4d7c3c1d47fc48c (patch) | |
tree | 959c67bc2442019a69d37877fc7e7bcb33225ab6 /src | |
parent | 23b3f16f3a4a27b7b24081b725666c5897fdbbee (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-x | src/server/game/Entities/Object/Object.h | 8 | ||||
-rwxr-xr-x | src/server/game/Grids/Grid.h | 30 | ||||
-rwxr-xr-x | src/server/game/Grids/ObjectGridLoader.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Maps/Map.cpp | 58 | ||||
-rwxr-xr-x | src/server/game/Maps/Map.h | 3 | ||||
-rwxr-xr-x | src/server/shared/Dynamic/TypeContainerFunctions.h | 51 |
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 |