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:
Shauren
2016-02-09 00:14:58 +01:00
parent aa432db36d
commit 25cdc5d980
9 changed files with 225 additions and 41 deletions

View File

@@ -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;