mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-15 04:32:35 -04:00
Core/Maps: Parse MFBO adt chunk to properly handle height where player counts as falling under the map
* This fixes the height at which player is instantly killed when falling from The Frozen Throne
* Set PLAYER_FLAGS_IS_OUT_OF_BOUNDS on players under the map to enable release spirit button while still falling
Note: Extracting new maps is required
(cherry picked from commit 4f78efd463)
# Conflicts:
# dep/PackageList.txt
# src/server/game/DataStores/DBCStructure.h
# src/server/game/Entities/Player/Player.cpp
# src/server/game/Handlers/MovementHandler.cpp
# src/tools/map_extractor/CMakeLists.txt
# src/tools/map_extractor/System.cpp
# src/tools/map_extractor/adt.h
# src/tools/map_extractor/loadlib.cpp
This commit is contained in:
@@ -4682,6 +4682,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
||||
|
||||
// remove death flag + set aura
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, 3, 0x00);
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
|
||||
|
||||
// This must be called always even on Players with race != RACE_NIGHTELF in case of faction change
|
||||
RemoveAurasDueToSpell(20584); // RACE_NIGHTELF speed bonuses
|
||||
@@ -5105,7 +5106,7 @@ void Player::RepopAtGraveyard()
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetAreaId());
|
||||
|
||||
// Such zones are considered unreachable as a ghost and the player must be automatically revived
|
||||
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) || GetTransport() || GetPositionZ() < -500.0f)
|
||||
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) || GetTransport() || GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY()))
|
||||
{
|
||||
ResurrectPlayer(0.5f);
|
||||
SpawnCorpseBones();
|
||||
@@ -5142,8 +5143,10 @@ void Player::RepopAtGraveyard()
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
else if (GetPositionZ() < -500.0f)
|
||||
else if (GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY()))
|
||||
TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
|
||||
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone)
|
||||
|
||||
@@ -386,7 +386,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
|
||||
|
||||
plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
|
||||
|
||||
if (movementInfo.pos.GetPositionZ() < -500.0f)
|
||||
if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
|
||||
{
|
||||
if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player)))
|
||||
{
|
||||
@@ -395,6 +395,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
|
||||
/// @todo discard movement packets after the player is rooted
|
||||
if (plrMover->IsAlive())
|
||||
{
|
||||
plrMover->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
|
||||
plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
|
||||
// player can be alive if GM/etc
|
||||
// change the death state to CORPSE to prevent the death timer from
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "VMapFactory.h"
|
||||
|
||||
u_map_magic MapMagic = { {'M','A','P','S'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','6'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','7'} };
|
||||
u_map_magic MapAreaMagic = { {'A','R','E','A'} };
|
||||
u_map_magic MapHeightMagic = { {'M','H','G','T'} };
|
||||
u_map_magic MapLiquidMagic = { {'M','L','I','Q'} };
|
||||
@@ -1644,13 +1644,15 @@ GridMap::GridMap()
|
||||
_flags = 0;
|
||||
// Area data
|
||||
_gridArea = 0;
|
||||
_areaMap = NULL;
|
||||
_areaMap = nullptr;
|
||||
// Height level data
|
||||
_gridHeight = INVALID_HEIGHT;
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
_gridIntHeightMultiplier = 0;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
m_V9 = nullptr;
|
||||
m_V8 = nullptr;
|
||||
_maxHeight = nullptr;
|
||||
_minHeight = nullptr;
|
||||
// Liquid data
|
||||
_liquidType = 0;
|
||||
_liquidOffX = 0;
|
||||
@@ -1658,9 +1660,9 @@ GridMap::GridMap()
|
||||
_liquidWidth = 0;
|
||||
_liquidHeight = 0;
|
||||
_liquidLevel = INVALID_HEIGHT;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
_liquidEntry = nullptr;
|
||||
_liquidFlags = nullptr;
|
||||
_liquidMap = nullptr;
|
||||
}
|
||||
|
||||
GridMap::~GridMap()
|
||||
@@ -1723,15 +1725,19 @@ void GridMap::unloadData()
|
||||
delete[] _areaMap;
|
||||
delete[] m_V9;
|
||||
delete[] m_V8;
|
||||
delete[] _maxHeight;
|
||||
delete[] _minHeight;
|
||||
delete[] _liquidEntry;
|
||||
delete[] _liquidFlags;
|
||||
delete[] _liquidMap;
|
||||
_areaMap = NULL;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
_areaMap = nullptr;
|
||||
m_V9 = nullptr;
|
||||
m_V8 = nullptr;
|
||||
_maxHeight = nullptr;
|
||||
_minHeight = nullptr;
|
||||
_liquidEntry = nullptr;
|
||||
_liquidFlags = nullptr;
|
||||
_liquidMap = nullptr;
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
}
|
||||
|
||||
@@ -1796,6 +1802,16 @@ bool GridMap::loadHeightData(FILE* in, uint32 offset, uint32 /*size*/)
|
||||
}
|
||||
else
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
|
||||
if (header.flags & MAP_HEIGHT_HAS_FLIGHT_BOUNDS)
|
||||
{
|
||||
_maxHeight = new float[16 * 16];
|
||||
_minHeight = new float[16 * 16];
|
||||
if (fread(_maxHeight, sizeof(float), 16 * 16, in) != 16 * 16 ||
|
||||
fread(_minHeight, sizeof(float), 16 * 16, in) != 16 * 16)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2066,6 +2082,18 @@ float GridMap::getHeightFromUint16(float x, float y) const
|
||||
return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight;
|
||||
}
|
||||
|
||||
float GridMap::getMinHeight(float x, float y) const
|
||||
{
|
||||
if (!_minHeight)
|
||||
return -500.0f;
|
||||
|
||||
x = 16 * (CENTER_GRID_ID - x / SIZE_OF_GRIDS);
|
||||
y = 16 * (CENTER_GRID_ID - y / SIZE_OF_GRIDS);
|
||||
int lx = (int)x & 15;
|
||||
int ly = (int)y & 15;
|
||||
return _minHeight[lx * 16 + ly];
|
||||
}
|
||||
|
||||
float GridMap::getLiquidLevel(float x, float y) const
|
||||
{
|
||||
if (!_liquidMap)
|
||||
@@ -2266,6 +2294,14 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float
|
||||
return mapHeight; // explicitly use map data
|
||||
}
|
||||
|
||||
float Map::GetMinHeight(float x, float y) const
|
||||
{
|
||||
if (GridMap const* grid = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
return grid->getMinHeight(x, y);
|
||||
|
||||
return -500.0f;
|
||||
}
|
||||
|
||||
inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, int32 /*groupId*/, WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry)
|
||||
{
|
||||
bool outdoor = true;
|
||||
|
||||
@@ -98,9 +98,10 @@ struct map_areaHeader
|
||||
uint16 gridArea;
|
||||
};
|
||||
|
||||
#define MAP_HEIGHT_NO_HEIGHT 0x0001
|
||||
#define MAP_HEIGHT_AS_INT16 0x0002
|
||||
#define MAP_HEIGHT_AS_INT8 0x0004
|
||||
#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
|
||||
{
|
||||
@@ -166,6 +167,8 @@ class GridMap
|
||||
uint16* m_uint16_V8;
|
||||
uint8* m_uint8_V8;
|
||||
};
|
||||
float* _maxHeight;
|
||||
float* _minHeight;
|
||||
// Height level data
|
||||
float _gridHeight;
|
||||
float _gridIntHeightMultiplier;
|
||||
@@ -206,6 +209,7 @@ public:
|
||||
|
||||
uint16 getArea(float x, float y) const;
|
||||
inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);}
|
||||
float getMinHeight(float x, float y) const;
|
||||
float getLiquidLevel(float x, float y) const;
|
||||
uint8 getTerrainType(float x, float y) const;
|
||||
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
|
||||
@@ -326,6 +330,7 @@ class Map : public GridRefManager<NGridType>
|
||||
// some calls like isInWater should not use vmaps due to processor power
|
||||
// can return INVALID_HEIGHT if under z+2 z coord not found height
|
||||
float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
|
||||
float GetMinHeight(float x, float y) const;
|
||||
|
||||
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ file(GLOB_RECURSE mapextractor_SRCS *.cpp *.h)
|
||||
set(include_Dirs
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/dep/libmpq
|
||||
${CMAKE_SOURCE_DIR}/src/common
|
||||
${CMAKE_SOURCE_DIR}/src/common/Utilities
|
||||
@@ -37,6 +38,7 @@ add_executable(mapextractor
|
||||
target_link_libraries(mapextractor
|
||||
common
|
||||
format
|
||||
g3dlib
|
||||
mpq
|
||||
${BZIP2_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "adt.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#include <G3D/Plane.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
extern ArchiveSet gOpenArchives;
|
||||
@@ -256,7 +257,7 @@ void ReadLiquidTypeTableDBC()
|
||||
|
||||
// Map file format data
|
||||
static char const* MAP_MAGIC = "MAPS";
|
||||
static char const* MAP_VERSION_MAGIC = "v1.6";
|
||||
static char const* MAP_VERSION_MAGIC = "v1.7";
|
||||
static char const* MAP_AREA_MAGIC = "AREA";
|
||||
static char const* MAP_HEIGHT_MAGIC = "MHGT";
|
||||
static char const* MAP_LIQUID_MAGIC = "MLIQ";
|
||||
@@ -285,9 +286,10 @@ struct map_areaHeader
|
||||
uint16 gridArea;
|
||||
};
|
||||
|
||||
#define MAP_HEIGHT_NO_HEIGHT 0x0001
|
||||
#define MAP_HEIGHT_AS_INT16 0x0002
|
||||
#define MAP_HEIGHT_AS_INT8 0x0004
|
||||
#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
|
||||
{
|
||||
@@ -346,6 +348,9 @@ uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE];
|
||||
float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
|
||||
float flight_box_max[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
float flight_box_min[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
|
||||
bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int /*cell_y*/, int /*cell_x*/, uint32 build)
|
||||
{
|
||||
ADT_file adt;
|
||||
@@ -521,6 +526,82 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int
|
||||
maxHeight = CONF_use_minHeight;
|
||||
}
|
||||
|
||||
bool hasFlightBox = false;
|
||||
if (adt_MFBO* mfbo = adt.a_grid->getMFBO())
|
||||
{
|
||||
static uint32 const indices[] =
|
||||
{
|
||||
3, 0, 4,
|
||||
0, 1, 4,
|
||||
1, 2, 4,
|
||||
2, 5, 4,
|
||||
5, 8, 4,
|
||||
8, 7, 4,
|
||||
7, 6, 4,
|
||||
6, 3, 4
|
||||
};
|
||||
|
||||
static float const boundGridCoords[] =
|
||||
{
|
||||
0.0f, 0.0f,
|
||||
0.0f, -266.66666f,
|
||||
0.0f, -533.33331f,
|
||||
-266.66666f, 0.0f,
|
||||
-266.66666f, -266.66666f,
|
||||
-266.66666f, -533.33331f,
|
||||
-533.33331f, 0.0f,
|
||||
-533.33331f, -266.66666f,
|
||||
-533.33331f, -533.33331f
|
||||
};
|
||||
|
||||
for (int gy = 0; gy < ADT_CELLS_PER_GRID; ++gy)
|
||||
{
|
||||
for (int gx = 0; gx < ADT_CELLS_PER_GRID; ++gx)
|
||||
{
|
||||
int32 quarterIndex = 0;
|
||||
if (gy > ADT_CELLS_PER_GRID / 2)
|
||||
{
|
||||
if (gx > ADT_CELLS_PER_GRID / 2)
|
||||
{
|
||||
quarterIndex = 4 + gx < gy;
|
||||
}
|
||||
else
|
||||
quarterIndex = 2;
|
||||
}
|
||||
else if (gx > ADT_CELLS_PER_GRID / 2)
|
||||
{
|
||||
quarterIndex = 7;
|
||||
}
|
||||
else
|
||||
quarterIndex = gx > gy;
|
||||
|
||||
quarterIndex *= 3;
|
||||
G3D::Plane planeMax(
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 0] * 2 + 0], boundGridCoords[indices[quarterIndex + 0] * 2 + 1], mfbo->max.coords[indices[quarterIndex + 0]]),
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 1] * 2 + 0], boundGridCoords[indices[quarterIndex + 1] * 2 + 1], mfbo->max.coords[indices[quarterIndex + 1]]),
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 2] * 2 + 0], boundGridCoords[indices[quarterIndex + 2] * 2 + 1], mfbo->max.coords[indices[quarterIndex + 2]])
|
||||
);
|
||||
|
||||
G3D::Plane planeMin(
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 0] * 2 + 0], boundGridCoords[indices[quarterIndex + 0] * 2 + 1], mfbo->min.coords[indices[quarterIndex + 0]]),
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 1] * 2 + 0], boundGridCoords[indices[quarterIndex + 1] * 2 + 1], mfbo->min.coords[indices[quarterIndex + 1]]),
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 2] * 2 + 0], boundGridCoords[indices[quarterIndex + 2] * 2 + 1], mfbo->min.coords[indices[quarterIndex + 2]])
|
||||
);
|
||||
|
||||
auto non_nan_distance = [](G3D::Plane const& plane) {
|
||||
auto d = plane.distance(G3D::Vector3(0.0f, 0.0f, 0.0f));
|
||||
assert(!G3D::isNaN(d));
|
||||
return d;
|
||||
};
|
||||
|
||||
flight_box_max[gy][gx] = non_nan_distance(planeMax);
|
||||
flight_box_min[gy][gx] = non_nan_distance(planeMin);
|
||||
}
|
||||
}
|
||||
|
||||
hasFlightBox = true;
|
||||
}
|
||||
|
||||
map.heightMapOffset = map.areaMapOffset + map.areaMapSize;
|
||||
map.heightMapSize = sizeof(map_heightHeader);
|
||||
|
||||
@@ -537,6 +618,12 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int
|
||||
if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit)
|
||||
heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT;
|
||||
|
||||
if (hasFlightBox)
|
||||
{
|
||||
heightHeader.flags |= MAP_HEIGHT_HAS_FLIGHT_BOUNDS;
|
||||
map.heightMapSize += sizeof(flight_box_max) + sizeof(flight_box_min);
|
||||
}
|
||||
|
||||
// Try store as packed in uint16 or uint8 values
|
||||
if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
|
||||
{
|
||||
@@ -859,6 +946,12 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int
|
||||
}
|
||||
}
|
||||
|
||||
if (heightHeader.flags & MAP_HEIGHT_HAS_FLIGHT_BOUNDS)
|
||||
{
|
||||
outFile.write(reinterpret_cast<char*>(flight_box_max), sizeof(flight_box_max));
|
||||
outFile.write(reinterpret_cast<char*>(flight_box_min), sizeof(flight_box_min));
|
||||
}
|
||||
|
||||
// Store liquid data if need
|
||||
if (map.liquidMapOffset)
|
||||
{
|
||||
|
||||
@@ -21,15 +21,16 @@
|
||||
#include "adt.h"
|
||||
|
||||
// Helper
|
||||
int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888};
|
||||
int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000};
|
||||
int holetab_h[4] = { 0x1111, 0x2222, 0x4444, 0x8888 };
|
||||
int holetab_v[4] = { 0x000F, 0x00F0, 0x0F00, 0xF000 };
|
||||
|
||||
u_map_fcc MHDRMagic = { {'R','D','H','M'} };
|
||||
u_map_fcc MCINMagic = { {'N','I','C','M'} };
|
||||
u_map_fcc MH2OMagic = { {'O','2','H','M'} };
|
||||
u_map_fcc MCNKMagic = { {'K','N','C','M'} };
|
||||
u_map_fcc MCVTMagic = { {'T','V','C','M'} };
|
||||
u_map_fcc MCLQMagic = { {'Q','L','C','M'} };
|
||||
u_map_fcc MHDRMagic = { { 'R','D','H','M' } };
|
||||
u_map_fcc MCINMagic = { { 'N','I','C','M' } };
|
||||
u_map_fcc MH2OMagic = { { 'O','2','H','M' } };
|
||||
u_map_fcc MCNKMagic = { { 'K','N','C','M' } };
|
||||
u_map_fcc MCVTMagic = { { 'T','V','C','M' } };
|
||||
u_map_fcc MCLQMagic = { { 'Q','L','C','M' } };
|
||||
u_map_fcc MFBOMagic = { { 'O','B','F','M' } };
|
||||
|
||||
bool isHole(int holes, int i, int j)
|
||||
{
|
||||
@@ -81,7 +82,7 @@ bool adt_MHDR::prepareLoadedData()
|
||||
if (fcc != MHDRMagic.fcc)
|
||||
return false;
|
||||
|
||||
if (size!=sizeof(adt_MHDR)-8)
|
||||
if (size != sizeof(adt_MHDR) - 8)
|
||||
return false;
|
||||
|
||||
// Check and prepare MCIN
|
||||
@@ -92,6 +93,9 @@ bool adt_MHDR::prepareLoadedData()
|
||||
if (offsMH2O && !getMH2O()->prepareLoadedData())
|
||||
return false;
|
||||
|
||||
if (offsMFBO && flags & 1 && !getMFBO()->prepareLoadedData())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -154,3 +158,8 @@ bool adt_MCLQ::prepareLoadedData()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adt_MFBO::prepareLoadedData()
|
||||
{
|
||||
return fcc == MFBOMagic.fcc;
|
||||
}
|
||||
|
||||
@@ -262,6 +262,28 @@ public:
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file min/max height chunk
|
||||
//
|
||||
class adt_MFBO
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
public:
|
||||
uint32 size;
|
||||
struct plane
|
||||
{
|
||||
int16 coords[9];
|
||||
};
|
||||
plane max;
|
||||
plane min;
|
||||
|
||||
bool prepareLoadedData();
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file header chunk
|
||||
//
|
||||
@@ -274,12 +296,12 @@ class adt_MHDR
|
||||
public:
|
||||
uint32 size;
|
||||
|
||||
uint32 pad;
|
||||
uint32 flags;
|
||||
uint32 offsMCIN; // MCIN
|
||||
uint32 offsTex; // MTEX
|
||||
uint32 offsModels; // MMDX
|
||||
uint32 offsModelsIds; // MMID
|
||||
uint32 offsMapObejcts; // MWMO
|
||||
uint32 offsTex; // MTEX
|
||||
uint32 offsModels; // MMDX
|
||||
uint32 offsModelsIds; // MMID
|
||||
uint32 offsMapObejcts; // MWMO
|
||||
uint32 offsMapObejctsIds; // MWID
|
||||
uint32 offsDoodsDef; // MDDF
|
||||
uint32 offsObjectsDef; // MODF
|
||||
@@ -291,9 +313,22 @@ public:
|
||||
uint32 data4;
|
||||
uint32 data5;
|
||||
bool prepareLoadedData();
|
||||
adt_MCIN *getMCIN(){ return (adt_MCIN *)((uint8 *)&pad+offsMCIN);}
|
||||
adt_MH2O *getMH2O(){ return offsMH2O ? (adt_MH2O *)((uint8 *)&pad+offsMH2O) : 0;}
|
||||
|
||||
adt_MCIN* getMCIN()
|
||||
{
|
||||
return reinterpret_cast<adt_MCIN*>(reinterpret_cast<uint8*>(&flags) + offsMCIN);
|
||||
}
|
||||
adt_MH2O* getMH2O()
|
||||
{
|
||||
if (offsMH2O)
|
||||
return reinterpret_cast<adt_MH2O*>(reinterpret_cast<uint8*>(&flags) + offsMH2O);
|
||||
return nullptr;
|
||||
}
|
||||
adt_MFBO* getMFBO()
|
||||
{
|
||||
if (flags & 1 && offsMFBO)
|
||||
return reinterpret_cast<adt_MFBO*>(reinterpret_cast<uint8*>(&flags) + offsMFBO);
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class ADT_file : public FileLoader{
|
||||
|
||||
@@ -80,7 +80,7 @@ struct map_liquidHeader
|
||||
namespace MMAP
|
||||
{
|
||||
|
||||
char const* MAP_VERSION_MAGIC = "v1.6";
|
||||
char const* MAP_VERSION_MAGIC = "v1.7";
|
||||
|
||||
TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ }
|
||||
TerrainBuilder::~TerrainBuilder() { }
|
||||
|
||||
Reference in New Issue
Block a user