forked from liza/Questionable
Add fallback for missing versper bay aetheryte tickets
This commit is contained in:
parent
0eb77927b3
commit
d20a768996
@ -1,11 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Numerics;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Questionable.Controller.Steps.Common;
|
using Questionable.Controller.Steps.Common;
|
||||||
|
using Questionable.Controller.Steps.Shared;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.V1;
|
using Questionable.Model.V1;
|
||||||
|
using AethernetShortcut = Questionable.Controller.Steps.Shared.AethernetShortcut;
|
||||||
|
|
||||||
namespace Questionable.Controller.Steps.Interactions;
|
namespace Questionable.Controller.Steps.Interactions;
|
||||||
|
|
||||||
@ -13,7 +16,7 @@ internal static class UseItem
|
|||||||
{
|
{
|
||||||
public const int VesperBayAetheryteTicket = 30362;
|
public const int VesperBayAetheryteTicket = 30362;
|
||||||
|
|
||||||
internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory
|
internal sealed class Factory(IServiceProvider serviceProvider, ILogger<Factory> logger) : ITaskFactory
|
||||||
{
|
{
|
||||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||||
{
|
{
|
||||||
@ -22,6 +25,16 @@ internal static class UseItem
|
|||||||
|
|
||||||
ArgumentNullException.ThrowIfNull(step.ItemId);
|
ArgumentNullException.ThrowIfNull(step.ItemId);
|
||||||
|
|
||||||
|
if (step.ItemId == VesperBayAetheryteTicket)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
InventoryManager* inventoryManager = InventoryManager.Instance();
|
||||||
|
if (inventoryManager->GetInventoryItemCount(step.ItemId.Value) == 0)
|
||||||
|
return CreateVesperBayFallbackTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var unmount = serviceProvider.GetRequiredService<UnmountTask>();
|
var unmount = serviceProvider.GetRequiredService<UnmountTask>();
|
||||||
if (step.GroundTarget == true)
|
if (step.GroundTarget == true)
|
||||||
{
|
{
|
||||||
@ -47,6 +60,23 @@ internal static class UseItem
|
|||||||
|
|
||||||
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
public ITask CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
|
||||||
=> throw new InvalidOperationException();
|
=> throw new InvalidOperationException();
|
||||||
|
|
||||||
|
private IEnumerable<ITask> CreateVesperBayFallbackTask()
|
||||||
|
{
|
||||||
|
logger.LogWarning("No vesper bay aetheryte tickets in inventory, navigating via ferry in Limsa instead");
|
||||||
|
|
||||||
|
uint npcId = 1003540;
|
||||||
|
ushort territoryId = 129;
|
||||||
|
Vector3 destination = new(-360.9217f, 8f, 38.92566f);
|
||||||
|
yield return serviceProvider.GetRequiredService<AetheryteShortcut.UseAetheryteShortcut>()
|
||||||
|
.With(null, EAetheryteLocation.Limsa, territoryId);
|
||||||
|
yield return serviceProvider.GetRequiredService<AethernetShortcut.UseAethernetShortcut>()
|
||||||
|
.With(EAetheryteLocation.Limsa, EAetheryteLocation.LimsaArcanist);
|
||||||
|
yield return serviceProvider.GetRequiredService<Move.MoveInternal>()
|
||||||
|
.With(territoryId, destination, dataId: npcId, sprint: false);
|
||||||
|
yield return serviceProvider.GetRequiredService<Interact.DoInteract>()
|
||||||
|
.With(npcId, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract class UseItemBase(ILogger logger) : ITask
|
internal abstract class UseItemBase(ILogger logger) : ITask
|
||||||
|
@ -45,7 +45,7 @@ internal static class AetheryteShortcut
|
|||||||
{
|
{
|
||||||
private DateTime _continueAt;
|
private DateTime _continueAt;
|
||||||
|
|
||||||
public QuestStep Step { get; set; } = null!;
|
public QuestStep? Step { get; set; }
|
||||||
public EAetheryteLocation TargetAetheryte { get; set; }
|
public EAetheryteLocation TargetAetheryte { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -54,7 +54,7 @@ internal static class AetheryteShortcut
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ushort ExpectedTerritoryId { get; set; }
|
public ushort ExpectedTerritoryId { get; set; }
|
||||||
|
|
||||||
public ITask With(QuestStep step, EAetheryteLocation targetAetheryte, ushort expectedTerritoryId)
|
public ITask With(QuestStep? step, EAetheryteLocation targetAetheryte, ushort expectedTerritoryId)
|
||||||
{
|
{
|
||||||
Step = step;
|
Step = step;
|
||||||
TargetAetheryte = targetAetheryte;
|
TargetAetheryte = targetAetheryte;
|
||||||
@ -66,7 +66,7 @@ internal static class AetheryteShortcut
|
|||||||
{
|
{
|
||||||
_continueAt = DateTime.Now.AddSeconds(8);
|
_continueAt = DateTime.Now.AddSeconds(8);
|
||||||
ushort territoryType = clientState.TerritoryType;
|
ushort territoryType = clientState.TerritoryType;
|
||||||
if (ExpectedTerritoryId == territoryType)
|
if (Step != null && ExpectedTerritoryId == territoryType)
|
||||||
{
|
{
|
||||||
if (Step.SkipIf.Contains(ESkipCondition.AetheryteShortcutIfInSameTerritory))
|
if (Step.SkipIf.Contains(ESkipCondition.AetheryteShortcutIfInSameTerritory))
|
||||||
{
|
{
|
||||||
|
@ -99,15 +99,7 @@ internal static class Move
|
|||||||
if (actualDistance > distance)
|
if (actualDistance > distance)
|
||||||
{
|
{
|
||||||
yield return serviceProvider.GetRequiredService<MoveInternal>()
|
yield return serviceProvider.GetRequiredService<MoveInternal>()
|
||||||
.With(Destination, m =>
|
.With(Step, Destination);
|
||||||
{
|
|
||||||
m.NavigateTo(EMovementType.Quest, Step.DataId, Destination,
|
|
||||||
fly: Step.Fly == true && gameFunctions.IsFlyingUnlocked(Step.TerritoryId),
|
|
||||||
sprint: Step.Sprint != false,
|
|
||||||
stopDistance: distance,
|
|
||||||
ignoreDistanceToObject: Step.IgnoreDistanceToObject == true,
|
|
||||||
land: Step.Land == true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -116,14 +108,7 @@ internal static class Move
|
|||||||
if (actualDistance > distance)
|
if (actualDistance > distance)
|
||||||
{
|
{
|
||||||
yield return serviceProvider.GetRequiredService<MoveInternal>()
|
yield return serviceProvider.GetRequiredService<MoveInternal>()
|
||||||
.With(Destination, m =>
|
.With(Step, Destination);
|
||||||
{
|
|
||||||
m.NavigateTo(EMovementType.Quest, Step.DataId, [Destination],
|
|
||||||
fly: Step.Fly == true && gameFunctions.IsFlyingUnlockedInCurrentZone(),
|
|
||||||
sprint: Step.Sprint != false,
|
|
||||||
stopDistance: distance,
|
|
||||||
land: Step.Land == true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,22 +117,68 @@ internal static class Move
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class MoveInternal(MovementController movementController, ILogger<MoveInternal> logger) : ITask
|
internal sealed class MoveInternal(
|
||||||
|
MovementController movementController,
|
||||||
|
GameFunctions gameFunctions,
|
||||||
|
ILogger<MoveInternal> logger) : ITask
|
||||||
{
|
{
|
||||||
public Action<MovementController> StartAction { get; set; } = null!;
|
public Action StartAction { get; set; } = null!;
|
||||||
public Vector3 Destination { get; set; }
|
public Vector3 Destination { get; set; }
|
||||||
|
|
||||||
public ITask With(Vector3 destination, Action<MovementController> startAction)
|
public ITask With(QuestStep step, Vector3 destination)
|
||||||
|
{
|
||||||
|
return With(
|
||||||
|
territoryId: step.TerritoryId,
|
||||||
|
destination: destination,
|
||||||
|
stopDistance: step.StopDistance,
|
||||||
|
dataId: step.DataId,
|
||||||
|
disableNavMesh: step.DisableNavmesh,
|
||||||
|
sprint: step.Sprint != false,
|
||||||
|
fly: step.Fly == true,
|
||||||
|
land: step.Land == true,
|
||||||
|
ignoreDistanceToObject: step.IgnoreDistanceToObject == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITask With(ushort territoryId, Vector3 destination, float? stopDistance = null, uint? dataId = null,
|
||||||
|
bool disableNavMesh = false, bool sprint = true, bool fly = false, bool land = false,
|
||||||
|
bool ignoreDistanceToObject = false)
|
||||||
{
|
{
|
||||||
Destination = destination;
|
Destination = destination;
|
||||||
StartAction = startAction;
|
|
||||||
|
if (!gameFunctions.IsFlyingUnlocked(territoryId))
|
||||||
|
{
|
||||||
|
fly = false;
|
||||||
|
land = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!disableNavMesh)
|
||||||
|
{
|
||||||
|
StartAction = () =>
|
||||||
|
movementController.NavigateTo(EMovementType.Quest, dataId, Destination,
|
||||||
|
fly: fly,
|
||||||
|
sprint: sprint,
|
||||||
|
stopDistance: stopDistance,
|
||||||
|
ignoreDistanceToObject: ignoreDistanceToObject,
|
||||||
|
land: land);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartAction = () =>
|
||||||
|
movementController.NavigateTo(EMovementType.Quest, dataId, [Destination],
|
||||||
|
fly: fly,
|
||||||
|
sprint: sprint,
|
||||||
|
stopDistance: stopDistance,
|
||||||
|
ignoreDistanceToObject: ignoreDistanceToObject,
|
||||||
|
land: land);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Start()
|
public bool Start()
|
||||||
{
|
{
|
||||||
logger.LogInformation("Moving to {Destination}", Destination.ToString("G", CultureInfo.InvariantCulture));
|
logger.LogInformation("Moving to {Destination}", Destination.ToString("G", CultureInfo.InvariantCulture));
|
||||||
StartAction(movementController);
|
StartAction();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user