From 334720dafead401ad055f55b773b70f900128b6b Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 29 Nov 2021 17:46:46 -0500 Subject: [PATCH] Core/Movement: Fix some undermap issues with random movement/fear/blink Port From (https://github.com/TrinityCore/TrinityCore/commit/4fcc4a330044e84baa1f58ff13e1b4ea7775eb66) --- Source/Game/Entities/Object/WorldObject.cs | 47 ++++++++++++++++--- Source/Game/Maps/Map.cs | 21 ++++++--- .../Movement/Generators/ConfusedGenerator.cs | 2 +- .../Movement/Generators/FleeingGenerator.cs | 2 +- .../Game/Movement/Generators/PathGenerator.cs | 4 +- .../Movement/Generators/RandomMovement.cs | 2 +- Source/Game/Spells/Spell.cs | 2 +- 7 files changed, 60 insertions(+), 20 deletions(-) diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 42a9bafe0..b78732ecd 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -3042,10 +3042,19 @@ namespace Game.Entities } public void UpdateAllowedPositionZ(float x, float y, ref float z) + { + float unused = 0f; + UpdateAllowedPositionZ(x, y, ref z, ref unused); + } + + public void UpdateAllowedPositionZ(float x, float y, ref float z, ref float groundZ) { // TODO: Allow transports to be part of dynamic vmap tree if (GetTransport()) + { + groundZ = z; return; + } Unit unit = ToUnit(); if (unit != null) @@ -3053,31 +3062,35 @@ namespace Game.Entities if (!unit.CanFly()) { bool canSwim = unit.CanSwim(); - float groundZ = z; + float ground_z = z; float max_z; if (canSwim) - max_z = GetMapWaterOrGroundLevel(x, y, z, ref groundZ); + max_z = GetMapWaterOrGroundLevel(x, y, z, ref ground_z); else - max_z = groundZ = GetMapHeight(x, y, z); + max_z = ground_z = GetMapHeight(x, y, z); if (max_z > MapConst.InvalidHeight) { // hovering units cannot go below their hover height float hoverOffset = unit.GetHoverOffset(); max_z += hoverOffset; - groundZ += hoverOffset; + ground_z += hoverOffset; if (z > max_z) z = max_z; - else if (z < groundZ) - z = groundZ; + else if (z < ground_z) + z = ground_z; } + + groundZ = ground_z; } else { float ground_z = GetMapHeight(x, y, z) + unit.GetHoverOffset(); if (z < ground_z) z = ground_z; + + groundZ = ground_z; } } else @@ -3085,6 +3098,8 @@ namespace Game.Entities float ground_z = GetMapHeight(x, y, z); if (ground_z > MapConst.InvalidHeight) z = ground_z; + + groundZ = ground_z; } } @@ -3295,10 +3310,28 @@ namespace Game.Entities } } + float groundZ = MapConst.VMAPInvalidHeightValue; GridDefines.NormalizeMapCoord(ref pos.posX); GridDefines.NormalizeMapCoord(ref pos.posY); - UpdateAllowedPositionZ(destx, desty, ref pos.posZ); + UpdateAllowedPositionZ(destx, desty, ref pos.posZ, ref groundZ); pos.SetOrientation(GetOrientation()); + + // position has no ground under it (or is too far away) + if (groundZ <= MapConst.InvalidHeight) + { + Unit unit = ToUnit(); + if (unit != null) + { + // unit can fly, ignore. + if (unit.CanFly()) + return; + + // fall back to gridHeight if any + float gridHeight = GetMap().GetGridHeight(GetPhaseShift(), pos.posX, pos.posY); + if (gridHeight > MapConst.InvalidHeight) + pos.posZ = gridHeight + unit.GetHoverOffset(); + } + } } public float GetFloorZ() diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index fed0f4ead..7d62ab3be 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -1719,13 +1719,9 @@ namespace Game.Maps // find raw .map surface under Z coordinates float mapHeight = MapConst.VMAPInvalidHeightValue; uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y); - GridMap gmap = GetGridMap(terrainMapId, x, y); - if (gmap != null) - { - float gridHeight = gmap.GetHeight(x, y); - if (MathFunctions.fuzzyGe(z, gridHeight - MapConst.GroundHeightTolerance)) - mapHeight = gridHeight; - } + float gridHeight = GetGridHeight(phaseShift, x, y); + if (MathFunctions.fuzzyGe(z, gridHeight - MapConst.GroundHeightTolerance)) + mapHeight = gridHeight; float vmapHeight = MapConst.VMAPInvalidHeightValue; if (checkVMap) @@ -1746,8 +1742,10 @@ namespace Game.Maps // or if the distance of the vmap height is less the land height distance if (vmapHeight > mapHeight || Math.Abs(mapHeight - z) > Math.Abs(vmapHeight - z)) return vmapHeight; + return mapHeight; // better use .map surface height } + return vmapHeight; // we have only vmapHeight (if have) } @@ -1764,6 +1762,15 @@ namespace Game.Maps return GetHeight(phaseShift, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), vmap, maxSearchDist); } + public float GetGridHeight(PhaseShift phaseShift, float x, float y) + { + GridMap gmap = GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y); + if (gmap != null) + return gmap.GetHeight(x, y); + + return MapConst.VMAPInvalidHeightValue; + } + public float GetMinHeight(PhaseShift phaseShift, float x, float y) { GridMap grid = GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y); diff --git a/Source/Game/Movement/Generators/ConfusedGenerator.cs b/Source/Game/Movement/Generators/ConfusedGenerator.cs index 16cc30d73..b1efa2e62 100644 --- a/Source/Game/Movement/Generators/ConfusedGenerator.cs +++ b/Source/Game/Movement/Generators/ConfusedGenerator.cs @@ -90,7 +90,7 @@ namespace Game.Movement } bool result = _path.CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); - if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath)) + if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath) || _path.GetPathType().HasAnyFlag(PathType.Shortcut)) { _timer.Reset(100); return true; diff --git a/Source/Game/Movement/Generators/FleeingGenerator.cs b/Source/Game/Movement/Generators/FleeingGenerator.cs index dab7dfcbe..69080ca3f 100644 --- a/Source/Game/Movement/Generators/FleeingGenerator.cs +++ b/Source/Game/Movement/Generators/FleeingGenerator.cs @@ -140,7 +140,7 @@ namespace Game.Movement } bool result = _path.CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); - if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath)) + if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath) || _path.GetPathType().HasAnyFlag(PathType.Shortcut)) { _timer.Reset(100); return; diff --git a/Source/Game/Movement/Generators/PathGenerator.cs b/Source/Game/Movement/Generators/PathGenerator.cs index 04251fad3..3b00eaff9 100644 --- a/Source/Game/Movement/Generators/PathGenerator.cs +++ b/Source/Game/Movement/Generators/PathGenerator.cs @@ -529,14 +529,14 @@ namespace Game.Movement // @todo check the exact cases Log.outDebug(LogFilter.Maps, "++ PathGenerator.BuildPointPath FAILED! path sized {0} returned\n", pointCount); BuildShortcut(); - pathType = PathType.NoPath; + pathType |= PathType.NoPath; return; } else if (pointCount == _pointPathLimit) { Log.outDebug(LogFilter.Maps, "++ PathGenerator.BuildPointPath FAILED! path sized {0} returned, lower than limit set to {1}\n", pointCount, _pointPathLimit); BuildShortcut(); - pathType = PathType.Short; + pathType |= PathType.Short; return; } diff --git a/Source/Game/Movement/Generators/RandomMovement.cs b/Source/Game/Movement/Generators/RandomMovement.cs index fa0f82bfc..d52820649 100644 --- a/Source/Game/Movement/Generators/RandomMovement.cs +++ b/Source/Game/Movement/Generators/RandomMovement.cs @@ -130,7 +130,7 @@ namespace Game.Movement } bool result = _path.CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ()); - if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath)) + if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath) || _path.GetPathType().HasAnyFlag(PathType.Shortcut)) { _timer.Reset(100); return; diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index fb86f8e7f..22180ba90 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -900,9 +900,9 @@ namespace Game.Spells pos.posX = m_preGeneratedPath.GetActualEndPosition().X; pos.posY = m_preGeneratedPath.GetActualEndPosition().Y; pos.posZ = m_preGeneratedPath.GetActualEndPosition().Z; + dest.Relocate(pos); } - dest.Relocate(pos); break; } case Targets.DestCasterGround: