From 97289c647fd66526d7c7379402a510c19d082878 Mon Sep 17 00:00:00 2001 From: Liza Carvelli Date: Tue, 11 Jun 2024 00:06:35 +0200 Subject: [PATCH] Skipping quest steps based on CompletionFlags now works --- .../MSQ/B-Garlemald/4397_Sea of Sorrow.json | 4 +-- .../4402_A Taste of the Moon.json | 15 +++++------ .../4448_Bonds of Adamantite.json | 3 +-- .../4456_Roads Paved of Sacrifice.json | 17 +++++++++++++ .../MSQ/G-UltimaThule/4461_Hello World.json | 2 +- Questionable/Controller/MovementController.cs | 6 +++++ .../Steps/BaseFactory/SkipCondition.cs | 2 +- .../Controller/Steps/BaseFactory/WaitAtEnd.cs | 4 +-- Questionable/GameFunctions.cs | 11 +++++--- Questionable/Model/V1/QuestStep.cs | 25 ++++++++++++++----- Questionable/Questionable.csproj | 2 +- 11 files changed, 66 insertions(+), 25 deletions(-) diff --git a/QuestPaths/Endwalker/MSQ/B-Garlemald/4397_Sea of Sorrow.json b/QuestPaths/Endwalker/MSQ/B-Garlemald/4397_Sea of Sorrow.json index a5c0d5edc..f6f1d860f 100644 --- a/QuestPaths/Endwalker/MSQ/B-Garlemald/4397_Sea of Sorrow.json +++ b/QuestPaths/Endwalker/MSQ/B-Garlemald/4397_Sea of Sorrow.json @@ -89,7 +89,7 @@ "Z": 419.7605 }, "TerritoryId": 959, - "InteractionType": "Instruction", + "InteractionType": "WaitForManualProgress", "Comment": "Follow Argos" }, { @@ -148,7 +148,7 @@ "Z": 523.5217 }, "TerritoryId": 959, - "InteractionType": "Instruction", + "InteractionType": "WaitForManualProgress", "Comment": "Follow Argos" }, { diff --git a/QuestPaths/Endwalker/MSQ/C-MareLamentorum/4402_A Taste of the Moon.json b/QuestPaths/Endwalker/MSQ/C-MareLamentorum/4402_A Taste of the Moon.json index 9a6ffa06a..cf4874dbf 100644 --- a/QuestPaths/Endwalker/MSQ/C-MareLamentorum/4402_A Taste of the Moon.json +++ b/QuestPaths/Endwalker/MSQ/C-MareLamentorum/4402_A Taste of the Moon.json @@ -110,18 +110,18 @@ "InteractionType": "Jump", "JumpDestination": { "Position": { - "X": -444.84818, - "Y": -160.76439, - "Z": -645.7075 + "X": -443.62042, + "Y": -160.7644, + "Z": -644.7719 } }, "Comment": "Platform 4" }, { "Position": { - "X": -444.84818, - "Y": -160.76439, - "Z": -645.7075 + "X": -443.62042, + "Y": -160.7644, + "Z": -644.7719 }, "TerritoryId": 959, "InteractionType": "Jump", @@ -280,7 +280,8 @@ "Z": -620.05035 }, "TerritoryId": 959, - "InteractionType": "Interact" + "InteractionType": "Interact", + "Comment": "FIXME Auto-playing quests seems to get stuck here/do nothing" } ] } diff --git a/QuestPaths/Endwalker/MSQ/F-Labyrinthos2/4448_Bonds of Adamantite.json b/QuestPaths/Endwalker/MSQ/F-Labyrinthos2/4448_Bonds of Adamantite.json index d0dae4ea3..32147f016 100644 --- a/QuestPaths/Endwalker/MSQ/F-Labyrinthos2/4448_Bonds of Adamantite.json +++ b/QuestPaths/Endwalker/MSQ/F-Labyrinthos2/4448_Bonds of Adamantite.json @@ -129,8 +129,7 @@ "Z": 301.63266 }, "TerritoryId": 956, - "InteractionType": "Interact", - "Comment": "TODO Should cancel navmesh if condition is [OccupiedInCutsceneEvent OR BetweenAreas]; then verify next marker distance" + "InteractionType": "WalkTo" } ] }, diff --git a/QuestPaths/Endwalker/MSQ/G-UltimaThule/4456_Roads Paved of Sacrifice.json b/QuestPaths/Endwalker/MSQ/G-UltimaThule/4456_Roads Paved of Sacrifice.json index 9752d9eda..8b00f3f79 100644 --- a/QuestPaths/Endwalker/MSQ/G-UltimaThule/4456_Roads Paved of Sacrifice.json +++ b/QuestPaths/Endwalker/MSQ/G-UltimaThule/4456_Roads Paved of Sacrifice.json @@ -105,6 +105,23 @@ { "Sequence": 5, "Steps": [ + { + "Position": { + "X": 26.119669, + "Y": 269.043, + "Z": -587.29144 + }, + "TerritoryId": 960, + "InteractionType": "WalkTo", + "CompletionQuestVariablesFlags": [ + null, + null, + null, + null, + null, + -128 + ] + }, { "DataId": 2012354, "Position": { diff --git a/QuestPaths/Endwalker/MSQ/G-UltimaThule/4461_Hello World.json b/QuestPaths/Endwalker/MSQ/G-UltimaThule/4461_Hello World.json index 62bce9fee..6f125f2eb 100644 --- a/QuestPaths/Endwalker/MSQ/G-UltimaThule/4461_Hello World.json +++ b/QuestPaths/Endwalker/MSQ/G-UltimaThule/4461_Hello World.json @@ -45,7 +45,7 @@ }, "TerritoryId": 960, "InteractionType": "WaitForManualProgress", - "Comment": "Identify Anomaly (Elbow/Knee)" + "Comment": "Identify Anomaly (Head, Elbow or Knee)" } ] }, diff --git a/Questionable/Controller/MovementController.cs b/Questionable/Controller/MovementController.cs index 999ecc9ad..a802434f7 100644 --- a/Questionable/Controller/MovementController.cs +++ b/Questionable/Controller/MovementController.cs @@ -112,6 +112,12 @@ internal sealed class MovementController : IDisposable if (IsPathRunning && Destination != null) { + if (_gameFunctions.IsLoadingScreenVisible()) + { + Stop(); + return; + } + Vector3 localPlayerPosition = _clientState.LocalPlayer?.Position ?? Vector3.Zero; if ((localPlayerPosition - Destination.Position).Length() < Destination.StopDistance) { diff --git a/Questionable/Controller/Steps/BaseFactory/SkipCondition.cs b/Questionable/Controller/Steps/BaseFactory/SkipCondition.cs index f025a622c..b7fa8e40d 100644 --- a/Questionable/Controller/Steps/BaseFactory/SkipCondition.cs +++ b/Questionable/Controller/Steps/BaseFactory/SkipCondition.cs @@ -76,7 +76,7 @@ internal static class SkipCondition } QuestWork? questWork = gameFunctions.GetQuestEx(QuestId); - if (questWork != null && Step.MatchesQuestVariables(questWork.Value)) + if (questWork != null && Step.MatchesQuestVariables(questWork.Value, true)) { logger.LogInformation("Skipping step, as quest variables match"); return true; diff --git a/Questionable/Controller/Steps/BaseFactory/WaitAtEnd.cs b/Questionable/Controller/Steps/BaseFactory/WaitAtEnd.cs index 91a43e262..22d14d666 100644 --- a/Questionable/Controller/Steps/BaseFactory/WaitAtEnd.cs +++ b/Questionable/Controller/Steps/BaseFactory/WaitAtEnd.cs @@ -18,7 +18,7 @@ internal static class WaitAtEnd { public IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) { - if (step.CompletionQuestVariablesFlags.Count == 6) + if (step.CompletionQuestVariablesFlags.Count == 6 && step.CompletionQuestVariablesFlags.Any(x => x is > 0)) { var task = serviceProvider.GetRequiredService() .With(quest, step); @@ -129,7 +129,7 @@ internal static class WaitAtEnd public ETaskResult Update() { QuestWork? questWork = gameFunctions.GetQuestEx(Quest.QuestId); - return questWork != null && Step.MatchesQuestVariables(questWork.Value) + return questWork != null && Step.MatchesQuestVariables(questWork.Value, false) ? ETaskResult.TaskComplete : ETaskResult.StillRunning; } diff --git a/Questionable/GameFunctions.cs b/Questionable/GameFunctions.cs index f9bb1183f..4542b5a04 100644 --- a/Questionable/GameFunctions.cs +++ b/Questionable/GameFunctions.cs @@ -534,9 +534,7 @@ internal sealed unsafe class GameFunctions public bool IsOccupied() { - if (_gameGui.TryGetAddonByName("FadeMiddle", out AtkUnitBase* fade) && - LAddon.IsAddonReady(fade) && - fade->IsVisible) + if (IsLoadingScreenVisible()) return true; return _condition[ConditionFlag.Occupied] || _condition[ConditionFlag.Occupied30] || @@ -546,4 +544,11 @@ internal sealed unsafe class GameFunctions _condition[ConditionFlag.Casting] || _condition[ConditionFlag.Unknown57] || _condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51]; } + + public bool IsLoadingScreenVisible() + { + return _gameGui.TryGetAddonByName("FadeMiddle", out AtkUnitBase* fade) && + LAddon.IsAddonReady(fade) && + fade->IsVisible; + } } diff --git a/Questionable/Model/V1/QuestStep.cs b/Questionable/Model/V1/QuestStep.cs index 31013f2ce..44e3ce446 100644 --- a/Questionable/Model/V1/QuestStep.cs +++ b/Questionable/Model/V1/QuestStep.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Text.Json.Serialization; @@ -50,7 +51,11 @@ internal sealed class QuestStep public IList CompletionQuestVariablesFlags { get; set; } = new List(); public IList DialogueChoices { get; set; } = new List(); - public unsafe bool MatchesQuestVariables(QuestWork questWork) + /// + /// Positive values: Must be set to this value; will wait for the step to have these set. + /// Negative values: Will skip if set to this value, won't wait for this to be set. + /// + public unsafe bool MatchesQuestVariables(QuestWork questWork, bool forSkip) { if (CompletionQuestVariablesFlags.Count != 6) return false; @@ -62,11 +67,19 @@ internal sealed class QuestStep continue; byte actualValue = questWork.Variables[i]; - byte expectedValue = check > 0 ? (byte)check : (byte)0; byte checkByte = check > 0 ? (byte)check : (byte)-check; - - if ((actualValue & checkByte) != expectedValue) - return false; + if (forSkip) + { + byte expectedValue = (byte)Math.Abs(check.Value); + if ((actualValue & checkByte) != expectedValue) + return false; + } + else if (!forSkip && check > 0) + { + byte expectedValue = check > 0 ? (byte)check : (byte)0; + if ((actualValue & checkByte) != expectedValue) + return false; + } } return true; diff --git a/Questionable/Questionable.csproj b/Questionable/Questionable.csproj index e4675d69e..dc5c89b7f 100644 --- a/Questionable/Questionable.csproj +++ b/Questionable/Questionable.csproj @@ -1,7 +1,7 @@  net8.0-windows - 0.8 + 0.9 12 enable true