From bbc394c386ecd42cdfa0ad2a3f072262abbb31e6 Mon Sep 17 00:00:00 2001 From: alydev Date: Wed, 19 Nov 2025 12:01:37 +1000 Subject: [PATCH] muffin v7.38.2 --- .../Questionable.QuestPaths.QuestSchema | 8 +- .../AssemblyQuestLoader.cs | 2 +- .../DutyOptions.cs | 2 + .../Questionable.Model.Questing/EDutyMode.cs | 8 + .../Duty.cs | 102 ++- .../Questionable.Data/ChangelogData.cs | 806 +++++++++--------- .../Questionable.External/QuestionableIpc.cs | 103 ++- .../DutyConfigComponent.cs | 138 ++- Questionable/Questionable/Configuration.cs | 4 + .../Questionable/QuestionablePlugin.cs | 1 + 10 files changed, 737 insertions(+), 437 deletions(-) create mode 100644 Questionable.Model/Questionable.Model.Questing/EDutyMode.cs diff --git a/QuestPaths/Questionable.QuestPaths.QuestSchema b/QuestPaths/Questionable.QuestPaths.QuestSchema index 5d78249..c91616d 100644 --- a/QuestPaths/Questionable.QuestPaths.QuestSchema +++ b/QuestPaths/Questionable.QuestPaths.QuestSchema @@ -1606,6 +1606,11 @@ "type": "string" } }, + "DutyMode": { + "type": "integer", + "description": "Overrides the default duty mode for this specific duty. 0 = Duty Support, 1 = Unsync (Solo), 2 = Unsync (Party). If not specified, uses the global configuration setting.", + "enum": [0, 1, 2] + }, "TestedAutoDutyVersion": { "type": "string", "pattern": "^0\\.\\d+\\.\\d+\\.\\d+$" @@ -1625,7 +1630,8 @@ "required": [ "ContentFinderConditionId", "Enabled" - ] + ], + "additionalProperties": false }, "DataId": { "type": "null" diff --git a/QuestPaths/Questionable.QuestPaths/AssemblyQuestLoader.cs b/QuestPaths/Questionable.QuestPaths/AssemblyQuestLoader.cs index e353399..312c020 100644 --- a/QuestPaths/Questionable.QuestPaths/AssemblyQuestLoader.cs +++ b/QuestPaths/Questionable.QuestPaths/AssemblyQuestLoader.cs @@ -35792,7 +35792,7 @@ public static class AssemblyQuestLoader CollectionsMarshal.SetCount(list33, num2); span3 = CollectionsMarshal.AsSpan(list33); index2 = 0; - span3[index2] = new QuestStep(EInteractionType.AcceptQuest, 1002236u, new Vector3(185.10718f, 14.095934f, 677.33264f), 135) + span3[index2] = new QuestStep(EInteractionType.CompleteQuest, 1002236u, new Vector3(185.10718f, 14.095934f, 677.33264f), 135) { AetheryteShortcut = EAetheryteLocation.LowerLaNosceaMorabyDrydocks }; diff --git a/Questionable.Model/Questionable.Model.Questing/DutyOptions.cs b/Questionable.Model/Questionable.Model.Questing/DutyOptions.cs index a9c08d5..2d961eb 100644 --- a/Questionable.Model/Questionable.Model.Questing/DutyOptions.cs +++ b/Questionable.Model/Questionable.Model.Questing/DutyOptions.cs @@ -11,4 +11,6 @@ public class DutyOptions public bool LowPriority { get; set; } public List Notes { get; set; } = new List(); + + public EDutyMode? DutyMode { get; set; } } diff --git a/Questionable.Model/Questionable.Model.Questing/EDutyMode.cs b/Questionable.Model/Questionable.Model.Questing/EDutyMode.cs new file mode 100644 index 0000000..eba16ca --- /dev/null +++ b/Questionable.Model/Questionable.Model.Questing/EDutyMode.cs @@ -0,0 +1,8 @@ +namespace Questionable.Model.Questing; + +public enum EDutyMode +{ + Support, + UnsyncSolo, + UnsyncParty +} diff --git a/Questionable/Questionable.Controller.Steps.Interactions/Duty.cs b/Questionable/Questionable.Controller.Steps.Interactions/Duty.cs index eea2ce7..64dee02 100644 --- a/Questionable/Questionable.Controller.Steps.Interactions/Duty.cs +++ b/Questionable/Questionable.Controller.Steps.Interactions/Duty.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; +using FFXIVClientStructs.FFXIV.Client.Game.Group; using LLib.Gear; +using Microsoft.Extensions.Logging; using Questionable.Controller.Steps.Common; using Questionable.Controller.Steps.Shared; using Questionable.Controller.Utils; @@ -17,7 +19,7 @@ namespace Questionable.Controller.Steps.Interactions; internal static class Duty { - internal sealed class Factory(AutoDutyIpc autoDutyIpc) : ITaskFactory + internal sealed class Factory(AutoDutyIpc autoDutyIpc, Configuration configuration) : ITaskFactory { public IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) { @@ -26,36 +28,94 @@ internal static class Duty yield break; } ArgumentNullException.ThrowIfNull(step.DutyOptions, "step.DutyOptions"); - uint contentFinderConditionId; - int dutyMode; if (autoDutyIpc.IsConfiguredToRunContent(step.DutyOptions)) { - contentFinderConditionId = step.DutyOptions.ContentFinderConditionId; - ElementId id = quest.Id; - if (id is QuestId) + AutoDutyIpc.DutyMode dutyMode = GetDutyMode(step.DutyOptions.ContentFinderConditionId, step.DutyOptions.DutyMode); + if (dutyMode == AutoDutyIpc.DutyMode.UnsyncRegular && (step.DutyOptions.DutyMode == EDutyMode.UnsyncParty || (!step.DutyOptions.DutyMode.HasValue && configuration.Duties.DutyModeOverrides.TryGetValue(step.DutyOptions.ContentFinderConditionId, out var value) && value == EDutyMode.UnsyncParty) || (!step.DutyOptions.DutyMode.HasValue && !configuration.Duties.DutyModeOverrides.ContainsKey(step.DutyOptions.ContentFinderConditionId) && configuration.Duties.DefaultDutyMode == EDutyMode.UnsyncParty))) { - ushort value = id.Value; - if (value >= 357 && value <= 360) - { - dutyMode = 2; - goto IL_00b2; - } + yield return new WaitForPartyTask(); + } + yield return new StartAutoDutyTask(step.DutyOptions.ContentFinderConditionId, dutyMode); + yield return new WaitAutoDutyTask(step.DutyOptions.ContentFinderConditionId); + if (!QuestWorkUtils.HasCompletionFlags(step.CompletionQuestVariablesFlags)) + { + yield return new WaitAtEnd.WaitNextStepOrSequence(); } - dutyMode = 1; - goto IL_00b2; } - if (!step.DutyOptions.LowPriority) + else if (!step.DutyOptions.LowPriority) { yield return new OpenDutyFinderTask(step.DutyOptions.ContentFinderConditionId); } - yield break; - IL_00b2: - yield return new StartAutoDutyTask(contentFinderConditionId, (AutoDutyIpc.DutyMode)dutyMode); - yield return new WaitAutoDutyTask(step.DutyOptions.ContentFinderConditionId); - if (!QuestWorkUtils.HasCompletionFlags(step.CompletionQuestVariablesFlags)) + } + + private AutoDutyIpc.DutyMode GetDutyMode(uint cfcId, EDutyMode? stepDutyMode) + { + if (stepDutyMode.HasValue) { - yield return new WaitAtEnd.WaitNextStepOrSequence(); + return ConvertToAutoDutyMode(stepDutyMode.Value); } + if (configuration.Duties.DutyModeOverrides.TryGetValue(cfcId, out var value)) + { + return ConvertToAutoDutyMode(value); + } + return ConvertToAutoDutyMode(configuration.Duties.DefaultDutyMode); + } + + private static AutoDutyIpc.DutyMode ConvertToAutoDutyMode(EDutyMode mode) + { + return mode switch + { + EDutyMode.Support => AutoDutyIpc.DutyMode.Support, + EDutyMode.UnsyncSolo => AutoDutyIpc.DutyMode.UnsyncRegular, + EDutyMode.UnsyncParty => AutoDutyIpc.DutyMode.UnsyncRegular, + _ => AutoDutyIpc.DutyMode.Support, + }; + } + } + + internal sealed record WaitForPartyTask : ITask + { + public override string ToString() + { + return "WaitForParty"; + } + } + + internal sealed class WaitForPartyExecutor(IChatGui chatGui, ILogger logger) : TaskExecutor() + { + private DateTime _lastWarningTime = DateTime.MinValue; + + protected override bool Start() + { + logger.LogInformation("Waiting for party members before starting duty..."); + return true; + } + + public unsafe override ETaskResult Update() + { + GroupManager* ptr = GroupManager.Instance(); + if (ptr == null) + { + return ETaskResult.StillRunning; + } + byte memberCount = ptr->MainGroup.MemberCount; + bool isAlliance = ptr->MainGroup.IsAlliance; + if (memberCount > 1 || isAlliance) + { + logger.LogInformation("Party detected with {MemberCount} members, proceeding with duty", memberCount); + return ETaskResult.TaskComplete; + } + if (DateTime.Now - _lastWarningTime > TimeSpan.FromSeconds(10L)) + { + chatGui.Print("[Questionable] Waiting for party members before starting duty (Unsync Party mode)...", "Questionable", 576); + _lastWarningTime = DateTime.Now; + } + return ETaskResult.StillRunning; + } + + public override bool ShouldInterruptOnDamage() + { + return false; } } diff --git a/Questionable/Questionable.Data/ChangelogData.cs b/Questionable/Questionable.Data/ChangelogData.cs index 56f6609..b1c315e 100644 --- a/Questionable/Questionable.Data/ChangelogData.cs +++ b/Questionable/Questionable.Data/ChangelogData.cs @@ -11,7 +11,7 @@ internal static class ChangelogData static ChangelogData() { - int num = 36; + int num = 37; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); @@ -24,473 +24,507 @@ internal static class ChangelogData Span span2 = CollectionsMarshal.AsSpan(list2); int num4 = 0; ref ChangeEntry reference2 = ref span2[num4]; - int num5 = 1; + int num5 = 2; List list3 = new List(num5); CollectionsMarshal.SetCount(list3, num5); Span span3 = CollectionsMarshal.AsSpan(list3); - int index = 0; - span3[index] = "Added new fields to quest schema"; - reference2 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list3); + int num6 = 0; + span3[num6] = "Auto Duty unsync options for each duty (Duty Support, Unsync Solo, Unsync Party)"; + num6++; + span3[num6] = "Added Auto Duty unsync options to quest schema and updated quests using old unsync method"; + reference2 = new ChangeEntry(EChangeCategory.Added, "Major features", list3); num4++; ref ChangeEntry reference3 = ref span2[num4]; - index = 3; - List list4 = new List(index); - CollectionsMarshal.SetCount(list4, index); + num6 = 3; + List list4 = new List(num6); + CollectionsMarshal.SetCount(list4, num6); span3 = CollectionsMarshal.AsSpan(list4); num5 = 0; + span3[num5] = "Added IPC for duty sync handling: GetDefaultDutyMode, SetDefaultDutyMode"; + num5++; + span3[num5] = "Added IPC for duty mode overrides: GetDutyModeOverride, SetDutyModeOverride"; + num5++; + span3[num5] = "Added IPC for clearing overrides: ClearDutyModeOverride, ClearAllDutyModeOverrides"; + reference3 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list4); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest (Constant Cravings)"); + reference = new ChangelogEntry("7.38.2", releaseDate, list2); + num2++; + ref ChangelogEntry reference4 = ref span[num2]; + DateOnly releaseDate2 = new DateOnly(2025, 11, 18); + num4 = 3; + List list5 = new List(num4); + CollectionsMarshal.SetCount(list5, num4); + span2 = CollectionsMarshal.AsSpan(list5); + num3 = 0; + ref ChangeEntry reference5 = ref span2[num3]; + num5 = 1; + List list6 = new List(num5); + CollectionsMarshal.SetCount(list6, num5); + span3 = CollectionsMarshal.AsSpan(list6); + num6 = 0; + span3[num6] = "Added new fields to quest schema"; + reference5 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list6); + num3++; + ref ChangeEntry reference6 = ref span2[num3]; + num6 = 3; + List list7 = new List(num6); + CollectionsMarshal.SetCount(list7, num6); + span3 = CollectionsMarshal.AsSpan(list7); + num5 = 0; span3[num5] = "A Faerie Tale Come True"; num5++; span3[num5] = "Constant Cravings"; num5++; span3[num5] = "A Bridge Too Full"; - reference3 = new ChangeEntry(EChangeCategory.QuestUpdates, "Added new quest paths", list4); - num4++; - ref ChangeEntry reference4 = ref span2[num4]; + reference6 = new ChangeEntry(EChangeCategory.QuestUpdates, "Added new quest paths", list7); + num3++; + ref ChangeEntry reference7 = ref span2[num3]; num5 = 3; - List list5 = new List(num5); - CollectionsMarshal.SetCount(list5, num5); - span3 = CollectionsMarshal.AsSpan(list5); - index = 0; - span3[index] = "Fixed various quest schemas"; - index++; - span3[index] = "Fixed changelog bullet point encoding"; - index++; - span3[index] = "Fixed item use to wait until item is used before next action"; - reference4 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list5); - reference = new ChangelogEntry("7.38.1", releaseDate, list2); + List list8 = new List(num5); + CollectionsMarshal.SetCount(list8, num5); + span3 = CollectionsMarshal.AsSpan(list8); + num6 = 0; + span3[num6] = "Fixed various quest schemas"; + num6++; + span3[num6] = "Fixed changelog bullet point encoding"; + num6++; + span3[num6] = "Fixed item use to wait until item is used before next action"; + reference7 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list8); + reference4 = new ChangelogEntry("7.38.1", releaseDate2, list5); num2++; - ref ChangelogEntry reference5 = ref span[num2]; - DateOnly releaseDate2 = new DateOnly(2025, 11, 17); - num4 = 5; - List list6 = new List(num4); - CollectionsMarshal.SetCount(list6, num4); - span2 = CollectionsMarshal.AsSpan(list6); - num3 = 0; - ref ChangeEntry reference6 = ref span2[num3]; - index = 2; - List list7 = new List(index); - CollectionsMarshal.SetCount(list7, index); - span3 = CollectionsMarshal.AsSpan(list7); + ref ChangelogEntry reference8 = ref span[num2]; + DateOnly releaseDate3 = new DateOnly(2025, 11, 17); + num3 = 5; + List list9 = new List(num3); + CollectionsMarshal.SetCount(list9, num3); + span2 = CollectionsMarshal.AsSpan(list9); + num4 = 0; + ref ChangeEntry reference9 = ref span2[num4]; + num6 = 2; + List list10 = new List(num6); + CollectionsMarshal.SetCount(list10, num6); + span3 = CollectionsMarshal.AsSpan(list10); num5 = 0; span3[num5] = "Quest sequence window to show expected sequences in each quest (with quest searching)"; num5++; span3[num5] = "Changelog"; - reference6 = new ChangeEntry(EChangeCategory.Added, "Major features", list7); - num3++; - ref ChangeEntry reference7 = ref span2[num3]; + reference9 = new ChangeEntry(EChangeCategory.Added, "Major features", list10); + num4++; + ref ChangeEntry reference10 = ref span2[num4]; num5 = 2; - List list8 = new List(num5); - CollectionsMarshal.SetCount(list8, num5); - span3 = CollectionsMarshal.AsSpan(list8); - index = 0; - span3[index] = "Updated quest schemas"; - index++; - span3[index] = "Added search bar to preferred mounts and capitalization to mirror game mount names"; - reference7 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list8); - num3++; - ref ChangeEntry reference8 = ref span2[num3]; - index = 3; - List list9 = new List(index); - CollectionsMarshal.SetCount(list9, index); - span3 = CollectionsMarshal.AsSpan(list9); + List list11 = new List(num5); + CollectionsMarshal.SetCount(list11, num5); + span3 = CollectionsMarshal.AsSpan(list11); + num6 = 0; + span3[num6] = "Updated quest schemas"; + num6++; + span3[num6] = "Added search bar to preferred mounts and capitalization to mirror game mount names"; + reference10 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list11); + num4++; + ref ChangeEntry reference11 = ref span2[num4]; + num6 = 3; + List list12 = new List(num6); + CollectionsMarshal.SetCount(list12, num6); + span3 = CollectionsMarshal.AsSpan(list12); num5 = 0; span3[num5] = "Renamed IsQuestCompleted → IsQuestComplete"; num5++; span3[num5] = "Renamed IsQuestAvailable → IsReadyToAcceptQuest"; num5++; span3[num5] = "Added GetCurrentTask IPC"; - reference8 = new ChangeEntry(EChangeCategory.Changed, "IPC changes", list9); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added all Hildibrand quests"); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed credits/cutscenes playback"); - reference5 = new ChangelogEntry("7.38.0", releaseDate2, list6); - num2++; - ref ChangelogEntry reference9 = ref span[num2]; - DateOnly releaseDate3 = new DateOnly(2025, 11, 8); - num3 = 1; - List list10 = new List(num3); - CollectionsMarshal.SetCount(list10, num3); - span2 = CollectionsMarshal.AsSpan(list10); - num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Fall Guys quest (Just Crowning Around)"); - reference9 = new ChangelogEntry("6.38", releaseDate3, list10); - num2++; - ref ChangelogEntry reference10 = ref span[num2]; - DateOnly releaseDate4 = new DateOnly(2025, 11, 8); - num4 = 1; - List list11 = new List(num4); - CollectionsMarshal.SetCount(list11, num4); - span2 = CollectionsMarshal.AsSpan(list11); - num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Cosmic Exploration and various unlock quests"); - reference10 = new ChangelogEntry("6.37", releaseDate4, list11); - num2++; - ref ChangelogEntry reference11 = ref span[num2]; - DateOnly releaseDate5 = new DateOnly(2025, 11, 2); - num3 = 1; - List list12 = new List(num3); - CollectionsMarshal.SetCount(list12, num3); - span2 = CollectionsMarshal.AsSpan(list12); - num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 6 quest (With High Spirits)"); - reference11 = new ChangelogEntry("6.36", releaseDate5, list12); + reference11 = new ChangeEntry(EChangeCategory.Changed, "IPC changes", list12); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added all Hildibrand quests"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed credits/cutscenes playback"); + reference8 = new ChangelogEntry("7.38.0", releaseDate3, list9); num2++; ref ChangelogEntry reference12 = ref span[num2]; - DateOnly releaseDate6 = new DateOnly(2025, 10, 28); + DateOnly releaseDate4 = new DateOnly(2025, 11, 8); num4 = 1; List list13 = new List(num4); CollectionsMarshal.SetCount(list13, num4); span2 = CollectionsMarshal.AsSpan(list13); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed level 3 MSQ handling if character started on non-XP buff world"); - reference12 = new ChangelogEntry("6.35", releaseDate6, list13); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Fall Guys quest (Just Crowning Around)"); + reference12 = new ChangelogEntry("6.38", releaseDate4, list13); num2++; ref ChangelogEntry reference13 = ref span[num2]; - DateOnly releaseDate7 = new DateOnly(2025, 10, 23); - num3 = 2; + DateOnly releaseDate5 = new DateOnly(2025, 11, 8); + num3 = 1; List list14 = new List(num3); CollectionsMarshal.SetCount(list14, num3); span2 = CollectionsMarshal.AsSpan(list14); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.Added, "Added clear priority quests on logout and on completion config settings"); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed priority quest importing to respect import order"); - reference13 = new ChangelogEntry("6.34", releaseDate7, list14); + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Cosmic Exploration and various unlock quests"); + reference13 = new ChangelogEntry("6.37", releaseDate5, list14); num2++; ref ChangelogEntry reference14 = ref span[num2]; - DateOnly releaseDate8 = new DateOnly(2025, 10, 23); + DateOnly releaseDate6 = new DateOnly(2025, 11, 2); num4 = 1; List list15 = new List(num4); CollectionsMarshal.SetCount(list15, num4); span2 = CollectionsMarshal.AsSpan(list15); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed RSR combat module"); - reference14 = new ChangelogEntry("6.33", releaseDate8, list15); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 6 quest (With High Spirits)"); + reference14 = new ChangelogEntry("6.36", releaseDate6, list15); num2++; ref ChangelogEntry reference15 = ref span[num2]; - DateOnly releaseDate9 = new DateOnly(2025, 10, 23); + DateOnly releaseDate7 = new DateOnly(2025, 10, 28); num3 = 1; List list16 = new List(num3); CollectionsMarshal.SetCount(list16, num3); span2 = CollectionsMarshal.AsSpan(list16); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 5 quest (Forged in Corn)"); - reference15 = new ChangelogEntry("6.32", releaseDate9, list16); + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed level 3 MSQ handling if character started on non-XP buff world"); + reference15 = new ChangelogEntry("6.35", releaseDate7, list16); num2++; ref ChangelogEntry reference16 = ref span[num2]; - DateOnly releaseDate10 = new DateOnly(2025, 10, 21); - num4 = 1; + DateOnly releaseDate8 = new DateOnly(2025, 10, 23); + num4 = 2; List list17 = new List(num4); CollectionsMarshal.SetCount(list17, num4); span2 = CollectionsMarshal.AsSpan(list17); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Added checks for moogle and allied society quests when using add all available quests"); - reference16 = new ChangelogEntry("6.31", releaseDate10, list17); + span2[num3] = new ChangeEntry(EChangeCategory.Added, "Added clear priority quests on logout and on completion config settings"); + num3++; + span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed priority quest importing to respect import order"); + reference16 = new ChangelogEntry("6.34", releaseDate8, list17); num2++; ref ChangelogEntry reference17 = ref span[num2]; - DateOnly releaseDate11 = new DateOnly(2025, 10, 21); + DateOnly releaseDate9 = new DateOnly(2025, 10, 23); num3 = 1; List list18 = new List(num3); CollectionsMarshal.SetCount(list18, num3); span2 = CollectionsMarshal.AsSpan(list18); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.Added, "Added button to journal that allows adding all available quests to priority"); - reference17 = new ChangelogEntry("6.30", releaseDate11, list18); + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed RSR combat module"); + reference17 = new ChangelogEntry("6.33", releaseDate9, list18); num2++; ref ChangelogEntry reference18 = ref span[num2]; - DateOnly releaseDate12 = new DateOnly(2025, 10, 20); - num4 = 2; + DateOnly releaseDate10 = new DateOnly(2025, 10, 23); + num4 = 1; List list19 = new List(num4); CollectionsMarshal.SetCount(list19, num4); span2 = CollectionsMarshal.AsSpan(list19); num3 = 0; - ref ChangeEntry reference19 = ref span2[num3]; - num5 = 2; - List list20 = new List(num5); - CollectionsMarshal.SetCount(list20, num5); - span3 = CollectionsMarshal.AsSpan(list20); - index = 0; - span3[index] = "Added item count to combat handling rework"; - index++; - span3[index] = "Updated Pandora conflicting features"; - reference19 = new ChangeEntry(EChangeCategory.Changed, "Combat handling improvements", list20); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest to purchase Gysahl Greens if not in inventory"); - reference18 = new ChangelogEntry("6.29", releaseDate12, list19); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 5 quest (Forged in Corn)"); + reference18 = new ChangelogEntry("6.32", releaseDate10, list19); + num2++; + ref ChangelogEntry reference19 = ref span[num2]; + DateOnly releaseDate11 = new DateOnly(2025, 10, 21); + num3 = 1; + List list20 = new List(num3); + CollectionsMarshal.SetCount(list20, num3); + span2 = CollectionsMarshal.AsSpan(list20); + num4 = 0; + span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Added checks for moogle and allied society quests when using add all available quests"); + reference19 = new ChangelogEntry("6.31", releaseDate11, list20); num2++; ref ChangelogEntry reference20 = ref span[num2]; - DateOnly releaseDate13 = new DateOnly(2025, 10, 19); - num3 = 1; - List list21 = new List(num3); - CollectionsMarshal.SetCount(list21, num3); + DateOnly releaseDate12 = new DateOnly(2025, 10, 21); + num4 = 1; + List list21 = new List(num4); + CollectionsMarshal.SetCount(list21, num4); span2 = CollectionsMarshal.AsSpan(list21); - num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Reworked kill count combat handling - combat and enemy kills are now processed instantly"); - reference20 = new ChangelogEntry("6.28", releaseDate13, list21); + num3 = 0; + span2[num3] = new ChangeEntry(EChangeCategory.Added, "Added button to journal that allows adding all available quests to priority"); + reference20 = new ChangelogEntry("6.30", releaseDate12, list21); num2++; ref ChangelogEntry reference21 = ref span[num2]; - DateOnly releaseDate14 = new DateOnly(2025, 10, 18); - num4 = 2; - List list22 = new List(num4); - CollectionsMarshal.SetCount(list22, num4); + DateOnly releaseDate13 = new DateOnly(2025, 10, 20); + num3 = 2; + List list22 = new List(num3); + CollectionsMarshal.SetCount(list22, num3); span2 = CollectionsMarshal.AsSpan(list22); - num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Improved Aether Current checking logic"); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Chocobo Taxi Stand CheckSkip error and Patch 7.3 Fantasia unlock quest date/time"); - reference21 = new ChangelogEntry("6.27", releaseDate14, list22); - num2++; - ref ChangelogEntry reference22 = ref span[num2]; - DateOnly releaseDate15 = new DateOnly(2025, 10, 18); - num3 = 1; - List list23 = new List(num3); - CollectionsMarshal.SetCount(list23, num3); - span2 = CollectionsMarshal.AsSpan(list23); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests"); - reference22 = new ChangelogEntry("6.26", releaseDate15, list23); + ref ChangeEntry reference22 = ref span2[num4]; + num5 = 2; + List list23 = new List(num5); + CollectionsMarshal.SetCount(list23, num5); + span3 = CollectionsMarshal.AsSpan(list23); + num6 = 0; + span3[num6] = "Added item count to combat handling rework"; + num6++; + span3[num6] = "Updated Pandora conflicting features"; + reference22 = new ChangeEntry(EChangeCategory.Changed, "Combat handling improvements", list23); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest to purchase Gysahl Greens if not in inventory"); + reference21 = new ChangelogEntry("6.29", releaseDate13, list22); num2++; ref ChangelogEntry reference23 = ref span[num2]; - DateOnly releaseDate16 = new DateOnly(2025, 10, 17); + DateOnly releaseDate14 = new DateOnly(2025, 10, 19); num4 = 1; List list24 = new List(num4); CollectionsMarshal.SetCount(list24, num4); span2 = CollectionsMarshal.AsSpan(list24); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added All Saints' Wake 2025 quests and 7.35 Yok Huy rank 4 quests"); - reference23 = new ChangelogEntry("6.25", releaseDate16, list24); + span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Reworked kill count combat handling - combat and enemy kills are now processed instantly"); + reference23 = new ChangelogEntry("6.28", releaseDate14, list24); num2++; ref ChangelogEntry reference24 = ref span[num2]; - DateOnly releaseDate17 = new DateOnly(2025, 10, 16); - num3 = 1; + DateOnly releaseDate15 = new DateOnly(2025, 10, 18); + num3 = 2; List list25 = new List(num3); CollectionsMarshal.SetCount(list25, num3); span2 = CollectionsMarshal.AsSpan(list25); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests and Deep Dungeon quest"); - reference24 = new ChangelogEntry("6.24", releaseDate17, list25); + span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Improved Aether Current checking logic"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Chocobo Taxi Stand CheckSkip error and Patch 7.3 Fantasia unlock quest date/time"); + reference24 = new ChangelogEntry("6.27", releaseDate15, list25); num2++; ref ChangelogEntry reference25 = ref span[num2]; - DateOnly releaseDate18 = new DateOnly(2025, 10, 13); + DateOnly releaseDate16 = new DateOnly(2025, 10, 18); num4 = 1; List list26 = new List(num4); CollectionsMarshal.SetCount(list26, num4); span2 = CollectionsMarshal.AsSpan(list26); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quest (Larder Logistics)"); - reference25 = new ChangelogEntry("6.23", releaseDate18, list26); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests"); + reference25 = new ChangelogEntry("6.26", releaseDate16, list26); num2++; ref ChangelogEntry reference26 = ref span[num2]; - DateOnly releaseDate19 = new DateOnly(2025, 10, 12); - num3 = 3; + DateOnly releaseDate17 = new DateOnly(2025, 10, 17); + num3 = 1; List list27 = new List(num3); CollectionsMarshal.SetCount(list27, num3); span2 = CollectionsMarshal.AsSpan(list27); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Prevent disabled or Locked quests from being started as 'Start as next quest'"); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Yok Huy quest and journal quest chain priority issues"); - reference26 = new ChangelogEntry("6.22", releaseDate19, list27); + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added All Saints' Wake 2025 quests and 7.35 Yok Huy rank 4 quests"); + reference26 = new ChangelogEntry("6.25", releaseDate17, list27); num2++; ref ChangelogEntry reference27 = ref span[num2]; - DateOnly releaseDate20 = new DateOnly(2025, 10, 12); - num4 = 2; + DateOnly releaseDate18 = new DateOnly(2025, 10, 16); + num4 = 1; List list28 = new List(num4); CollectionsMarshal.SetCount(list28, num4); span2 = CollectionsMarshal.AsSpan(list28); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Added, "Added expansion abbreviation to journal window"); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); - reference27 = new ChangelogEntry("6.21", releaseDate20, list28); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests and Deep Dungeon quest"); + reference27 = new ChangelogEntry("6.24", releaseDate18, list28); num2++; ref ChangelogEntry reference28 = ref span[num2]; - DateOnly releaseDate21 = new DateOnly(2025, 10, 10); - num3 = 2; + DateOnly releaseDate19 = new DateOnly(2025, 10, 13); + num3 = 1; List list29 = new List(num3); CollectionsMarshal.SetCount(list29, num3); span2 = CollectionsMarshal.AsSpan(list29); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Allow completed repeatable quests to be used with 'Add quest and requirements to priority' feature"); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 quest (A Work of Cart)"); - reference28 = new ChangelogEntry("6.20", releaseDate21, list29); + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quest (Larder Logistics)"); + reference28 = new ChangelogEntry("6.23", releaseDate19, list29); num2++; ref ChangelogEntry reference29 = ref span[num2]; - DateOnly releaseDate22 = new DateOnly(2025, 10, 9); + DateOnly releaseDate20 = new DateOnly(2025, 10, 12); num4 = 3; List list30 = new List(num4); CollectionsMarshal.SetCount(list30, num4); span2 = CollectionsMarshal.AsSpan(list30); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Added, "Added config to batch Allied Society quest turn-ins"); + span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Prevent disabled or Locked quests from being started as 'Start as next quest'"); num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Repeatable quests now show correct availability state in journal"); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); num3++; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 2 quests"); - reference29 = new ChangelogEntry("6.19", releaseDate22, list30); + span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Yok Huy quest and journal quest chain priority issues"); + reference29 = new ChangelogEntry("6.22", releaseDate20, list30); num2++; ref ChangelogEntry reference30 = ref span[num2]; - DateOnly releaseDate23 = new DateOnly(2025, 10, 9); + DateOnly releaseDate21 = new DateOnly(2025, 10, 12); num3 = 2; List list31 = new List(num3); CollectionsMarshal.SetCount(list31, num3); span2 = CollectionsMarshal.AsSpan(list31); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Show once completed quests with improved state display"); + span2[num4] = new ChangeEntry(EChangeCategory.Added, "Added expansion abbreviation to journal window"); num4++; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy daily quest and improvements to various Yok Huy quests"); - reference30 = new ChangelogEntry("6.18", releaseDate23, list31); + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); + reference30 = new ChangelogEntry("6.21", releaseDate21, list31); num2++; ref ChangelogEntry reference31 = ref span[num2]; - DateOnly releaseDate24 = new DateOnly(2025, 10, 8); - num4 = 1; + DateOnly releaseDate22 = new DateOnly(2025, 10, 10); + num4 = 2; List list32 = new List(num4); CollectionsMarshal.SetCount(list32, num4); span2 = CollectionsMarshal.AsSpan(list32); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 and rank 2 quests"); - reference31 = new ChangelogEntry("6.17", releaseDate24, list32); + span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Allow completed repeatable quests to be used with 'Add quest and requirements to priority' feature"); + num3++; + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 quest (A Work of Cart)"); + reference31 = new ChangelogEntry("6.20", releaseDate22, list32); num2++; ref ChangelogEntry reference32 = ref span[num2]; - DateOnly releaseDate25 = new DateOnly(2025, 10, 8); - num3 = 1; + DateOnly releaseDate23 = new DateOnly(2025, 10, 9); + num3 = 3; List list33 = new List(num3); CollectionsMarshal.SetCount(list33, num3); span2 = CollectionsMarshal.AsSpan(list33); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon quest (Faerie Tale)"); - reference32 = new ChangelogEntry("6.16", releaseDate25, list33); + span2[num4] = new ChangeEntry(EChangeCategory.Added, "Added config to batch Allied Society quest turn-ins"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Repeatable quests now show correct availability state in journal"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 2 quests"); + reference32 = new ChangelogEntry("6.19", releaseDate23, list33); num2++; ref ChangelogEntry reference33 = ref span[num2]; - DateOnly releaseDate26 = new DateOnly(2025, 10, 8); + DateOnly releaseDate24 = new DateOnly(2025, 10, 9); num4 = 2; List list34 = new List(num4); CollectionsMarshal.SetCount(list34, num4); span2 = CollectionsMarshal.AsSpan(list34); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Dalamud cleanup"); + span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Show once completed quests with improved state display"); num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest level requirement check log spam"); - reference33 = new ChangelogEntry("6.15", releaseDate26, list34); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy daily quest and improvements to various Yok Huy quests"); + reference33 = new ChangelogEntry("6.18", releaseDate24, list34); num2++; ref ChangelogEntry reference34 = ref span[num2]; - DateOnly releaseDate27 = new DateOnly(2025, 10, 8); + DateOnly releaseDate25 = new DateOnly(2025, 10, 8); num3 = 1; List list35 = new List(num3); CollectionsMarshal.SetCount(list35, num3); span2 = CollectionsMarshal.AsSpan(list35); num4 = 0; - span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check logic if quest were MSQ"); - reference34 = new ChangelogEntry("6.14", releaseDate27, list35); + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 and rank 2 quests"); + reference34 = new ChangelogEntry("6.17", releaseDate25, list35); num2++; ref ChangelogEntry reference35 = ref span[num2]; - DateOnly releaseDate28 = new DateOnly(2025, 10, 8); - num4 = 2; + DateOnly releaseDate26 = new DateOnly(2025, 10, 8); + num4 = 1; List list36 = new List(num4); CollectionsMarshal.SetCount(list36, num4); span2 = CollectionsMarshal.AsSpan(list36); num3 = 0; - ref ChangeEntry reference36 = ref span2[num3]; - index = 3; - List list37 = new List(index); - CollectionsMarshal.SetCount(list37, index); - span3 = CollectionsMarshal.AsSpan(list37); + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon quest (Faerie Tale)"); + reference35 = new ChangelogEntry("6.16", releaseDate26, list36); + num2++; + ref ChangelogEntry reference36 = ref span[num2]; + DateOnly releaseDate27 = new DateOnly(2025, 10, 8); + num3 = 2; + List list37 = new List(num3); + CollectionsMarshal.SetCount(list37, num3); + span2 = CollectionsMarshal.AsSpan(list37); + num4 = 0; + span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Dalamud cleanup"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest level requirement check log spam"); + reference36 = new ChangelogEntry("6.15", releaseDate27, list37); + num2++; + ref ChangelogEntry reference37 = ref span[num2]; + DateOnly releaseDate28 = new DateOnly(2025, 10, 8); + num4 = 1; + List list38 = new List(num4); + CollectionsMarshal.SetCount(list38, num4); + span2 = CollectionsMarshal.AsSpan(list38); + num3 = 0; + span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check logic if quest were MSQ"); + reference37 = new ChangelogEntry("6.14", releaseDate28, list38); + num2++; + ref ChangelogEntry reference38 = ref span[num2]; + DateOnly releaseDate29 = new DateOnly(2025, 10, 8); + num3 = 2; + List list39 = new List(num3); + CollectionsMarshal.SetCount(list39, num3); + span2 = CollectionsMarshal.AsSpan(list39); + num4 = 0; + ref ChangeEntry reference39 = ref span2[num4]; + num6 = 3; + List list40 = new List(num6); + CollectionsMarshal.SetCount(list40, num6); + span3 = CollectionsMarshal.AsSpan(list40); num5 = 0; span3[num5] = "Context menu option to add required quests and their chain to priority list"; num5++; span3[num5] = "AetheryteShortcut to multiple quests"; num5++; span3[num5] = "Artisan as a recommended plugin/dependency"; - reference36 = new ChangeEntry(EChangeCategory.Added, "Quest improvements", list37); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check and priority list issues"); - reference35 = new ChangelogEntry("6.13", releaseDate28, list36); - num2++; - ref ChangelogEntry reference37 = ref span[num2]; - DateOnly releaseDate29 = new DateOnly(2025, 10, 7); - num3 = 4; - List list38 = new List(num3); - CollectionsMarshal.SetCount(list38, num3); - span2 = CollectionsMarshal.AsSpan(list38); - num4 = 0; - ref ChangeEntry reference38 = ref span2[num4]; - num5 = 4; - List list39 = new List(num5); - CollectionsMarshal.SetCount(list39, num5); - span3 = CollectionsMarshal.AsSpan(list39); - index = 0; - span3[index] = "FATE combat handling with auto level syncing"; - index++; - span3[index] = "Start accepted quests from journal with 'Start as next quest'"; - index++; - span3[index] = "Update quest tracking when quests are hidden or prioritised in game"; - index++; - span3[index] = "QuestMap as a recommended plugin/dependency"; - reference38 = new ChangeEntry(EChangeCategory.Added, "FATE and quest tracking", list39); + reference39 = new ChangeEntry(EChangeCategory.Added, "Quest improvements", list40); num4++; - ref ChangeEntry reference39 = ref span2[num4]; - index = 3; - List list40 = new List(index); - CollectionsMarshal.SetCount(list40, index); - span3 = CollectionsMarshal.AsSpan(list40); + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check and priority list issues"); + reference38 = new ChangelogEntry("6.13", releaseDate29, list39); + num2++; + ref ChangelogEntry reference40 = ref span[num2]; + DateOnly releaseDate30 = new DateOnly(2025, 10, 7); + num4 = 4; + List list41 = new List(num4); + CollectionsMarshal.SetCount(list41, num4); + span2 = CollectionsMarshal.AsSpan(list41); + num3 = 0; + ref ChangeEntry reference41 = ref span2[num3]; + num5 = 4; + List list42 = new List(num5); + CollectionsMarshal.SetCount(list42, num5); + span3 = CollectionsMarshal.AsSpan(list42); + num6 = 0; + span3[num6] = "FATE combat handling with auto level syncing"; + num6++; + span3[num6] = "Start accepted quests from journal with 'Start as next quest'"; + num6++; + span3[num6] = "Update quest tracking when quests are hidden or prioritised in game"; + num6++; + span3[num6] = "QuestMap as a recommended plugin/dependency"; + reference41 = new ChangeEntry(EChangeCategory.Added, "FATE and quest tracking", list42); + num3++; + ref ChangeEntry reference42 = ref span2[num3]; + num6 = 3; + List list43 = new List(num6); + CollectionsMarshal.SetCount(list43, num6); + span3 = CollectionsMarshal.AsSpan(list43); num5 = 0; span3[num5] = "Always prioritise next quest during teleportation/zone transitions"; num5++; span3[num5] = "Improved accepted quest logic with abandoned quest detection"; num5++; span3[num5] = "Show quests without quest paths as Locked"; - reference39 = new ChangeEntry(EChangeCategory.Changed, "Quest prioritisation improvements", list40); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon, Hildibrand, Yok Huy, Monster Hunter Wilds Collab, and Doman Enclave quests"); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed accepted/active quest display and Hildibrand quest issues"); - reference37 = new ChangelogEntry("6.12", releaseDate29, list38); - num2++; - ref ChangelogEntry reference40 = ref span[num2]; - DateOnly releaseDate30 = new DateOnly(2025, 10, 3); - num4 = 1; - List list41 = new List(num4); - CollectionsMarshal.SetCount(list41, num4); - span2 = CollectionsMarshal.AsSpan(list41); - num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Added remaining checks for quest priority to prevent infinite teleport looping"); - reference40 = new ChangelogEntry("6.11", releaseDate30, list41); - num2++; - ref ChangelogEntry reference41 = ref span[num2]; - DateOnly releaseDate31 = new DateOnly(2025, 10, 2); - num3 = 1; - List list42 = new List(num3); - CollectionsMarshal.SetCount(list42, num3); - span2 = CollectionsMarshal.AsSpan(list42); - num4 = 0; - ref ChangeEntry reference42 = ref span2[num4]; - num5 = 2; - List list43 = new List(num5); - CollectionsMarshal.SetCount(list43, num5); - span3 = CollectionsMarshal.AsSpan(list43); - index = 0; - span3[index] = "Don't show quests as available if player doesn't meet level requirements"; - index++; - span3[index] = "Updated 'required for MSQ' text in Crystal Tower quest preset window"; - reference42 = new ChangeEntry(EChangeCategory.Changed, "Quest window improvements", list43); - reference41 = new ChangelogEntry("6.10", releaseDate31, list42); + reference42 = new ChangeEntry(EChangeCategory.Changed, "Quest prioritisation improvements", list43); + num3++; + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon, Hildibrand, Yok Huy, Monster Hunter Wilds Collab, and Doman Enclave quests"); + num3++; + span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed accepted/active quest display and Hildibrand quest issues"); + reference40 = new ChangelogEntry("6.12", releaseDate30, list41); num2++; ref ChangelogEntry reference43 = ref span[num2]; - DateOnly releaseDate32 = new DateOnly(2025, 9, 21); - num4 = 5; - List list44 = new List(num4); - CollectionsMarshal.SetCount(list44, num4); + DateOnly releaseDate31 = new DateOnly(2025, 10, 3); + num3 = 1; + List list44 = new List(num3); + CollectionsMarshal.SetCount(list44, num3); span2 = CollectionsMarshal.AsSpan(list44); + num4 = 0; + span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Added remaining checks for quest priority to prevent infinite teleport looping"); + reference43 = new ChangelogEntry("6.11", releaseDate31, list44); + num2++; + ref ChangelogEntry reference44 = ref span[num2]; + DateOnly releaseDate32 = new DateOnly(2025, 10, 2); + num4 = 1; + List list45 = new List(num4); + CollectionsMarshal.SetCount(list45, num4); + span2 = CollectionsMarshal.AsSpan(list45); num3 = 0; - ref ChangeEntry reference44 = ref span2[num3]; - index = 4; - List list45 = new List(index); - CollectionsMarshal.SetCount(list45, index); - span3 = CollectionsMarshal.AsSpan(list45); + ref ChangeEntry reference45 = ref span2[num3]; + num5 = 2; + List list46 = new List(num5); + CollectionsMarshal.SetCount(list46, num5); + span3 = CollectionsMarshal.AsSpan(list46); + num6 = 0; + span3[num6] = "Don't show quests as available if player doesn't meet level requirements"; + num6++; + span3[num6] = "Updated 'required for MSQ' text in Crystal Tower quest preset window"; + reference45 = new ChangeEntry(EChangeCategory.Changed, "Quest window improvements", list46); + reference44 = new ChangelogEntry("6.10", releaseDate32, list45); + num2++; + ref ChangelogEntry reference46 = ref span[num2]; + DateOnly releaseDate33 = new DateOnly(2025, 9, 21); + num3 = 5; + List list47 = new List(num3); + CollectionsMarshal.SetCount(list47, num3); + span2 = CollectionsMarshal.AsSpan(list47); + num4 = 0; + ref ChangeEntry reference47 = ref span2[num4]; + num6 = 4; + List list48 = new List(num6); + CollectionsMarshal.SetCount(list48, num6); + span3 = CollectionsMarshal.AsSpan(list48); num5 = 0; span3[num5] = "Reworked event quest handling - automatically displays when events are active"; num5++; @@ -499,28 +533,28 @@ internal static class ChangelogData span3[num5] = "Reworked Priority Quests tab (Manual Priority and Quest Presets)"; num5++; span3[num5] = "Quest path viewer site (https://wigglymuffin.github.io/FFXIV-Tools/)"; - reference44 = new ChangeEntry(EChangeCategory.Added, "Major system reworks", list45); - num3++; - ref ChangeEntry reference45 = ref span2[num3]; + reference47 = new ChangeEntry(EChangeCategory.Added, "Major system reworks", list48); + num4++; + ref ChangeEntry reference48 = ref span2[num4]; num5 = 4; - List list46 = new List(num5); - CollectionsMarshal.SetCount(list46, num5); - span3 = CollectionsMarshal.AsSpan(list46); - index = 0; - span3[index] = "Questionable.IsQuestCompleted"; - index++; - span3[index] = "Questionable.IsQuestAvailable"; - index++; - span3[index] = "Questionable.IsQuestAccepted"; - index++; - span3[index] = "Questionable.IsQuestUnobtainable"; - reference45 = new ChangeEntry(EChangeCategory.Added, "New IPC commands", list46); - num3++; - ref ChangeEntry reference46 = ref span2[num3]; - index = 5; - List list47 = new List(index); - CollectionsMarshal.SetCount(list47, index); - span3 = CollectionsMarshal.AsSpan(list47); + List list49 = new List(num5); + CollectionsMarshal.SetCount(list49, num5); + span3 = CollectionsMarshal.AsSpan(list49); + num6 = 0; + span3[num6] = "Questionable.IsQuestCompleted"; + num6++; + span3[num6] = "Questionable.IsQuestAvailable"; + num6++; + span3[num6] = "Questionable.IsQuestAccepted"; + num6++; + span3[num6] = "Questionable.IsQuestUnobtainable"; + reference48 = new ChangeEntry(EChangeCategory.Added, "New IPC commands", list49); + num4++; + ref ChangeEntry reference49 = ref span2[num4]; + num6 = 5; + List list50 = new List(num6); + CollectionsMarshal.SetCount(list50, num6); + span3 = CollectionsMarshal.AsSpan(list50); num5 = 0; span3[num5] = "Improved JSON quest validation with specific error reasons"; num5++; @@ -531,99 +565,99 @@ internal static class ChangelogData span3[num5] = "Improved DialogueChoices regex matching"; num5++; span3[num5] = "Improved refresh checker for all quest states"; - reference46 = new ChangeEntry(EChangeCategory.Changed, "Various improvements", list47); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.31 Occult Crescent quests"); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed cutscene crashes, Single Player Duty triggers, and various quest issues"); - reference43 = new ChangelogEntry("6.9", releaseDate32, list44); + reference49 = new ChangeEntry(EChangeCategory.Changed, "Various improvements", list50); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.31 Occult Crescent quests"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed cutscene crashes, Single Player Duty triggers, and various quest issues"); + reference46 = new ChangelogEntry("6.9", releaseDate33, list47); num2++; - ref ChangelogEntry reference47 = ref span[num2]; - DateOnly releaseDate33 = new DateOnly(2025, 9, 2); - num3 = 4; - List list48 = new List(num3); - CollectionsMarshal.SetCount(list48, num3); - span2 = CollectionsMarshal.AsSpan(list48); - num4 = 0; - ref ChangeEntry reference48 = ref span2[num4]; - num5 = 4; - List list49 = new List(num5); - CollectionsMarshal.SetCount(list49, num5); - span3 = CollectionsMarshal.AsSpan(list49); - index = 0; - span3[index] = "Help commands and priority quest command"; - index++; - span3[index] = "Prevent 'CompleteQuest' step setting"; - index++; - span3[index] = "Duty counts and controls in 'Quest Battles' tab"; - index++; - span3[index] = "'Refresh quest timer' setting (WIP)"; - reference48 = new ChangeEntry(EChangeCategory.Added, "Command and UI improvements", list49); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Improved 'Clear All' buttons to require CTRL being held"); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Zodiac quests and 7.31 Cosmic/Occult Crescent quests"); - num4++; - span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Fishing for Friendship and Cosmic Exploration quests"); - reference47 = new ChangelogEntry("6.8", releaseDate33, list48); - num2++; - ref ChangelogEntry reference49 = ref span[num2]; - DateOnly releaseDate34 = new DateOnly(2025, 8, 27); + ref ChangelogEntry reference50 = ref span[num2]; + DateOnly releaseDate34 = new DateOnly(2025, 9, 2); num4 = 4; - List list50 = new List(num4); - CollectionsMarshal.SetCount(list50, num4); - span2 = CollectionsMarshal.AsSpan(list50); + List list51 = new List(num4); + CollectionsMarshal.SetCount(list51, num4); + span2 = CollectionsMarshal.AsSpan(list51); num3 = 0; - ref ChangeEntry reference50 = ref span2[num3]; - index = 2; - List list51 = new List(index); - CollectionsMarshal.SetCount(list51, index); - span3 = CollectionsMarshal.AsSpan(list51); + ref ChangeEntry reference51 = ref span2[num3]; + num5 = 4; + List list52 = new List(num5); + CollectionsMarshal.SetCount(list52, num5); + span3 = CollectionsMarshal.AsSpan(list52); + num6 = 0; + span3[num6] = "Help commands and priority quest command"; + num6++; + span3[num6] = "Prevent 'CompleteQuest' step setting"; + num6++; + span3[num6] = "Duty counts and controls in 'Quest Battles' tab"; + num6++; + span3[num6] = "'Refresh quest timer' setting (WIP)"; + reference51 = new ChangeEntry(EChangeCategory.Added, "Command and UI improvements", list52); + num3++; + span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Improved 'Clear All' buttons to require CTRL being held"); + num3++; + span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Zodiac quests and 7.31 Cosmic/Occult Crescent quests"); + num3++; + span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Fishing for Friendship and Cosmic Exploration quests"); + reference50 = new ChangelogEntry("6.8", releaseDate34, list51); + num2++; + ref ChangelogEntry reference52 = ref span[num2]; + DateOnly releaseDate35 = new DateOnly(2025, 8, 27); + num3 = 4; + List list53 = new List(num3); + CollectionsMarshal.SetCount(list53, num3); + span2 = CollectionsMarshal.AsSpan(list53); + num4 = 0; + ref ChangeEntry reference53 = ref span2[num4]; + num6 = 2; + List list54 = new List(num6); + CollectionsMarshal.SetCount(list54, num6); + span3 = CollectionsMarshal.AsSpan(list54); num5 = 0; span3[num5] = "Icon to 'Clear All' button in stop conditions"; num5++; span3[num5] = "Duty counts and 'Enable All' button in 'Duties' tab"; - reference50 = new ChangeEntry(EChangeCategory.Added, "UI improvements", list51); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Renamed 'Clear' button to 'Clear All' in priority window"); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Rising 2025 Event Quests"); - num3++; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed clipboard assigning blacklist to whitelist in 'Duties' tab"); - reference49 = new ChangelogEntry("6.7", releaseDate34, list50); - num2++; - ref ChangelogEntry reference51 = ref span[num2]; - DateOnly releaseDate35 = new DateOnly(2025, 8, 25); - num3 = 2; - List list52 = new List(num3); - CollectionsMarshal.SetCount(list52, num3); - span2 = CollectionsMarshal.AsSpan(list52); - num4 = 0; - ref ChangeEntry reference52 = ref span2[num4]; - num5 = 2; - List list53 = new List(num5); - CollectionsMarshal.SetCount(list53, num5); - span3 = CollectionsMarshal.AsSpan(list53); - index = 0; - span3[index] = "Missing emotes to schema and emote handler"; - index++; - span3[index] = "Improved stop conditions with 'Clear All' button"; - reference52 = new ChangeEntry(EChangeCategory.Added, "Emote support and stop conditions", list53); + reference53 = new ChangeEntry(EChangeCategory.Added, "UI improvements", list54); num4++; - span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Stop at level functionality"); - reference51 = new ChangelogEntry("6.6", releaseDate35, list52); + span2[num4] = new ChangeEntry(EChangeCategory.Changed, "Renamed 'Clear' button to 'Clear All' in priority window"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Rising 2025 Event Quests"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed clipboard assigning blacklist to whitelist in 'Duties' tab"); + reference52 = new ChangelogEntry("6.7", releaseDate35, list53); num2++; - ref ChangelogEntry reference53 = ref span[num2]; + ref ChangelogEntry reference54 = ref span[num2]; DateOnly releaseDate36 = new DateOnly(2025, 8, 25); num4 = 2; - List list54 = new List(num4); - CollectionsMarshal.SetCount(list54, num4); - span2 = CollectionsMarshal.AsSpan(list54); + List list55 = new List(num4); + CollectionsMarshal.SetCount(list55, num4); + span2 = CollectionsMarshal.AsSpan(list55); num3 = 0; - span2[num3] = new ChangeEntry(EChangeCategory.Fixed, "Potential fix to single/solo duties softlocking"); + ref ChangeEntry reference55 = ref span2[num3]; + num5 = 2; + List list56 = new List(num5); + CollectionsMarshal.SetCount(list56, num5); + span3 = CollectionsMarshal.AsSpan(list56); + num6 = 0; + span3[num6] = "Missing emotes to schema and emote handler"; + num6++; + span3[num6] = "Improved stop conditions with 'Clear All' button"; + reference55 = new ChangeEntry(EChangeCategory.Added, "Emote support and stop conditions", list56); num3++; - span2[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added San d'Oria: The Second Walk and various side quests"); - reference53 = new ChangelogEntry("6.5", releaseDate36, list54); + span2[num3] = new ChangeEntry(EChangeCategory.Changed, "Stop at level functionality"); + reference54 = new ChangelogEntry("6.6", releaseDate36, list55); + num2++; + ref ChangelogEntry reference56 = ref span[num2]; + DateOnly releaseDate37 = new DateOnly(2025, 8, 25); + num3 = 2; + List list57 = new List(num3); + CollectionsMarshal.SetCount(list57, num3); + span2 = CollectionsMarshal.AsSpan(list57); + num4 = 0; + span2[num4] = new ChangeEntry(EChangeCategory.Fixed, "Potential fix to single/solo duties softlocking"); + num4++; + span2[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added San d'Oria: The Second Walk and various side quests"); + reference56 = new ChangelogEntry("6.5", releaseDate37, list57); Changelogs = list; } } diff --git a/Questionable/Questionable.External/QuestionableIpc.cs b/Questionable/Questionable.External/QuestionableIpc.cs index a961cc7..8b31d7d 100644 --- a/Questionable/Questionable.External/QuestionableIpc.cs +++ b/Questionable/Questionable.External/QuestionableIpc.cs @@ -72,6 +72,18 @@ internal sealed class QuestionableIpc : IDisposable private const string IpcExportQuestPriority = "Questionable.ExportQuestPriority"; + private const string IpcGetDefaultDutyMode = "Questionable.GetDefaultDutyMode"; + + private const string IpcSetDefaultDutyMode = "Questionable.SetDefaultDutyMode"; + + private const string IpcGetDutyModeOverride = "Questionable.GetDutyModeOverride"; + + private const string IpcSetDutyModeOverride = "Questionable.SetDutyModeOverride"; + + private const string IpcClearDutyModeOverride = "Questionable.ClearDutyModeOverride"; + + private const string IpcClearAllDutyModeOverrides = "Questionable.ClearAllDutyModeOverrides"; + private readonly QuestController _questController; private readonly QuestRegistry _questRegistry; @@ -80,6 +92,10 @@ internal sealed class QuestionableIpc : IDisposable private readonly ManualPriorityComponent _manualPriorityComponent; + private readonly Configuration _configuration; + + private readonly IDalamudPluginInterface _pluginInterface; + private readonly ICallGateProvider _isRunning; private readonly ICallGateProvider _getCurrentQuestId; @@ -114,13 +130,27 @@ internal sealed class QuestionableIpc : IDisposable private readonly ICallGateProvider _exportQuestPriority; - public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, ManualPriorityComponent manualPriorityComponent, IDalamudPluginInterface pluginInterface) + private readonly ICallGateProvider _getDefaultDutyMode; + + private readonly ICallGateProvider _setDefaultDutyMode; + + private readonly ICallGateProvider _getDutyModeOverride; + + private readonly ICallGateProvider _setDutyModeOverride; + + private readonly ICallGateProvider _clearDutyModeOverride; + + private readonly ICallGateProvider _clearAllDutyModeOverrides; + + public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, ManualPriorityComponent manualPriorityComponent, Configuration configuration, IDalamudPluginInterface pluginInterface) { QuestionableIpc questionableIpc = this; _questController = questController; _questRegistry = questRegistry; _questFunctions = questFunctions; _manualPriorityComponent = manualPriorityComponent; + _configuration = configuration; + _pluginInterface = pluginInterface; _isRunning = pluginInterface.GetIpcProvider("Questionable.IsRunning"); _isRunning.RegisterFunc(() => questController.AutomationType != QuestController.EAutomationType.Manual || questController.IsRunning); _getCurrentQuestId = pluginInterface.GetIpcProvider("Questionable.GetCurrentQuestId"); @@ -156,6 +186,18 @@ internal sealed class QuestionableIpc : IDisposable _insertQuestPriority.RegisterFunc(InsertQuestPriority); _exportQuestPriority = pluginInterface.GetIpcProvider("Questionable.ExportQuestPriority"); _exportQuestPriority.RegisterFunc(_manualPriorityComponent.EncodeQuestPriority); + _getDefaultDutyMode = pluginInterface.GetIpcProvider("Questionable.GetDefaultDutyMode"); + _getDefaultDutyMode.RegisterFunc(GetDefaultDutyMode); + _setDefaultDutyMode = pluginInterface.GetIpcProvider("Questionable.SetDefaultDutyMode"); + _setDefaultDutyMode.RegisterFunc(SetDefaultDutyMode); + _getDutyModeOverride = pluginInterface.GetIpcProvider("Questionable.GetDutyModeOverride"); + _getDutyModeOverride.RegisterFunc(GetDutyModeOverride); + _setDutyModeOverride = pluginInterface.GetIpcProvider("Questionable.SetDutyModeOverride"); + _setDutyModeOverride.RegisterFunc(SetDutyModeOverride); + _clearDutyModeOverride = pluginInterface.GetIpcProvider("Questionable.ClearDutyModeOverride"); + _clearDutyModeOverride.RegisterFunc(ClearDutyModeOverride); + _clearAllDutyModeOverrides = pluginInterface.GetIpcProvider("Questionable.ClearAllDutyModeOverrides"); + _clearAllDutyModeOverrides.RegisterFunc(ClearAllDutyModeOverrides); } private bool StartQuest(string questId, bool single) @@ -296,8 +338,67 @@ internal sealed class QuestionableIpc : IDisposable return true; } + private int GetDefaultDutyMode() + { + return (int)_configuration.Duties.DefaultDutyMode; + } + + private bool SetDefaultDutyMode(int dutyMode) + { + if (!Enum.IsDefined(typeof(EDutyMode), dutyMode)) + { + return false; + } + _configuration.Duties.DefaultDutyMode = (EDutyMode)dutyMode; + _pluginInterface.SavePluginConfig(_configuration); + return true; + } + + private int GetDutyModeOverride(uint contentFinderConditionId) + { + if (_configuration.Duties.DutyModeOverrides.TryGetValue(contentFinderConditionId, out var value)) + { + return (int)value; + } + return -1; + } + + private bool SetDutyModeOverride(uint contentFinderConditionId, int dutyMode) + { + if (!Enum.IsDefined(typeof(EDutyMode), dutyMode)) + { + return false; + } + _configuration.Duties.DutyModeOverrides[contentFinderConditionId] = (EDutyMode)dutyMode; + _pluginInterface.SavePluginConfig(_configuration); + return true; + } + + private bool ClearDutyModeOverride(uint contentFinderConditionId) + { + bool num = _configuration.Duties.DutyModeOverrides.Remove(contentFinderConditionId); + if (num) + { + _pluginInterface.SavePluginConfig(_configuration); + } + return num; + } + + private bool ClearAllDutyModeOverrides() + { + _configuration.Duties.DutyModeOverrides.Clear(); + _pluginInterface.SavePluginConfig(_configuration); + return true; + } + public void Dispose() { + _clearAllDutyModeOverrides.UnregisterFunc(); + _clearDutyModeOverride.UnregisterFunc(); + _setDutyModeOverride.UnregisterFunc(); + _getDutyModeOverride.UnregisterFunc(); + _setDefaultDutyMode.UnregisterFunc(); + _getDefaultDutyMode.UnregisterFunc(); _exportQuestPriority.UnregisterFunc(); _insertQuestPriority.UnregisterFunc(); _clearQuestPriority.UnregisterFunc(); diff --git a/Questionable/Questionable.Windows.ConfigComponents/DutyConfigComponent.cs b/Questionable/Questionable.Windows.ConfigComponents/DutyConfigComponent.cs index c91dbaa..8c049e8 100644 --- a/Questionable/Questionable.Windows.ConfigComponents/DutyConfigComponent.cs +++ b/Questionable/Questionable.Windows.ConfigComponents/DutyConfigComponent.cs @@ -27,6 +27,10 @@ internal sealed class DutyConfigComponent : ConfigComponent private const string DutyClipboardPrefix = "qst:duty:"; + private const string ModePrefix = "M:"; + + private static readonly string[] DutyModeLabels = new string[3] { "Duty Support", "Unsync (Solo)", "Unsync (Party)" }; + private readonly QuestRegistry _questRegistry; private readonly AutoDutyIpc _autoDutyIpc; @@ -72,6 +76,21 @@ internal sealed class DutyConfigComponent : ConfigComponent } ImGui.SameLine(); ImGuiComponents.HelpMarker("The combat module used for this is configured by AutoDuty, ignoring whichever selection you've made in Questionable's \"General\" configuration."); + using (ImRaii.Disabled(!v)) + { + ImGui.Spacing(); + ImGui.Text("Default duty mode:"); + ImGui.SameLine(); + int currentItem = (int)base.Configuration.Duties.DefaultDutyMode; + ImGui.SetNextItemWidth(200f); + if (ImGui.Combo("##DefaultDutyMode", ref currentItem, in DutyModeLabels, DutyModeLabels.Length)) + { + base.Configuration.Duties.DefaultDutyMode = (EDutyMode)currentItem; + Save(); + } + ImGui.SameLine(); + ImGuiComponents.HelpMarker("\ufffd Duty Support: Run with NPC party members (level synced)\n\ufffd Unsync (Solo): Run alone at your current level (unsynced)\n\ufffd Unsync (Party): Run with your party at current level (unsynced)\n\nYou can override this setting for individual duties below."); + } ImGui.Separator(); using (ImRaii.Disabled(!v)) { @@ -94,7 +113,7 @@ internal sealed class DutyConfigComponent : ConfigComponent private void DrawConfigTable(bool runInstancedContentWithAutoDuty) { - using ImRaii.IEndObject endObject = ImRaii.Child("DutyConfiguration", new Vector2(650f, 400f), border: true); + using ImRaii.IEndObject endObject = ImRaii.Child("DutyConfiguration", new Vector2(950f, 400f), border: true); if (!endObject) { return; @@ -119,44 +138,49 @@ internal sealed class DutyConfigComponent : ConfigComponent ImU8String table = new ImU8String(6, 1); table.AppendLiteral("Duties"); table.AppendFormatted(eExpansionVersion); - using ImRaii.IEndObject endObject2 = ImRaii.Table(table, 2, ImGuiTableFlags.SizingFixedFit); + using ImRaii.IEndObject endObject2 = ImRaii.Table(table, 3, ImGuiTableFlags.SizingFixedFit); if (!ImRaii.IEndObject.op_True(endObject2)) { continue; } ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch); - ImGui.TableSetupColumn("Options", ImGuiTableColumnFlags.WidthFixed, 200f); + ImGui.TableSetupColumn("Enabled", ImGuiTableColumnFlags.WidthFixed, 200f); + ImGui.TableSetupColumn("Mode", ImGuiTableColumnFlags.WidthFixed, 150f); if (!_contentFinderConditionNames.TryGetValue(eExpansionVersion, out List value)) { continue; } - foreach (var (num3, value2, text2) in value) + foreach (DutyInfo item3 in value) { - if (!_questRegistry.TryGetDutyByContentFinderConditionId(num3, out DutyOptions dutyOptions)) + item3.Deconstruct(out uint CfcId, out uint TerritoryId, out string Name); + uint num = CfcId; + uint value2 = TerritoryId; + string text = Name; + if (!_questRegistry.TryGetDutyByContentFinderConditionId(num, out DutyOptions dutyOptions)) { continue; } ImGui.TableNextRow(); string[] items = (dutyOptions.Enabled ? SupportedCfcOptions : UnsupportedCfcOptions); int currentItem = 0; - if (base.Configuration.Duties.WhitelistedDutyCfcIds.Contains(num3)) + if (base.Configuration.Duties.WhitelistedDutyCfcIds.Contains(num)) { currentItem = 1; } - if (base.Configuration.Duties.BlacklistedDutyCfcIds.Contains(num3)) + if (base.Configuration.Duties.BlacklistedDutyCfcIds.Contains(num)) { currentItem = 2; } if (ImGui.TableNextColumn()) { ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(text2); + ImGui.TextUnformatted(text); if (ImGui.IsItemHovered() && base.Configuration.Advanced.AdditionalStatusInformation) { using ImRaii.IEndObject endObject3 = ImRaii.Tooltip(); if (endObject3) { - ImGui.TextUnformatted(text2); + ImGui.TextUnformatted(text); ImGui.Separator(); table = new ImU8String(13, 1); table.AppendLiteral("TerritoryId: "); @@ -164,11 +188,11 @@ internal sealed class DutyConfigComponent : ConfigComponent ImGui.BulletText(table); table = new ImU8String(26, 1); table.AppendLiteral("ContentFinderConditionId: "); - table.AppendFormatted(num3); + table.AppendFormatted(num); ImGui.BulletText(table); } } - if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(num3)) + if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(num)) { ImGuiComponents.HelpMarker("This duty is not supported by AutoDuty", FontAwesomeIcon.Times, ImGuiColors.DalamudRed); } @@ -177,31 +201,72 @@ internal sealed class DutyConfigComponent : ConfigComponent ConfigComponent.DrawNotes(dutyOptions.Enabled, dutyOptions.Notes); } } + if (ImGui.TableNextColumn()) + { + table = new ImU8String(16, 1); + table.AppendLiteral("##DungeonEnabled"); + table.AppendFormatted(num); + using (ImRaii.PushId(table)) + { + ImGui.SetNextItemWidth(200f); + if (ImGui.Combo(string.Empty, ref currentItem, in items, items.Length)) + { + base.Configuration.Duties.WhitelistedDutyCfcIds.Remove(num); + base.Configuration.Duties.BlacklistedDutyCfcIds.Remove(num); + switch (currentItem) + { + case 1: + base.Configuration.Duties.WhitelistedDutyCfcIds.Add(num); + break; + case 2: + base.Configuration.Duties.BlacklistedDutyCfcIds.Add(num); + break; + } + Save(); + } + } + } if (!ImGui.TableNextColumn()) { continue; } - table = new ImU8String(9, 1); - table.AppendLiteral("##Dungeon"); - table.AppendFormatted(num3); + table = new ImU8String(13, 1); + table.AppendLiteral("##DungeonMode"); + table.AppendFormatted(num); using (ImRaii.PushId(table)) { - ImGui.SetNextItemWidth(200f); - if (ImGui.Combo(string.Empty, ref currentItem, in items, items.Length)) + EDutyMode value3; + bool flag = base.Configuration.Duties.DutyModeOverrides.TryGetValue(num, out value3); + EDutyMode num2 = (flag ? value3 : ((EDutyMode)(-1))); + Name = "Use Default"; + string[] dutyModeLabels = DutyModeLabels; + int num3 = 0; + string[] array = new string[1 + dutyModeLabels.Length]; + array[num3] = Name; + num3++; + ReadOnlySpan readOnlySpan = new ReadOnlySpan(dutyModeLabels); + readOnlySpan.CopyTo(new Span(array).Slice(num3, readOnlySpan.Length)); + num3 += readOnlySpan.Length; + string[] items2 = array; + int currentItem2 = (int)(num2 + 1); + ImGui.SetNextItemWidth(150f); + if (ImGui.Combo(string.Empty, ref currentItem2, in items2, items2.Length)) { - base.Configuration.Duties.WhitelistedDutyCfcIds.Remove(num3); - base.Configuration.Duties.BlacklistedDutyCfcIds.Remove(num3); - switch (currentItem) + if (currentItem2 == 0) { - case 1: - base.Configuration.Duties.WhitelistedDutyCfcIds.Add(num3); - break; - case 2: - base.Configuration.Duties.BlacklistedDutyCfcIds.Add(num3); - break; + base.Configuration.Duties.DutyModeOverrides.Remove(num); + } + else + { + base.Configuration.Duties.DutyModeOverrides[num] = (EDutyMode)(currentItem2 - 1); } Save(); } + if (ImGui.IsItemHovered()) + { + EDutyMode eDutyMode = (flag ? value3 : base.Configuration.Duties.DefaultDutyMode); + ImGui.SetTooltip(flag ? ("Override: " + DutyModeLabels[(int)eDutyMode]) : ("Using default: " + DutyModeLabels[(int)eDutyMode])); + } } } } @@ -261,13 +326,14 @@ internal sealed class DutyConfigComponent : ConfigComponent private void DrawClipboardButtons() { - using (ImRaii.Disabled(base.Configuration.Duties.WhitelistedDutyCfcIds.Count + base.Configuration.Duties.BlacklistedDutyCfcIds.Count == 0)) + using (ImRaii.Disabled(base.Configuration.Duties.WhitelistedDutyCfcIds.Count + base.Configuration.Duties.BlacklistedDutyCfcIds.Count + base.Configuration.Duties.DutyModeOverrides.Count == 0)) { if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Copy, "Export to clipboard")) { IEnumerable first = base.Configuration.Duties.WhitelistedDutyCfcIds.Select((uint x) => $"{"+"}{x}"); IEnumerable second = base.Configuration.Duties.BlacklistedDutyCfcIds.Select((uint x) => $"{"-"}{x}"); - ImGui.SetClipboardText("qst:duty:" + Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Join(";", first.Concat(second))))); + IEnumerable second2 = base.Configuration.Duties.DutyModeOverrides.Select((KeyValuePair x) => $"{"M:"}{x.Key}:{x.Value}"); + ImGui.SetClipboardText("qst:duty:" + Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Join(";", first.Concat(second).Concat(second2))))); } } ImGui.SameLine(); @@ -282,6 +348,7 @@ internal sealed class DutyConfigComponent : ConfigComponent string text2 = Encoding.UTF8.GetString(Convert.FromBase64String(text)); base.Configuration.Duties.WhitelistedDutyCfcIds.Clear(); base.Configuration.Duties.BlacklistedDutyCfcIds.Clear(); + base.Configuration.Duties.DutyModeOverrides.Clear(); string[] array = text2.Split(";"); foreach (string text3 in array) { @@ -293,7 +360,22 @@ internal sealed class DutyConfigComponent : ConfigComponent { base.Configuration.Duties.BlacklistedDutyCfcIds.Add(result2); } + if (!text3.StartsWith("M:", StringComparison.InvariantCulture)) + { + continue; + } + ReadOnlySpan span = text3.AsSpan("M:".Length); + int num2 = span.IndexOf(':'); + if (num2 > 0 && uint.TryParse(span.Slice(0, num2), CultureInfo.InvariantCulture, out var result3)) + { + int num3 = num2 + 1; + if (int.TryParse(span.Slice(num3, span.Length - num3), CultureInfo.InvariantCulture, out var result4) && Enum.IsDefined(typeof(EDutyMode), result4)) + { + base.Configuration.Duties.DutyModeOverrides[result3] = (EDutyMode)result4; + } + } } + Save(); } } @@ -305,6 +387,8 @@ internal sealed class DutyConfigComponent : ConfigComponent { base.Configuration.Duties.WhitelistedDutyCfcIds.Clear(); base.Configuration.Duties.BlacklistedDutyCfcIds.Clear(); + base.Configuration.Duties.DutyModeOverrides.Clear(); + base.Configuration.Duties.DefaultDutyMode = EDutyMode.Support; Save(); } } diff --git a/Questionable/Questionable/Configuration.cs b/Questionable/Questionable/Configuration.cs index b0d331a..7be21f3 100644 --- a/Questionable/Questionable/Configuration.cs +++ b/Questionable/Questionable/Configuration.cs @@ -69,6 +69,10 @@ internal sealed class Configuration : IPluginConfiguration public HashSet BlacklistedDutyCfcIds { get; set; } = new HashSet(); + public EDutyMode DefaultDutyMode { get; set; } + + public Dictionary DutyModeOverrides { get; set; } = new Dictionary(); + public Dictionary ExpansionHeaderStates { get; set; } = new Dictionary(); } diff --git a/Questionable/Questionable/QuestionablePlugin.cs b/Questionable/Questionable/QuestionablePlugin.cs index 1bd86de..e8ec30c 100644 --- a/Questionable/Questionable/QuestionablePlugin.cs +++ b/Questionable/Questionable/QuestionablePlugin.cs @@ -153,6 +153,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin, IDisposable serviceCollection.AddTaskFactoryAndExecutor(); serviceCollection.AddTaskFactoryAndExecutor(); serviceCollection.AddTaskFactoryAndExecutor(); + serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskFactory();