Add experimental navmesh path replay (mostly for finding stuck places)
This commit is contained in:
parent
069833a8f8
commit
0bd15c03f5
@ -263,6 +263,16 @@
|
||||
{
|
||||
"Sequence": 5,
|
||||
"Steps": [
|
||||
{
|
||||
"Position": {
|
||||
"X": -136.90475,
|
||||
"Y": -215.01514,
|
||||
"Z": 330.17505
|
||||
},
|
||||
"TerritoryId": 1189,
|
||||
"InteractionType": "WalkTo",
|
||||
"Mount": true
|
||||
},
|
||||
{
|
||||
"DataId": 1047669,
|
||||
"Position": {
|
||||
|
@ -53,6 +53,7 @@ internal sealed class QuestController
|
||||
|
||||
|
||||
public QuestProgress? CurrentQuest { get; set; }
|
||||
public SimulationProgress? SimulatedQuest { get; set; }
|
||||
public string? DebugState { get; private set; }
|
||||
public string? Comment { get; private set; }
|
||||
|
||||
@ -110,7 +111,16 @@ internal sealed class QuestController
|
||||
{
|
||||
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)
|
||||
@ -302,6 +312,14 @@ internal sealed class QuestController
|
||||
}
|
||||
}
|
||||
|
||||
public void SimulateQuest(Quest? quest)
|
||||
{
|
||||
if (quest != null)
|
||||
SimulatedQuest = new SimulationProgress(quest, 0);
|
||||
else
|
||||
SimulatedQuest = null;
|
||||
}
|
||||
|
||||
private void UpdateCurrentTask()
|
||||
{
|
||||
if (_gameFunctions.IsOccupied())
|
||||
@ -464,6 +482,8 @@ internal sealed class QuestController
|
||||
}
|
||||
}
|
||||
|
||||
public sealed record SimulationProgress(Quest Quest, byte Sequence);
|
||||
|
||||
public void Skip(ushort questQuestId, byte currentQuestSequence)
|
||||
{
|
||||
lock (_lock)
|
||||
|
@ -6,6 +6,7 @@ using Dalamud.Plugin.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller;
|
||||
using Questionable.Data;
|
||||
using Questionable.Model;
|
||||
using Questionable.Windows;
|
||||
|
||||
namespace Questionable;
|
||||
@ -18,15 +19,18 @@ internal sealed class DalamudInitializer : IDisposable
|
||||
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;
|
||||
@ -34,10 +38,12 @@ internal sealed class DalamudInitializer : IDisposable
|
||||
_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);
|
||||
@ -83,10 +89,46 @@ internal sealed class DalamudInitializer : IDisposable
|
||||
}
|
||||
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();
|
||||
|
@ -8,6 +8,7 @@ using Dalamud.Game.Text;
|
||||
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;
|
||||
@ -202,6 +203,101 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
||||
_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");
|
||||
|
Loading…
Reference in New Issue
Block a user