},
"TerritoryId": 958,
"InteractionType": "Interact",
- "Mount": false,
- "Comment": "TODO Should cancel Navmesh on fade out"
+ "Mount": false
}
]
},
internal sealed class AdvancedConfiguration
{
+ public bool DebugOverlay { get; set; }
public bool NeverFly { get; set; }
}
}
private readonly MovementController _movementController;
private readonly NavigationShortcutController _navigationShortcutController;
private readonly WindowSystem _windowSystem;
- private readonly DebugWindow _debugWindow;
+ private readonly QuestWindow _questWindow;
private readonly ConfigWindow _configWindow;
public DalamudInitializer(DalamudPluginInterface pluginInterface, IFramework framework,
ICommandManager commandManager, QuestController questController, MovementController movementController,
GameUiController gameUiController, NavigationShortcutController navigationShortcutController,
- WindowSystem windowSystem, DebugWindow debugWindow, ConfigWindow configWindow)
+ WindowSystem windowSystem, QuestWindow questWindow, DebugOverlay debugOverlay, ConfigWindow configWindow)
{
_pluginInterface = pluginInterface;
_framework = framework;
_movementController = movementController;
_navigationShortcutController = navigationShortcutController;
_windowSystem = windowSystem;
- _debugWindow = debugWindow;
+ _questWindow = questWindow;
_configWindow = configWindow;
- _windowSystem.AddWindow(debugWindow);
+ _windowSystem.AddWindow(questWindow);
_windowSystem.AddWindow(configWindow);
+ _windowSystem.AddWindow(debugOverlay);
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
- _pluginInterface.UiBuilder.OpenMainUi += _debugWindow.Toggle;
+ _pluginInterface.UiBuilder.OpenMainUi += _questWindow.Toggle;
_pluginInterface.UiBuilder.OpenConfigUi += _configWindow.Toggle;
_framework.Update += FrameworkUpdate;
_commandManager.AddHandler("/qst", new CommandInfo(ProcessCommand)
if (arguments is "c" or "config")
_configWindow.Toggle();
else
- _debugWindow.Toggle();
+ _questWindow.Toggle();
}
public void Dispose()
{
_commandManager.RemoveHandler("/qst");
_framework.Update -= FrameworkUpdate;
- _pluginInterface.UiBuilder.OpenMainUi -= _debugWindow.Toggle;
+ _pluginInterface.UiBuilder.OpenMainUi -= _questWindow.Toggle;
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
_windowSystem.RemoveAllWindows();
serviceCollection.AddTaskWithFactory<AetheryteShortcut.Factory, AetheryteShortcut.UseAetheryteShortcut>();
serviceCollection.AddTaskWithFactory<SkipCondition.Factory, SkipCondition.CheckTask>();
serviceCollection.AddTaskWithFactory<AethernetShortcut.Factory, AethernetShortcut.UseAethernetShortcut>();
+ serviceCollection.AddTaskWithFactory<WaitAtStart.Factory, WaitAtStart.WaitDelay>();
serviceCollection.AddTaskWithFactory<Move.Factory, Move.MoveInternal, Move.ExpectToBeNearDataId>();
serviceCollection.AddTransient<Move.MoveBuilder>();
serviceCollection.AddSingleton<GameUiController>();
serviceCollection.AddSingleton<NavigationShortcutController>();
- serviceCollection.AddSingleton<DebugWindow>();
+ serviceCollection.AddSingleton<QuestWindow>();
serviceCollection.AddSingleton<ConfigWindow>();
+ serviceCollection.AddSingleton<DebugOverlay>();
serviceCollection.AddSingleton<DalamudInitializer>();
_serviceProvider = serviceCollection.BuildServiceProvider();
_serviceProvider.GetRequiredService<QuestRegistry>().Reload();
- _serviceProvider.GetRequiredService<DebugWindow>();
+ _serviceProvider.GetRequiredService<QuestWindow>();
_serviceProvider.GetRequiredService<DalamudInitializer>();
}
ImGui.Separator();
+ bool debugOverlay = _configuration.Advanced.DebugOverlay;
+ if (ImGui.Checkbox("Enable debug overlay", ref debugOverlay))
+ {
+ _configuration.Advanced.DebugOverlay = debugOverlay;
+ Save();
+ }
+
bool neverFly = _configuration.Advanced.NeverFly;
if (ImGui.Checkbox("Disable flying (even if unlocked for the zone)", ref neverFly))
{
--- /dev/null
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Numerics;
+using Dalamud.Interface.Utility;
+using Dalamud.Interface.Windowing;
+using Dalamud.Plugin.Services;
+using ImGuiNET;
+using Questionable.Controller;
+using Questionable.Model.V1;
+
+namespace Questionable.Windows;
+
+internal sealed class DebugOverlay : Window
+{
+ private readonly QuestController _questController;
+ private readonly IGameGui _gameGui;
+ private readonly Configuration _configuration;
+
+ public DebugOverlay(QuestController questController, IGameGui gameGui, Configuration configuration)
+ : base("Questionable Debug Overlay###QuestionableDebugOverlay",
+ ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoBackground |
+ ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoSavedSettings, true)
+ {
+ _questController = questController;
+ _gameGui = gameGui;
+ _configuration = configuration;
+
+ Position = Vector2.Zero;
+ PositionCondition = ImGuiCond.Always;
+ Size = ImGui.GetIO().DisplaySize;
+ SizeCondition = ImGuiCond.Always;
+ IsOpen = true;
+ }
+
+ public override bool DrawConditions() => _configuration.Advanced.DebugOverlay;
+
+ public override void PreDraw()
+ {
+ Size = ImGui.GetIO().DisplaySize;
+ }
+
+ public override void Draw()
+ {
+ var currentQuest = _questController.CurrentQuest;
+ if (currentQuest == null)
+ return;
+
+ var sequence = currentQuest.Quest.FindSequence(currentQuest.Sequence);
+ if (sequence == null)
+ return;
+
+ for (int i = currentQuest.Step; i <= sequence.Steps.Count; ++i)
+ {
+ QuestStep? step = sequence.FindStep(i);
+ if (step == null || step.Position == null)
+ continue;
+
+ bool visible = _gameGui.WorldToScreen(step.Position.Value, out Vector2 screenPos);
+ if (!visible)
+ continue;
+
+ ImGui.GetWindowDrawList().AddCircleFilled(screenPos, 3f, 0xFF0000FF);
+ ImGui.GetWindowDrawList().AddText(screenPos + new Vector2(10, -8), 0xFF0000FF,
+ $"{i}: {step.InteractionType}\n{step.Position.Value.ToString("G", CultureInfo.InvariantCulture)}\n{step.Comment}");
+ }
+ }
+}
+++ /dev/null
-using System;
-using System.Diagnostics;
-using System.Globalization;
-using System.Linq;
-using System.Numerics;
-using Dalamud.Game.ClientState.Objects;
-using Dalamud.Interface;
-using Dalamud.Interface.Colors;
-using Dalamud.Interface.Components;
-using Dalamud.Plugin;
-using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Client.Game;
-using FFXIVClientStructs.FFXIV.Client.Game.Control;
-using FFXIVClientStructs.FFXIV.Client.Game.Object;
-using FFXIVClientStructs.FFXIV.Client.UI.Agent;
-using ImGuiNET;
-using LLib.ImGui;
-using Microsoft.Extensions.Logging;
-using Questionable.Controller;
-using Questionable.Controller.Steps.BaseFactory;
-using Questionable.External;
-using Questionable.Model;
-using Questionable.Model.V1;
-
-namespace Questionable.Windows;
-
-internal sealed class DebugWindow : LWindow, IPersistableWindowConfig
-{
- private readonly DalamudPluginInterface _pluginInterface;
- private readonly MovementController _movementController;
- private readonly QuestController _questController;
- private readonly GameFunctions _gameFunctions;
- private readonly IClientState _clientState;
- private readonly IFramework _framework;
- private readonly ITargetManager _targetManager;
- private readonly GameUiController _gameUiController;
- private readonly Configuration _configuration;
- private readonly NavmeshIpc _navmeshIpc;
- private readonly ILogger<DebugWindow> _logger;
-
- public DebugWindow(DalamudPluginInterface pluginInterface,
- MovementController movementController,
- QuestController questController,
- GameFunctions gameFunctions,
- IClientState clientState,
- IFramework framework,
- ITargetManager targetManager,
- GameUiController gameUiController,
- Configuration configuration,
- NavmeshIpc navmeshIpc,
- ILogger<DebugWindow> logger)
- : base("Questionable", ImGuiWindowFlags.AlwaysAutoResize)
- {
- _pluginInterface = pluginInterface;
- _movementController = movementController;
- _questController = questController;
- _gameFunctions = gameFunctions;
- _clientState = clientState;
- _framework = framework;
- _targetManager = targetManager;
- _gameUiController = gameUiController;
- _configuration = configuration;
- _navmeshIpc = navmeshIpc;
- _logger = logger;
-
-#if DEBUG
- IsOpen = true;
-#endif
- SizeConstraints = new WindowSizeConstraints
- {
- MinimumSize = new Vector2(200, 30),
- MaximumSize = default
- };
- RespectCloseHotkey = false;
- }
-
- public WindowConfig WindowConfig => _configuration.DebugWindowConfig;
-
- public void SaveWindowConfig() => _pluginInterface.SavePluginConfig(_configuration);
-
- public override bool DrawConditions()
- {
- if (!_clientState.IsLoggedIn || _clientState.LocalPlayer == null)
- return false;
-
- var currentQuest = _questController.CurrentQuest;
- return currentQuest == null || !currentQuest.Quest.Data.TerritoryBlacklist.Contains(_clientState.TerritoryType);
- }
-
- public override void Draw()
- {
- DrawQuest();
- ImGui.Separator();
-
- DrawCreationUtils();
- ImGui.Separator();
-
- DrawQuickAccessButtons();
- DrawRemainingTasks();
- }
-
- private unsafe void DrawQuest()
- {
- var currentQuest = _questController.CurrentQuest;
- if (currentQuest != null)
- {
- ImGui.TextUnformatted($"Quest: {currentQuest.Quest.Name} / {currentQuest.Sequence} / {currentQuest.Step}");
-
- ImGui.BeginDisabled();
- var questWork = _gameFunctions.GetQuestEx(currentQuest.Quest.QuestId);
- if (questWork != null)
- {
- var qw = questWork.Value;
- string vars = "";
- for (int i = 0; i < 6; ++i)
- {
- vars += qw.Variables[i] + " ";
- if (i % 2 == 1)
- vars += " ";
- }
-
- // For combat quests, a sequence to kill 3 enemies works a bit like this:
- // Trigger enemies → 0
- // Kill first enemy → 1
- // Kill second enemy → 2
- // Last enemy → increase sequence, reset variable to 0
- // The order in which enemies are killed doesn't seem to matter.
- // If multiple waves spawn, this continues to count up (e.g. 1 enemy from wave 1, 2 enemies from wave 2, 1 from wave 3) would count to 3 then 0
- ImGui.Text($"QW: {vars.Trim()}");
- }
- else
- ImGui.TextUnformatted("(Not accepted)");
-
- ImGui.TextUnformatted(_questController.DebugState ?? "--");
- ImGui.EndDisabled();
- ImGui.TextUnformatted(_questController.Comment ?? "--");
-
- //var nextStep = _questController.GetNextStep();
- //ImGui.BeginDisabled(nextStep.Step == null);
- ImGui.Text(_questController.ToStatString());
- //ImGui.EndDisabled();
-
- ImGui.BeginDisabled(_questController.IsRunning);
- if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
- {
- _questController.ExecuteNextStep(true);
- }
-
- ImGui.SameLine();
-
- if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.StepForward, "Step"))
- {
- _questController.ExecuteNextStep(false);
- }
-
- ImGui.EndDisabled();
- ImGui.SameLine();
-
- if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop))
- {
- _movementController.Stop();
- _questController.Stop("Manual");
- }
-
- QuestStep? currentStep = currentQuest.Quest
- .FindSequence(currentQuest.Sequence)
- ?.FindStep(currentQuest.Step);
- bool lastStep = currentStep ==
- currentQuest.Quest.FindSequence(currentQuest.Sequence)?.Steps.LastOrDefault();
- bool colored = currentStep != null
- && !lastStep
- && currentStep.InteractionType == EInteractionType.Instruction
- && _questController.HasCurrentTaskMatching<WaitAtEnd.WaitNextStepOrSequence>();
-
- ImGui.BeginDisabled(lastStep);
- if (colored)
- ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen);
- if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ArrowCircleRight, "Skip"))
- {
- _movementController.Stop();
- _questController.Skip(currentQuest.Quest.QuestId, currentQuest.Sequence);
- }
-
- if (colored)
- ImGui.PopStyleColor();
- ImGui.EndDisabled();
-
- bool autoAcceptNextQuest = _configuration.General.AutoAcceptNextQuest;
- if (ImGui.Checkbox("Automatically accept next quest", ref autoAcceptNextQuest))
- {
- _configuration.General.AutoAcceptNextQuest = autoAcceptNextQuest;
- _pluginInterface.SavePluginConfig(_configuration);
- }
- }
- else
- ImGui.Text("No active quest");
- }
-
- private unsafe void DrawCreationUtils()
- {
- Debug.Assert(_clientState.LocalPlayer != null, "_clientState.LocalPlayer != null");
-
- ImGui.Text(
- $"Current TerritoryId: {_clientState.TerritoryType}, Flying: {(_gameFunctions.IsFlyingUnlockedInCurrentZone() ? "Yes" : "No")}");
-
- var q = _gameFunctions.GetCurrentQuest();
- ImGui.Text($"Current Quest: {q.CurrentQuest} → {q.Sequence}");
-
- var questManager = QuestManager.Instance();
- if (questManager != null)
- {
- // unsure how these are sorted
- for (int i = 0; i < 1 /*questManager->TrackedQuestsSpan.Length*/; ++i)
- {
- var trackedQuest = questManager->TrackedQuestsSpan[i];
- switch (trackedQuest.QuestType)
- {
- default:
- ImGui.Text($"Tracked quest {i}: {trackedQuest.QuestType}, {trackedQuest.Index}");
- break;
-
- case 1:
- ImGui.Text(
- $"Tracked quest: {questManager->NormalQuestsSpan[trackedQuest.Index].QuestId}, {trackedQuest.Index}");
- break;
- }
- }
- }
-
-
- if (_targetManager.Target != null)
- {
- ImGui.Separator();
- ImGui.Text(string.Create(CultureInfo.InvariantCulture,
- $"Target: {_targetManager.Target.Name} ({_targetManager.Target.ObjectKind}; {_targetManager.Target.DataId})"));
-
- GameObject* gameObject = (GameObject*)_targetManager.Target.Address;
- ImGui.Text(string.Create(CultureInfo.InvariantCulture,
- $"Distance: {(_targetManager.Target.Position - _clientState.LocalPlayer.Position).Length():F2}, Y: {_targetManager.Target.Position.Y - _clientState.LocalPlayer.Position.Y:F2} | QM: {gameObject->NamePlateIconId}"));
-
- ImGui.BeginDisabled(!_movementController.IsNavmeshReady);
- if (!_movementController.IsPathfinding)
- {
- if (ImGui.Button("Move to Target"))
- {
- _movementController.NavigateTo(EMovementType.DebugWindow, _targetManager.Target.DataId,
- _targetManager.Target.Position, _gameFunctions.IsFlyingUnlockedInCurrentZone(),
- true);
- }
- }
- else
- {
- if (ImGui.Button("Cancel pathfinding"))
- _movementController.ResetPathfinding();
- }
-
- ImGui.EndDisabled();
-
- ImGui.SameLine();
- if (ImGui.Button("Interact"))
- {
- ulong result = TargetSystem.Instance()->InteractWithObject(
- (GameObject*)_targetManager.Target.Address, false);
- _logger.LogInformation("XXXXX Interaction Result: {Result}", result);
- }
-
- ImGui.SameLine();
-
- ImGui.Button("Copy");
- if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
- {
- ImGui.SetClipboardText($$"""
- "DataId": {{_targetManager.Target.DataId}},
- "Position": {
- "X": {{_targetManager.Target.Position.X.ToString(CultureInfo.InvariantCulture)}},
- "Y": {{_targetManager.Target.Position.Y.ToString(CultureInfo.InvariantCulture)}},
- "Z": {{_targetManager.Target.Position.Z.ToString(CultureInfo.InvariantCulture)}}
- },
- "TerritoryId": {{_clientState.TerritoryType}},
- "InteractionType": "Interact"
- """);
- }
- else if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
- {
- EAetheryteLocation location = (EAetheryteLocation)_targetManager.Target.DataId;
- ImGui.SetClipboardText(string.Create(CultureInfo.InvariantCulture,
- $"{{EAetheryteLocation.{location}, new({_targetManager.Target.Position.X}f, {_targetManager.Target.Position.Y}f, {_targetManager.Target.Position.Z}f)}},"));
- }
- }
- else
- {
- ImGui.Button($"Copy");
- if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
- {
- ImGui.SetClipboardText($$"""
- "Position": {
- "X": {{_clientState.LocalPlayer.Position.X.ToString(CultureInfo.InvariantCulture)}},
- "Y": {{_clientState.LocalPlayer.Position.Y.ToString(CultureInfo.InvariantCulture)}},
- "Z": {{_clientState.LocalPlayer.Position.Z.ToString(CultureInfo.InvariantCulture)}}
- },
- "TerritoryId": {{_clientState.TerritoryType}},
- "InteractionType": ""
- """);
- }
- else if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
- {
- Vector3 position = _clientState.LocalPlayer!.Position;
- ImGui.SetClipboardText(string.Create(CultureInfo.InvariantCulture,
- $"new({position.X}f, {position.Y}f, {position.Z}f)"));
- }
- }
- }
-
- private unsafe void DrawQuickAccessButtons()
- {
- var map = AgentMap.Instance();
- ImGui.BeginDisabled(map == null || map->IsFlagMarkerSet == 0 ||
- map->FlagMapMarker.TerritoryId != _clientState.TerritoryType ||
- !_navmeshIpc.IsReady);
- if (ImGui.Button("Move to Flag"))
- {
- _movementController.Destination = null;
- _gameFunctions.ExecuteCommand(
- $"/vnav {(_gameFunctions.IsFlyingUnlockedInCurrentZone() ? "flyflag" : "moveflag")}");
- }
-
- ImGui.EndDisabled();
-
- ImGui.SameLine();
-
- ImGui.BeginDisabled(!_movementController.IsPathRunning);
- if (ImGui.Button("Stop Nav"))
- {
- _movementController.Stop();
- _questController.Stop("Manual");
- }
-
- ImGui.EndDisabled();
-
- if (ImGui.Button("Reload Data"))
- {
- _questController.Reload();
- _framework.RunOnTick(() => _gameUiController.HandleCurrentDialogueChoices(),
- TimeSpan.FromMilliseconds(200));
- }
- }
-
- private void DrawRemainingTasks()
- {
- var remainingTasks = _questController.GetRemainingTaskNames();
- if (remainingTasks.Count > 0)
- {
- ImGui.Separator();
- ImGui.BeginDisabled();
- foreach (var task in remainingTasks)
- ImGui.TextUnformatted(task);
- ImGui.EndDisabled();
- }
- }
-}
--- /dev/null
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Numerics;
+using Dalamud.Game.ClientState.Objects;
+using Dalamud.Interface;
+using Dalamud.Interface.Colors;
+using Dalamud.Interface.Components;
+using Dalamud.Plugin;
+using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Client.Game;
+using FFXIVClientStructs.FFXIV.Client.Game.Control;
+using FFXIVClientStructs.FFXIV.Client.Game.Object;
+using FFXIVClientStructs.FFXIV.Client.UI.Agent;
+using ImGuiNET;
+using LLib.ImGui;
+using Microsoft.Extensions.Logging;
+using Questionable.Controller;
+using Questionable.Controller.Steps.BaseFactory;
+using Questionable.External;
+using Questionable.Model;
+using Questionable.Model.V1;
+
+namespace Questionable.Windows;
+
+internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
+{
+ private readonly DalamudPluginInterface _pluginInterface;
+ private readonly MovementController _movementController;
+ private readonly QuestController _questController;
+ private readonly GameFunctions _gameFunctions;
+ private readonly IClientState _clientState;
+ private readonly IFramework _framework;
+ private readonly ITargetManager _targetManager;
+ private readonly GameUiController _gameUiController;
+ private readonly Configuration _configuration;
+ private readonly NavmeshIpc _navmeshIpc;
+ private readonly ILogger<QuestWindow> _logger;
+
+ public QuestWindow(DalamudPluginInterface pluginInterface,
+ MovementController movementController,
+ QuestController questController,
+ GameFunctions gameFunctions,
+ IClientState clientState,
+ IFramework framework,
+ ITargetManager targetManager,
+ GameUiController gameUiController,
+ Configuration configuration,
+ NavmeshIpc navmeshIpc,
+ ILogger<QuestWindow> logger)
+ : base("Questionable###Questionable", ImGuiWindowFlags.AlwaysAutoResize)
+ {
+ _pluginInterface = pluginInterface;
+ _movementController = movementController;
+ _questController = questController;
+ _gameFunctions = gameFunctions;
+ _clientState = clientState;
+ _framework = framework;
+ _targetManager = targetManager;
+ _gameUiController = gameUiController;
+ _configuration = configuration;
+ _navmeshIpc = navmeshIpc;
+ _logger = logger;
+
+#if DEBUG
+ IsOpen = true;
+#endif
+ SizeConstraints = new WindowSizeConstraints
+ {
+ MinimumSize = new Vector2(200, 30),
+ MaximumSize = default
+ };
+ RespectCloseHotkey = false;
+ }
+
+ public WindowConfig WindowConfig => _configuration.DebugWindowConfig;
+
+ public void SaveWindowConfig() => _pluginInterface.SavePluginConfig(_configuration);
+
+ public override bool DrawConditions()
+ {
+ if (!_clientState.IsLoggedIn || _clientState.LocalPlayer == null)
+ return false;
+
+ var currentQuest = _questController.CurrentQuest;
+ return currentQuest == null || !currentQuest.Quest.Data.TerritoryBlacklist.Contains(_clientState.TerritoryType);
+ }
+
+ public override void Draw()
+ {
+ DrawQuest();
+ ImGui.Separator();
+
+ DrawCreationUtils();
+ ImGui.Separator();
+
+ DrawQuickAccessButtons();
+ DrawRemainingTasks();
+ }
+
+ private unsafe void DrawQuest()
+ {
+ var currentQuest = _questController.CurrentQuest;
+ if (currentQuest != null)
+ {
+ ImGui.TextUnformatted($"Quest: {currentQuest.Quest.Name} / {currentQuest.Sequence} / {currentQuest.Step}");
+
+ ImGui.BeginDisabled();
+ var questWork = _gameFunctions.GetQuestEx(currentQuest.Quest.QuestId);
+ if (questWork != null)
+ {
+ var qw = questWork.Value;
+ string vars = "";
+ for (int i = 0; i < 6; ++i)
+ {
+ vars += qw.Variables[i] + " ";
+ if (i % 2 == 1)
+ vars += " ";
+ }
+
+ // For combat quests, a sequence to kill 3 enemies works a bit like this:
+ // Trigger enemies → 0
+ // Kill first enemy → 1
+ // Kill second enemy → 2
+ // Last enemy → increase sequence, reset variable to 0
+ // The order in which enemies are killed doesn't seem to matter.
+ // If multiple waves spawn, this continues to count up (e.g. 1 enemy from wave 1, 2 enemies from wave 2, 1 from wave 3) would count to 3 then 0
+ ImGui.Text($"QW: {vars.Trim()}");
+ }
+ else
+ ImGui.TextUnformatted("(Not accepted)");
+
+ ImGui.TextUnformatted(_questController.DebugState ?? "--");
+ ImGui.EndDisabled();
+ ImGui.TextUnformatted(_questController.Comment ?? "--");
+
+ //var nextStep = _questController.GetNextStep();
+ //ImGui.BeginDisabled(nextStep.Step == null);
+ ImGui.Text(_questController.ToStatString());
+ //ImGui.EndDisabled();
+
+ ImGui.BeginDisabled(_questController.IsRunning);
+ if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
+ {
+ _questController.ExecuteNextStep(true);
+ }
+
+ ImGui.SameLine();
+
+ if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.StepForward, "Step"))
+ {
+ _questController.ExecuteNextStep(false);
+ }
+
+ ImGui.EndDisabled();
+ ImGui.SameLine();
+
+ if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop))
+ {
+ _movementController.Stop();
+ _questController.Stop("Manual");
+ }
+
+ QuestStep? currentStep = currentQuest.Quest
+ .FindSequence(currentQuest.Sequence)
+ ?.FindStep(currentQuest.Step);
+ bool lastStep = currentStep ==
+ currentQuest.Quest.FindSequence(currentQuest.Sequence)?.Steps.LastOrDefault();
+ bool colored = currentStep != null
+ && !lastStep
+ && currentStep.InteractionType == EInteractionType.Instruction
+ && _questController.HasCurrentTaskMatching<WaitAtEnd.WaitNextStepOrSequence>();
+
+ ImGui.BeginDisabled(lastStep);
+ if (colored)
+ ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen);
+ if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ArrowCircleRight, "Skip"))
+ {
+ _movementController.Stop();
+ _questController.Skip(currentQuest.Quest.QuestId, currentQuest.Sequence);
+ }
+
+ if (colored)
+ ImGui.PopStyleColor();
+ ImGui.EndDisabled();
+
+ bool autoAcceptNextQuest = _configuration.General.AutoAcceptNextQuest;
+ if (ImGui.Checkbox("Automatically accept next quest", ref autoAcceptNextQuest))
+ {
+ _configuration.General.AutoAcceptNextQuest = autoAcceptNextQuest;
+ _pluginInterface.SavePluginConfig(_configuration);
+ }
+ }
+ else
+ ImGui.Text("No active quest");
+ }
+
+ private unsafe void DrawCreationUtils()
+ {
+ Debug.Assert(_clientState.LocalPlayer != null, "_clientState.LocalPlayer != null");
+
+ ImGui.Text(
+ $"Current TerritoryId: {_clientState.TerritoryType}, Flying: {(_gameFunctions.IsFlyingUnlockedInCurrentZone() ? "Yes" : "No")}");
+
+ var q = _gameFunctions.GetCurrentQuest();
+ ImGui.Text($"Current Quest: {q.CurrentQuest} → {q.Sequence}");
+
+ var questManager = QuestManager.Instance();
+ if (questManager != null)
+ {
+ // unsure how these are sorted
+ for (int i = 0; i < 1 /*questManager->TrackedQuestsSpan.Length*/; ++i)
+ {
+ var trackedQuest = questManager->TrackedQuestsSpan[i];
+ switch (trackedQuest.QuestType)
+ {
+ default:
+ ImGui.Text($"Tracked quest {i}: {trackedQuest.QuestType}, {trackedQuest.Index}");
+ break;
+
+ case 1:
+ ImGui.Text(
+ $"Tracked quest: {questManager->NormalQuestsSpan[trackedQuest.Index].QuestId}, {trackedQuest.Index}");
+ break;
+ }
+ }
+ }
+
+
+ if (_targetManager.Target != null)
+ {
+ ImGui.Separator();
+ ImGui.Text(string.Create(CultureInfo.InvariantCulture,
+ $"Target: {_targetManager.Target.Name} ({_targetManager.Target.ObjectKind}; {_targetManager.Target.DataId})"));
+
+ GameObject* gameObject = (GameObject*)_targetManager.Target.Address;
+ ImGui.Text(string.Create(CultureInfo.InvariantCulture,
+ $"Distance: {(_targetManager.Target.Position - _clientState.LocalPlayer.Position).Length():F2}, Y: {_targetManager.Target.Position.Y - _clientState.LocalPlayer.Position.Y:F2} | QM: {gameObject->NamePlateIconId}"));
+
+ ImGui.BeginDisabled(!_movementController.IsNavmeshReady);
+ if (!_movementController.IsPathfinding)
+ {
+ if (ImGui.Button("Move to Target"))
+ {
+ _movementController.NavigateTo(EMovementType.DebugWindow, _targetManager.Target.DataId,
+ _targetManager.Target.Position, _gameFunctions.IsFlyingUnlockedInCurrentZone(),
+ true);
+ }
+ }
+ else
+ {
+ if (ImGui.Button("Cancel pathfinding"))
+ _movementController.ResetPathfinding();
+ }
+
+ ImGui.EndDisabled();
+
+ ImGui.SameLine();
+ if (ImGui.Button("Interact"))
+ {
+ ulong result = TargetSystem.Instance()->InteractWithObject(
+ (GameObject*)_targetManager.Target.Address, false);
+ _logger.LogInformation("XXXXX Interaction Result: {Result}", result);
+ }
+
+ ImGui.SameLine();
+
+ ImGui.Button("Copy");
+ if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
+ {
+ ImGui.SetClipboardText($$"""
+ "DataId": {{_targetManager.Target.DataId}},
+ "Position": {
+ "X": {{_targetManager.Target.Position.X.ToString(CultureInfo.InvariantCulture)}},
+ "Y": {{_targetManager.Target.Position.Y.ToString(CultureInfo.InvariantCulture)}},
+ "Z": {{_targetManager.Target.Position.Z.ToString(CultureInfo.InvariantCulture)}}
+ },
+ "TerritoryId": {{_clientState.TerritoryType}},
+ "InteractionType": "Interact"
+ """);
+ }
+ else if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
+ {
+ EAetheryteLocation location = (EAetheryteLocation)_targetManager.Target.DataId;
+ ImGui.SetClipboardText(string.Create(CultureInfo.InvariantCulture,
+ $"{{EAetheryteLocation.{location}, new({_targetManager.Target.Position.X}f, {_targetManager.Target.Position.Y}f, {_targetManager.Target.Position.Z}f)}},"));
+ }
+ }
+ else
+ {
+ ImGui.Button($"Copy");
+ if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
+ {
+ ImGui.SetClipboardText($$"""
+ "Position": {
+ "X": {{_clientState.LocalPlayer.Position.X.ToString(CultureInfo.InvariantCulture)}},
+ "Y": {{_clientState.LocalPlayer.Position.Y.ToString(CultureInfo.InvariantCulture)}},
+ "Z": {{_clientState.LocalPlayer.Position.Z.ToString(CultureInfo.InvariantCulture)}}
+ },
+ "TerritoryId": {{_clientState.TerritoryType}},
+ "InteractionType": ""
+ """);
+ }
+ else if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
+ {
+ Vector3 position = _clientState.LocalPlayer!.Position;
+ ImGui.SetClipboardText(string.Create(CultureInfo.InvariantCulture,
+ $"new({position.X}f, {position.Y}f, {position.Z}f)"));
+ }
+ }
+ }
+
+ private unsafe void DrawQuickAccessButtons()
+ {
+ var map = AgentMap.Instance();
+ ImGui.BeginDisabled(map == null || map->IsFlagMarkerSet == 0 ||
+ map->FlagMapMarker.TerritoryId != _clientState.TerritoryType ||
+ !_navmeshIpc.IsReady);
+ if (ImGui.Button("Move to Flag"))
+ {
+ _movementController.Destination = null;
+ _gameFunctions.ExecuteCommand(
+ $"/vnav {(_gameFunctions.IsFlyingUnlockedInCurrentZone() ? "flyflag" : "moveflag")}");
+ }
+
+ ImGui.EndDisabled();
+
+ ImGui.SameLine();
+
+ ImGui.BeginDisabled(!_movementController.IsPathRunning);
+ if (ImGui.Button("Stop Nav"))
+ {
+ _movementController.Stop();
+ _questController.Stop("Manual");
+ }
+
+ ImGui.EndDisabled();
+
+ if (ImGui.Button("Reload Data"))
+ {
+ _questController.Reload();
+ _framework.RunOnTick(() => _gameUiController.HandleCurrentDialogueChoices(),
+ TimeSpan.FromMilliseconds(200));
+ }
+ }
+
+ private void DrawRemainingTasks()
+ {
+ var remainingTasks = _questController.GetRemainingTaskNames();
+ if (remainingTasks.Count > 0)
+ {
+ ImGui.Separator();
+ ImGui.BeginDisabled();
+ foreach (var task in remainingTasks)
+ ImGui.TextUnformatted(task);
+ ImGui.EndDisabled();
+ }
+ }
+}