forked from aly/qstbak
217 lines
10 KiB
C#
217 lines
10 KiB
C#
using System;
|
|
using System.Numerics;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using Dalamud.Plugin;
|
|
using Questionable.Controller;
|
|
using Questionable.Data;
|
|
|
|
namespace Questionable.Windows.ConfigComponents;
|
|
|
|
internal sealed class QuestsConfigComponent : ConfigComponent
|
|
{
|
|
private static readonly string[] RoleQuestPreferenceNames = new string[6] { "Default (current job)", "Tank", "Healer", "Melee DPS", "Physical Ranged DPS", "Caster" };
|
|
|
|
private readonly string[] _msqPriorityNames = new string[3] { "Always (MSQ first)", "After Tracked (MSQ last)", "Manual (never auto-accept MSQ)" };
|
|
|
|
private readonly QuestRegistry _questRegistry;
|
|
|
|
private readonly TerritoryData _territoryData;
|
|
|
|
public QuestsConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration, QuestRegistry questRegistry, TerritoryData territoryData)
|
|
: base(pluginInterface, configuration)
|
|
{
|
|
_questRegistry = questRegistry;
|
|
_territoryData = territoryData;
|
|
}
|
|
|
|
public override void DrawTab()
|
|
{
|
|
DrawStoryAndProgression();
|
|
UiThemeUtils.SectionSpacing();
|
|
DrawSideContent();
|
|
UiThemeUtils.SectionSpacing();
|
|
DrawPriorityQuests();
|
|
UiThemeUtils.SectionSpacing();
|
|
DrawQuestDetails();
|
|
}
|
|
|
|
private void DrawStoryAndProgression()
|
|
{
|
|
UiThemeUtils.SectionHeader("Story & Progression");
|
|
(Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple = UiThemeUtils.BeginCard();
|
|
Vector2 item = tuple.ContentStartPos;
|
|
float item2 = tuple.AvailableWidth;
|
|
ImDrawListPtr item3 = tuple.DrawList;
|
|
int currentItem = (int)base.Configuration.General.MsqPriority;
|
|
ImGui.SetNextItemWidth(MathF.Min(ImGui.GetContentRegionAvail().X * 0.6f, 260f));
|
|
if (UiThemeUtils.ThemedCombo("MSQ Priority", ref currentItem, _msqPriorityNames, _msqPriorityNames.Length))
|
|
{
|
|
base.Configuration.General.MsqPriority = (Configuration.EMsqPriorityMode)currentItem;
|
|
Save();
|
|
}
|
|
ImGui.SameLine();
|
|
UiThemeUtils.InfoIcon("Controls when the Main Scenario Quest (MSQ) is automatically accepted:\n\n• Always: Auto-accept MSQ immediately\n• After Tracked: Complete accepted quests first, then pick up MSQ\n• Manual: Never auto-accept MSQ, only do manually accepted quests");
|
|
bool value = base.Configuration.General.SkipLowPriorityDuties;
|
|
if (UiThemeUtils.WrappedCheckbox("Unlock certain optional dungeons and raids (instead of waiting for completion)", ref value))
|
|
{
|
|
base.Configuration.General.SkipLowPriorityDuties = value;
|
|
Save();
|
|
}
|
|
ImGui.SameLine();
|
|
UiThemeUtils.InfoIcon(BuildLowPriorityDutyTooltip());
|
|
bool value2 = base.Configuration.Advanced.SkipARealmRebornHardModePrimals;
|
|
if (UiThemeUtils.WrappedCheckbox("Don't pick up ARR hard mode primal quests", ref value2, "Hard mode Ifrit/Garuda/Titan are required for the Patch 2.5 quest 'Good Intentions' and to start Heavensward."))
|
|
{
|
|
base.Configuration.Advanced.SkipARealmRebornHardModePrimals = value2;
|
|
Save();
|
|
}
|
|
bool value3 = base.Configuration.Advanced.SkipCrystalTowerRaids;
|
|
if (UiThemeUtils.WrappedCheckbox("Don't pick up Crystal Tower quests", ref value3, "Crystal Tower raids are required for the Patch 2.55 quest 'A Time to Every Purpose' and to start Heavensward."))
|
|
{
|
|
base.Configuration.Advanced.SkipCrystalTowerRaids = value3;
|
|
Save();
|
|
}
|
|
UiThemeUtils.EndCard(item, item2, item3);
|
|
}
|
|
|
|
private void DrawSideContent()
|
|
{
|
|
UiThemeUtils.SectionHeader("Side Content");
|
|
(Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple = UiThemeUtils.BeginCard();
|
|
Vector2 item = tuple.ContentStartPos;
|
|
float item2 = tuple.AvailableWidth;
|
|
ImDrawListPtr item3 = tuple.DrawList;
|
|
bool value = base.Configuration.Advanced.SkipClassJobQuests;
|
|
if (UiThemeUtils.WrappedCheckbox("Don't pick up class/job quests", ref value, "Class and job skills for A Realm Reborn, Heavensward and (for the Lv70 skills) Stormblood are locked behind quests. Not recommended if you plan on queueing for instances with duty finder/party finder.\n\nNote: This setting is ignored for the first class/job quest if your character is not high enough level to start the level 4 MSQ."))
|
|
{
|
|
base.Configuration.Advanced.SkipClassJobQuests = value;
|
|
Save();
|
|
}
|
|
bool value2 = base.Configuration.Advanced.SkipRoleQuests;
|
|
if (UiThemeUtils.WrappedCheckbox("Don't pick up role quests", ref value2, "At least one Shadowbringers role quest line must be completed for the 5.0 MSQ. Disabling this means you must complete role quests manually."))
|
|
{
|
|
base.Configuration.Advanced.SkipRoleQuests = value2;
|
|
Save();
|
|
}
|
|
using (ImRaii.Disabled(value2))
|
|
{
|
|
using (ImRaii.PushIndent())
|
|
{
|
|
int currentItem = (int)base.Configuration.Advanced.RoleQuestPreference;
|
|
ImGui.SetNextItemWidth(MathF.Min(260f, ImGui.GetContentRegionAvail().X));
|
|
if (UiThemeUtils.ThemedCombo("Role quest line", ref currentItem, RoleQuestPreferenceNames, RoleQuestPreferenceNames.Length))
|
|
{
|
|
base.Configuration.Advanced.RoleQuestPreference = (ERoleQuestPreference)currentItem;
|
|
Save();
|
|
}
|
|
ImGui.SameLine();
|
|
UiThemeUtils.InfoIcon("Which role quest line to prioritize. Default follows your current job's role. Your current job must match the selected role for quests to be picked up.");
|
|
bool value3 = base.Configuration.Advanced.ContinueRoleQuestsAfterShb;
|
|
if (UiThemeUtils.WrappedCheckbox("Continue role quests after Shadowbringers", ref value3, "When enabled, also prioritizes Endwalker and Dawntrail role quests for the selected role. These are not required for MSQ progression."))
|
|
{
|
|
base.Configuration.Advanced.ContinueRoleQuestsAfterShb = value3;
|
|
Save();
|
|
}
|
|
}
|
|
}
|
|
bool value4 = base.Configuration.Advanced.SkipAetherCurrents;
|
|
if (UiThemeUtils.WrappedCheckbox("Don't pick up aether currents/aether current quests", ref value4, "If not done during the MSQ by Questionable, you have to manually pick up any missed aether currents/quests. There is no way to automatically pick up all missing aether currents."))
|
|
{
|
|
base.Configuration.Advanced.SkipAetherCurrents = value4;
|
|
Save();
|
|
}
|
|
bool value5 = base.Configuration.Advanced.AutoPrioritizeAlliedSocietyRankUp;
|
|
if (UiThemeUtils.WrappedCheckbox("Auto-prioritize allied society rank up quests", ref value5, "Automatically prioritizes rank up quests when at reputation capacity, and reorders daily turn-ins to minimize wasted reputation."))
|
|
{
|
|
base.Configuration.Advanced.AutoPrioritizeAlliedSocietyRankUp = value5;
|
|
Save();
|
|
}
|
|
UiThemeUtils.EndCard(item, item2, item3);
|
|
}
|
|
|
|
private void DrawPriorityQuests()
|
|
{
|
|
UiThemeUtils.SectionHeader("Priority Quests");
|
|
(Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple = UiThemeUtils.BeginCard();
|
|
Vector2 item = tuple.ContentStartPos;
|
|
float item2 = tuple.AvailableWidth;
|
|
ImDrawListPtr item3 = tuple.DrawList;
|
|
bool value = base.Configuration.General.PersistPriorityQuestsBetweenSessions;
|
|
if (UiThemeUtils.WrappedCheckbox("Save priority quests between sessions", ref value, "When enabled, your priority quest list will be saved and restored when the plugin reloads or the game restarts."))
|
|
{
|
|
base.Configuration.General.PersistPriorityQuestsBetweenSessions = value;
|
|
Save();
|
|
}
|
|
bool value2 = base.Configuration.General.ClearPriorityQuestsOnLogout;
|
|
if (UiThemeUtils.WrappedCheckbox("Clear priority quests on character logout", ref value2, "Clears the priority queue when your character logs out. This also clears the saved list if persistence is enabled."))
|
|
{
|
|
base.Configuration.General.ClearPriorityQuestsOnLogout = value2;
|
|
Save();
|
|
}
|
|
bool value3 = base.Configuration.General.ClearPriorityQuestsOnCompletion;
|
|
if (UiThemeUtils.WrappedCheckbox("Remove priority quests when completed", ref value3, "Automatically removes completed quests from your priority queue. This helps keep your priority list clean without manual intervention."))
|
|
{
|
|
base.Configuration.General.ClearPriorityQuestsOnCompletion = value3;
|
|
Save();
|
|
}
|
|
UiThemeUtils.EndCard(item, item2, item3);
|
|
}
|
|
|
|
private void DrawQuestDetails()
|
|
{
|
|
UiThemeUtils.SectionHeader("Quest Details");
|
|
var (contentStartPos, availableWidth, drawList) = UiThemeUtils.BeginCard();
|
|
ImGui.AlignTextToFramePadding();
|
|
ImGui.Text("Chocobo Name:");
|
|
ImGui.SameLine();
|
|
string buf = base.Configuration.Advanced.ChocoboName;
|
|
ImGui.SetNextItemWidth(MathF.Min(260f, ImGui.GetContentRegionAvail().X));
|
|
if (ImGui.InputText("##ChocoboName", ref buf, 20))
|
|
{
|
|
base.Configuration.Advanced.ChocoboName = FormatChocoboName(buf);
|
|
Save();
|
|
}
|
|
if (!string.IsNullOrEmpty(buf) && buf.Length < 2)
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(in UiThemeUtils.StatusLocked, "Name must be at least 2 characters");
|
|
}
|
|
ImGui.SameLine();
|
|
UiThemeUtils.InfoIcon("The name to give your chocobo during the 'My Little Chocobo' quest.\nMust be 2-20 characters. First letter will be capitalized.\nIf left empty, defaults to 'Kweh'.");
|
|
bool value = base.Configuration.Advanced.PreventQuestCompletion;
|
|
if (UiThemeUtils.WrappedCheckbox("Prevent quest completion", ref value, "When enabled, Questionable will not attempt to turn-in and complete quests. This will do everything automatically except the final turn-in step."))
|
|
{
|
|
base.Configuration.Advanced.PreventQuestCompletion = value;
|
|
Save();
|
|
}
|
|
UiThemeUtils.EndCard(contentStartPos, availableWidth, drawList);
|
|
}
|
|
|
|
private string BuildLowPriorityDutyTooltip()
|
|
{
|
|
string text = "Questionable automatically picks up some optional quests (e.g. for aether currents, or the ARR alliance raids).\nIf this setting is enabled, Questionable will continue with other quests, instead of waiting for manual completion of the duty.\n\nThis affects the following dungeons and raids:";
|
|
foreach (var lowPriorityContentFinderConditionQuest in _questRegistry.LowPriorityContentFinderConditionQuests)
|
|
{
|
|
if (_territoryData.TryGetContentFinderCondition(lowPriorityContentFinderConditionQuest.ContentFinderConditionId, out TerritoryData.ContentFinderConditionData contentFinderConditionData))
|
|
{
|
|
text = text + "\n• " + contentFinderConditionData.Name;
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private static string FormatChocoboName(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
name = name.Trim();
|
|
if (name.Length == 0)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
return name.Substring(0, 1).ToUpperInvariant() + ((name.Length > 1) ? name.Substring(1).ToLowerInvariant() : string.Empty);
|
|
}
|
|
}
|