1
0
Fork 0
forked from aly/qstbak

muffin v7.4.10

This commit is contained in:
alydev 2026-01-19 08:31:23 +10:00
parent 2df81c5d15
commit b8dd142c23
47 changed files with 3604 additions and 1058 deletions

View file

@ -0,0 +1,248 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
using Questionable.Controller;
using Questionable.Functions;
using Questionable.Model;
using Questionable.Model.Questing;
using Questionable.Windows.QuestComponents;
using Questionable.Windows.Utils;
namespace Questionable.Windows.ConfigComponents;
internal sealed class BlacklistConfigComponent : ConfigComponent
{
private readonly IDalamudPluginInterface _pluginInterface;
private readonly QuestSelector _questSelector;
private readonly QuestRegistry _questRegistry;
private readonly QuestFunctions _questFunctions;
private readonly QuestTooltipComponent _questTooltipComponent;
private readonly UiUtils _uiUtils;
public BlacklistConfigComponent(IDalamudPluginInterface pluginInterface, QuestSelector questSelector, QuestFunctions questFunctions, QuestRegistry questRegistry, QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, Configuration configuration)
: base(pluginInterface, configuration)
{
BlacklistConfigComponent blacklistConfigComponent = this;
_pluginInterface = pluginInterface;
_questSelector = questSelector;
_questRegistry = questRegistry;
_questFunctions = questFunctions;
_questTooltipComponent = questTooltipComponent;
_uiUtils = uiUtils;
_questSelector.SuggestionPredicate = (Quest quest) => !configuration.General.BlacklistedQuests.Contains(quest.Id);
_questSelector.DefaultPredicate = (Quest quest) => !quest.Root.Disabled && questFunctions.IsQuestAccepted(quest.Id);
_questSelector.QuestSelected = delegate(Quest quest)
{
configuration.General.BlacklistedQuests.Add(quest.Id);
blacklistConfigComponent.Save();
};
}
public override void DrawTab()
{
using ImRaii.IEndObject endObject = ImRaii.TabItem("Blacklist###QuestBlacklist");
if (!endObject)
{
return;
}
ImGui.TextWrapped("Blacklisted quests will never be automatically picked up or executed by Questionable.");
ImGui.TextWrapped("Use this to permanently skip specific quests you don't want to do.");
ImGui.Separator();
DrawCurrentlyAcceptedQuests();
HashSet<ElementId> blacklistedQuests = base.Configuration.General.BlacklistedQuests;
ImU8String text = new ImU8String(22, 1);
text.AppendLiteral("Blacklisted Quests (");
text.AppendFormatted(blacklistedQuests.Count);
text.AppendLiteral("):");
ImGui.Text(text);
using (ImRaii.IEndObject endObject2 = ImRaii.Child("BlacklistedQuestsList", new Vector2(-1f, 200f), border: true))
{
if (endObject2)
{
if (blacklistedQuests.Count > 0)
{
ElementId elementId = null;
int num = 0;
foreach (ElementId item in blacklistedQuests.OrderBy((ElementId x) => x.ToString()))
{
if (!_questRegistry.TryGetQuest(item, out Quest quest))
{
ImU8String id = new ImU8String(5, 1);
id.AppendLiteral("Quest");
id.AppendFormatted(item);
using (ImRaii.PushId(id))
{
ImGui.AlignTextToFramePadding();
Vector4 col = new Vector4(0.7f, 0.7f, 0.7f, 1f);
ImU8String text2 = new ImU8String(16, 1);
text2.AppendLiteral("Unknown Quest (");
text2.AppendFormatted(item);
text2.AppendLiteral(")");
ImGui.TextColored(in col, text2);
ImGui.SameLine(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X - ImGui.GetStyle().FramePadding.X * 2f);
if (ImGuiComponents.IconButton($"##Remove{num}", FontAwesomeIcon.Times))
{
elementId = item;
}
}
num++;
continue;
}
ImU8String id2 = new ImU8String(5, 1);
id2.AppendLiteral("Quest");
id2.AppendFormatted(item);
using (ImRaii.PushId(id2))
{
(Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(item);
bool flag;
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
{
ImGui.AlignTextToFramePadding();
ImGui.TextColored(in questStyle.Item1, questStyle.Item2.ToIconString());
flag = ImGui.IsItemHovered();
}
ImGui.SameLine();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(quest.Info.Name);
flag |= ImGui.IsItemHovered();
if (flag)
{
_questTooltipComponent.Draw(quest.Info);
}
ImGui.SameLine(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X - ImGui.GetStyle().FramePadding.X * 2f);
if (ImGuiComponents.IconButton($"##Remove{num}", FontAwesomeIcon.Times))
{
elementId = item;
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Remove from blacklist");
}
}
num++;
}
if (elementId != null)
{
base.Configuration.General.BlacklistedQuests.Remove(elementId);
Save();
}
}
else
{
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.7f, 0.7f, 0.7f, 1f));
ImGui.TextWrapped("No quests blacklisted. Use the dropdown above or add from currently accepted quests.");
ImGui.PopStyleColor();
}
}
}
_questSelector.DrawSelection();
if (blacklistedQuests.Count <= 0)
{
return;
}
using (ImRaii.Disabled(!ImGui.IsKeyDown(ImGuiKey.ModCtrl)))
{
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Trash, "Clear All"))
{
base.Configuration.General.BlacklistedQuests.Clear();
Save();
}
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
{
ImGui.SetTooltip("Hold CTRL to enable this button.");
}
}
private void DrawCurrentlyAcceptedQuests()
{
List<Quest> currentlyAcceptedQuests = GetCurrentlyAcceptedQuests();
ImGui.Text("Currently Accepted Quests:");
using (ImRaii.IEndObject endObject = ImRaii.Child("AcceptedQuestsList", new Vector2(-1f, 100f), border: true))
{
if (endObject)
{
if (currentlyAcceptedQuests.Count > 0)
{
foreach (Quest item in currentlyAcceptedQuests)
{
ImU8String id = new ImU8String(13, 1);
id.AppendLiteral("AcceptedQuest");
id.AppendFormatted(item.Id);
using (ImRaii.PushId(id))
{
(Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(item.Id);
bool flag = false;
bool flag2 = base.Configuration.General.BlacklistedQuests.Contains(item.Id);
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
{
ImGui.AlignTextToFramePadding();
ImGui.TextColored(flag2 ? new Vector4(0.5f, 0.5f, 0.5f, 1f) : questStyle.Item1, questStyle.Item2.ToIconString());
flag = ImGui.IsItemHovered();
}
ImGui.SameLine();
ImGui.AlignTextToFramePadding();
ImGui.TextColored(flag2 ? new Vector4(0.7f, 0.7f, 0.7f, 1f) : new Vector4(1f, 1f, 1f, 1f), item.Info.Name);
if (flag | ImGui.IsItemHovered())
{
_questTooltipComponent.Draw(item.Info);
}
ImGui.SameLine(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize(FontAwesomeIcon.Ban.ToIconString()).X - ImGui.GetStyle().FramePadding.X * 2f);
using (ImRaii.Disabled(flag2))
{
if (ImGuiComponents.IconButton($"##Blacklist{item.Id}", FontAwesomeIcon.Ban))
{
base.Configuration.General.BlacklistedQuests.Add(item.Id);
Save();
}
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
{
ImGui.SetTooltip(flag2 ? "Quest already blacklisted" : "Add this quest to blacklist");
}
}
}
}
else
{
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.7f, 0.7f, 0.7f, 1f));
ImGui.TextWrapped("No quests currently accepted");
ImGui.PopStyleColor();
}
}
}
ImGui.Spacing();
}
private List<Quest> GetCurrentlyAcceptedQuests()
{
List<Quest> list = new List<Quest>();
try
{
foreach (Quest allQuest in _questRegistry.AllQuests)
{
if (_questFunctions.IsQuestAccepted(allQuest.Id))
{
list.Add(allQuest);
}
}
list.Sort((Quest a, Quest b) => string.Compare(a.Info.Name, b.Info.Name, StringComparison.OrdinalIgnoreCase));
}
catch (Exception)
{
list.Clear();
}
return list;
}
}

View file

@ -22,6 +22,8 @@ internal sealed class DebugConfigComponent : ConfigComponent
}
ImGui.TextColored(ImGuiColors.DalamudRed, "Enabling any option here may cause unexpected behavior. Use at your own risk.");
ImGui.Separator();
DrawChocoboSettings();
ImGui.Separator();
bool v = base.Configuration.Advanced.DebugOverlay;
if (ImGui.Checkbox("Enable debug overlay", ref v))
{
@ -120,4 +122,55 @@ internal sealed class DebugConfigComponent : ConfigComponent
ImGuiComponents.HelpMarker("When enabled, Questionable will not attempt to turn-in and complete quests. This will do everything automatically except the final turn-in step.");
}
}
private void DrawChocoboSettings()
{
ImGui.Text("Chocobo Settings");
using (ImRaii.PushIndent())
{
ImGui.AlignTextToFramePadding();
ImGui.Text("Chocobo Name:");
ImGui.SameLine();
string buf = base.Configuration.Advanced.ChocoboName;
ImGui.SetNextItemWidth(200f);
if (ImGui.InputText("##ChocoboName", ref buf, 20))
{
string chocoboName = FormatChocoboName(buf);
base.Configuration.Advanced.ChocoboName = chocoboName;
Save();
}
if (!string.IsNullOrEmpty(buf) && buf.Length < 2)
{
ImGui.SameLine();
ImGui.TextColored(ImGuiColors.DalamudRed, "Name must be at least 2 characters");
}
ImGui.SameLine();
ImGuiComponents.HelpMarker("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'.");
}
}
private static string FormatChocoboName(string name)
{
if (string.IsNullOrEmpty(name))
{
return string.Empty;
}
name = name.Trim();
if (name.Length == 0)
{
return string.Empty;
}
string text = name.Substring(0, 1).ToUpperInvariant();
string text2;
if (name.Length <= 1)
{
text2 = string.Empty;
}
else
{
string text3 = name;
text2 = text3.Substring(1, text3.Length - 1).ToLowerInvariant();
}
return text + text2;
}
}

View file

@ -35,6 +35,8 @@ internal sealed class GeneralConfigComponent : ConfigComponent
private readonly string[] _grandCompanyNames = new string[4] { "None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames" };
private readonly string[] _msqPriorityNames = new string[3] { "Always (MSQ first)", "After Tracked (MSQ last)", "Manual (never auto-accept MSQ)" };
private readonly EClassJob[] _classJobIds;
private readonly string[] _classJobNames;
@ -159,6 +161,28 @@ internal sealed class GeneralConfigComponent : ConfigComponent
base.Configuration.General.GrandCompany = (FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany)currentItem2;
Save();
}
int currentItem3 = (int)base.Configuration.General.MsqPriority;
if (ImGui.Combo((ImU8String)"MSQ Priority", ref currentItem3, (ReadOnlySpan<string>)_msqPriorityNames, _msqPriorityNames.Length))
{
base.Configuration.General.MsqPriority = (Configuration.EMsqPriorityMode)currentItem3;
Save();
}
ImGui.SameLine();
using (ImRaii.PushFont(UiBuilder.IconFont))
{
ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
}
if (ImGui.IsItemHovered())
{
using (ImRaii.Tooltip())
{
ImGui.Text("Controls when the Main Scenario Quest (MSQ) is automatically accepted:");
ImGui.Spacing();
ImGui.BulletText("Always: Auto-accept MSQ immediately");
ImGui.BulletText("After Tracked: Complete accepted quests first, then pick up MSQ");
ImGui.BulletText("Manual: Never auto-accept MSQ, only do manually accepted quests");
}
}
int num3 = Array.IndexOf(_classJobIds, base.Configuration.General.CombatJob);
if (num3 == -1)
{
@ -253,10 +277,48 @@ internal sealed class GeneralConfigComponent : ConfigComponent
ImGui.Text("Questing");
using (ImRaii.PushIndent())
{
bool v7 = base.Configuration.General.CinemaMode;
if (ImGui.Checkbox("Cinema Mode (watch cutscenes)", ref v7))
bool v7 = base.Configuration.General.AutoSolveQte;
if (ImGui.Checkbox("Automatically solve Quick Time Events (QTEs)", ref v7))
{
base.Configuration.General.CinemaMode = v7;
base.Configuration.General.AutoSolveQte = v7;
Save();
}
ImGui.SameLine();
using (ImRaii.PushFont(UiBuilder.IconFont))
{
ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
}
if (ImGui.IsItemHovered())
{
using (ImRaii.Tooltip())
{
ImGui.Text("Automatically mashes the button during Active Time Maneuver (ATM)");
ImGui.Text("prompts that appear in certain duties and quest battles.");
}
}
bool v8 = base.Configuration.General.AutoSnipe;
if (ImGui.Checkbox("Automatically complete snipe quests", ref v8))
{
base.Configuration.General.AutoSnipe = v8;
Save();
}
ImGui.SameLine();
using (ImRaii.PushFont(UiBuilder.IconFont))
{
ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
}
if (ImGui.IsItemHovered())
{
using (ImRaii.Tooltip())
{
ImGui.Text("Automatically completes sniping minigames introduced in Stormblood.");
ImGui.Text("When enabled, snipe targets are instantly hit without manual aiming.");
}
}
bool v9 = base.Configuration.General.CinemaMode;
if (ImGui.Checkbox("Cinema Mode (watch cutscenes)", ref v9))
{
base.Configuration.General.CinemaMode = v9;
Save();
}
ImGui.SameLine();
@ -275,16 +337,16 @@ internal sealed class GeneralConfigComponent : ConfigComponent
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.7f, 1f), "Recommended for first-time story playthroughs.");
}
}
bool v8 = base.Configuration.General.ConfigureTextAdvance;
if (ImGui.Checkbox("Automatically configure TextAdvance with the recommended settings", ref v8))
bool v10 = base.Configuration.General.ConfigureTextAdvance;
if (ImGui.Checkbox("Automatically configure TextAdvance with the recommended settings", ref v10))
{
base.Configuration.General.ConfigureTextAdvance = v8;
base.Configuration.General.ConfigureTextAdvance = v10;
Save();
}
bool v9 = base.Configuration.General.SkipLowPriorityDuties;
if (ImGui.Checkbox("Unlock certain optional dungeons and raids (instead of waiting for completion)", ref v9))
bool v11 = base.Configuration.General.SkipLowPriorityDuties;
if (ImGui.Checkbox("Unlock certain optional dungeons and raids (instead of waiting for completion)", ref v11))
{
base.Configuration.General.SkipLowPriorityDuties = v9;
base.Configuration.General.SkipLowPriorityDuties = v11;
Save();
}
ImGui.SameLine();
@ -312,10 +374,10 @@ internal sealed class GeneralConfigComponent : ConfigComponent
}
}
ImGui.Spacing();
bool v10 = base.Configuration.General.AutoStepRefreshEnabled;
if (ImGui.Checkbox("Automatically refresh quest steps when stuck", ref v10))
bool v12 = base.Configuration.General.AutoStepRefreshEnabled;
if (ImGui.Checkbox("Automatically refresh quest steps when stuck", ref v12))
{
base.Configuration.General.AutoStepRefreshEnabled = v10;
base.Configuration.General.AutoStepRefreshEnabled = v12;
Save();
}
ImGui.SameLine();
@ -331,20 +393,20 @@ internal sealed class GeneralConfigComponent : ConfigComponent
ImGui.Text("This helps resume automated quest completion when interruptions occur.");
}
}
using (ImRaii.Disabled(!v10))
using (ImRaii.Disabled(!v12))
{
ImGui.Indent();
int v11 = base.Configuration.General.AutoStepRefreshDelaySeconds;
int v13 = base.Configuration.General.AutoStepRefreshDelaySeconds;
ImGui.SetNextItemWidth(150f);
if (ImGui.SliderInt("Refresh delay (seconds)", ref v11, 10, 180))
if (ImGui.SliderInt("Refresh delay (seconds)", ref v13, 10, 180))
{
base.Configuration.General.AutoStepRefreshDelaySeconds = v11;
base.Configuration.General.AutoStepRefreshDelaySeconds = v13;
Save();
}
Vector4 col = new Vector4(0.7f, 0.7f, 0.7f, 1f);
ImU8String text4 = new ImU8String(77, 1);
text4.AppendLiteral("Quest steps will refresh automatically after ");
text4.AppendFormatted(v11);
text4.AppendFormatted(v13);
text4.AppendLiteral(" seconds if no progress is made.");
ImGui.TextColored(in col, text4);
ImGui.Unindent();
@ -352,16 +414,48 @@ internal sealed class GeneralConfigComponent : ConfigComponent
ImGui.Spacing();
ImGui.Separator();
ImGui.Text("Priority Quest Management");
bool v12 = base.Configuration.General.ClearPriorityQuestsOnLogout;
if (ImGui.Checkbox("Clear priority quests on character logout", ref v12))
bool v14 = base.Configuration.General.PersistPriorityQuestsBetweenSessions;
if (ImGui.Checkbox("Save priority quests between sessions", ref v14))
{
base.Configuration.General.ClearPriorityQuestsOnLogout = v12;
base.Configuration.General.PersistPriorityQuestsBetweenSessions = v14;
Save();
}
bool v13 = base.Configuration.General.ClearPriorityQuestsOnCompletion;
if (ImGui.Checkbox("Remove priority quests when completed", ref v13))
ImGui.SameLine();
using (ImRaii.PushFont(UiBuilder.IconFont))
{
base.Configuration.General.ClearPriorityQuestsOnCompletion = v13;
ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
}
if (ImGui.IsItemHovered())
{
using (ImRaii.Tooltip())
{
ImGui.Text("When enabled, your priority quest list will be saved and restored");
ImGui.Text("when the plugin reloads or the game restarts.");
}
}
bool v15 = base.Configuration.General.ClearPriorityQuestsOnLogout;
if (ImGui.Checkbox("Clear priority quests on character logout", ref v15))
{
base.Configuration.General.ClearPriorityQuestsOnLogout = v15;
Save();
}
ImGui.SameLine();
using (ImRaii.PushFont(UiBuilder.IconFont))
{
ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
}
if (ImGui.IsItemHovered())
{
using (ImRaii.Tooltip())
{
ImGui.Text("Clears the priority queue when your character logs out.");
ImGui.Text("This also clears the saved list if persistence is enabled.");
}
}
bool v16 = base.Configuration.General.ClearPriorityQuestsOnCompletion;
if (ImGui.Checkbox("Remove priority quests when completed", ref v16))
{
base.Configuration.General.ClearPriorityQuestsOnCompletion = v16;
Save();
}
ImGui.SameLine();

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
@ -13,7 +12,6 @@ using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using Questionable.Controller;
using Questionable.External;
namespace Questionable.Windows.ConfigComponents;
@ -58,7 +56,7 @@ internal sealed class PluginConfigComponent : ConfigComponent
private readonly ICommandManager _commandManager;
public PluginConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration, CombatController combatController, UiUtils uiUtils, ICommandManager commandManager, AutomatonIpc automatonIpc, PandorasBoxIpc pandorasBoxIpc)
public PluginConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration, CombatController combatController, UiUtils uiUtils, ICommandManager commandManager)
: base(pluginInterface, configuration)
{
_configuration = configuration;
@ -66,34 +64,12 @@ internal sealed class PluginConfigComponent : ConfigComponent
_pluginInterface = pluginInterface;
_uiUtils = uiUtils;
_commandManager = commandManager;
PluginInfo[] obj = new PluginInfo[5]
_recommendedPlugins = new global::_003C_003Ez__ReadOnlyArray<PluginInfo>(new PluginInfo[3]
{
new PluginInfo("Artisan", "Artisan", "Handles automatic crafting for quests that require\ncrafted items.", new Uri("https://github.com/PunishXIV/Artisan"), new Uri("https://puni.sh/api/plugins")),
new PluginInfo("AutoDuty", "AutoDuty", "Automatically handles dungeon and trial completion during\nMain Scenario Quest progression.", new Uri("https://github.com/erdelf/AutoDuty"), new Uri("https://puni.sh/api/repository/erdelf")),
null,
null,
null
};
Uri websiteUri = new Uri("https://github.com/Jaksuhn/Automaton");
Uri dalamudRepositoryUri = new Uri("https://puni.sh/api/repository/croizat");
int num = 1;
List<PluginDetailInfo> list = new List<PluginDetailInfo>(num);
CollectionsMarshal.SetCount(list, num);
Span<PluginDetailInfo> span = CollectionsMarshal.AsSpan(list);
int index = 0;
span[index] = new PluginDetailInfo("'Sniper no sniping' enabled", "Automatically completes sniping tasks introduced in Stormblood", () => automatonIpc.IsAutoSnipeEnabled);
obj[2] = new PluginInfo("CBT (formerly known as Automaton)", "Automaton", "Automaton is a collection of automation-related tweaks.", websiteUri, dalamudRepositoryUri, "/cbt", list);
Uri websiteUri2 = new Uri("https://github.com/PunishXIV/PandorasBox");
Uri dalamudRepositoryUri2 = new Uri("https://puni.sh/api/plugins");
index = 1;
List<PluginDetailInfo> list2 = new List<PluginDetailInfo>(index);
CollectionsMarshal.SetCount(list2, index);
Span<PluginDetailInfo> span2 = CollectionsMarshal.AsSpan(list2);
num = 0;
span2[num] = new PluginDetailInfo("'Auto Active Time Maneuver' enabled", "Automatically completes active time maneuvers in\nsingle player instances, trials and raids\"", () => pandorasBoxIpc.IsAutoActiveTimeManeuverEnabled);
obj[3] = new PluginInfo("Pandora's Box", "PandorasBox", "Pandora's Box is a collection of tweaks.", websiteUri2, dalamudRepositoryUri2, "/pandora", list2);
obj[4] = new PluginInfo("QuestMap", "QuestMap", "Displays quest objectives and markers on the map for\nbetter navigation and tracking.", new Uri("https://github.com/rreminy/QuestMap"), null);
_recommendedPlugins = new global::_003C_003Ez__ReadOnlyArray<PluginInfo>(obj);
new PluginInfo("QuestMap", "QuestMap", "Displays quest objectives and markers on the map for\nbetter navigation and tracking.", new Uri("https://github.com/rreminy/QuestMap"), null)
});
}
public override void DrawTab()

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
@ -39,6 +40,8 @@ internal sealed class StopConditionComponent : ConfigComponent
private readonly QuestController _questController;
private ElementId? _draggedItem;
public StopConditionComponent(IDalamudPluginInterface pluginInterface, QuestSelector questSelector, QuestFunctions questFunctions, QuestRegistry questRegistry, QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, IObjectTable objectTable, IClientState clientState, QuestController questController, Configuration configuration)
: base(pluginInterface, configuration)
{
@ -167,112 +170,172 @@ internal sealed class StopConditionComponent : ConfigComponent
ImGui.SetTooltip("Hold CTRL to enable this button.");
}
ImGui.Separator();
ImGui.Text("(Drag arrow buttons to reorder)");
}
Quest quest = null;
for (int i = 0; i < questsToStopAfter.Count; i++)
DrawStopQuestList(questsToStopAfter);
}
}
private void DrawStopQuestList(List<ElementId> questsToStopAfter)
{
Quest quest = null;
Quest quest2 = null;
int index = 0;
float x = ImGui.GetContentRegionAvail().X;
List<(Vector2, Vector2)> list = new List<(Vector2, Vector2)>();
for (int i = 0; i < questsToStopAfter.Count; i++)
{
Vector2 item = ImGui.GetCursorScreenPos() + new Vector2(0f, (0f - ImGui.GetStyle().ItemSpacing.Y) / 2f);
ElementId elementId = questsToStopAfter[i];
if (!_questRegistry.TryGetQuest(elementId, out Quest quest3))
{
ElementId elementId = questsToStopAfter[i];
if (!_questRegistry.TryGetQuest(elementId, out Quest quest2))
continue;
}
ImU8String id = new ImU8String(5, 1);
id.AppendLiteral("Quest");
id.AppendFormatted(elementId);
using (ImRaii.PushId(id))
{
ImGui.AlignTextToFramePadding();
ImU8String text = new ImU8String(1, 1);
text.AppendFormatted(i + 1);
text.AppendLiteral(".");
ImGui.Text(text);
ImGui.SameLine();
(Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(elementId);
bool flag;
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
{
continue;
}
ImU8String id = new ImU8String(5, 1);
id.AppendLiteral("Quest");
id.AppendFormatted(elementId);
using (ImRaii.PushId(id))
{
(Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(elementId);
bool flag;
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
{
ImGui.AlignTextToFramePadding();
ImGui.TextColored(in questStyle.Item1, questStyle.Item2.ToIconString());
flag = ImGui.IsItemHovered();
}
ImGui.SameLine();
ImGui.AlignTextToFramePadding();
ImGui.Text(quest2.Info.Name);
flag |= ImGui.IsItemHovered();
if (flag)
ImGui.TextColored(in questStyle.Item1, questStyle.Item2.ToIconString());
flag = ImGui.IsItemHovered();
}
ImGui.SameLine();
ImGui.AlignTextToFramePadding();
ImGui.Text(quest3.Info.Name);
flag |= ImGui.IsItemHovered();
if (flag)
{
_questTooltipComponent.Draw(quest3.Info);
}
string text2 = elementId.ToString();
int currentItem = (int)base.Configuration.Stop.QuestStopModes.GetValueOrDefault(text2, Questionable.Configuration.EStopConditionMode.Stop);
ImGui.SameLine();
ImGui.SetNextItemWidth(70f);
ImU8String label = new ImU8String(6, 1);
label.AppendLiteral("##Mode");
label.AppendFormatted(text2);
if (ImGui.Combo(label, ref currentItem, (ReadOnlySpan<string>)StopModeNames, StopModeNames.Length))
{
base.Configuration.Stop.QuestStopModes[text2] = (Configuration.EStopConditionMode)currentItem;
Save();
}
ImGui.SameLine();
base.Configuration.Stop.QuestSequences.TryGetValue(text2, out var value);
bool v = value.HasValue;
ImU8String label2 = new ImU8String(8, 1);
label2.AppendLiteral("##UseSeq");
label2.AppendFormatted(text2);
if (ImGui.Checkbox(label2, ref v))
{
if (v)
{
_questTooltipComponent.Draw(quest2.Info);
base.Configuration.Stop.QuestSequences[text2] = 1;
}
string text3 = elementId.ToString();
int currentItem3 = (int)base.Configuration.Stop.QuestStopModes.GetValueOrDefault(text3, Questionable.Configuration.EStopConditionMode.Stop);
ImGui.SameLine();
ImGui.SetNextItemWidth(70f);
ImU8String label = new ImU8String(6, 1);
label.AppendLiteral("##Mode");
label.AppendFormatted(text3);
if (ImGui.Combo(label, ref currentItem3, (ReadOnlySpan<string>)StopModeNames, StopModeNames.Length))
else
{
if (currentItem3 == 0)
{
quest = quest2;
}
else
{
base.Configuration.Stop.QuestStopModes[text3] = (Configuration.EStopConditionMode)currentItem3;
Save();
}
base.Configuration.Stop.QuestSequences.Remove(text2);
}
Save();
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Stop at specific sequence (unchecked = stop on quest completion)");
}
using (ImRaii.Disabled(!v))
{
ImGui.SameLine();
base.Configuration.Stop.QuestSequences.TryGetValue(text3, out var value);
bool v2 = value.HasValue;
ImU8String label2 = new ImU8String(8, 1);
label2.AppendLiteral("##UseSeq");
label2.AppendFormatted(text3);
if (ImGui.Checkbox(label2, ref v2))
ImGui.Text("Seq:");
ImGui.SameLine();
ImGui.SetNextItemWidth(85f);
int data = value ?? 1;
ImU8String label3 = new ImU8String(10, 1);
label3.AppendLiteral("##SeqValue");
label3.AppendFormatted(text2);
if (ImGui.InputInt(label3, ref data, 1, 1) && v)
{
if (v2)
{
base.Configuration.Stop.QuestSequences[text3] = 1;
}
else
{
base.Configuration.Stop.QuestSequences.Remove(text3);
}
base.Configuration.Stop.QuestSequences[text2] = Math.Max(0, Math.Min(255, data));
Save();
}
if (ImGui.IsItemHovered())
}
if (questsToStopAfter.Count > 1)
{
using (ImRaii.PushFont(UiBuilder.IconFont))
{
ImGui.SetTooltip("Stop at specific sequence (unchecked = stop on quest completion)");
ImGui.SameLine(ImGui.GetContentRegionAvail().X + ImGui.GetStyle().WindowPadding.X - ImGui.CalcTextSize(FontAwesomeIcon.ArrowsUpDown.ToIconString()).X - ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X - ImGui.GetStyle().FramePadding.X * 4f - ImGui.GetStyle().ItemSpacing.X);
}
using (ImRaii.Disabled(!v2))
if (_draggedItem == elementId)
{
ImGui.SameLine();
ImGui.Text("Seq:");
ImGui.SameLine();
ImGui.SetNextItemWidth(85f);
int data3 = value ?? 1;
ImU8String label3 = new ImU8String(10, 1);
label3.AppendLiteral("##SeqValue");
label3.AppendFormatted(text3);
if (ImGui.InputInt(label3, ref data3, 1, 1) && v2)
{
base.Configuration.Stop.QuestSequences[text3] = Math.Max(0, Math.Min(255, data3));
Save();
}
ImGuiComponents.IconButton("##Move", FontAwesomeIcon.ArrowsUpDown, ImGui.ColorConvertU32ToFloat4(ImGui.GetColorU32(ImGuiCol.ButtonActive)));
}
else
{
ImGuiComponents.IconButton("##Move", FontAwesomeIcon.ArrowsUpDown);
}
if (_draggedItem == null && ImGui.IsItemActive() && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
{
_draggedItem = elementId;
}
ImGui.SameLine();
}
else
{
using (ImRaii.PushFont(UiBuilder.IconFont))
{
ImGui.SameLine(ImGui.GetContentRegionAvail().X + ImGui.GetStyle().WindowPadding.X - ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X - ImGui.GetStyle().FramePadding.X * 2f);
}
if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times))
{
quest = quest2;
}
}
if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times))
{
quest = quest3;
}
}
if (quest != null)
Vector2 item2 = new Vector2(item.X + x, ImGui.GetCursorScreenPos().Y - ImGui.GetStyle().ItemSpacing.Y + 2f);
list.Add((item, item2));
}
if (!ImGui.IsMouseDragging(ImGuiMouseButton.Left))
{
_draggedItem = null;
}
else if (_draggedItem != null)
{
int num = questsToStopAfter.FindIndex((ElementId elementId2) => elementId2 == _draggedItem);
if (num >= 0 && num < list.Count)
{
string key2 = quest.Id.ToString();
base.Configuration.Stop.QuestsToStopAfter.Remove(quest.Id);
base.Configuration.Stop.QuestSequences.Remove(key2);
base.Configuration.Stop.QuestStopModes.Remove(key2);
Save();
var (pMin, pMax) = list[num];
ImGui.GetWindowDrawList().AddRect(pMin, pMax, ImGui.GetColorU32(ImGuiColors.DalamudGrey), 3f, ImDrawFlags.RoundCornersAll);
int num2 = list.FindIndex(((Vector2 TopLeft, Vector2 BottomRight) tuple2) => ImGui.IsMouseHoveringRect(tuple2.TopLeft, tuple2.BottomRight, clip: true));
if (num2 >= 0 && num != num2)
{
quest2 = (_questRegistry.TryGetQuest(_draggedItem, out Quest quest4) ? quest4 : null);
index = num2;
}
}
}
if (quest != null)
{
string key = quest.Id.ToString();
base.Configuration.Stop.QuestsToStopAfter.Remove(quest.Id);
base.Configuration.Stop.QuestSequences.Remove(key);
base.Configuration.Stop.QuestStopModes.Remove(key);
Save();
}
if (quest2 != null)
{
questsToStopAfter.Remove(quest2.Id);
questsToStopAfter.Insert(index, quest2.Id);
Save();
}
}
private void DrawCurrentlyAcceptedQuests()