From e6b9631ed02e70ff5e516272dd1aa52db1b9dac1 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Fri, 18 Feb 2022 17:27:32 -0500 Subject: [PATCH] Core/Objects: further improvements for MovePositionToFirstCollision Port From (https://github.com/TrinityCore/TrinityCore/commit/26e7da1622b217f66d28771836014ca9023efd16) --- Source/Game/Entities/Object/WorldObject.cs | 26 ++++++++++- .../Game/Movement/Generators/PathGenerator.cs | 44 +++++++++++++++---- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index f141a09cf..3f94c673a 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -3425,15 +3425,37 @@ namespace Game.Entities // Use a detour raycast to get our first collision point PathGenerator path = new(this); path.CalculatePath(destx, desty, destz, false, true); + + // We have a invalid path result. Skip further processing. + if ((path.GetPathType() & ~(PathType.Normal | PathType.Shortcut | PathType.Incomplete | PathType.FarFromPoly)) != 0) + return; + Vector3 result = path.GetPath()[path.GetPath().Length - 1]; destx = result.X; desty = result.Y; destz = result.Z; - UpdateAllowedPositionZ(destx, desty, ref destz); + // Object is using a shortcut. Check static LOS + float halfHeight = GetCollisionHeight() * 0.5f; + if (path.GetPathType().HasFlag(PathType.Shortcut)) + { + bool vmapCol = Global.VMapMgr.GetObjectHitPos(PhasingHandler.GetTerrainMapId(GetPhaseShift(), GetMap(), pos.posX, pos.posY), + pos.posX, pos.posY, pos.posZ + halfHeight, + destx, desty, destz + halfHeight, + out destx, out desty, out destz, -0.5f); + + destz -= halfHeight; + + // Collided with static LOS object, move back to collision point + if (vmapCol) + { + destx -= SharedConst.ContactDistance * MathF.Cos(angle); + desty -= SharedConst.ContactDistance * MathF.Sin(angle); + dist = MathF.Sqrt((pos.posX - destx) * (pos.posX - destx) + (pos.posY - desty) * (pos.posY - desty)); + } + } // check dynamic collision - float halfHeight = GetCollisionHeight() * 0.5f; bool col = GetMap().GetObjectHitPos(GetPhaseShift(), pos.posX, pos.posY, pos.posZ + halfHeight, destx, desty, destz + halfHeight, out destx, out desty, out destz, -0.5f); destz -= halfHeight; diff --git a/Source/Game/Movement/Generators/PathGenerator.cs b/Source/Game/Movement/Generators/PathGenerator.cs index 712d3b213..1785c0e7e 100644 --- a/Source/Game/Movement/Generators/PathGenerator.cs +++ b/Source/Game/Movement/Generators/PathGenerator.cs @@ -190,8 +190,9 @@ namespace Game.Movement } // we may need a better number here - bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f); - if (farFromPoly) + bool startFarFromPoly = distToStartPoly > 7.0f; + bool endFarFromPoly = distToEndPoly > 7.0f; + if (startFarFromPoly || endFarFromPoly) { Log.outDebug(LogFilter.Maps, "++ BuildPolyPath . farFromPoly distToStartPoly={0:F3} distToEndPoly={1:F3}\n", distToStartPoly, distToEndPoly); @@ -222,7 +223,13 @@ namespace Game.Movement if (buildShotrcut) { BuildShortcut(); - pathType = PathType.Normal | PathType.NotUsingPath | PathType.FarFromPoly; + pathType = PathType.Normal | PathType.NotUsingPath; + + if (startFarFromPoly) + pathType |= PathType.FarFromPolyStart; + if (endFarFromPoly) + pathType |= PathType.FarFromPolyEnd; + return; } else @@ -236,7 +243,12 @@ namespace Game.Movement SetActualEndPosition(new Vector3(endPoint[2], endPoint[0], endPoint[1])); } - pathType = PathType.Incomplete | PathType.FarFromPoly; + pathType = PathType.Incomplete; + + if (startFarFromPoly) + pathType |= PathType.FarFromPolyStart; + if (endFarFromPoly) + pathType |= PathType.FarFromPolyEnd; } } @@ -251,7 +263,17 @@ namespace Game.Movement _pathPolyRefs[0] = startPoly; _polyLength = 1; - pathType = farFromPoly ? PathType.Incomplete | PathType.FarFromPoly : PathType.Normal; + if (startFarFromPoly || endFarFromPoly) + { + pathType = PathType.Incomplete; + + if (startFarFromPoly) + pathType |= PathType.FarFromPolyStart; + if (endFarFromPoly) + pathType |= PathType.FarFromPolyEnd; + } + else + pathType = PathType.Normal; BuildPointPath(startPoint, endPoint); return; @@ -374,6 +396,7 @@ namespace Game.Movement Detour.dtVlerp(hitPos, startPoint, endPoint, hit); _pathPoints[1] = new Vector3(hitPos[2], hitPos[0], hitPos[1]); + NormalizePath(); pathType = PathType.Incomplete; return; } @@ -447,6 +470,7 @@ namespace Game.Movement Detour.dtVlerp(hitPos, startPoint, endPoint, hit); _pathPoints[1] = new Vector3(hitPos[2], hitPos[0], hitPos[1]); + NormalizePath(); pathType = PathType.Incomplete; return; } @@ -482,8 +506,10 @@ namespace Game.Movement else pathType = PathType.Incomplete; - if (farFromPoly) - pathType |= PathType.FarFromPoly; + if (startFarFromPoly) + pathType |= PathType.FarFromPolyStart; + if (endFarFromPoly) + pathType |= PathType.FarFromPolyEnd; // generate the point-path out of our up-to-date poly-path BuildPointPath(startPoint, endPoint); @@ -1061,7 +1087,9 @@ namespace Game.Movement NoPath = 0x08, // no valid path at all or error in generating one NotUsingPath = 0x10, // used when we are either flying/swiming or on map w/o mmaps Short = 0x20, // path is longer or equal to its limited path length - FarFromPoly = 0x40 // start of end positions are far from the mmap poligon + FarFromPolyStart = 0x40, // start position is far from the mmap poligon + FarFromPolyEnd = 0x80, // end positions is far from the mmap poligon + FarFromPoly = FarFromPolyStart | FarFromPolyEnd // start or end positions are far from the mmap poligon } public enum NavArea