From 0a6be12061d7e3dedab32c3f516254edcbeec958 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 20 Jan 2023 11:02:16 +0100 Subject: [PATCH] fix(combat): prevent quitting before an operation is finished --- .../NosSmooth.Extensions.Combat/CombatManager.cs | 14 +++++++++----- .../NosSmooth.Extensions.Combat/CombatState.cs | 9 +++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Extensions/NosSmooth.Extensions.Combat/CombatManager.cs b/Extensions/NosSmooth.Extensions.Combat/CombatManager.cs index 6a23ee1..874a26e 100644 --- a/Extensions/NosSmooth.Extensions.Combat/CombatManager.cs +++ b/Extensions/NosSmooth.Extensions.Combat/CombatManager.cs @@ -47,16 +47,16 @@ public class CombatManager : IStatefulEntity long? currentTarget = null; long? previousTarget = null; - while (!combatState.ShouldQuit && !ct.IsCancellationRequested) + while (!(combatState.ShouldQuit && combatState.CanQuit) && !ct.IsCancellationRequested) { var commandResult = await _client.SendCommandAsync ( new AttackCommand ( currentTarget, - async (c) => + async (ct) => { - while (!combatState.ShouldQuit && currentTarget == previousTarget) + while (!(combatState.ShouldQuit && combatState.CanQuit) && currentTarget == previousTarget) { var iterationResult = await HandleAttackIterationAsync(combatState, technique, ct); @@ -102,7 +102,6 @@ public class CombatManager : IStatefulEntity if (!technique.ShouldContinue(combatState)) { combatState.QuitCombat(); - return Result<(bool, long?)>.FromSuccess((false, null)); } // the operations need time for execution and/or @@ -147,7 +146,7 @@ public class CombatManager : IStatefulEntity currentOperation = null; } - if (currentOperation is null) + if (currentOperation is null && !combatState.ShouldQuit) { // waiting for an operation. currentOperation = combatState.NextOperation(queueType); @@ -163,6 +162,11 @@ public class CombatManager : IStatefulEntity } } + if (currentOperation is null) + { // should quit, do nothing. + return (false, null); + } + if (!currentOperation.IsExecuting()) { // not executing, check can be used, execute if can. var canBeUsedResult = currentOperation.CanBeUsed(combatState); diff --git a/Extensions/NosSmooth.Extensions.Combat/CombatState.cs b/Extensions/NosSmooth.Extensions.Combat/CombatState.cs index 96e6f68..1832e19 100644 --- a/Extensions/NosSmooth.Extensions.Combat/CombatState.cs +++ b/Extensions/NosSmooth.Extensions.Combat/CombatState.cs @@ -45,6 +45,14 @@ internal class CombatState : ICombatState /// public INostaleClient Client { get; } + /// + /// Gets whether the manager may currently quit. + /// + /// + /// Used for finishing the current operations. + /// + public bool CanQuit => _currentOperations.Values.All(x => !x.IsExecuting() || x.IsFinished()); + /// public bool IsWaitingOnOperation => _currentOperations.Any(x => !x.Value.IsExecuting()); @@ -61,6 +69,7 @@ internal class CombatState : ICombatState if (nextOperation is not null) { + _operations[queueType].RemoveFirst(); _currentOperations[queueType] = nextOperation; return nextOperation; } -- 2.49.0