muffin v7.5.13
This commit is contained in:
parent
911ed68baa
commit
acf3e3cb18
69 changed files with 2731 additions and 1425 deletions
|
|
@ -5,21 +5,28 @@ using Microsoft.Extensions.Logging;
|
|||
using Questionable.Controller.CustomDelivery;
|
||||
using Questionable.Controller.Steps;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.Controller.Steps.Interactions;
|
||||
using Questionable.Controller.Steps.Movement;
|
||||
using Questionable.Controller.Steps.Shared;
|
||||
using Questionable.Model.Questing;
|
||||
using SmartNav;
|
||||
|
||||
namespace Questionable.Navigation;
|
||||
|
||||
internal sealed class SmartNavReRouteService(ReRoutePolicy reRoutePolicy, SmartNavTaskMapper taskMapper, Configuration configuration, ILogger<SmartNavReRouteService> logger)
|
||||
{
|
||||
public void SetDestination(uint territoryId, Vector3 position)
|
||||
private ETravelMode _travelMode;
|
||||
|
||||
public void SetDestination(uint territoryId, Vector3 position, ETravelMode travelMode = ETravelMode.Auto)
|
||||
{
|
||||
reRoutePolicy.SetDestination(territoryId, position);
|
||||
_travelMode = travelMode;
|
||||
var (allowMount, allowFlight) = GetCapabilities(travelMode);
|
||||
reRoutePolicy.SetDestination(territoryId, position, allowMount, allowFlight);
|
||||
}
|
||||
|
||||
public void ClearDestination()
|
||||
{
|
||||
_travelMode = ETravelMode.Auto;
|
||||
reRoutePolicy.ClearDestination();
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +58,7 @@ internal sealed class SmartNavReRouteService(ReRoutePolicy reRoutePolicy, SmartN
|
|||
if (reRouteDecision is ReRouteDecision.Replan replan)
|
||||
{
|
||||
taskQueue.Reset();
|
||||
foreach (ITask item2 in taskMapper.MapInstructions(replan.Instructions))
|
||||
foreach (ITask item2 in taskMapper.MapInstructions(replan.Instructions, null, _travelMode))
|
||||
{
|
||||
taskQueue.Enqueue(item2);
|
||||
}
|
||||
|
|
@ -79,10 +86,33 @@ internal sealed class SmartNavReRouteService(ReRoutePolicy reRoutePolicy, SmartN
|
|||
|
||||
private static bool IsMovementTask(ITask task)
|
||||
{
|
||||
if (task is MoveTask || task is LandTask || task is Mount.MountTask || task is AetheryteTeleport.Task || task is AethernetRide.Task || task is WaitNavmesh.Task || task is WaitCondition.Task || task is WarpInteract.Task || task is TaxiInteract.Task || task is SubRegionTransport.Task || task is TicketTeleport.Task)
|
||||
if (!(task is MoveTask))
|
||||
{
|
||||
return true;
|
||||
if (task is Dive.Task task2)
|
||||
{
|
||||
if (task2.SmartNavRouted)
|
||||
{
|
||||
goto IL_006c;
|
||||
}
|
||||
}
|
||||
else if (task is LandTask || task is Mount.MountTask || task is AetheryteTeleport.Task || task is AethernetRide.Task || task is WaitNavmesh.Task || task is WaitCondition.Task || task is WarpInteract.Task || task is TaxiInteract.Task || task is SubRegionTransport.Task || task is TicketTeleport.Task)
|
||||
{
|
||||
goto IL_006c;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
goto IL_006c;
|
||||
IL_006c:
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static (bool AllowMount, bool AllowFlight) GetCapabilities(ETravelMode travelMode)
|
||||
{
|
||||
return travelMode switch
|
||||
{
|
||||
ETravelMode.OnFoot => (AllowMount: false, AllowFlight: false),
|
||||
ETravelMode.GroundMount => (AllowMount: true, AllowFlight: false),
|
||||
_ => (AllowMount: true, AllowFlight: true),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,27 @@ internal sealed class SmartNavRouteEnqueuer(NavRouter navRouter, PlayerNavStateB
|
|||
{
|
||||
return false;
|
||||
}
|
||||
List<NavInstruction> list = instructionBuilder.Build(routeResult, territoryId).TakeWhile((NavInstruction x) => !(x is NavInstruction.Move move) || !move.IsFinal).ToList();
|
||||
List<NavInstruction> list = instructionBuilder.Build(routeResult, territoryId).TakeWhile(delegate(NavInstruction x)
|
||||
{
|
||||
if (x is NavInstruction.Move move)
|
||||
{
|
||||
if (move.IsFinal)
|
||||
{
|
||||
goto IL_0026;
|
||||
}
|
||||
}
|
||||
else if (x is NavInstruction.Swim { IsFinal: not false })
|
||||
{
|
||||
goto IL_0026;
|
||||
}
|
||||
bool flag = false;
|
||||
goto IL_002c;
|
||||
IL_0026:
|
||||
flag = true;
|
||||
goto IL_002c;
|
||||
IL_002c:
|
||||
return !flag;
|
||||
}).ToList();
|
||||
if (list.Count == 0)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -120,6 +140,18 @@ internal sealed class SmartNavRouteEnqueuer(NavRouter navRouter, PlayerNavStateB
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if (instruction is NavInstruction.Swim)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (instruction is NavInstruction.DiveEntry)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (instruction is NavInstruction.Surface)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (instruction is NavInstruction.AethernetHop)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Numerics;
|
|||
using Dalamud.Plugin.Services;
|
||||
using Questionable.Controller.Steps;
|
||||
using Questionable.Controller.Steps.Common;
|
||||
using Questionable.Controller.Steps.Interactions;
|
||||
using Questionable.Controller.Steps.Movement;
|
||||
using Questionable.Controller.Steps.Shared;
|
||||
using Questionable.Data;
|
||||
|
|
@ -15,13 +16,22 @@ namespace Questionable.Navigation;
|
|||
|
||||
internal sealed class SmartNavTaskMapper(IClientState clientState, TerritoryData territoryData)
|
||||
{
|
||||
public IEnumerable<ITask> MapInstructions(IReadOnlyList<NavInstruction> instructions, QuestStep? step = null)
|
||||
private const float SurfaceExitRise = 3f;
|
||||
|
||||
public IEnumerable<ITask> MapInstructions(IReadOnlyList<NavInstruction> instructions, QuestStep? step = null, ETravelMode travelMode = ETravelMode.Auto)
|
||||
{
|
||||
for (int i = 0; i < instructions.Count; i++)
|
||||
{
|
||||
foreach (ITask item in Map(instructions[i], NextTravelInstruction(instructions, i), step))
|
||||
{
|
||||
yield return item;
|
||||
if (item is MoveTask task && !(instructions[i] is NavInstruction.Swim))
|
||||
{
|
||||
yield return ApplyTravelMode(task, travelMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,66 +58,131 @@ internal sealed class SmartNavTaskMapper(IClientState clientState, TerritoryData
|
|||
{
|
||||
if (!(instruction is NavInstruction.Move move))
|
||||
{
|
||||
if (!(instruction is NavInstruction.Land))
|
||||
if (!(instruction is NavInstruction.Swim swim))
|
||||
{
|
||||
if (!(instruction is NavInstruction.Unmount))
|
||||
if (!(instruction is NavInstruction.DiveEntry dive))
|
||||
{
|
||||
NavInstruction.WaitForTerritory waitForTerritory = instruction as NavInstruction.WaitForTerritory;
|
||||
if ((object)waitForTerritory == null)
|
||||
if (!(instruction is NavInstruction.Surface surface))
|
||||
{
|
||||
if (!(instruction is NavInstruction.WaitForNavmesh))
|
||||
if (!(instruction is NavInstruction.Land))
|
||||
{
|
||||
if (!(instruction is NavInstruction.InteractWarp interactWarp))
|
||||
if (!(instruction is NavInstruction.Unmount))
|
||||
{
|
||||
if (!(instruction is NavInstruction.UseTeleportTicket useTeleportTicket))
|
||||
NavInstruction.WaitForTerritory waitForTerritory = instruction as NavInstruction.WaitForTerritory;
|
||||
if ((object)waitForTerritory == null)
|
||||
{
|
||||
if (!(instruction is NavInstruction.SubRegionTransport subRegionTransport))
|
||||
if (!(instruction is NavInstruction.WaitForNavmesh))
|
||||
{
|
||||
throw new InvalidOperationException($"Unmapped NavInstruction: {instruction}");
|
||||
if (!(instruction is NavInstruction.InteractWarp interactWarp))
|
||||
{
|
||||
if (!(instruction is NavInstruction.UseTeleportTicket useTeleportTicket))
|
||||
{
|
||||
if (!(instruction is NavInstruction.SubRegionTransport subRegionTransport))
|
||||
{
|
||||
throw new InvalidOperationException($"Unmapped NavInstruction: {instruction}");
|
||||
}
|
||||
yield return new SubRegionTransport.Task(subRegionTransport.From, subRegionTransport.To, subRegionTransport.Territory);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new TicketTeleport.Task(useTeleportTicket.ItemId, useTeleportTicket.Territory);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WarpInteract.Task(interactWarp.NpcDataId, interactWarp.WarpRowId, interactWarp.FromTerritory, interactWarp.ToTerritory);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WaitNavmesh.Task();
|
||||
}
|
||||
yield return new SubRegionTransport.Task(subRegionTransport.From, subRegionTransport.To, subRegionTransport.Territory);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new TicketTeleport.Task(useTeleportTicket.ItemId, useTeleportTicket.Territory);
|
||||
yield return new WaitCondition.Task(() => waitForTerritory.Acceptable.Contains(clientState.TerritoryType), waitForTerritory.Description);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WarpInteract.Task(interactWarp.NpcDataId, interactWarp.WarpRowId, interactWarp.FromTerritory, interactWarp.ToTerritory);
|
||||
yield return new Mount.UnmountTask();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WaitNavmesh.Task();
|
||||
yield return new LandTask();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WaitCondition.Task(() => waitForTerritory.Acceptable.Contains(clientState.TerritoryType), waitForTerritory.Description);
|
||||
ushort territory = surface.Territory;
|
||||
Vector3 position = surface.Position;
|
||||
position.Y = surface.Position.Y + 3f;
|
||||
Vector3 destination = position;
|
||||
bool? mount = true;
|
||||
string targetNodeId = surface.TargetNodeId;
|
||||
string approachNodeId = surface.ApproachNodeId;
|
||||
yield return new MoveTask(territory, destination, mount, MountRequired: false, DismountRequired: false, null, null, DisableNavmesh: true, null, Fly: true, Land: false, IgnoreDistanceToObject: false, RestartNavigation: true, EInteractionType.None, SmartNavRouted: true, AllowZoneTransition: false, targetNodeId, approachNodeId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new Mount.UnmountTask();
|
||||
yield return new Dive.Task
|
||||
{
|
||||
SmartNavRouted = true
|
||||
};
|
||||
ushort territory2 = dive.Territory;
|
||||
Vector3 position = dive.Position;
|
||||
position.Y = dive.Position.Y - 25f;
|
||||
Vector3 destination2 = position;
|
||||
string approachNodeId = dive.TargetNodeId;
|
||||
string targetNodeId = dive.ApproachNodeId;
|
||||
yield return new MoveTask(territory2, destination2, null, MountRequired: false, DismountRequired: false, null, null, DisableNavmesh: true, null, Fly: true, Land: false, IgnoreDistanceToObject: false, RestartNavigation: true, EInteractionType.None, SmartNavRouted: true, AllowZoneTransition: false, approachNodeId, targetNodeId);
|
||||
}
|
||||
}
|
||||
else if (swim.IsFinal && step != null)
|
||||
{
|
||||
Vector3 destination3 = step.Position ?? swim.Position;
|
||||
yield return new MoveTask(step, destination3)with
|
||||
{
|
||||
Fly = true,
|
||||
Land = false,
|
||||
SmartNavRouted = true,
|
||||
RouteTargetNodeId = swim.TargetNodeId,
|
||||
RouteApproachNodeId = swim.ApproachNodeId
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new LandTask();
|
||||
NavInstruction.Swim swim2 = swim;
|
||||
ushort territory3 = swim2.Territory;
|
||||
Vector3 position2 = swim2.Position;
|
||||
float? stopDistance = swim2.StopDistance;
|
||||
string targetNodeId = swim2.TargetNodeId;
|
||||
string approachNodeId = swim2.ApproachNodeId;
|
||||
yield return new MoveTask(territory3, position2, null, MountRequired: false, DismountRequired: false, stopDistance, null, DisableNavmesh: false, null, Fly: true, Land: false, IgnoreDistanceToObject: false, RestartNavigation: true, EInteractionType.None, SmartNavRouted: true, AllowZoneTransition: false, targetNodeId, approachNodeId);
|
||||
}
|
||||
}
|
||||
else if (move.IsFinal && step != null)
|
||||
{
|
||||
Vector3 destination = step.Position ?? move.Position;
|
||||
yield return new MoveTask(step, destination)with
|
||||
Vector3 destination4 = step.Position ?? move.Position;
|
||||
MoveTask moveTask = new MoveTask(step, destination4)with
|
||||
{
|
||||
Fly = (move.Fly || step.Fly == true),
|
||||
Land = (move.Fly || step.Land == true),
|
||||
SmartNavRouted = true,
|
||||
RouteTargetNodeId = move.TargetNodeId,
|
||||
RouteApproachNodeId = move.ApproachNodeId
|
||||
Fly = (move.Fly || step.Fly == true)
|
||||
};
|
||||
MoveTask moveTask2 = moveTask;
|
||||
bool flag = move.Fly || step.Land == true;
|
||||
if (!flag)
|
||||
{
|
||||
EArrivalMode arrivalMode = step.ArrivalMode;
|
||||
bool flag2 = (uint)(arrivalMode - 2) <= 1u;
|
||||
flag = flag2;
|
||||
}
|
||||
moveTask2.Land = flag;
|
||||
moveTask.SmartNavRouted = true;
|
||||
moveTask.RouteTargetNodeId = move.TargetNodeId;
|
||||
moveTask.RouteApproachNodeId = move.ApproachNodeId;
|
||||
yield return moveTask;
|
||||
if (step != null)
|
||||
{
|
||||
bool? fly = step.Fly;
|
||||
|
|
@ -116,22 +191,30 @@ internal sealed class SmartNavTaskMapper(IClientState clientState, TerritoryData
|
|||
yield return new LandTask();
|
||||
}
|
||||
}
|
||||
if (step.ArrivalMode == EArrivalMode.StayMounted && !step.DismountRequired)
|
||||
{
|
||||
yield return new Mount.MountTask(step.TerritoryId, Mount.EMountIf.Always);
|
||||
}
|
||||
else if (step.ArrivalMode == EArrivalMode.Dismount && !step.MountRequired)
|
||||
{
|
||||
yield return new Mount.UnmountTask();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NavInstruction.Move move2 = move;
|
||||
ushort territory = move2.Territory;
|
||||
Vector3 position = move2.Position;
|
||||
bool? mount = move2.Mount;
|
||||
float? stopDistance = move2.StopDistance;
|
||||
ushort territory4 = move2.Territory;
|
||||
Vector3 position3 = move2.Position;
|
||||
bool? mount2 = move2.Mount;
|
||||
float? stopDistance2 = move2.StopDistance;
|
||||
uint? dataId = move2.DataId;
|
||||
bool disableNavmesh = move2.DisableNavmesh;
|
||||
bool fly2 = move2.Fly;
|
||||
bool landAtTarget = move2.LandAtTarget;
|
||||
bool flag = move2.Fly;
|
||||
bool flag2 = move2.LandAtTarget;
|
||||
bool allowZoneTransition = move2.AllowZoneTransition;
|
||||
string targetNodeId = move2.TargetNodeId;
|
||||
string approachNodeId = move2.ApproachNodeId;
|
||||
yield return new MoveTask(territory, position, mount, MountRequired: false, DismountRequired: false, stopDistance, dataId, disableNavmesh, null, fly2, landAtTarget, IgnoreDistanceToObject: false, RestartNavigation: true, EInteractionType.None, SmartNavRouted: true, allowZoneTransition, targetNodeId, approachNodeId);
|
||||
string approachNodeId = move2.TargetNodeId;
|
||||
string targetNodeId = move2.ApproachNodeId;
|
||||
yield return new MoveTask(territory4, position3, mount2, MountRequired: false, DismountRequired: false, stopDistance2, dataId, disableNavmesh, null, flag, flag2, IgnoreDistanceToObject: false, RestartNavigation: true, EInteractionType.None, SmartNavRouted: true, allowZoneTransition, approachNodeId, targetNodeId);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -147,4 +230,50 @@ internal sealed class SmartNavTaskMapper(IClientState clientState, TerritoryData
|
|||
yield return new AetheryteTeleport.MoveAwayFromAetheryte(teleport.Target);
|
||||
}
|
||||
}
|
||||
|
||||
private static MoveTask ApplyTravelMode(MoveTask task, ETravelMode travelMode)
|
||||
{
|
||||
if (travelMode == ETravelMode.Auto)
|
||||
{
|
||||
return task;
|
||||
}
|
||||
if (task.MountRequired)
|
||||
{
|
||||
return task with
|
||||
{
|
||||
Mount = true,
|
||||
Fly = (travelMode == ETravelMode.Flying && task.Fly),
|
||||
Land = (travelMode == ETravelMode.Flying && task.Land)
|
||||
};
|
||||
}
|
||||
if (task.DismountRequired)
|
||||
{
|
||||
return task with
|
||||
{
|
||||
Mount = false,
|
||||
Fly = false,
|
||||
Land = false
|
||||
};
|
||||
}
|
||||
return travelMode switch
|
||||
{
|
||||
ETravelMode.OnFoot => task with
|
||||
{
|
||||
Mount = false,
|
||||
Fly = false,
|
||||
Land = false
|
||||
},
|
||||
ETravelMode.GroundMount => task with
|
||||
{
|
||||
Mount = true,
|
||||
Fly = false,
|
||||
Land = false
|
||||
},
|
||||
ETravelMode.Flying => task with
|
||||
{
|
||||
Mount = true
|
||||
},
|
||||
_ => task,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue