Core/Movement: merged Collision height handling from 335 branch to reduce the probability that creatures are falling under the map

This commit is contained in:
Ovahlord
2019-02-17 23:40:24 +01:00
parent 3357ae7940
commit 50a91bd590
16 changed files with 134 additions and 138 deletions

View File

@@ -2312,7 +2312,7 @@ float GridMap::getLiquidLevel(float x, float y) const
}
// Get water state on map
inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data, float collisionHeight)
{
// Check water type (if no water return)
if (!_liquidGlobalFlags && !_liquidFlags)
@@ -2378,7 +2378,7 @@ inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 R
float ground_level = getHeight(x, y);
// Check water level and ground level
if (liquid_level < ground_level || z < ground_level - 2)
if (liquid_level < ground_level || z < ground_level)
return LIQUID_MAP_NO_WATER;
// All ok in water -> store data
@@ -2393,13 +2393,13 @@ inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 R
// For speed check as int values
float delta = liquid_level - z;
if (delta > 2.0f) // Under water
if (delta > collisionHeight) // Under water
return LIQUID_MAP_UNDER_WATER;
if (delta > 0.0f) // In water
return LIQUID_MAP_IN_WATER;
if (delta > -0.1f) // Walk on water
if (delta > -0.1f) // Walk on water
return LIQUID_MAP_WATER_WALK;
// Above water
// Above water
return LIQUID_MAP_ABOVE_WATER;
}
@@ -2442,18 +2442,18 @@ bool Map::HasGrid(uint32 mapId, int32 gx, int32 gy) const
return childMapItr != m_childTerrainMaps->end() && (*childMapItr)->GridMaps[gx][gy] && (*childMapItr)->GridMaps[gx][gy]->fileExists();
}
float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const
float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/, float collisionHeight /*= DEFAULT_COLLISION_HEIGHT*/) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeight(phaseShift, x, y, z, true, 50.0f);
float ground_z = GetHeight(phaseShift, x, y, z + collisionHeight, true, 50.0f);
if (ground)
*ground = ground_z;
LiquidData liquid_status;
ZLiquidStatus res = GetLiquidStatus(phaseShift, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
ZLiquidStatus res = GetLiquidStatus(phaseShift, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status, collisionHeight);
return res ? liquid_status.level : ground_z;
}
@@ -2468,8 +2468,7 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float
if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y))
{
float gridHeight = gmap->getHeight(x, y);
// look from a bit higher pos to find the floor, ignore under surface case
if (G3D::fuzzyGe(z, gridHeight - GROUND_HEIGHT_TOLERANCE))
if (z > gridHeight)
mapHeight = gridHeight;
}
@@ -2478,7 +2477,7 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->isHeightCalcEnabled())
vmapHeight = vmgr->getHeight(terrainMapId, x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor
vmapHeight = vmgr->getHeight(terrainMapId, x, y, z, maxSearchDist);
}
// mapHeight set for any above raw ground Z or <= INVALID_HEIGHT
@@ -2563,7 +2562,7 @@ void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32&
zoneid = area->zone;
}
ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const
ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data, float collisionHeight) const
{
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
@@ -2621,11 +2620,11 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
float delta = liquid_level - z;
// Get position delta
if (delta > 2.0f) // Under water
if (delta > collisionHeight) // Under water
return LIQUID_MAP_UNDER_WATER;
if (delta > 0.0f) // In water
return LIQUID_MAP_IN_WATER;
if (delta > -0.1f) // Walk on water
if (delta > -0.1f) // Walk on water
return LIQUID_MAP_WATER_WALK;
result = LIQUID_MAP_ABOVE_WATER;
}
@@ -2636,7 +2635,7 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y))
{
LiquidData map_data;
ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data);
ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data, collisionHeight);
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
{
@@ -2655,7 +2654,7 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
return result;
}
void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType) const
void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType, float collisionHeight) const
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
VMAP::AreaAndLiquidData vmapData;
@@ -2758,7 +2757,7 @@ void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x,
data.liquidInfo->type_flags = 1 << liquidFlagType;
float delta = vmapData.liquidInfo->level - z;
if (delta > 2.0f)
if (delta > collisionHeight)
data.liquidStatus = LIQUID_MAP_UNDER_WATER;
else if (delta > 0.0f)
data.liquidStatus = LIQUID_MAP_IN_WATER;
@@ -2771,7 +2770,7 @@ void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x,
if (gmap && useGridLiquid)
{
LiquidData gridMapLiquid;
ZLiquidStatus gridMapStatus = gmap->GetLiquidStatus(x, y, z, reqLiquidType, &gridMapLiquid);
ZLiquidStatus gridMapStatus = gmap->GetLiquidStatus(x, y, z, reqLiquidType, &gridMapLiquid, collisionHeight);
if (gridMapStatus != LIQUID_MAP_NO_WATER && (gridMapLiquid.level > vmapData.floorZ))
{
if (GetId() == 530 && gridMapLiquid.entry == 2)