Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Core/Grids): Grid improvements #20955

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c2331f1
WIP grid improvements
Takenbacon Dec 17, 2024
203325d
silly mistakes
Takenbacon Dec 17, 2024
b471dc0
Fix include
Takenbacon Dec 18, 2024
7abdeec
Merge branch 'master' into grid_improvements
Takenbacon Dec 18, 2024
2327425
Remove redundant AddObjectHelpers
Takenbacon Dec 18, 2024
8addb49
Cleanup unused code in Grid.h
Takenbacon Dec 23, 2024
6dd56e4
Fix crash at grid unload
Takenbacon Dec 23, 2024
85c7ae2
Should be a continue and not a return, oops
Takenbacon Dec 23, 2024
0f4ae6d
Move GridMap structure to a new grid terrain class. Needs more struct…
Takenbacon Jan 15, 2025
69cba24
Merge branch 'master' into grid_improvements
Takenbacon Jan 15, 2025
daae43b
More refactoring
Takenbacon Jan 21, 2025
e761e30
Misc changes/fixes
Takenbacon Jan 21, 2025
22eefc3
Couple missed changes
Takenbacon Jan 22, 2025
3788f0f
Log total map cells too
Takenbacon Jan 22, 2025
6feb995
Revise how grids are naturally loaded
Takenbacon Feb 3, 2025
6469312
Load all instance grids on map create
Takenbacon Feb 3, 2025
dd51e98
Merge branch 'master' into grid_improvements
Takenbacon Feb 3, 2025
0e6eead
Fix a couple missing includes on GCC
Takenbacon Feb 3, 2025
6ffcf9c
And another...
Takenbacon Feb 3, 2025
695374f
...And another
Takenbacon Feb 3, 2025
4751cf9
I'll get them all eventually lol
Takenbacon Feb 3, 2025
d311ea0
G3d include
Takenbacon Feb 3, 2025
0cf4df5
boop
Takenbacon Feb 3, 2025
fef5124
boopv2
Takenbacon Feb 4, 2025
e95c902
boopv3
Takenbacon Feb 4, 2025
b03cd05
boopv4
Takenbacon Feb 4, 2025
2f2895c
boopv5
Takenbacon Feb 4, 2025
793d251
boopv6
Takenbacon Feb 4, 2025
4d613d5
boopv7
Takenbacon Feb 4, 2025
ad023ed
boopv8 lol
Takenbacon Feb 4, 2025
6ad0d8d
Merge branch 'master' into grid_improvements
Kitzunu Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/server/game/Globals/ObjectMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2305,8 +2305,8 @@ void ObjectMgr::AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const*
{
if (mask & 1)
{
CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
cell_guids.creatures.insert(guid);
}
}
Expand All @@ -2319,8 +2319,8 @@ void ObjectMgr::RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData co
{
if (mask & 1)
{
CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
cell_guids.creatures.erase(guid);
}
}
Expand Down Expand Up @@ -2608,8 +2608,8 @@ void ObjectMgr::AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData con
{
if (mask & 1)
{
CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
cell_guids.gameobjects.insert(guid);
}
}
Expand All @@ -2622,8 +2622,8 @@ void ObjectMgr::RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectDat
{
if (mask & 1)
{
CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
cell_guids.gameobjects.erase(guid);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/server/game/Globals/ObjectMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1147,12 +1147,12 @@ class ObjectMgr
return nullptr;
}

CellObjectGuids const& GetCellObjectGuids(uint16 mapid, uint8 spawnMode, uint32 cell_id)
CellObjectGuids const& GetGridObjectGuids(uint16 mapid, uint8 spawnMode, uint32 gridId)
{
MapObjectGuids::const_iterator itr1 = _mapObjectGuidsStore.find(MAKE_PAIR32(mapid, spawnMode));
if (itr1 != _mapObjectGuidsStore.end())
{
CellObjectGuidsMap::const_iterator itr2 = itr1->second.find(cell_id);
CellObjectGuidsMap::const_iterator itr2 = itr1->second.find(gridId);
if (itr2 != itr1->second.end())
return itr2->second;
}
Expand Down
58 changes: 35 additions & 23 deletions src/server/game/Grids/NGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,86 +28,98 @@
template
<
uint32 N,
class ACTIVE_OBJECT,
class PLAYER_OBJECT,
class WORLD_OBJECT_TYPES,
class GRID_OBJECT_TYPES
>
class NGrid
{
public:
typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> GridType;
typedef Grid<PLAYER_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> GridType;
NGrid(uint32 id, int32 x, int32 y)
: i_gridId(id), i_x(x), i_y(y), i_GridObjectDataLoaded(false)
{
}

GridType& GetGridType(const uint32 x, const uint32 y)
GridType* GetGridType(const uint32 x, const uint32 y)
{
ASSERT(x < N && y < N);
return i_cells[x][y];
return i_cells[x][y].get();
}

[[nodiscard]] GridType const& GetGridType(const uint32 x, const uint32 y) const
[[nodiscard]] GridType const* GetGridType(const uint32 x, const uint32 y) const
{
ASSERT(x < N && y < N);
return i_cells[x][y];
return i_cells[x][y].get();
}

[[nodiscard]] uint32 GetGridId() const { return i_gridId; }
[[nodiscard]] int32 getX() const { return i_x; }
[[nodiscard]] int32 getY() const { return i_y; }

void link(GridRefMgr<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> >* pTo)
void link(GridRefMgr<NGrid<N, PLAYER_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> >* pTo)
{
i_Reference.link(pTo, this);
}
[[nodiscard]] bool isGridObjectDataLoaded() const { return i_GridObjectDataLoaded; }
void setGridObjectDataLoaded(bool pLoaded) { i_GridObjectDataLoaded = pLoaded; }

/*
template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT* obj)
{
GetGridType(x, y).AddWorldObject(obj);
GetCell(x, y).AddWorldObject(obj);
}

template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT* obj)
{
GetGridType(x, y).RemoveWorldObject(obj);
GetCell(x, y).RemoveWorldObject(obj);
}

template<class SPECIFIC_OBJECT> void AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
template<class SPECIFIC_OBJECT> void AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT* obj)
{
GetGridType(x, y).AddGridObject(obj);
GetCell(x, y).AddGridObject(obj);
}

template<class SPECIFIC_OBJECT> void RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
template<class SPECIFIC_OBJECT> void RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT* obj)
{
GetGridType(x, y).RemoveGridObject(obj);
GetCell(x, y).RemoveGridObject(obj);
}
*/

// Visit all Grids (cells) in NGrid (grid)
template<class T, class TT>
void VisitAllGrids(TypeContainerVisitor<T, TypeMapContainer<TT> >& visitor)
{
for (uint32 x = 0; x < N; ++x)
for (uint32 y = 0; y < N; ++y)
GetGridType(x, y).Visit(visitor);
for (auto& cellX : i_cells)
for (auto& cellY : cellX)
cellY->Visit(visitor);
}

// Visit a single Grid (cell) in NGrid (grid)
template<class T, class TT>
void VisitGrid(const uint32 x, const uint32 y, TypeContainerVisitor<T, TypeMapContainer<TT> >& visitor)
{
GetGridType(x, y).Visit(visitor);
GridType* gridType = GetGridType(x, y);
if (!gridType)
return;

gridType->Visit(visitor);
}

private:
// Creates and returns the cell if not already created
GridType& GetCell(uint32 const x, uint32 const y)
{
GridType* cell = GetGridType(x, y);
if (!cell)
i_cells[x][y] = std::make_unique<GridType>();

return *i_cells[x][y];
}

uint32 i_gridId;
GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> > i_Reference;
GridReference<NGrid<N, PLAYER_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> > i_Reference;
int32 i_x;
int32 i_y;
GridType i_cells[N][N];
bool i_GridObjectDataLoaded;
std::array<std::array<std::unique_ptr<GridType>, N>, N> i_cells; // N * N array
};
#endif
147 changes: 21 additions & 126 deletions src/server/game/Grids/ObjectGridLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,86 +22,21 @@
#include "DynamicObject.h"
#include "GameObject.h"
#include "GridNotifiers.h"
#include "ObjectMgr.h"
#include "Transport.h"

// for loading world object at grid loading (Corpses)
//TODO: to implement npc on transport, also need to load npcs at grid loading
class ObjectWorldLoader
{
public:
explicit ObjectWorldLoader(ObjectGridLoader& gloader)
: i_cell(gloader.i_cell), i_map(gloader.i_map), i_grid(gloader.i_grid), i_corpses(gloader.i_corpses)
{}

void Visit(CorpseMapType& m);

template<class T> void Visit(GridRefMgr<T>&) { }

private:
Cell i_cell;
Map* i_map;
NGridType& i_grid;
public:
uint32& i_corpses;
};

template<class T> void ObjectGridLoader::SetObjectCell(T* /*obj*/, CellCoord const& /*cellCoord*/)
{
}

template<> void ObjectGridLoader::SetObjectCell(Creature* obj, CellCoord const& cellCoord)
{
Cell cell(cellCoord);
obj->SetCurrentCell(cell);
}

template<> void ObjectGridLoader::SetObjectCell(GameObject* obj, CellCoord const& cellCoord)
{
Cell cell(cellCoord);
obj->SetCurrentCell(cell);
}

template <class T>
void AddObjectHelper(CellCoord& cell, GridRefMgr<T>& m, uint32& count, Map* /*map*/, T* obj)
void ObjectGridLoader::AddObjectHelper(Map* map, T* obj)
{
obj->AddToGrid(m);
ObjectGridLoader::SetObjectCell(obj, cell);
obj->AddToWorld();
++count;
}
CellCoord cellCoord = Acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
Cell cell(cellCoord);

template <>
void AddObjectHelper(CellCoord& cell, CreatureMapType& m, uint32& count, Map* map, Creature* obj)
{
obj->AddToGrid(m);
ObjectGridLoader::SetObjectCell(obj, cell);
map->AddToGrid(obj, cell);
obj->AddToWorld();
if (obj->isActiveObject())
map->AddToActive(obj);

++count;
}

template <>
void AddObjectHelper(CellCoord& cell, GameObjectMapType& m, uint32& count, Map* map, GameObject* obj)
{
obj->AddToGrid(m);
ObjectGridLoader::SetObjectCell(obj, cell);
obj->AddToWorld();
if (obj->isActiveObject())
map->AddToActive(obj);

++count;
}

template <class T>
void LoadHelper(CellGuidSet const& /*guid_set*/, CellCoord& /*cell*/, GridRefMgr<T>& /*m*/, uint32& /*count*/, Map* /*map*/)
{
}

template <>
void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefMgr<Creature>& m, uint32& count, Map* map)
void ObjectGridLoader::LoadCreatures(CellGuidSet const& guid_set, Map* map)
{
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
{
Expand All @@ -113,7 +48,7 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefMgr<Creatur
continue;
}

AddObjectHelper(cell, m, count, map, obj);
AddObjectHelper<Creature>(map, obj);

if (!obj->IsMoveInLineOfSightDisabled() && obj->GetDefaultMovementType() == IDLE_MOTION_TYPE && !obj->isNeedNotify(NOTIFY_VISIBILITY_CHANGED | NOTIFY_AI_RELOCATION))
{
Expand All @@ -127,8 +62,7 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefMgr<Creatur
}
}

template <>
void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefMgr<GameObject>& m, uint32& count, Map* map)
void ObjectGridLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map)
{
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
{
Expand All @@ -142,71 +76,32 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord& cell, GridRefMgr<GameObj
continue;
}

AddObjectHelper(cell, m, count, map, obj);
AddObjectHelper<GameObject>(map, obj);
}
}

void ObjectGridLoader::Visit(GameObjectMapType& m)
void ObjectGridLoader::LoadAllCellsInGrid()
{
CellCoord cellCoord = i_cell.GetCellCoord();
CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
LoadHelper(cell_guids.gameobjects, cellCoord, m, i_gameObjects, i_map);
}
CellObjectGuids const& cell_guids = sObjectMgr->GetGridObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), i_grid.GetGridId());
LoadGameObjects(cell_guids.gameobjects, i_map);
LoadCreatures(cell_guids.creatures, i_map);

void ObjectGridLoader::Visit(CreatureMapType& m)
{
CellCoord cellCoord = i_cell.GetCellCoord();
CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
LoadHelper(cell_guids.creatures, cellCoord, m, i_creatures, i_map);
}

void ObjectWorldLoader::Visit(CorpseMapType& /*m*/)
{
CellCoord cellCoord = i_cell.GetCellCoord();
if (std::unordered_set<Corpse*> const* corpses = i_map->GetCorpsesInCell(cellCoord.GetId()))
if (std::unordered_set<Corpse*> const* corpses = i_map->GetCorpsesInCell(i_grid.GetGridId()))
{
for (Corpse* corpse : *corpses)
{
corpse->AddToWorld();
GridType& cell = i_grid.GetGridType(i_cell.CellX(), i_cell.CellY());
if (corpse->IsWorldObject())
cell.AddWorldObject(corpse);
else
cell.AddGridObject(corpse);

++i_corpses;
}
}
}

void ObjectGridLoader::LoadN(void)
{
i_gameObjects = 0;
i_creatures = 0;
i_corpses = 0;
i_cell.data.Part.cell_y = 0;
for (uint32 x = 0; x < MAX_NUMBER_OF_CELLS; ++x)
{
i_cell.data.Part.cell_x = x;
for (uint32 y = 0; y < MAX_NUMBER_OF_CELLS; ++y)
{
i_cell.data.Part.cell_y = y;
if (corpse->IsInGrid())
continue;

//Load creatures and game objects
{
TypeContainerVisitor<ObjectGridLoader, GridTypeMapContainer> visitor(*this);
i_grid.VisitGrid(x, y, visitor);
}
CellCoord cellCoord = Acore::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
Cell cell(cellCoord);

//Load corpses (not bones)
{
ObjectWorldLoader worker(*this);
TypeContainerVisitor<ObjectWorldLoader, WorldTypeMapContainer> visitor(worker);
i_grid.VisitGrid(x, y, visitor);
}
if (corpse->IsWorldObject())
i_grid.AddWorldObject(cell.CellX(), cell.CellY(), corpse);
else
i_grid.AddGridObject(cell.CellX(), cell.CellY(), corpse);
}
}
LOG_DEBUG("maps", "{} GameObjects, {} Creatures, and {} Corpses/Bones loaded for grid {} on map {}", i_gameObjects, i_creatures, i_corpses, i_grid.GetGridId(), i_map->GetId());
}

template<class T>
Expand Down
Loading
Loading