fix(Core/Grids): Grid improvements (#20955)

This commit is contained in:
Takenbacon
2025-02-14 13:11:27 -08:00
committed by GitHub
parent 10183efd51
commit ee69a569c4
67 changed files with 1955 additions and 2026 deletions

View File

@@ -26,6 +26,7 @@
#include "GameObjectModel.h"
#include "GridDefines.h"
#include "GridRefMgr.h"
#include "MapGridManager.h"
#include "MapRefMgr.h"
#include "ObjectDefines.h"
#include "ObjectGuid.h"
@@ -33,6 +34,7 @@
#include "Position.h"
#include "SharedDefines.h"
#include "TaskScheduler.h"
#include "GridTerrainData.h"
#include <bitset>
#include <list>
#include <memory>
@@ -81,101 +83,9 @@ struct ScriptAction
ScriptInfo const* script; // pointer to static script data
};
// ******************************************
// Map file format defines
// ******************************************
struct map_fileheader
{
uint32 mapMagic;
uint32 versionMagic;
uint32 buildMagic;
uint32 areaMapOffset;
uint32 areaMapSize;
uint32 heightMapOffset;
uint32 heightMapSize;
uint32 liquidMapOffset;
uint32 liquidMapSize;
uint32 holesOffset;
uint32 holesSize;
};
#define MAP_AREA_NO_AREA 0x0001
struct map_areaHeader
{
uint32 fourcc;
uint16 flags;
uint16 gridArea;
};
#define MAP_HEIGHT_NO_HEIGHT 0x0001
#define MAP_HEIGHT_AS_INT16 0x0002
#define MAP_HEIGHT_AS_INT8 0x0004
#define MAP_HEIGHT_HAS_FLIGHT_BOUNDS 0x0008
struct map_heightHeader
{
uint32 fourcc;
uint32 flags;
float gridHeight;
float gridMaxHeight;
};
#define MAP_LIQUID_NO_TYPE 0x0001
#define MAP_LIQUID_NO_HEIGHT 0x0002
struct map_liquidHeader
{
uint32 fourcc;
uint8 flags;
uint8 liquidFlags;
uint16 liquidType;
uint8 offsetX;
uint8 offsetY;
uint8 width;
uint8 height;
float liquidLevel;
};
enum LiquidStatus
{
LIQUID_MAP_NO_WATER = 0x00000000,
LIQUID_MAP_ABOVE_WATER = 0x00000001,
LIQUID_MAP_WATER_WALK = 0x00000002,
LIQUID_MAP_IN_WATER = 0x00000004,
LIQUID_MAP_UNDER_WATER = 0x00000008
};
#define MAP_LIQUID_STATUS_SWIMMING (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)
#define MAP_LIQUID_STATUS_IN_CONTACT (MAP_LIQUID_STATUS_SWIMMING | LIQUID_MAP_WATER_WALK)
#define MAP_LIQUID_TYPE_NO_WATER 0x00
#define MAP_LIQUID_TYPE_WATER 0x01
#define MAP_LIQUID_TYPE_OCEAN 0x02
#define MAP_LIQUID_TYPE_MAGMA 0x04
#define MAP_LIQUID_TYPE_SLIME 0x08
#define MAP_ALL_LIQUIDS (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)
#define MAP_LIQUID_TYPE_DARK_WATER 0x10
#define MAX_HEIGHT 100000.0f // can be use for find ground height at surface
#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
#define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT
#define DEFAULT_HEIGHT_SEARCH 50.0f // default search distance to find height at nearby locations
#define MIN_UNLOAD_DELAY 1 // immediate unload
struct LiquidData
{
LiquidData() = default;
uint32 Entry{0};
uint32 Flags{0};
float Level{INVALID_HEIGHT};
float DepthLevel{INVALID_HEIGHT};
LiquidStatus Status{LIQUID_MAP_NO_WATER};
};
struct PositionFullTerrainStatus
{
PositionFullTerrainStatus() = default;
@@ -196,71 +106,6 @@ enum LineOfSightChecks
LINEOFSIGHT_ALL_CHECKS = LINEOFSIGHT_CHECK_VMAP | LINEOFSIGHT_CHECK_GOBJECT_ALL
};
class GridMap
{
uint32 _flags;
union
{
float* m_V9;
uint16* m_uint16_V9;
uint8* m_uint8_V9;
};
union
{
float* m_V8;
uint16* m_uint16_V8;
uint8* m_uint8_V8;
};
int16* _maxHeight;
int16* _minHeight;
// Height level data
float _gridHeight;
float _gridIntHeightMultiplier;
// Area data
uint16* _areaMap;
// Liquid data
float _liquidLevel;
uint16* _liquidEntry;
uint8* _liquidFlags;
float* _liquidMap;
uint16 _gridArea;
uint16 _liquidGlobalEntry;
uint8 _liquidGlobalFlags;
uint8 _liquidOffX;
uint8 _liquidOffY;
uint8 _liquidWidth;
uint8 _liquidHeight;
uint16* _holes;
bool loadAreaData(FILE* in, uint32 offset, uint32 size);
bool loadHeightData(FILE* in, uint32 offset, uint32 size);
bool loadLiquidData(FILE* in, uint32 offset, uint32 size);
bool loadHolesData(FILE* in, uint32 offset, uint32 size);
[[nodiscard]] bool isHole(int row, int col) const;
// Get height functions and pointers
typedef float (GridMap::*GetHeightPtr) (float x, float y) const;
GetHeightPtr _gridGetHeight;
[[nodiscard]] float getHeightFromFloat(float x, float y) const;
[[nodiscard]] float getHeightFromUint16(float x, float y) const;
[[nodiscard]] float getHeightFromUint8(float x, float y) const;
[[nodiscard]] float getHeightFromFlat(float x, float y) const;
public:
GridMap();
~GridMap();
bool loadData(char* filaname);
void unloadData();
[[nodiscard]] uint16 getArea(float x, float y) const;
[[nodiscard]] inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);}
[[nodiscard]] float getMinHeight(float x, float y) const;
[[nodiscard]] float getLiquidLevel(float x, float y) const;
[[nodiscard]] LiquidData const GetLiquidData(float x, float y, float z, float collisionHeight, uint8 ReqLiquidType) const;
};
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform
#if defined(__GNUC__)
#pragma pack(1)
@@ -307,9 +152,10 @@ enum EncounterCreditType : uint8
ENCOUNTER_CREDIT_CAST_SPELL = 1,
};
class Map : public GridRefMgr<NGridType>
class Map : public GridRefMgr<MapGridType>
{
friend class MapReference;
friend class GridObjectLoader;
public:
Map(uint32 id, uint32 InstanceId, uint8 SpawnMode, Map* _parent = nullptr);
~Map() override;
@@ -348,6 +194,7 @@ public:
[[nodiscard]] float GetVisibilityRange() const { return m_VisibleDistance; }
void SetVisibilityRange(float range) { m_VisibleDistance = range; }
void OnCreateMap();
//function for setting up visibility distance for maps on per-type/per-Id basis
virtual void InitVisibilityDistance();
@@ -358,26 +205,28 @@ public:
template<class T, class CONTAINER> void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER>& visitor);
[[nodiscard]] bool IsRemovalGrid(float x, float y) const
{
GridCoord p = Acore::ComputeGridCoord(x, y);
return !getNGrid(p.x_coord, p.y_coord);
}
[[nodiscard]] bool IsGridLoaded(float x, float y) const
bool IsGridLoaded(GridCoord const& gridCoord) const;
bool IsGridLoaded(float x, float y) const
{
return IsGridLoaded(Acore::ComputeGridCoord(x, y));
}
bool IsGridCreated(GridCoord const& gridCoord) const;
bool IsGridCreated(float x, float y) const
{
return IsGridCreated(Acore::ComputeGridCoord(x, y));
}
void LoadGrid(float x, float y);
void LoadAllCells();
bool UnloadGrid(NGridType& ngrid);
void LoadAllGrids();
void LoadGridsInRange(Position const& center, float radius);
bool UnloadGrid(MapGridType& grid);
virtual void UnloadAll();
[[nodiscard]] uint32 GetId() const { return i_mapEntry->MapID; }
std::shared_ptr<GridTerrainData> GetGridTerrainDataSharedPtr(GridCoord const& gridCoord);
GridTerrainData* GetGridTerrainData(GridCoord const& gridCoord);
GridTerrainData* GetGridTerrainData(float x, float y);
static bool ExistMap(uint32 mapid, int gx, int gy);
static bool ExistVMap(uint32 mapid, int gx, int gy);
[[nodiscard]] uint32 GetId() const { return i_mapEntry->MapID; }
[[nodiscard]] Map const* GetParent() const { return m_parentMap; }
@@ -627,8 +476,7 @@ public:
// Do whatever you want to all the players in map [including GameMasters], i.e.: param exec = [&](Player* p) { p->Whatever(); }
void DoForAllPlayers(std::function<void(Player*)> exec);
GridMap* GetGrid(float x, float y);
void EnsureGridCreated(const GridCoord&);
void EnsureGridCreated(GridCoord const& gridCoord);
[[nodiscard]] bool AllTransportsEmpty() const; // pussywizard
void AllTransportsRemovePassengers(); // pussywizard
[[nodiscard]] TransportsContainer const& GetAllTransports() const { return _transports; }
@@ -659,13 +507,12 @@ public:
virtual std::string GetDebugInfo() const;
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
void LoadMap(int gx, int gy, bool reload = false);
uint32 GetCreatedGridsCount();
uint32 GetLoadedGridsCount();
uint32 GetCreatedCellsInGridCount(uint16 const x, uint16 const y);
uint32 GetCreatedCellsInMapCount();
// Load MMap Data
void LoadMMap(int gx, int gy);
private:
template<class T> void InitializeObject(T* obj);
void AddCreatureToMoveList(Creature* c);
@@ -679,33 +526,22 @@ private:
std::vector<GameObject*> _gameObjectsToMove;
std::vector<DynamicObject*> _dynamicObjectsToMove;
[[nodiscard]] bool IsGridLoaded(const GridCoord&) const;
void EnsureGridCreated_i(const GridCoord&);
bool EnsureGridLoaded(Cell const& cell);
MapGridType* GetMapGrid(uint16 const x, uint16 const y);
void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); }
[[nodiscard]] NGridType* getNGrid(uint32 x, uint32 y) const
{
ASSERT(x < MAX_NUMBER_OF_GRIDS && y < MAX_NUMBER_OF_GRIDS);
return i_grids[x][y];
}
bool EnsureGridLoaded(Cell const&);
[[nodiscard]] bool isGridObjectDataLoaded(uint32 x, uint32 y) const { return getNGrid(x, y)->isGridObjectDataLoaded(); }
void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x, y)->setGridObjectDataLoaded(pLoaded); }
void setNGrid(NGridType* grid, uint32 x, uint32 y);
void ScriptsProcess();
void UpdateActiveCells(const float& x, const float& y, const uint32 t_diff);
void SendObjectUpdates();
protected:
// Type specific code for add/remove to/from grid
template<class T>
void AddToGrid(T* object, Cell const& cell);
std::mutex Lock;
std::mutex GridLock;
std::shared_mutex MMapLock;
MapGridManager _mapGridManager;
MapEntry const* i_mapEntry;
uint8 i_spawnMode;
uint32 i_InstanceId;
@@ -739,10 +575,8 @@ private:
//InstanceMaps and BattlegroundMaps...
Map* m_parentMap;
NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
GridMap* GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP* TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells;
std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP* TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells_large;
std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP * TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells;
std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP * TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells_large;
bool i_scriptLock;
std::unordered_set<WorldObject*> i_objectsToRemove;
@@ -752,10 +586,6 @@ private:
typedef std::multimap<time_t, ScriptAction> ScriptScheduleMap;
ScriptScheduleMap m_scriptSchedule;
// Type specific code for add/remove to/from grid
template<class T>
void AddToGrid(T* object, Cell const& cell);
template<class T>
void DeleteFromWorld(T*);
@@ -875,16 +705,14 @@ private:
template<class T, class CONTAINER>
inline void Map::Visit(Cell const& cell, TypeContainerVisitor<T, CONTAINER>& visitor)
{
const uint32 x = cell.GridX();
const uint32 y = cell.GridY();
const uint32 cell_x = cell.CellX();
const uint32 cell_y = cell.CellY();
uint32 const grid_x = cell.GridX();
uint32 const grid_y = cell.GridY();
if (!cell.NoCreate() || IsGridLoaded(GridCoord(x, y)))
{
EnsureGridLoaded(cell);
getNGrid(x, y)->VisitGrid(cell_x, cell_y, visitor);
}
// If grid is not loaded, nothing to visit.
if (!IsGridLoaded(GridCoord(grid_x, grid_y)))
return;
GetMapGrid(grid_x, grid_y)->VisitCell(cell.CellX(), cell.CellY(), visitor);
}
#endif