From 4fcc4a330044e84baa1f58ff13e1b4ea7775eb66 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 7 Apr 2019 20:15:40 +0200 Subject: Core/Movement: Fix some undermap issues with random movement/fear/blink (#22937) * Core/Movement: - Only move to point if there is a path that is not a shortcut (which will make the unit move through terrain) - Added new function to check if there is a vmap floor without search distance - Units that can fly, are underground but far above the vmap floor will stay underground (bronze drakes in tanaris) - Don't remove PATHFIND_SHORTCUT from path type in some cases * Core/Object: Ignore UpdateAllowedPositionZ for flying units. - This will make flying units go through mountains instead of going to the top and back to the bottom to reach you. * Core/Object: Revert some changes and let MovePositionToFirstCollision deal with a position without ground * Missing groundZ change for objects on transport * use CanFly instead of IsFlying (cherry picked from commit 9fcbd8f15d249070aabc25d48df86681e8ec3d11) --- src/server/game/Entities/Object/Object.cpp | 35 ++++++++++++++++++++++++++++-- src/server/game/Entities/Object/Object.h | 2 +- 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'src/server/game/Entities/Object') diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index cbc607e7b66..0b53fa7cf4b 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1250,11 +1250,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()) { @@ -1280,12 +1285,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 @@ -1293,6 +1304,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; } } @@ -3102,10 +3116,27 @@ 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()) + { + // unit can fly, ignore. + if (unit->CanFly()) + return; + + // fall back to gridHeight if any + float gridHeight = GetMap()->GetGridHeight(GetPhaseShift(), pos.m_positionX, pos.m_positionY); + if (gridHeight > INVALID_HEIGHT) + pos.m_positionZ = gridHeight + unit->GetHoverOffset(); + } + } } void WorldObject::PlayDistanceSound(uint32 soundId, Player* target /*= nullptr*/) diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 8af47209787..24c48e8ccb6 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -433,7 +433,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; -- cgit v1.2.3