From c98be9d2d7a6f4f983bf6560b0afdabc1d82ab95 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 17 Mar 2019 12:29:08 +0100 Subject: [PATCH] Core/Objects: merged new changes from undermap issue fixup PR --- src/server/game/Entities/Object/Object.cpp | 36 ++++++++++++++++++++-- src/server/game/Entities/Object/Object.h | 2 +- src/server/game/Maps/Map.cpp | 5 ++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 14d0106171b..810b662ea2c 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1655,11 +1655,16 @@ void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const z = new_z + (isType(TYPEMASK_UNIT) ? static_cast(this)->GetHoverOffset() : 0.0f); } -void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const +void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z, float* groundZ) const { // TODO: Allow transports to be part of dynamic vmap tree if (GetTransport()) + { + if (groundZ) + *groundZ = z; + return; + } if (Unit const* unit = ToUnit()) { @@ -1685,12 +1690,18 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const else if (z < ground_z) z = ground_z; } + + if (groundZ) + *groundZ = ground_z; } else { float ground_z = GetMapHeight(x, y, z) + unit->GetHoverOffset(); if (z < ground_z) z = ground_z; + + if (groundZ) + *groundZ = ground_z; } } else @@ -1698,6 +1709,9 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const float ground_z = GetMapHeight(x, y, z); if (ground_z > INVALID_HEIGHT) z = ground_z; + + if (groundZ) + *groundZ = ground_z; } } @@ -2596,10 +2610,28 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float } } + float groundZ = VMAP_INVALID_HEIGHT_VALUE; Trinity::NormalizeMapCoord(pos.m_positionX); Trinity::NormalizeMapCoord(pos.m_positionY); - UpdateAllowedPositionZ(destx, desty, pos.m_positionZ); + UpdateAllowedPositionZ(destx, desty, pos.m_positionZ, &groundZ); pos.SetOrientation(GetOrientation()); + + // position has no ground under it (or is too far away) + if (groundZ <= INVALID_HEIGHT) + { + if (Unit const* unit = ToUnit()) + { + // flying, ignore. + if (unit->IsFlying()) + return; + + // fall back to gridHeight if any + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(GetPhaseShift(), GetMap(), pos.m_positionX, pos.m_positionY); + float gridHeight = GetMap()->GetGridHeight(terrainMapId, pos.m_positionX, pos.m_positionY); + if (gridHeight > INVALID_HEIGHT) + pos.m_positionZ = gridHeight + unit->GetHoverOffset(); + } + } } void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update) diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 93479bc2736..2c7b5855056 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -294,7 +294,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation virtual float GetCombatReach() const { return 0.0f; } // overridden (only) in Unit void UpdateGroundPositionZ(float x, float y, float &z) const; - void UpdateAllowedPositionZ(float x, float y, float &z) const; + void UpdateAllowedPositionZ(float x, float y, float &z, float* groundZ = nullptr) const; void GetRandomPoint(Position const& srcPos, float distance, float& rand_x, float& rand_y, float& rand_z) const; Position GetRandomPoint(Position const& srcPos, float distance) const; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index f6f19bb6f18..91822e8ea4c 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2535,7 +2535,10 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float { // find raw .map surface under Z coordinates uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y); - float const mapHeight = GetGridHeight(terrainMapId, x, y); + float mapHeight = VMAP_INVALID_HEIGHT_VALUE; + float gridHeight = GetGridHeight(terrainMapId, x, y); + if (G3D::fuzzyGe(z, gridHeight - GROUND_HEIGHT_TOLERANCE)) + mapHeight = gridHeight; float vmapHeight = VMAP_INVALID_HEIGHT_VALUE; if (checkVMap)