mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-04 11:33:48 +00:00
fix(Core/Grids): Grid improvements (#20955)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user