{
"Sequence": 5,
"Steps": [
+ {
+ "Position": {
+ "X": -136.90475,
+ "Y": -215.01514,
+ "Z": 330.17505
+ },
+ "TerritoryId": 1189,
+ "InteractionType": "WalkTo",
+ "Mount": true
+ },
{
"DataId": 1047669,
"Position": {
public QuestProgress? CurrentQuest { get; set; }
+ public SimulationProgress? SimulatedQuest { get; set; }
public string? DebugState { get; private set; }
public string? Comment { get; private set; }
{
DebugState = null;
- (ushort currentQuestId, byte currentSequence) = _gameFunctions.GetCurrentQuest();
+ ushort currentQuestId;
+ byte currentSequence;
+ if (SimulatedQuest != null)
+ {
+ currentQuestId = SimulatedQuest.Quest.QuestId;
+ currentSequence = SimulatedQuest.Sequence;
+ }
+ else
+ (currentQuestId, currentSequence) = _gameFunctions.GetCurrentQuest();
+
if (currentQuestId == 0)
{
if (CurrentQuest != null)
}
}
+ public void SimulateQuest(Quest? quest)
+ {
+ if (quest != null)
+ SimulatedQuest = new SimulationProgress(quest, 0);
+ else
+ SimulatedQuest = null;
+ }
+
private void UpdateCurrentTask()
{
if (_gameFunctions.IsOccupied())
}
}
+ public sealed record SimulationProgress(Quest Quest, byte Sequence);
+
public void Skip(ushort questQuestId, byte currentQuestSequence)
{
lock (_lock)
using Microsoft.Extensions.Logging;
using Questionable.Controller;
using Questionable.Data;
+using Questionable.Model;
using Questionable.Windows;
namespace Questionable;
private readonly QuestController _questController;
private readonly MovementController _movementController;
private readonly NavigationShortcutController _navigationShortcutController;
+ private readonly IChatGui _chatGui;
private readonly WindowSystem _windowSystem;
private readonly QuestWindow _questWindow;
- private readonly ConfigWindow _configWindow;
private readonly DebugOverlay _debugOverlay;
+ private readonly ConfigWindow _configWindow;
+ private readonly QuestRegistry _questRegistry;
public DalamudInitializer(IDalamudPluginInterface pluginInterface, IFramework framework,
ICommandManager commandManager, QuestController questController, MovementController movementController,
- GameUiController gameUiController, NavigationShortcutController navigationShortcutController,
- WindowSystem windowSystem, QuestWindow questWindow, DebugOverlay debugOverlay, ConfigWindow configWindow)
+ GameUiController gameUiController, NavigationShortcutController navigationShortcutController, IChatGui chatGui,
+ WindowSystem windowSystem, QuestWindow questWindow, DebugOverlay debugOverlay, ConfigWindow configWindow,
+ QuestRegistry questRegistry)
{
_pluginInterface = pluginInterface;
_framework = framework;
_questController = questController;
_movementController = movementController;
_navigationShortcutController = navigationShortcutController;
+ _chatGui = chatGui;
_windowSystem = windowSystem;
_questWindow = questWindow;
- _configWindow = configWindow;
_debugOverlay = debugOverlay;
+ _configWindow = configWindow;
+ _questRegistry = questRegistry;
_windowSystem.AddWindow(questWindow);
_windowSystem.AddWindow(configWindow);
}
else if (arguments.StartsWith("do", StringComparison.Ordinal))
{
+ if (!_debugOverlay.DrawConditions())
+ {
+ _chatGui.PrintError("[Questionable] You don't have the debug overlay enabled.");
+ return;
+ }
+
if (arguments.Length >= 4 && ushort.TryParse(arguments.AsSpan(3), out ushort questId))
- _debugOverlay.HighlightedQuest = questId;
+ {
+ if (_questRegistry.IsKnownQuest(questId))
+ {
+ _debugOverlay.HighlightedQuest = questId;
+ _chatGui.Print($"[Questionable] Set highlighted quest to {questId}.");
+ }
+ else
+ _chatGui.PrintError($"[Questionable] Unknown quest {questId}.");
+ }
else
+ {
_debugOverlay.HighlightedQuest = null;
+ _chatGui.Print("[Questionable] Cleared highlighted quest.");
+ }
+ }
+ else if (arguments.StartsWith("sim", StringComparison.InvariantCulture))
+ {
+ string[] parts = arguments.Split(' ');
+ if (parts.Length == 2 && ushort.TryParse(parts[1], out ushort questId))
+ {
+ if (_questRegistry.TryGetQuest(questId, out Quest? quest))
+ {
+ _questController.SimulateQuest(quest);
+ _chatGui.Print($"[Questionable] Simulating quest {questId}.");
+ }
+ else
+ _chatGui.PrintError($"[Questionable] Unknown quest {questId}.");
+ }
+ else
+ {
+ _questController.SimulateQuest(null);
+ _chatGui.Print("[Questionable] Cleared simulated quest.");
+ }
}
else if (string.IsNullOrEmpty(arguments))
_questWindow.Toggle();
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
+using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
_configuration.General.AutoAcceptNextQuest = autoAcceptNextQuest;
_pluginInterface.SavePluginConfig(_configuration);
}
+
+
+ if (_questController.SimulatedQuest != null)
+ {
+ ImGui.Separator();
+ ImGui.TextColored(ImGuiColors.DalamudRed, "Quest sim active (experimental)");
+ ImGui.Text($"Sequence: {_questController.SimulatedQuest.Sequence}");
+
+ ImGui.BeginDisabled(_questController.SimulatedQuest.Sequence == 0);
+ if (ImGuiComponents.IconButton(FontAwesomeIcon.Minus))
+ {
+ _movementController.Stop();
+ _questController.Stop("Sim-");
+
+ byte oldSequence = _questController.SimulatedQuest.Sequence;
+ byte newSequence = _questController.SimulatedQuest.Quest.Data.QuestSequence
+ .Select(x => (byte)x.Sequence)
+ .LastOrDefault(x => x < oldSequence, byte.MinValue);
+
+ _questController.SimulatedQuest = _questController.SimulatedQuest with
+ {
+ Sequence = newSequence,
+ };
+ }
+
+ ImGui.EndDisabled();
+
+ ImGui.SameLine();
+ ImGui.BeginDisabled(_questController.SimulatedQuest.Sequence >= 255);
+ if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
+ {
+ _movementController.Stop();
+ _questController.Stop("Sim+");
+
+ byte oldSequence = _questController.SimulatedQuest.Sequence;
+ byte newSequence = _questController.SimulatedQuest.Quest.Data.QuestSequence
+ .Select(x => (byte)x.Sequence)
+ .FirstOrDefault(x => x > oldSequence, byte.MaxValue);
+
+ _questController.SimulatedQuest = _questController.SimulatedQuest with
+ {
+ Sequence = newSequence,
+ };
+ }
+
+ ImGui.EndDisabled();
+
+ var simulatedSequence =
+ _questController.SimulatedQuest.Quest.FindSequence(_questController.SimulatedQuest.Sequence);
+ if (simulatedSequence != null)
+ {
+ using var _ = ImRaii.PushId("SimulatedStep");
+
+ ImGui.Text($"Step: {currentQuest.Step} / {simulatedSequence.Steps.Count - 1}");
+
+ ImGui.BeginDisabled(currentQuest.Step == 0);
+ if (ImGuiComponents.IconButton(FontAwesomeIcon.Minus))
+ {
+ _movementController.Stop();
+ _questController.Stop("SimStep-");
+
+ _questController.CurrentQuest = currentQuest with
+ {
+ Step = Math.Min(currentQuest.Step - 1, simulatedSequence.Steps.Count - 1),
+ };
+ }
+
+ ImGui.EndDisabled();
+
+ ImGui.SameLine();
+ ImGui.BeginDisabled(currentQuest.Step >= simulatedSequence.Steps.Count);
+ if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
+ {
+ _movementController.Stop();
+ _questController.Stop("SimStep+");
+
+ _questController.CurrentQuest = currentQuest with
+ {
+ Step = currentQuest.Step == simulatedSequence.Steps.Count - 1
+ ? 255
+ : (currentQuest.Step + 1),
+ };
+ }
+
+ ImGui.EndDisabled();
+
+ if (ImGui.Button("Clear sim"))
+ {
+ _questController.SimulateQuest(null);
+
+ _movementController.Stop();
+ _questController.Stop("ClearSim");
+ }
+ }
+ }
}
else
ImGui.Text("No active quest");