564 lines
19 KiB
C#
564 lines
19 KiB
C#
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");
|
|
}
|
|
}
|
|
}
|