mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-17 21:50:50 -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:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user