Core/Maps
* Corrected liquid type extraction in maps - MCLQ chunk must be parsed together with MH2O (they stack) * Fixed liquid detection in WMO objects * Implemented LiquidType.dbc use, players will now get proper auras in special liquids * Turned off slime damage by default (Naxxramas uses periodic damage aura for this purpose) * Implemented liquid type overrides basing on area/zone * Renamed final temp_gameobject_models to GameObjectModels.dtree (the temporary one produced by vmap extractor remains unaffected) Note: Map and Vmap re-extraction is required
This commit is contained in:
@@ -41,7 +41,7 @@ union u_map_magic
|
||||
};
|
||||
|
||||
u_map_magic MapMagic = { {'M','A','P','S'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','1'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','2'} };
|
||||
u_map_magic MapAreaMagic = { {'A','R','E','A'} };
|
||||
u_map_magic MapHeightMagic = { {'M','H','G','T'} };
|
||||
u_map_magic MapLiquidMagic = { {'M','L','I','Q'} };
|
||||
@@ -1044,7 +1044,8 @@ GridMap::GridMap()
|
||||
_liquidWidth = 0;
|
||||
_liquidHeight = 0;
|
||||
_liquidLevel = INVALID_HEIGHT;
|
||||
_liquidData = NULL;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
}
|
||||
|
||||
@@ -1106,12 +1107,14 @@ void GridMap::unloadData()
|
||||
delete[] _areaMap;
|
||||
delete[] m_V9;
|
||||
delete[] m_V8;
|
||||
delete[] _liquidData;
|
||||
delete[] _liquidEntry;
|
||||
delete[] _liquidFlags;
|
||||
delete[] _liquidMap;
|
||||
_areaMap = NULL;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
_liquidData = NULL;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
}
|
||||
@@ -1192,18 +1195,22 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
|
||||
_liquidOffX = header.offsetX;
|
||||
_liquidOffY = header.offsetY;
|
||||
_liquidWidth = header.width;
|
||||
_liquidHeight= header.height;
|
||||
_liquidHeight = header.height;
|
||||
_liquidLevel = header.liquidLevel;
|
||||
|
||||
if (!(header.flags & MAP_LIQUID_NO_TYPE))
|
||||
{
|
||||
_liquidData = new uint8 [16*16];
|
||||
if (fread(_liquidData, sizeof(uint8), 16*16, in) != 16*16)
|
||||
_liquidEntry = new uint16[16*16];
|
||||
if (fread(_liquidEntry, sizeof(uint16), 16*16, in) != 16*16)
|
||||
return false;
|
||||
|
||||
_liquidFlags = new uint8[16*16];
|
||||
if (fread(_liquidFlags, sizeof(uint8), 16*16, in) != 16*16)
|
||||
return false;
|
||||
}
|
||||
if (!(header.flags & MAP_LIQUID_NO_HEIGHT))
|
||||
{
|
||||
_liquidMap = new float [_liquidWidth*_liquidHeight];
|
||||
_liquidMap = new float[_liquidWidth*_liquidHeight];
|
||||
if (fread(_liquidMap, sizeof(float), _liquidWidth*_liquidHeight, in) != _liquidWidth*_liquidHeight)
|
||||
return false;
|
||||
}
|
||||
@@ -1462,23 +1469,24 @@ float GridMap::getLiquidLevel(float x, float y)
|
||||
return _liquidMap[cx_int*_liquidWidth + cy_int];
|
||||
}
|
||||
|
||||
// Why does this return LIQUID data?
|
||||
uint8 GridMap::getTerrainType(float x, float y)
|
||||
{
|
||||
if (!_liquidData)
|
||||
if (!_liquidFlags)
|
||||
return 0;
|
||||
|
||||
x = 16 * (32 - x/SIZE_OF_GRIDS);
|
||||
y = 16 * (32 - y/SIZE_OF_GRIDS);
|
||||
int lx = (int)x & 15;
|
||||
int ly = (int)y & 15;
|
||||
return _liquidData[lx*16 + ly];
|
||||
return _liquidFlags[lx*16 + ly];
|
||||
}
|
||||
|
||||
// Get water state on map
|
||||
inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
|
||||
{
|
||||
// Check water type (if no water return)
|
||||
if (!_liquidType && !_liquidData)
|
||||
if (!_liquidType && !_liquidFlags)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// Get cell
|
||||
@@ -1489,7 +1497,37 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R
|
||||
int y_int = (int)cy & (MAP_RESOLUTION-1);
|
||||
|
||||
// Check water type in cell
|
||||
uint8 type = _liquidData ? _liquidData[(x_int>>3)*16 + (y_int>>3)] : _liquidType;
|
||||
int idx=(x_int>>3)*16 + (y_int>>3);
|
||||
uint8 type = _liquidFlags ? _liquidFlags[idx] : _liquidType;
|
||||
uint32 entry = 0;
|
||||
if (_liquidEntry)
|
||||
{
|
||||
if (LiquidTypeEntry const* liquidEntry = sLiquidTypeStore.LookupEntry(_liquidEntry[idx]))
|
||||
{
|
||||
entry = liquidEntry->Id;
|
||||
type &= MAP_LIQUID_TYPE_DARK_WATER;
|
||||
uint32 liqTypeIdx = liquidEntry->Type;
|
||||
if (entry < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(getArea(x, y), MAPID_INVALID))
|
||||
{
|
||||
uint32 overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
|
||||
if (!overrideLiquid && area->zone)
|
||||
if (area = GetAreaEntryByAreaID(area->zone))
|
||||
overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
|
||||
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
|
||||
{
|
||||
entry = overrideLiquid;
|
||||
liqTypeIdx = liq->Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type |= 1 << liqTypeIdx;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 0)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
@@ -1518,20 +1556,20 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R
|
||||
// All ok in water -> store data
|
||||
if (data)
|
||||
{
|
||||
data->type = type;
|
||||
data->entry = entry;
|
||||
data->type_flags = type;
|
||||
data->level = liquid_level;
|
||||
data->depth_level = ground_level;
|
||||
}
|
||||
|
||||
// For speed check as int values
|
||||
int delta = int((liquid_level - z) * 10);
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > 20) // Under water
|
||||
if (delta > 2.0f) // Under water
|
||||
return LIQUID_MAP_UNDER_WATER;
|
||||
if (delta > 0) // In water
|
||||
if (delta > 0.0f) // In water
|
||||
return LIQUID_MAP_IN_WATER;
|
||||
if (delta > -1) // Walk on water
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
// Above water
|
||||
return LIQUID_MAP_ABOVE_WATER;
|
||||
@@ -1722,8 +1760,9 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
|
||||
{
|
||||
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
|
||||
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
|
||||
float liquid_level, ground_level = INVALID_HEIGHT;
|
||||
uint32 liquid_type;
|
||||
float liquid_level = INVALID_HEIGHT;
|
||||
float ground_level = INVALID_HEIGHT;
|
||||
uint32 liquid_type = 0;
|
||||
if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_MAPS, "getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type);
|
||||
@@ -1733,20 +1772,46 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
|
||||
// All ok in water -> store data
|
||||
if (data)
|
||||
{
|
||||
data->type = liquid_type;
|
||||
// hardcoded in client like this
|
||||
if (GetId() == 530 && liquid_type == 2)
|
||||
liquid_type = 15;
|
||||
|
||||
uint32 liquidFlagType = 0;
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type))
|
||||
liquidFlagType = liq->Type;
|
||||
|
||||
if (liquid_type && liquid_type < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(GetAreaFlag(x, y, z), GetId()))
|
||||
{
|
||||
uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
|
||||
if (!overrideLiquid && area->zone)
|
||||
if (area = GetAreaEntryByAreaID(area->zone))
|
||||
overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
|
||||
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
|
||||
{
|
||||
liquid_type = overrideLiquid;
|
||||
liquidFlagType = liq->Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->level = liquid_level;
|
||||
data->depth_level = ground_level;
|
||||
|
||||
data->entry = liquid_type;
|
||||
data->type_flags = 1 << liquidFlagType;
|
||||
}
|
||||
|
||||
// For speed check as int values
|
||||
int delta = int((liquid_level - z) * 10);
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > 20) // Under water
|
||||
if (delta > 2.0f) // Under water
|
||||
return LIQUID_MAP_UNDER_WATER;
|
||||
if (delta > 0 ) // In water
|
||||
if (delta > 0.0f) // In water
|
||||
return LIQUID_MAP_IN_WATER;
|
||||
if (delta > -1) // Walk on water
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
result = LIQUID_MAP_ABOVE_WATER;
|
||||
}
|
||||
@@ -1760,7 +1825,13 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
|
||||
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
// hardcoded in client like this
|
||||
if (GetId() == 530 && map_data.entry == 2)
|
||||
map_data.entry = 15;
|
||||
|
||||
*data = map_data;
|
||||
}
|
||||
return map_result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,8 @@ enum ZLiquidStatus
|
||||
|
||||
struct LiquidData
|
||||
{
|
||||
uint32 type;
|
||||
uint32 type_flags;
|
||||
uint32 entry;
|
||||
float level;
|
||||
float depth_level;
|
||||
};
|
||||
@@ -163,7 +164,8 @@ class GridMap
|
||||
|
||||
// Liquid data
|
||||
float _liquidLevel;
|
||||
uint8* _liquidData;
|
||||
uint16* _liquidEntry;
|
||||
uint8* _liquidFlags;
|
||||
float* _liquidMap;
|
||||
uint16 _gridArea;
|
||||
uint16 _liquidType;
|
||||
|
||||
Reference in New Issue
Block a user