muffin v7.38.8
This commit is contained in:
parent
5e2d8f648b
commit
3e10cbbbf2
51 changed files with 2585 additions and 1972 deletions
|
|
@ -73,6 +73,8 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
private readonly IClientState _clientState;
|
||||
|
||||
private readonly IObjectTable _objectTable;
|
||||
|
||||
private readonly GameFunctions _gameFunctions;
|
||||
|
||||
private readonly ChatFunctions _chatFunctions;
|
||||
|
|
@ -89,6 +91,8 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
private Task<List<Vector3>>? _pathfindTask;
|
||||
|
||||
private long _pathfindStartTime;
|
||||
|
||||
public bool IsNavmeshReady
|
||||
{
|
||||
get
|
||||
|
|
@ -138,10 +142,15 @@ internal sealed class MovementController : IDisposable
|
|||
|
||||
public int BuiltNavmeshPercent => _navmeshIpc.GetBuildProgress();
|
||||
|
||||
public MovementController(NavmeshIpc navmeshIpc, IClientState clientState, GameFunctions gameFunctions, ChatFunctions chatFunctions, ICondition condition, MovementOverrideController movementOverrideController, AetheryteData aetheryteData, ILogger<MovementController> logger)
|
||||
public bool IsNavmeshPathfindInProgress => _navmeshIpc.IsPathfindInProgress;
|
||||
|
||||
public int NumQueuedPathfindRequests => _navmeshIpc.NumQueuedPathfindRequests;
|
||||
|
||||
public MovementController(NavmeshIpc navmeshIpc, IClientState clientState, IObjectTable objectTable, GameFunctions gameFunctions, ChatFunctions chatFunctions, ICondition condition, MovementOverrideController movementOverrideController, AetheryteData aetheryteData, ILogger<MovementController> logger)
|
||||
{
|
||||
_navmeshIpc = navmeshIpc;
|
||||
_clientState = clientState;
|
||||
_objectTable = objectTable;
|
||||
_gameFunctions = gameFunctions;
|
||||
_chatFunctions = chatFunctions;
|
||||
_condition = condition;
|
||||
|
|
@ -154,16 +163,51 @@ internal sealed class MovementController : IDisposable
|
|||
{
|
||||
if (_pathfindTask != null && Destination != null)
|
||||
{
|
||||
if (!_pathfindTask.IsCompleted && Environment.TickCount64 - _pathfindStartTime > 30000 && _navmeshIpc.NumQueuedPathfindRequests > 5)
|
||||
{
|
||||
_logger.LogWarning("Pathfinding appears stuck: {QueuedRequests} queued requests, task running for {Duration}ms", _navmeshIpc.NumQueuedPathfindRequests, Environment.TickCount64 - _pathfindStartTime);
|
||||
}
|
||||
if (_pathfindTask.IsCompletedSuccessfully)
|
||||
{
|
||||
_logger.LogInformation("Pathfinding complete, got {Count} points", _pathfindTask.Result.Count);
|
||||
if (_pathfindTask.Result.Count == 0)
|
||||
{
|
||||
if (Destination.NavmeshCalculations == 1)
|
||||
{
|
||||
_logger.LogWarning("Initial pathfinding returned 0 points, attempting to find accessible destination");
|
||||
Vector3? vector = TryFindAccessibleDestination(Destination.Position, Destination.IsFlying, Destination.Land);
|
||||
if (vector.HasValue && Vector3.Distance(Destination.Position, vector.Value) < 30f)
|
||||
{
|
||||
_logger.LogInformation("Retrying pathfinding with adjusted destination: {AdjustedDestination}", vector.Value.ToString("G", CultureInfo.InvariantCulture));
|
||||
Restart(Destination with
|
||||
{
|
||||
Position = vector.Value
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (Destination.IsFlying && Destination.Land)
|
||||
{
|
||||
_logger.LogWarning("Adjusted destination failed, trying tolerance-based pathfinding");
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(30L));
|
||||
Vector3 vector2 = _objectTable[0]?.Position ?? Vector3.Zero;
|
||||
if (Destination.IsFlying)
|
||||
{
|
||||
Vector3 vector3 = vector2;
|
||||
vector3.Y = vector2.Y + 0.2f;
|
||||
vector2 = vector3;
|
||||
}
|
||||
_pathfindStartTime = Environment.TickCount64;
|
||||
_pathfindTask = _navmeshIpc.PathfindWithTolerance(vector2, Destination.Position, Destination.IsFlying, 10f, _cancellationTokenSource.Token);
|
||||
Destination.NavmeshCalculations++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ResetPathfinding();
|
||||
throw new PathfindingFailedException();
|
||||
}
|
||||
List<Vector3> list = _pathfindTask.Result.Skip(1).ToList();
|
||||
Vector3 p = _clientState.LocalPlayer?.Position ?? list[0];
|
||||
Vector3 p = _objectTable[0]?.Position ?? list[0];
|
||||
if (Destination.IsFlying && !_condition[ConditionFlag.InFlight] && _condition[ConditionFlag.Mounted] && (IsOnFlightPath(p) || list.Any(IsOnFlightPath)))
|
||||
{
|
||||
ActionManager.Instance()->UseAction(ActionType.GeneralAction, 2u, 3758096384uL, 0u, ActionManager.UseActionMode.None, 0u, null);
|
||||
|
|
@ -179,6 +223,7 @@ internal sealed class MovementController : IDisposable
|
|||
_logger.LogInformation("Running navmesh recalculation with fudged point ({From} to {To})", list.Last(), Destination.Position);
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(30L));
|
||||
_pathfindStartTime = Environment.TickCount64;
|
||||
_pathfindTask = _navmeshIpc.Pathfind(list.Last(), Destination.Position, Destination.IsFlying, _cancellationTokenSource.Token);
|
||||
return;
|
||||
}
|
||||
|
|
@ -220,7 +265,7 @@ internal sealed class MovementController : IDisposable
|
|||
Restart(Destination);
|
||||
return;
|
||||
}
|
||||
Vector3 vector = _clientState.LocalPlayer?.Position ?? Vector3.Zero;
|
||||
Vector3 vector4 = _objectTable[0]?.Position ?? Vector3.Zero;
|
||||
if (Destination.MovementType == EMovementType.Landing)
|
||||
{
|
||||
if (!_condition[ConditionFlag.InFlight])
|
||||
|
|
@ -228,9 +273,9 @@ internal sealed class MovementController : IDisposable
|
|||
Stop();
|
||||
}
|
||||
}
|
||||
else if ((vector - Destination.Position).Length() < Destination.StopDistance)
|
||||
else if ((vector4 - Destination.Position).Length() < Destination.StopDistance)
|
||||
{
|
||||
if (vector.Y - Destination.Position.Y <= Destination.VerticalStopDistance)
|
||||
if (vector4.Y - Destination.Position.Y <= Destination.VerticalStopDistance)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
|
@ -239,7 +284,7 @@ internal sealed class MovementController : IDisposable
|
|||
IGameObject gameObject = _gameFunctions.FindObjectByDataId(Destination.DataId.Value);
|
||||
if ((gameObject is ICharacter || gameObject is IEventObj) ? true : false)
|
||||
{
|
||||
if (Math.Abs(vector.Y - gameObject.Position.Y) < 1.95f)
|
||||
if (Math.Abs(vector4.Y - gameObject.Position.Y) < 1.95f)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
|
@ -250,7 +295,7 @@ internal sealed class MovementController : IDisposable
|
|||
{
|
||||
Stop();
|
||||
}
|
||||
else if (Math.Abs(vector.Y - gameObject.Position.Y) < 1.95f)
|
||||
else if (Math.Abs(vector4.Y - gameObject.Position.Y) < 1.95f)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
|
@ -268,10 +313,10 @@ internal sealed class MovementController : IDisposable
|
|||
else
|
||||
{
|
||||
List<Vector3> waypoints = _navmeshIpc.GetWaypoints();
|
||||
Vector3? vector2 = _clientState.LocalPlayer?.Position;
|
||||
if (vector2.HasValue && (!Destination.ShouldRecalculateNavmesh() || !RecalculateNavmesh(waypoints, vector2.Value)) && !Destination.IsFlying && !_condition[ConditionFlag.Mounted] && !_gameFunctions.HasStatusPreventingSprint() && Destination.CanSprint)
|
||||
Vector3? vector5 = _objectTable[0]?.Position;
|
||||
if (vector5.HasValue && (!Destination.ShouldRecalculateNavmesh() || !RecalculateNavmesh(waypoints, vector5.Value)) && !Destination.IsFlying && !_condition[ConditionFlag.Mounted] && !_gameFunctions.HasStatusPreventingSprint() && Destination.CanSprint)
|
||||
{
|
||||
TriggerSprintIfNeeded(waypoints, vector2.Value);
|
||||
TriggerSprintIfNeeded(waypoints, vector5.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -331,7 +376,7 @@ internal sealed class MovementController : IDisposable
|
|||
Destination.NavmeshCalculations++;
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(30L));
|
||||
Vector3 vector2 = _clientState.LocalPlayer.Position;
|
||||
Vector3 vector2 = _objectTable[0]?.Position ?? Vector3.Zero;
|
||||
if (fly && _aetheryteData.CalculateDistance(vector2, _clientState.TerritoryType, EAetheryteLocation.CoerthasCentralHighlandsCampDragonhead) < 11f)
|
||||
{
|
||||
Vector3 vector = vector2;
|
||||
|
|
@ -345,7 +390,16 @@ internal sealed class MovementController : IDisposable
|
|||
vector.Y = vector2.Y + 0.2f;
|
||||
vector2 = vector;
|
||||
}
|
||||
_pathfindTask = _navmeshIpc.Pathfind(vector2, to, fly, _cancellationTokenSource.Token);
|
||||
_pathfindStartTime = Environment.TickCount64;
|
||||
if (fly && land)
|
||||
{
|
||||
_logger.LogInformation("Using tolerance-based pathfinding for landing (tolerance: 5.0)");
|
||||
_pathfindTask = _navmeshIpc.PathfindWithTolerance(vector2, to, fly, 5f, _cancellationTokenSource.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pathfindTask = _navmeshIpc.Pathfind(vector2, to, fly, _cancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
|
||||
public void NavigateTo(EMovementType type, uint? dataId, List<Vector3> to, bool fly, bool sprint, float? stopDistance, float? verticalStopDistance = null, bool land = false)
|
||||
|
|
@ -380,6 +434,46 @@ internal sealed class MovementController : IDisposable
|
|||
_pathfindTask = null;
|
||||
}
|
||||
|
||||
private Vector3? TryFindAccessibleDestination(Vector3 target, bool flying, bool landing)
|
||||
{
|
||||
float[] array = ((!(flying && landing)) ? ((!flying) ? new float[3] { 1f, 3f, 5f } : new float[3] { 2f, 5f, 10f }) : new float[3] { 5f, 10f, 15f });
|
||||
float[] array2 = ((!flying) ? new float[3] { 1f, 2f, 3f } : new float[3] { 3f, 5f, 10f });
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
float num = array[i];
|
||||
float num2 = array2[Math.Min(i, array2.Length - 1)];
|
||||
Vector3? vector = _navmeshIpc.FindNearestMeshPoint(target, num, num2);
|
||||
if (vector.HasValue)
|
||||
{
|
||||
float num3 = Vector3.Distance(target, vector.Value);
|
||||
if (num3 <= num * 1.5f)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
_logger.LogInformation("Adjusted destination from {Original} to {Adjusted} (distance: {Distance:F2}, extent: {ExtentXZ}/{ExtentY})", target.ToString("G", CultureInfo.InvariantCulture), vector.Value.ToString("G", CultureInfo.InvariantCulture), num3, num, num2);
|
||||
}
|
||||
return vector.Value;
|
||||
}
|
||||
}
|
||||
Vector3? pointOnFloor = _navmeshIpc.GetPointOnFloor(target, flying, num);
|
||||
if (!pointOnFloor.HasValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float num4 = Vector3.Distance(target, pointOnFloor.Value);
|
||||
if (num4 <= num * 1.5f)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
_logger.LogInformation("Adjusted destination via floor point from {Original} to {Adjusted} (distance: {Distance:F2}, extent: {ExtentXZ})", target.ToString("G", CultureInfo.InvariantCulture), pointOnFloor.Value.ToString("G", CultureInfo.InvariantCulture), num4, num);
|
||||
}
|
||||
return pointOnFloor.Value;
|
||||
}
|
||||
}
|
||||
_logger.LogWarning("Could not find accessible mesh point near {Target} within max extent {MaxExtent}", target.ToString("G", CultureInfo.InvariantCulture), array[^1]);
|
||||
return null;
|
||||
}
|
||||
|
||||
private unsafe bool RecalculateNavmesh(List<Vector3> navPoints, Vector3 start)
|
||||
{
|
||||
if (Destination == null)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue