muffin v7.38.8

This commit is contained in:
alydev 2025-11-30 10:36:46 +10:00
parent 5e2d8f648b
commit 3e10cbbbf2
51 changed files with 2585 additions and 1972 deletions

View file

@ -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)