qstcompanion v1.0.1
This commit is contained in:
parent
3e10cbbbf2
commit
44c67ab71b
79 changed files with 21148 additions and 0 deletions
|
|
@ -0,0 +1,171 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using QuestionableCompanion.Helpers;
|
||||
using QuestionableCompanion.Models;
|
||||
using QuestionableCompanion.Services;
|
||||
|
||||
namespace QuestionableCompanion.Windows;
|
||||
|
||||
public class AlliedSocietyPriorityWindow : Window, IDisposable
|
||||
{
|
||||
private readonly Configuration configuration;
|
||||
|
||||
private readonly AlliedSocietyDatabase database;
|
||||
|
||||
private List<AlliedSocietyPriority> editingPriorities = new List<AlliedSocietyPriority>();
|
||||
|
||||
private int? draggedIndex;
|
||||
|
||||
private const string DragDropId = "ALLIED_SOCIETY_PRIORITY";
|
||||
|
||||
private readonly Dictionary<byte, string> societyNames = new Dictionary<byte, string>
|
||||
{
|
||||
{ 1, "Amalj'aa" },
|
||||
{ 2, "Sylphs" },
|
||||
{ 3, "Kobolds" },
|
||||
{ 4, "Sahagin" },
|
||||
{ 5, "Ixal" },
|
||||
{ 6, "Vanu Vanu" },
|
||||
{ 7, "Vath" },
|
||||
{ 8, "Moogles" },
|
||||
{ 9, "Kojin" },
|
||||
{ 10, "Ananta" },
|
||||
{ 11, "Namazu" },
|
||||
{ 12, "Pixies" },
|
||||
{ 13, "Qitari" },
|
||||
{ 14, "Dwarves" },
|
||||
{ 15, "Arkasodara" },
|
||||
{ 16, "Omicrons" },
|
||||
{ 17, "Loporrits" },
|
||||
{ 18, "Pelupelu" },
|
||||
{ 19, "Mamool Ja" },
|
||||
{ 20, "Yok Huy" }
|
||||
};
|
||||
|
||||
public AlliedSocietyPriorityWindow(Configuration configuration, AlliedSocietyDatabase database)
|
||||
: base("Allied Society Priority Configuration", ImGuiWindowFlags.NoCollapse)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.database = database;
|
||||
base.Size = new Vector2(400f, 600f);
|
||||
base.SizeCondition = ImGuiCond.FirstUseEver;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnOpen()
|
||||
{
|
||||
if (configuration.AlliedSociety.RotationConfig.Priorities.Count == 0)
|
||||
{
|
||||
configuration.AlliedSociety.RotationConfig.InitializeDefaults();
|
||||
database.SaveToConfig();
|
||||
}
|
||||
editingPriorities = (from p in configuration.AlliedSociety.RotationConfig.Priorities
|
||||
orderby p.Order
|
||||
select new AlliedSocietyPriority
|
||||
{
|
||||
SocietyId = p.SocietyId,
|
||||
Enabled = p.Enabled,
|
||||
Order = p.Order
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
ImGui.TextWrapped("Drag societies to reorder priorities. Uncheck to disable specific societies.");
|
||||
ImGui.Separator();
|
||||
float availableHeight = ImGui.GetWindowSize().Y - 120f;
|
||||
ImGui.BeginChild("PriorityList", new Vector2(0f, availableHeight), border: true);
|
||||
for (int i = 0; i < editingPriorities.Count; i++)
|
||||
{
|
||||
AlliedSocietyPriority priority = editingPriorities[i];
|
||||
string name = (societyNames.ContainsKey(priority.SocietyId) ? societyNames[priority.SocietyId] : $"Unknown ({priority.SocietyId})");
|
||||
ImGui.PushID(i);
|
||||
if (draggedIndex == i)
|
||||
{
|
||||
uint highlightColor = ImGui.ColorConvertFloat4ToU32(new Vector4(0f, 0.7f, 0f, 0.3f));
|
||||
Vector2 cursorPos = ImGui.GetCursorScreenPos();
|
||||
Vector2 itemSize = new Vector2(ImGui.GetContentRegionAvail().X, ImGui.GetFrameHeight());
|
||||
ImGui.GetWindowDrawList().AddRectFilled(cursorPos, cursorPos + itemSize, highlightColor);
|
||||
}
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImU8String label = new ImU8String(6, 1);
|
||||
label.AppendFormatted(FontAwesomeIcon.ArrowsUpDownLeftRight.ToIconString());
|
||||
label.AppendLiteral("##drag");
|
||||
ImGui.Button(label);
|
||||
ImGui.PopFont();
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetMouseCursor(ImGuiMouseCursor.ResizeAll);
|
||||
}
|
||||
if (ImGui.BeginDragDropSource())
|
||||
{
|
||||
draggedIndex = i;
|
||||
ImGuiDragDrop.SetDragDropPayload("ALLIED_SOCIETY_PRIORITY", i);
|
||||
ImGui.Text(name);
|
||||
ImGui.EndDragDropSource();
|
||||
}
|
||||
else if (draggedIndex == i && !ImGui.IsMouseDown(ImGuiMouseButton.Left))
|
||||
{
|
||||
draggedIndex = null;
|
||||
}
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
if (ImGuiDragDrop.AcceptDragDropPayload<int>("ALLIED_SOCIETY_PRIORITY", out var sourceIndex) && sourceIndex != i)
|
||||
{
|
||||
AlliedSocietyPriority item = editingPriorities[sourceIndex];
|
||||
editingPriorities.RemoveAt(sourceIndex);
|
||||
editingPriorities.Insert(i, item);
|
||||
UpdateOrders();
|
||||
draggedIndex = i;
|
||||
}
|
||||
ImGui.EndDragDropTarget();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
bool enabled = priority.Enabled;
|
||||
ImU8String label2 = new ImU8String(9, 0);
|
||||
label2.AppendLiteral("##enabled");
|
||||
if (ImGui.Checkbox(label2, ref enabled))
|
||||
{
|
||||
priority.Enabled = enabled;
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(name);
|
||||
ImGui.PopID();
|
||||
}
|
||||
ImGui.EndChild();
|
||||
ImGui.Separator();
|
||||
if (ImGui.Button("Save"))
|
||||
{
|
||||
Save();
|
||||
base.IsOpen = false;
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Cancel"))
|
||||
{
|
||||
base.IsOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateOrders()
|
||||
{
|
||||
for (int i = 0; i < editingPriorities.Count; i++)
|
||||
{
|
||||
editingPriorities[i].Order = i;
|
||||
}
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
UpdateOrders();
|
||||
configuration.AlliedSociety.RotationConfig.Priorities = editingPriorities;
|
||||
database.SaveToConfig();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,564 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using QuestionableCompanion.Services;
|
||||
|
||||
namespace QuestionableCompanion.Windows;
|
||||
|
||||
public class ConfigWindow : Window, IDisposable
|
||||
{
|
||||
private readonly Configuration configuration;
|
||||
|
||||
private readonly Plugin plugin;
|
||||
|
||||
public ConfigWindow(Plugin plugin)
|
||||
: base("Questionable Companion Settings###QCSettings")
|
||||
{
|
||||
base.Size = new Vector2(600f, 400f);
|
||||
base.SizeCondition = ImGuiCond.FirstUseEver;
|
||||
this.plugin = plugin;
|
||||
configuration = plugin.Configuration;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public override void PreDraw()
|
||||
{
|
||||
if (configuration.IsConfigWindowMovable)
|
||||
{
|
||||
base.Flags &= ~ImGuiWindowFlags.NoMove;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Flags |= ImGuiWindowFlags.NoMove;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1f, 0.8f, 0.2f, 1f));
|
||||
ImGui.TextWrapped("Configuration Moved!");
|
||||
ImGui.PopStyleColor();
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextWrapped("The configuration interface has been moved to the new Main Window for a better user experience.");
|
||||
ImGui.Spacing();
|
||||
ImGui.TextWrapped("All settings are now available in the Main Window with improved organization and features:");
|
||||
ImGui.Spacing();
|
||||
ImGui.BulletText("Quest Rotation Management");
|
||||
ImGui.BulletText("Event Quest Automation");
|
||||
ImGui.BulletText("MSQ Progress Tracking");
|
||||
ImGui.BulletText("DC Travel Configuration");
|
||||
ImGui.BulletText("Advanced Settings");
|
||||
ImGui.BulletText("And much more!");
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
if (ImGui.Button(size: new Vector2(ImGui.GetContentRegionAvail().X, 50f), label: "Open Main Window (Settings Tab)"))
|
||||
{
|
||||
plugin.ToggleMainUi();
|
||||
base.IsOpen = false;
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.7f, 0.7f, 0.7f, 1f));
|
||||
ImGui.TextWrapped("This legacy configuration window will be removed in a future update.");
|
||||
ImGui.TextWrapped("Please use the Main Window for all configuration needs.");
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
|
||||
private void DrawGeneralTab()
|
||||
{
|
||||
ImGui.Text("General Settings");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool autoStart = configuration.AutoStartOnLogin;
|
||||
if (ImGui.Checkbox("Auto-start on login", ref autoStart))
|
||||
{
|
||||
configuration.AutoStartOnLogin = autoStart;
|
||||
configuration.Save();
|
||||
}
|
||||
bool dryRun = configuration.EnableDryRun;
|
||||
if (ImGui.Checkbox("Enable Dry Run Mode (simulate without executing)", ref dryRun))
|
||||
{
|
||||
configuration.EnableDryRun = dryRun;
|
||||
configuration.Save();
|
||||
}
|
||||
bool restoreState = configuration.RestoreStateOnLoad;
|
||||
if (ImGui.Checkbox("Restore state on plugin load", ref restoreState))
|
||||
{
|
||||
configuration.RestoreStateOnLoad = restoreState;
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Text("Execution Settings");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
int maxRetries = configuration.MaxRetryAttempts;
|
||||
if (ImGui.SliderInt("Max retry attempts", ref maxRetries, 1, 10))
|
||||
{
|
||||
configuration.MaxRetryAttempts = maxRetries;
|
||||
configuration.Save();
|
||||
}
|
||||
int switchDelay = configuration.CharacterSwitchDelay;
|
||||
if (ImGui.SliderInt("Character switch delay (seconds)", ref switchDelay, 3, 15))
|
||||
{
|
||||
configuration.CharacterSwitchDelay = switchDelay;
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Text("Logging Settings");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
int maxLogs = configuration.MaxLogEntries;
|
||||
if (ImGui.SliderInt("Max log entries", ref maxLogs, 50, 500))
|
||||
{
|
||||
configuration.MaxLogEntries = maxLogs;
|
||||
configuration.Save();
|
||||
}
|
||||
bool showDebug = configuration.ShowDebugLogs;
|
||||
if (ImGui.Checkbox("Show debug logs", ref showDebug))
|
||||
{
|
||||
configuration.ShowDebugLogs = showDebug;
|
||||
configuration.Save();
|
||||
}
|
||||
bool logToFile = configuration.LogToFile;
|
||||
if (ImGui.Checkbox("Log to file", ref logToFile))
|
||||
{
|
||||
configuration.LogToFile = logToFile;
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Text("UI Settings");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool movable = configuration.IsConfigWindowMovable;
|
||||
if (ImGui.Checkbox("Movable config window", ref movable))
|
||||
{
|
||||
configuration.IsConfigWindowMovable = movable;
|
||||
configuration.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAdvancedFeaturesTab()
|
||||
{
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Submarine Management");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableSubmarineCheck = configuration.EnableSubmarineCheck;
|
||||
if (ImGui.Checkbox("Enable Submarine Monitoring", ref enableSubmarineCheck))
|
||||
{
|
||||
configuration.EnableSubmarineCheck = enableSubmarineCheck;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Automatically monitor submarines and pause quest rotation when submarines are ready");
|
||||
}
|
||||
if (configuration.EnableSubmarineCheck)
|
||||
{
|
||||
ImGui.Indent();
|
||||
int submarineCheckInterval = configuration.SubmarineCheckInterval;
|
||||
if (ImGui.SliderInt("Check Interval (seconds)", ref submarineCheckInterval, 30, 300))
|
||||
{
|
||||
configuration.SubmarineCheckInterval = submarineCheckInterval;
|
||||
configuration.Save();
|
||||
}
|
||||
int submarineReloginCooldown = configuration.SubmarineReloginCooldown;
|
||||
if (ImGui.SliderInt("Cooldown after Relog (seconds)", ref submarineReloginCooldown, 60, 300))
|
||||
{
|
||||
configuration.SubmarineReloginCooldown = submarineReloginCooldown;
|
||||
configuration.Save();
|
||||
}
|
||||
int submarineWaitTime = configuration.SubmarineWaitTime;
|
||||
if (ImGui.SliderInt("Wait time before submarine (seconds)", ref submarineWaitTime, 10, 120))
|
||||
{
|
||||
configuration.SubmarineWaitTime = submarineWaitTime;
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Unindent();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Movement Monitor");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableMovementMonitor = configuration.EnableMovementMonitor;
|
||||
if (ImGui.Checkbox("Enable Movement Monitor", ref enableMovementMonitor))
|
||||
{
|
||||
configuration.EnableMovementMonitor = enableMovementMonitor;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Automatically detect if player is stuck and send /qst reload");
|
||||
}
|
||||
if (configuration.EnableMovementMonitor)
|
||||
{
|
||||
ImGui.Indent();
|
||||
int movementCheckInterval = configuration.MovementCheckInterval;
|
||||
if (ImGui.SliderInt("Check Interval (seconds)##movement", ref movementCheckInterval, 3, 30))
|
||||
{
|
||||
configuration.MovementCheckInterval = movementCheckInterval;
|
||||
configuration.Save();
|
||||
}
|
||||
int movementStuckThreshold = configuration.MovementStuckThreshold;
|
||||
if (ImGui.SliderInt("Stuck Threshold (seconds)", ref movementStuckThreshold, 15, 120))
|
||||
{
|
||||
configuration.MovementStuckThreshold = movementStuckThreshold;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Time without movement before sending /qst reload");
|
||||
}
|
||||
ImGui.Unindent();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(1f, 0.5f, 0.3f, 1f), "Combat Handling");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableCombatHandling = configuration.EnableCombatHandling;
|
||||
if (ImGui.Checkbox("Enable Combat Handling", ref enableCombatHandling))
|
||||
{
|
||||
configuration.EnableCombatHandling = enableCombatHandling;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Automatically enable RSR/VBMAI/BMRAI when HP drops below threshold during combat");
|
||||
}
|
||||
if (configuration.EnableCombatHandling)
|
||||
{
|
||||
ImGui.Indent();
|
||||
int combatHPThreshold = configuration.CombatHPThreshold;
|
||||
if (ImGui.SliderInt("HP Threshold (%)", ref combatHPThreshold, 1, 99))
|
||||
{
|
||||
configuration.CombatHPThreshold = combatHPThreshold;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Enable combat automation when HP drops below this percentage\nCommands: /rsr manual, /vbmai on, /bmrai on");
|
||||
}
|
||||
ImGui.TextWrapped("When HP drops below threshold:");
|
||||
ImGui.BulletText("/rsr manual");
|
||||
ImGui.BulletText("/vbmai on");
|
||||
ImGui.BulletText("/bmrai on");
|
||||
ImGui.Spacing();
|
||||
ImGui.TextWrapped("When combat ends:");
|
||||
ImGui.BulletText("/rsr off");
|
||||
ImGui.BulletText("/vbmai off");
|
||||
ImGui.BulletText("/bmrai off");
|
||||
ImGui.Unindent();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(1f, 0.3f, 0.3f, 1f), "Death Handling");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableDeathHandling = configuration.EnableDeathHandling;
|
||||
if (ImGui.Checkbox("Enable Death Handling", ref enableDeathHandling))
|
||||
{
|
||||
configuration.EnableDeathHandling = enableDeathHandling;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Automatically respawn when player dies");
|
||||
}
|
||||
if (configuration.EnableDeathHandling)
|
||||
{
|
||||
ImGui.Indent();
|
||||
int deathRespawnDelay = configuration.DeathRespawnDelay;
|
||||
if (ImGui.SliderInt("Teleport Delay (seconds)", ref deathRespawnDelay, 1, 30))
|
||||
{
|
||||
configuration.DeathRespawnDelay = deathRespawnDelay;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Time to wait after respawn before teleporting back to death location");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.TextWrapped("On Death:");
|
||||
ImGui.BulletText("Detect 0% HP");
|
||||
ImGui.BulletText("Save position & territory");
|
||||
ImGui.BulletText("Auto-click SelectYesNo (respawn)");
|
||||
ImU8String text = new ImU8String(13, 1);
|
||||
text.AppendLiteral("Wait ");
|
||||
text.AppendFormatted(configuration.DeathRespawnDelay);
|
||||
text.AppendLiteral(" seconds");
|
||||
ImGui.BulletText(text);
|
||||
ImGui.BulletText("Teleport back to death location");
|
||||
ImGui.Unindent();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Logging Settings");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool logToDalamud = configuration.LogToDalamud;
|
||||
if (ImGui.Checkbox("Log to Dalamud Log", ref logToDalamud))
|
||||
{
|
||||
configuration.LogToDalamud = logToDalamud;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Enable to also log to Dalamud log (can cause spam)");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Dungeon Automation");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableAutoDutyUnsynced = configuration.EnableAutoDutyUnsynced;
|
||||
if (ImGui.Checkbox("Enable AutoDuty Unsynced", ref enableAutoDutyUnsynced))
|
||||
{
|
||||
configuration.EnableAutoDutyUnsynced = enableAutoDutyUnsynced;
|
||||
configuration.Save();
|
||||
plugin.GetDungeonAutomation()?.SetDutyModeBasedOnConfig();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Run dungeons unsynced for faster completion");
|
||||
}
|
||||
if (configuration.EnableAutoDutyUnsynced)
|
||||
{
|
||||
ImGui.Indent();
|
||||
int autoDutyPartySize = configuration.AutoDutyPartySize;
|
||||
if (ImGui.SliderInt("Party Size Check (members)", ref autoDutyPartySize, 1, 8))
|
||||
{
|
||||
configuration.AutoDutyPartySize = autoDutyPartySize;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Minimum party size required before starting dungeon");
|
||||
}
|
||||
int autoDutyMaxWaitForParty = configuration.AutoDutyMaxWaitForParty;
|
||||
if (ImGui.SliderInt("Max Wait for Party (seconds)", ref autoDutyMaxWaitForParty, 10, 120))
|
||||
{
|
||||
configuration.AutoDutyMaxWaitForParty = autoDutyMaxWaitForParty;
|
||||
configuration.Save();
|
||||
}
|
||||
int autoDutyReInviteInterval = configuration.AutoDutyReInviteInterval;
|
||||
if (ImGui.SliderInt("Re-invite Interval (seconds)", ref autoDutyReInviteInterval, 5, 60))
|
||||
{
|
||||
configuration.AutoDutyReInviteInterval = autoDutyReInviteInterval;
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Unindent();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Quest Automation");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableQSTReloadTracking = configuration.EnableQSTReloadTracking;
|
||||
if (ImGui.Checkbox("Enable QST Reload Tracking", ref enableQSTReloadTracking))
|
||||
{
|
||||
configuration.EnableQSTReloadTracking = enableQSTReloadTracking;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Track Questionable reloads and switch character if too many reloads occur");
|
||||
}
|
||||
if (configuration.EnableQSTReloadTracking)
|
||||
{
|
||||
ImGui.Indent();
|
||||
int maxQSTReloadsBeforeSwitch = configuration.MaxQSTReloadsBeforeSwitch;
|
||||
if (ImGui.SliderInt("Max Reloads before switch", ref maxQSTReloadsBeforeSwitch, 1, 20))
|
||||
{
|
||||
configuration.MaxQSTReloadsBeforeSwitch = maxQSTReloadsBeforeSwitch;
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Unindent();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Character Management");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableMultiModeAfterRotation = configuration.EnableMultiModeAfterRotation;
|
||||
if (ImGui.Checkbox("Enable Multi-Mode after Rotation", ref enableMultiModeAfterRotation))
|
||||
{
|
||||
configuration.EnableMultiModeAfterRotation = enableMultiModeAfterRotation;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Enable AutoRetainer Multi-Mode after completing character rotation");
|
||||
}
|
||||
bool returnToHomeworldOnStopQuest = configuration.ReturnToHomeworldOnStopQuest;
|
||||
if (ImGui.Checkbox("Return to Homeworld on Stop Quest", ref returnToHomeworldOnStopQuest))
|
||||
{
|
||||
configuration.ReturnToHomeworldOnStopQuest = returnToHomeworldOnStopQuest;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Automatically return to homeworld when stop quest is completed");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Safe Wait Settings");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableSafeWaitBefore = configuration.EnableSafeWaitBeforeCharacterSwitch;
|
||||
if (ImGui.Checkbox("Enable Safe Wait Before Character Switch", ref enableSafeWaitBefore))
|
||||
{
|
||||
configuration.EnableSafeWaitBeforeCharacterSwitch = enableSafeWaitBefore;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Wait for character to stabilize (movement, actions) before switching");
|
||||
}
|
||||
bool enableSafeWaitAfter = configuration.EnableSafeWaitAfterCharacterSwitch;
|
||||
if (ImGui.Checkbox("Enable Safe Wait After Character Switch", ref enableSafeWaitAfter))
|
||||
{
|
||||
configuration.EnableSafeWaitAfterCharacterSwitch = enableSafeWaitAfter;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Wait for character to fully load after switching");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "Quest Pre-Check");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
bool enableQuestPreCheck = configuration.EnableQuestPreCheck;
|
||||
if (ImGui.Checkbox("Enable Quest Pre-Check", ref enableQuestPreCheck))
|
||||
{
|
||||
configuration.EnableQuestPreCheck = enableQuestPreCheck;
|
||||
configuration.Save();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Check quest completion status before starting rotation to skip completed characters");
|
||||
}
|
||||
ImGui.TextWrapped("Quest Pre-Check scans all characters for completed quests before rotation starts, preventing unnecessary character switches.");
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(0.3f, 0.8f, 1f, 1f), "DC Travel World Selector");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextWrapped("Configure world travel for Data Center travel quests. Requires Lifestream plugin.");
|
||||
ImGui.Spacing();
|
||||
string[] datacenters = configuration.WorldsByDatacenter.Keys.ToArray();
|
||||
int currentDCIndex = Array.IndexOf(datacenters, configuration.SelectedDatacenter);
|
||||
if (currentDCIndex < 0)
|
||||
{
|
||||
currentDCIndex = 0;
|
||||
}
|
||||
ImGui.Text("Select Datacenter:");
|
||||
if (ImGui.Combo((ImU8String)"##DCSelector", ref currentDCIndex, (ReadOnlySpan<string>)datacenters, datacenters.Length))
|
||||
{
|
||||
configuration.SelectedDatacenter = datacenters[currentDCIndex];
|
||||
if (configuration.WorldsByDatacenter.TryGetValue(configuration.SelectedDatacenter, out List<string> newWorlds) && newWorlds.Count > 0)
|
||||
{
|
||||
configuration.DCTravelWorld = newWorlds[0];
|
||||
}
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
if (configuration.WorldsByDatacenter.TryGetValue(configuration.SelectedDatacenter, out List<string> worlds))
|
||||
{
|
||||
string[] worldArray = worlds.ToArray();
|
||||
int currentWorldIndex = Array.IndexOf(worldArray, configuration.DCTravelWorld);
|
||||
if (currentWorldIndex < 0)
|
||||
{
|
||||
currentWorldIndex = 0;
|
||||
}
|
||||
ImGui.Text("Select Target World:");
|
||||
if (ImGui.Combo((ImU8String)"##WorldSelector", ref currentWorldIndex, (ReadOnlySpan<string>)worldArray, worldArray.Length))
|
||||
{
|
||||
configuration.DCTravelWorld = worldArray[currentWorldIndex];
|
||||
configuration.EnableDCTravel = !string.IsNullOrEmpty(configuration.DCTravelWorld);
|
||||
configuration.Save();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
LifestreamIPC lifestreamIPC = Plugin.Instance?.LifestreamIPC;
|
||||
if (lifestreamIPC != null && !lifestreamIPC.IsAvailable)
|
||||
{
|
||||
lifestreamIPC.ForceCheckAvailability();
|
||||
}
|
||||
bool lifestreamAvailable = lifestreamIPC?.IsAvailable ?? false;
|
||||
if (!lifestreamAvailable)
|
||||
{
|
||||
ImGui.BeginDisabled();
|
||||
}
|
||||
bool enableDCTravel = configuration.EnableDCTravel;
|
||||
if (ImGui.Checkbox("Enable DC Travel", ref enableDCTravel))
|
||||
{
|
||||
configuration.EnableDCTravel = enableDCTravel;
|
||||
configuration.Save();
|
||||
}
|
||||
if (!lifestreamAvailable)
|
||||
{
|
||||
ImGui.EndDisabled();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
if (!lifestreamAvailable)
|
||||
{
|
||||
ImGui.SetTooltip("Lifestream plugin is required for DC Travel!\nPlease install and enable Lifestream to use this feature.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.SetTooltip("Enable automatic DC travel when DC travel quests are detected");
|
||||
}
|
||||
}
|
||||
if (!lifestreamAvailable)
|
||||
{
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(1f, 0.5f, 0f, 1f), "⚠\ufe0f Lifestream plugin not available!");
|
||||
ImGui.TextWrapped("DC Travel requires Lifestream to be installed and enabled.");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
if (configuration.EnableDCTravel && !string.IsNullOrEmpty(configuration.DCTravelWorld))
|
||||
{
|
||||
Vector4 col = new Vector4(0.2f, 1f, 0.2f, 1f);
|
||||
ImU8String text2 = new ImU8String(21, 1);
|
||||
text2.AppendLiteral("✓ DC Travel ACTIVE → ");
|
||||
text2.AppendFormatted(configuration.DCTravelWorld);
|
||||
ImGui.TextColored(in col, text2);
|
||||
ImU8String text3 = new ImU8String(100, 1);
|
||||
text3.AppendLiteral("Character will travel to ");
|
||||
text3.AppendFormatted(configuration.DCTravelWorld);
|
||||
text3.AppendLiteral(" immediately after login, then return to homeworld before character switch.");
|
||||
ImGui.TextWrapped(text3);
|
||||
}
|
||||
else if (!configuration.EnableDCTravel)
|
||||
{
|
||||
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.7f, 1f), "○ DC Travel disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(new Vector4(1f, 0.5f, 0f, 1f), "⚠ DC Travel enabled but no world selected!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(new Vector4(1f, 0.5f, 0f, 1f), "No worlds available for selected datacenter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using QuestionableCompanion.Services;
|
||||
|
||||
namespace QuestionableCompanion.Windows;
|
||||
|
||||
public class DebugWindow : Window, IDisposable
|
||||
{
|
||||
private readonly Plugin plugin;
|
||||
|
||||
private readonly CombatDutyDetectionService? combatDutyDetection;
|
||||
|
||||
private readonly DeathHandlerService? deathHandler;
|
||||
|
||||
private readonly DungeonAutomationService? dungeonAutomation;
|
||||
|
||||
public DebugWindow(Plugin plugin, CombatDutyDetectionService? combatDutyDetection, DeathHandlerService? deathHandler, DungeonAutomationService? dungeonAutomation)
|
||||
: base("QST Companion Debug###QSTDebug", ImGuiWindowFlags.NoCollapse)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.combatDutyDetection = combatDutyDetection;
|
||||
this.deathHandler = deathHandler;
|
||||
this.dungeonAutomation = dungeonAutomation;
|
||||
base.Size = new Vector2(500f, 400f);
|
||||
base.SizeCondition = ImGuiCond.FirstUseEver;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
ImGui.TextColored(new Vector4(1f, 0.5f, 0f, 1f), " DEBUG MENU - FOR TESTING ONLY ");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(1f, 0.3f, 0.3f, 1f), "Combat Handling");
|
||||
ImGui.Separator();
|
||||
if (combatDutyDetection != null)
|
||||
{
|
||||
ImU8String text = new ImU8String(11, 1);
|
||||
text.AppendLiteral("In Combat: ");
|
||||
text.AppendFormatted(combatDutyDetection.IsInCombat);
|
||||
ImGui.Text(text);
|
||||
ImU8String text2 = new ImU8String(9, 1);
|
||||
text2.AppendLiteral("In Duty: ");
|
||||
text2.AppendFormatted(combatDutyDetection.IsInDuty);
|
||||
ImGui.Text(text2);
|
||||
ImU8String text3 = new ImU8String(15, 1);
|
||||
text3.AppendLiteral("In Duty Queue: ");
|
||||
text3.AppendFormatted(combatDutyDetection.IsInDutyQueue);
|
||||
ImGui.Text(text3);
|
||||
ImU8String text4 = new ImU8String(14, 1);
|
||||
text4.AppendLiteral("Should Pause: ");
|
||||
text4.AppendFormatted(combatDutyDetection.ShouldPauseAutomation);
|
||||
ImGui.Text(text4);
|
||||
ImGui.Spacing();
|
||||
if (ImGui.Button("Test Combat Detection"))
|
||||
{
|
||||
combatDutyDetection.Update();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Manually trigger combat detection update");
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Reset Combat State"))
|
||||
{
|
||||
combatDutyDetection.Reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Combat Detection Service not available");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(1f, 0.3f, 0.3f, 1f), "Death Handling");
|
||||
ImGui.Separator();
|
||||
if (deathHandler != null)
|
||||
{
|
||||
ImU8String text5 = new ImU8String(9, 1);
|
||||
text5.AppendLiteral("Is Dead: ");
|
||||
text5.AppendFormatted(deathHandler.IsDead);
|
||||
ImGui.Text(text5);
|
||||
ImU8String text6 = new ImU8String(19, 1);
|
||||
text6.AppendLiteral("Time Since Death: ");
|
||||
text6.AppendFormatted(deathHandler.TimeSinceDeath.TotalSeconds, "F1");
|
||||
text6.AppendLiteral("s");
|
||||
ImGui.Text(text6);
|
||||
ImGui.Spacing();
|
||||
if (ImGui.Button("Test Death Detection"))
|
||||
{
|
||||
deathHandler.Update();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Manually trigger death detection update");
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Reset Death State"))
|
||||
{
|
||||
deathHandler.Reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Death Handler Service not available");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.TextColored(new Vector4(1f, 0.3f, 0.3f, 1f), "Dungeon Automation");
|
||||
ImGui.Separator();
|
||||
if (dungeonAutomation != null)
|
||||
{
|
||||
ImU8String text7 = new ImU8String(19, 1);
|
||||
text7.AppendLiteral("Waiting for Party: ");
|
||||
text7.AppendFormatted(dungeonAutomation.IsWaitingForParty);
|
||||
ImGui.Text(text7);
|
||||
ImU8String text8 = new ImU8String(20, 1);
|
||||
text8.AppendLiteral("Current Party Size: ");
|
||||
text8.AppendFormatted(dungeonAutomation.CurrentPartySize);
|
||||
ImGui.Text(text8);
|
||||
ImGui.Spacing();
|
||||
if (ImGui.Button("Test Party Invite"))
|
||||
{
|
||||
dungeonAutomation.StartDungeonAutomation();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Test BTB enable + invite + party wait");
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Test Party Disband"))
|
||||
{
|
||||
dungeonAutomation.DisbandParty();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Test party disband with /pcmd breakup");
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Reset Dungeon State"))
|
||||
{
|
||||
dungeonAutomation.Reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Dungeon Automation Service not available");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.TextColored(new Vector4(0.5f, 0.8f, 1f, 1f), "Info");
|
||||
ImGui.Text("This debug menu allows testing of individual features.");
|
||||
ImGui.Text("Use /qstcomp dbg to toggle this window.");
|
||||
}
|
||||
}
|
||||
3368
QuestionableCompanion/QuestionableCompanion.Windows/NewMainWindow.cs
Normal file
3368
QuestionableCompanion/QuestionableCompanion.Windows/NewMainWindow.cs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue