If you start moving while in combat (because mounting isn't possible), use mount as soon as you're out of combat

This commit is contained in:
Liza 2024-11-04 17:20:42 +01:00
parent cc8f326d7e
commit 6ef6dbfdb4
Signed by: liza
GPG Key ID: 7199F8D727D55F67
3 changed files with 71 additions and 19 deletions

View File

@ -35,21 +35,21 @@ internal static class Mount
private bool _mountTriggered;
private DateTime _retryAt = DateTime.MinValue;
protected override bool Start()
public MountResult EvaluateMountState()
{
if (condition[ConditionFlag.Mounted])
return false;
return MountResult.DontMount;
if (!territoryData.CanUseMount(Task.TerritoryId))
{
logger.LogInformation("Can't use mount in current territory {Id}", Task.TerritoryId);
return false;
return MountResult.DontMount;
}
if (gameFunctions.HasStatusPreventingMount())
{
logger.LogInformation("Can't mount due to status preventing sprint or mount");
return false;
return MountResult.DontMount;
}
if (Task.MountIf == EMountIf.AwayFromPosition)
@ -59,7 +59,7 @@ internal static class Mount
if (Task.TerritoryId == clientState.TerritoryType && distance < 30f && !Conditions.IsDiving)
{
logger.LogInformation("Not using mount, as we're close to the target");
return false;
return MountResult.DontMount;
}
logger.LogInformation(
@ -72,11 +72,13 @@ internal static class Mount
if (!condition[ConditionFlag.InCombat])
{
_retryAt = DateTime.Now.AddSeconds(0.5);
return true;
return MountResult.Mount;
}
else
return MountResult.WhenOutOfCombat;
}
return false;
}
protected override bool Start() => EvaluateMountState() == MountResult.Mount;
public override ETaskResult Update()
{
@ -108,6 +110,13 @@ internal static class Mount
}
}
internal enum MountResult
{
DontMount,
Mount,
WhenOutOfCombat,
}
internal sealed record UnmountTask : ITask
{
public bool ShouldRedoOnInterrupt() => true;

View File

@ -87,19 +87,23 @@ internal static class MoveTo
private readonly GameFunctions _gameFunctions;
private readonly ILogger<MoveExecutor> _logger;
private readonly IClientState _clientState;
private readonly ICondition _condition;
private readonly Mount.MountExecutor _mountExecutor;
private readonly Mount.UnmountExecutor _unmountExecutor;
private Action? _startAction;
private Vector3 _destination;
private bool _canRestart;
private ITaskExecutor? _nestedExecutor;
private (ITaskExecutor Executor, ITask Task, bool Triggered)? _nestedExecutor =
(new NoOpTaskExecutor(), new NoOpTask(), true);
public MoveExecutor(
MovementController movementController,
GameFunctions gameFunctions,
ILogger<MoveExecutor> logger,
IClientState clientState,
ICondition condition,
IDataManager dataManager,
Mount.MountExecutor mountExecutor,
Mount.UnmountExecutor unmountExecutor)
@ -108,6 +112,7 @@ internal static class MoveTo
_gameFunctions = gameFunctions;
_logger = logger;
_clientState = clientState;
_condition = condition;
_mountExecutor = mountExecutor;
_unmountExecutor = unmountExecutor;
_cannotExecuteAtThisTime = dataManager.GetString<LogMessage>(579, x => x.Text)!;
@ -161,16 +166,18 @@ internal static class MoveTo
var mountTask = new Mount.MountTask(Task.TerritoryId, Mount.EMountIf.Always);
if (_mountExecutor.Start(mountTask))
{
_nestedExecutor = _mountExecutor;
_nestedExecutor = (_mountExecutor, mountTask, true);
return true;
}
else if (_mountExecutor.EvaluateMountState() == Mount.MountResult.WhenOutOfCombat)
_nestedExecutor = (_mountExecutor, mountTask, false);
}
else if (Task.Mount == false)
{
var mountTask = new Mount.UnmountTask();
if (_unmountExecutor.Start(mountTask))
{
_nestedExecutor = _unmountExecutor;
_nestedExecutor = (_unmountExecutor, mountTask, true);
return true;
}
}
@ -187,21 +194,43 @@ internal static class MoveTo
var mountTask = new Mount.MountTask(Task.TerritoryId, mountIf, _destination);
if (_mountExecutor.Start(mountTask))
{
_nestedExecutor = _mountExecutor;
_nestedExecutor = (_mountExecutor, mountTask, true);
return true;
}
else if (_mountExecutor.EvaluateMountState() == Mount.MountResult.WhenOutOfCombat)
_nestedExecutor = (_mountExecutor, mountTask, false);
}
}
_nestedExecutor = new NoOpTaskExecutor();
if (_startAction != null && (_nestedExecutor == null || _nestedExecutor.Value.Triggered == false))
_startAction();
return true;
}
public override ETaskResult Update()
{
if (_nestedExecutor != null)
if (_nestedExecutor is { } nestedExecutor)
{
if (_nestedExecutor.Update() == ETaskResult.TaskComplete)
if (nestedExecutor is { Triggered: false, Executor: Mount.MountExecutor mountExecutor })
{
if (!_condition[ConditionFlag.InCombat])
{
if (mountExecutor.EvaluateMountState() == Mount.MountResult.DontMount)
_nestedExecutor = (new NoOpTaskExecutor(), new NoOpTask(), true);
else
{
if (_movementController.IsPathfinding || _movementController.IsPathRunning)
_movementController.Stop();
if (nestedExecutor.Executor.Start(nestedExecutor.Task))
{
_nestedExecutor = nestedExecutor with { Triggered = true };
return ETaskResult.StillRunning;
}
}
}
}
else if (nestedExecutor.Executor.Update() == ETaskResult.TaskComplete)
{
_nestedExecutor = null;
if (_startAction != null)
@ -213,6 +242,7 @@ internal static class MoveTo
else
return ETaskResult.TaskComplete;
}
return ETaskResult.StillRunning;
}
@ -245,6 +275,17 @@ internal static class MoveTo
return ETaskResult.TaskComplete;
}
public override bool WasInterrupted()
{
if (Task.Fly && _condition[ConditionFlag.InCombat] && !_condition[ConditionFlag.Mounted] &&
_nestedExecutor is { Triggered: false, Executor: Mount.MountExecutor mountExecutor } &&
mountExecutor.EvaluateMountState() == Mount.MountResult.WhenOutOfCombat)
{
return true;
}
return base.WasInterrupted();
}
public bool OnErrorToast(SeString message)
{
@ -255,7 +296,9 @@ internal static class MoveTo
}
}
private sealed class NoOpTaskExecutor : TaskExecutor<ITask>
private sealed record NoOpTask : ITask;
private sealed class NoOpTaskExecutor : TaskExecutor<NoOpTask>
{
protected override bool Start() => true;
@ -306,7 +349,6 @@ internal static class MoveTo
GameFunctions gameFunctions,
IClientState clientState) : TaskExecutor<WaitForNearDataId>
{
protected override bool Start() => true;
public override ETaskResult Update()
@ -328,7 +370,8 @@ internal static class MoveTo
public override string ToString() => "Land";
}
internal sealed class LandExecutor(IClientState clientState, ICondition condition, ILogger<LandExecutor> logger) : TaskExecutor<LandTask>
internal sealed class LandExecutor(IClientState clientState, ICondition condition, ILogger<LandExecutor> logger)
: TaskExecutor<LandTask>
{
private bool _landing;
private DateTime _continueAt;

View File

@ -23,7 +23,7 @@ internal abstract class TaskExecutor<T> : ITaskExecutor
public InteractionProgressContext? ProgressContext { get; set; }
ITask ITaskExecutor.CurrentTask => Task;
public bool WasInterrupted()
public virtual bool WasInterrupted()
{
if (ProgressContext is {} progressContext)
{