Add mini quest window

This commit is contained in:
Liza 2024-08-10 00:57:09 +02:00
parent 7dc78ed8cb
commit 6f2ca7d438
Signed by: liza
GPG Key ID: 7199F8D727D55F67
4 changed files with 130 additions and 84 deletions

View File

@ -17,7 +17,6 @@ internal sealed class CommandHandler : IDisposable
private readonly IChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly QuestController _questController; private readonly QuestController _questController;
private readonly MovementController _movementController; private readonly MovementController _movementController;
private readonly QuickAccessButtonsComponent _quickAccessButtonsComponent;
private readonly QuestRegistry _questRegistry; private readonly QuestRegistry _questRegistry;
private readonly ConfigWindow _configWindow; private readonly ConfigWindow _configWindow;
private readonly DebugOverlay _debugOverlay; private readonly DebugOverlay _debugOverlay;
@ -31,7 +30,6 @@ internal sealed class CommandHandler : IDisposable
IChatGui chatGui, IChatGui chatGui,
QuestController questController, QuestController questController,
MovementController movementController, MovementController movementController,
QuickAccessButtonsComponent quickAccessButtonsComponent,
QuestRegistry questRegistry, QuestRegistry questRegistry,
ConfigWindow configWindow, ConfigWindow configWindow,
DebugOverlay debugOverlay, DebugOverlay debugOverlay,
@ -44,7 +42,6 @@ internal sealed class CommandHandler : IDisposable
_chatGui = chatGui; _chatGui = chatGui;
_questController = questController; _questController = questController;
_movementController = movementController; _movementController = movementController;
_quickAccessButtonsComponent = quickAccessButtonsComponent;
_questRegistry = questRegistry; _questRegistry = questRegistry;
_configWindow = configWindow; _configWindow = configWindow;
_debugOverlay = debugOverlay; _debugOverlay = debugOverlay;
@ -87,7 +84,7 @@ internal sealed class CommandHandler : IDisposable
break; break;
case "reload": case "reload":
_quickAccessButtonsComponent.Reload(); _questWindow.Reload();
break; break;
case "do": case "do":

View File

@ -56,7 +56,9 @@ internal sealed class ActiveQuestComponent
_chatGui = chatGui; _chatGui = chatGui;
} }
public void Draw() public event EventHandler? Reload;
public void Draw(bool isMinimized)
{ {
var currentQuestDetails = _questController.CurrentQuestDetails; var currentQuestDetails = _questController.CurrentQuestDetails;
QuestController.QuestProgress? currentQuest = currentQuestDetails?.Progress; QuestController.QuestProgress? currentQuest = currentQuestDetails?.Progress;
@ -64,7 +66,7 @@ internal sealed class ActiveQuestComponent
if (currentQuest != null) if (currentQuest != null)
{ {
DrawQuestNames(currentQuest, currentQuestType); DrawQuestNames(currentQuest, currentQuestType);
var questWork = DrawQuestWork(currentQuest); var questWork = DrawQuestWork(currentQuest, isMinimized);
if (_combatController.IsRunning) if (_combatController.IsRunning)
ImGui.TextColored(ImGuiColors.DalamudOrange, "In Combat"); ImGui.TextColored(ImGuiColors.DalamudOrange, "In Combat");
@ -77,28 +79,32 @@ internal sealed class ActiveQuestComponent
QuestSequence? currentSequence = currentQuest.Quest.FindSequence(currentQuest.Sequence); QuestSequence? currentSequence = currentQuest.Quest.FindSequence(currentQuest.Sequence);
QuestStep? currentStep = currentSequence?.FindStep(currentQuest.Step); QuestStep? currentStep = currentSequence?.FindStep(currentQuest.Step);
bool colored = currentStep is if (!isMinimized)
{ InteractionType: EInteractionType.Instruction or EInteractionType.WaitForManualProgress }; {
if (colored) bool colored = currentStep is
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudOrange); { InteractionType: EInteractionType.Instruction or EInteractionType.WaitForManualProgress };
ImGui.TextUnformatted(currentStep?.Comment ?? if (colored)
currentSequence?.Comment ?? currentQuest.Quest.Root.Comment ?? string.Empty); ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudOrange);
if (colored) ImGui.TextUnformatted(currentStep?.Comment ??
ImGui.PopStyleColor(); currentSequence?.Comment ?? currentQuest.Quest.Root.Comment ?? string.Empty);
if (colored)
ImGui.PopStyleColor();
//var nextStep = _questController.GetNextStep(); //var nextStep = _questController.GetNextStep();
//ImGui.BeginDisabled(nextStep.Step == null); //ImGui.BeginDisabled(nextStep.Step == null);
ImGui.Text(_questController.ToStatString()); ImGui.Text(_questController.ToStatString());
//ImGui.EndDisabled(); //ImGui.EndDisabled();
}
DrawQuestButtons(currentQuest, currentStep, questWork); DrawQuestButtons(currentQuest, currentStep, questWork, isMinimized);
DrawSimulationControls(); DrawSimulationControls();
} }
else else
{ {
ImGui.Text("No active quest"); ImGui.Text("No active quest");
ImGui.TextColored(ImGuiColors.DalamudGrey, $"{_questRegistry.Count} quests loaded"); if (!isMinimized)
ImGui.TextColored(ImGuiColors.DalamudGrey, $"{_questRegistry.Count} quests loaded");
if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop)) if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop))
{ {
@ -157,11 +163,16 @@ internal sealed class ActiveQuestComponent
} }
} }
private QuestProgressInfo? DrawQuestWork(QuestController.QuestProgress currentQuest) private QuestProgressInfo? DrawQuestWork(QuestController.QuestProgress currentQuest, bool isMinimized)
{ {
var questWork = _questFunctions.GetQuestProgressInfo(currentQuest.Quest.Id); var questWork = _questFunctions.GetQuestProgressInfo(currentQuest.Quest.Id);
if (questWork != null) if (questWork != null)
{ {
if (isMinimized)
return questWork;
Vector4 color; Vector4 color;
unsafe unsafe
{ {
@ -203,7 +214,7 @@ internal sealed class ActiveQuestComponent
} }
private void DrawQuestButtons(QuestController.QuestProgress currentQuest, QuestStep? currentStep, private void DrawQuestButtons(QuestController.QuestProgress currentQuest, QuestStep? currentStep,
QuestProgressInfo? questProgressInfo) QuestProgressInfo? questProgressInfo, bool isMinimized)
{ {
ImGui.BeginDisabled(_questController.IsRunning); ImGui.BeginDisabled(_questController.IsRunning);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Play)) if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
@ -215,11 +226,14 @@ internal sealed class ActiveQuestComponent
_questController.ExecuteNextStep(QuestController.EAutomationType.Automatic); _questController.ExecuteNextStep(QuestController.EAutomationType.Automatic);
} }
ImGui.SameLine(); if (!isMinimized)
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.StepForward, "Step"))
{ {
_questController.ExecuteNextStep(QuestController.EAutomationType.Manual); ImGui.SameLine();
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.StepForward, "Step"))
{
_questController.ExecuteNextStep(QuestController.EAutomationType.Manual);
}
} }
ImGui.EndDisabled(); ImGui.EndDisabled();
@ -232,39 +246,48 @@ internal sealed class ActiveQuestComponent
_gatheringController.Stop("Manual"); _gatheringController.Stop("Manual");
} }
bool lastStep = currentStep == if (isMinimized)
currentQuest.Quest.FindSequence(currentQuest.Sequence)?.Steps.LastOrDefault();
bool colored = currentStep != null
&& !lastStep
&& currentStep.InteractionType == EInteractionType.Instruction
&& _questController.HasCurrentTaskMatching<WaitAtEnd.WaitNextStepOrSequence>(out _);
ImGui.BeginDisabled(lastStep);
if (colored)
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ArrowCircleRight, "Skip"))
{
_movementController.Stop();
_questController.Skip(currentQuest.Quest.Id, currentQuest.Sequence);
}
if (colored)
ImGui.PopStyleColor();
ImGui.EndDisabled();
if (_commandManager.Commands.TryGetValue("/questinfo", out var commandInfo))
{ {
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiComponents.IconButton(FontAwesomeIcon.Atlas)) if (ImGuiComponents.IconButton(FontAwesomeIcon.RedoAlt))
_commandManager.DispatchCommand("/questinfo", Reload?.Invoke(this, EventArgs.Empty);
currentQuest.Quest.Id.ToString() ?? string.Empty, commandInfo);
} }
else
bool autoAcceptNextQuest = _configuration.General.AutoAcceptNextQuest;
if (ImGui.Checkbox("Automatically accept next quest", ref autoAcceptNextQuest))
{ {
_configuration.General.AutoAcceptNextQuest = autoAcceptNextQuest; bool lastStep = currentStep ==
_pluginInterface.SavePluginConfig(_configuration); currentQuest.Quest.FindSequence(currentQuest.Sequence)?.Steps.LastOrDefault();
bool colored = currentStep != null
&& !lastStep
&& currentStep.InteractionType == EInteractionType.Instruction
&& _questController.HasCurrentTaskMatching<WaitAtEnd.WaitNextStepOrSequence>(out _);
ImGui.BeginDisabled(lastStep);
if (colored)
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ArrowCircleRight, "Skip"))
{
_movementController.Stop();
_questController.Skip(currentQuest.Quest.Id, currentQuest.Sequence);
}
if (colored)
ImGui.PopStyleColor();
ImGui.EndDisabled();
if (_commandManager.Commands.TryGetValue("/questinfo", out var commandInfo))
{
ImGui.SameLine();
if (ImGuiComponents.IconButton(FontAwesomeIcon.Atlas))
_commandManager.DispatchCommand("/questinfo",
currentQuest.Quest.Id.ToString() ?? string.Empty, commandInfo);
}
bool autoAcceptNextQuest = _configuration.General.AutoAcceptNextQuest;
if (ImGui.Checkbox("Automatically accept next quest", ref autoAcceptNextQuest))
{
_configuration.General.AutoAcceptNextQuest = autoAcceptNextQuest;
_pluginInterface.SavePluginConfig(_configuration);
}
} }
} }

View File

@ -18,9 +18,7 @@ namespace Questionable.Windows.QuestComponents;
internal sealed class QuickAccessButtonsComponent internal sealed class QuickAccessButtonsComponent
{ {
private readonly QuestController _questController;
private readonly MovementController _movementController; private readonly MovementController _movementController;
private readonly GameUiController _gameUiController;
private readonly GameFunctions _gameFunctions; private readonly GameFunctions _gameFunctions;
private readonly ChatFunctions _chatFunctions; private readonly ChatFunctions _chatFunctions;
private readonly QuestRegistry _questRegistry; private readonly QuestRegistry _questRegistry;
@ -29,12 +27,10 @@ internal sealed class QuickAccessButtonsComponent
private readonly JournalProgressWindow _journalProgressWindow; private readonly JournalProgressWindow _journalProgressWindow;
private readonly IClientState _clientState; private readonly IClientState _clientState;
private readonly ICondition _condition; private readonly ICondition _condition;
private readonly IFramework _framework;
private readonly ICommandManager _commandManager; private readonly ICommandManager _commandManager;
public QuickAccessButtonsComponent(QuestController questController, public QuickAccessButtonsComponent(
MovementController movementController, MovementController movementController,
GameUiController gameUiController,
GameFunctions gameFunctions, GameFunctions gameFunctions,
ChatFunctions chatFunctions, ChatFunctions chatFunctions,
QuestRegistry questRegistry, QuestRegistry questRegistry,
@ -43,12 +39,9 @@ internal sealed class QuickAccessButtonsComponent
JournalProgressWindow journalProgressWindow, JournalProgressWindow journalProgressWindow,
IClientState clientState, IClientState clientState,
ICondition condition, ICondition condition,
IFramework framework,
ICommandManager commandManager) ICommandManager commandManager)
{ {
_questController = questController;
_movementController = movementController; _movementController = movementController;
_gameUiController = gameUiController;
_gameFunctions = gameFunctions; _gameFunctions = gameFunctions;
_chatFunctions = chatFunctions; _chatFunctions = chatFunctions;
_questRegistry = questRegistry; _questRegistry = questRegistry;
@ -57,10 +50,11 @@ internal sealed class QuickAccessButtonsComponent
_journalProgressWindow = journalProgressWindow; _journalProgressWindow = journalProgressWindow;
_clientState = clientState; _clientState = clientState;
_condition = condition; _condition = condition;
_framework = framework;
_commandManager = commandManager; _commandManager = commandManager;
} }
public event EventHandler? Reload;
public unsafe void Draw() public unsafe void Draw()
{ {
var map = AgentMap.Instance(); var map = AgentMap.Instance();
@ -89,8 +83,8 @@ internal sealed class QuickAccessButtonsComponent
ImGui.SetTooltip("Hold CTRL to enable this button.\nRebuilding the navmesh will take some time."); ImGui.SetTooltip("Hold CTRL to enable this button.\nRebuilding the navmesh will take some time.");
} }
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.RedoAlt,"Reload Data")) if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.RedoAlt, "Reload Data"))
Reload(); Reload?.Invoke(this, EventArgs.Empty);
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiComponents.IconButton(FontAwesomeIcon.ChartColumn)) if (ImGuiComponents.IconButton(FontAwesomeIcon.ChartColumn))
@ -105,13 +99,6 @@ internal sealed class QuickAccessButtonsComponent
} }
} }
public void Reload()
{
_questController.Reload();
_framework.RunOnTick(() => _gameUiController.HandleCurrentDialogueChoices(),
TimeSpan.FromMilliseconds(200));
}
private bool DrawValidationIssuesButton() private bool DrawValidationIssuesButton()
{ {
int errorCount = _questRegistry.ValidationErrorCount; int errorCount = _questRegistry.ValidationErrorCount;

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Numerics; using System.Numerics;
using Dalamud.Interface;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using ImGuiNET; using ImGuiNET;
@ -24,6 +25,9 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
private readonly CreationUtilsComponent _creationUtilsComponent; private readonly CreationUtilsComponent _creationUtilsComponent;
private readonly QuickAccessButtonsComponent _quickAccessButtonsComponent; private readonly QuickAccessButtonsComponent _quickAccessButtonsComponent;
private readonly RemainingTasksComponent _remainingTasksComponent; private readonly RemainingTasksComponent _remainingTasksComponent;
private readonly IFramework _framework;
private readonly GameUiController _gameUiController;
private readonly TitleBarButton _minimizeButton;
public QuestWindow(IDalamudPluginInterface pluginInterface, public QuestWindow(IDalamudPluginInterface pluginInterface,
QuestController questController, QuestController questController,
@ -34,8 +38,11 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
ARealmRebornComponent aRealmRebornComponent, ARealmRebornComponent aRealmRebornComponent,
CreationUtilsComponent creationUtilsComponent, CreationUtilsComponent creationUtilsComponent,
QuickAccessButtonsComponent quickAccessButtonsComponent, QuickAccessButtonsComponent quickAccessButtonsComponent,
RemainingTasksComponent remainingTasksComponent) RemainingTasksComponent remainingTasksComponent,
: base($"Questionable v{PluginVersion.ToString(2)}###Questionable", ImGuiWindowFlags.AlwaysAutoResize) IFramework framework,
GameUiController gameUiController)
: base($"Questionable v{PluginVersion.ToString(2)}###Questionable",
ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoCollapse)
{ {
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_questController = questController; _questController = questController;
@ -47,6 +54,8 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
_creationUtilsComponent = creationUtilsComponent; _creationUtilsComponent = creationUtilsComponent;
_quickAccessButtonsComponent = quickAccessButtonsComponent; _quickAccessButtonsComponent = quickAccessButtonsComponent;
_remainingTasksComponent = remainingTasksComponent; _remainingTasksComponent = remainingTasksComponent;
_framework = framework;
_gameUiController = gameUiController;
#if DEBUG #if DEBUG
IsOpen = true; IsOpen = true;
@ -57,9 +66,27 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
MaximumSize = default MaximumSize = default
}; };
RespectCloseHotkey = false; RespectCloseHotkey = false;
_minimizeButton = new TitleBarButton
{
Icon = FontAwesomeIcon.Minus,
Priority = int.MinValue,
IconOffset = new Vector2(1.5f, 1),
Click = _ =>
{
IsMinimized = !IsMinimized;
_minimizeButton!.Icon = IsMinimized ? FontAwesomeIcon.WindowMaximize : FontAwesomeIcon.Minus;
},
AvailableClickthrough = true,
};
TitleBarButtons.Insert(0, _minimizeButton);
_activeQuestComponent.Reload += OnReload;
_quickAccessButtonsComponent.Reload += OnReload;
} }
public WindowConfig WindowConfig => _configuration.DebugWindowConfig; public WindowConfig WindowConfig => _configuration.DebugWindowConfig;
public bool IsMinimized { get; set; }
public void SaveWindowConfig() => _pluginInterface.SavePluginConfig(_configuration); public void SaveWindowConfig() => _pluginInterface.SavePluginConfig(_configuration);
@ -82,19 +109,31 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
public override void Draw() public override void Draw()
{ {
_activeQuestComponent.Draw(); _activeQuestComponent.Draw(IsMinimized);
ImGui.Separator(); if (!IsMinimized)
if (_aRealmRebornComponent.ShouldDraw)
{ {
_aRealmRebornComponent.Draw();
ImGui.Separator(); ImGui.Separator();
if (_aRealmRebornComponent.ShouldDraw)
{
_aRealmRebornComponent.Draw();
ImGui.Separator();
}
_creationUtilsComponent.Draw();
ImGui.Separator();
_quickAccessButtonsComponent.Draw();
_remainingTasksComponent.Draw();
} }
}
_creationUtilsComponent.Draw(); private void OnReload(object? sender, EventArgs e) => Reload();
ImGui.Separator();
_quickAccessButtonsComponent.Draw(); internal void Reload()
_remainingTasksComponent.Draw(); {
_questController.Reload();
_framework.RunOnTick(() => _gameUiController.HandleCurrentDialogueChoices(),
TimeSpan.FromMilliseconds(200));
} }
} }