diff --git a/Questionable/Questionable.Controller.GameUi/CreditsController.cs b/Questionable/Questionable.Controller.GameUi/CreditsController.cs index 771e883..c184d1f 100644 --- a/Questionable/Questionable.Controller.GameUi/CreditsController.cs +++ b/Questionable/Questionable.Controller.GameUi/CreditsController.cs @@ -52,13 +52,16 @@ internal sealed class CreditsController : IDisposable private readonly IAddonLifecycle _addonLifecycle; + private readonly Configuration _configuration; + private readonly ILogger _logger; private static readonly object _lock = new object(); - public CreditsController(IAddonLifecycle addonLifecycle, ILogger logger) + public CreditsController(IAddonLifecycle addonLifecycle, Configuration configuration, ILogger logger) { _addonLifecycle = addonLifecycle; + _configuration = configuration; _logger = logger; lock (_lock) { @@ -105,6 +108,11 @@ internal sealed class CreditsController : IDisposable private void HandleCutscene(Action nativeAction, AddonArgs args) { + if (_configuration.General.CinemaMode) + { + _logger.LogDebug("HandleCutscene: Cinema Mode enabled, not skipping cutscene."); + return; + } long num = ((args.Addon.Address == IntPtr.Zero) ? 0 : ((IntPtr)args.Addon.Address).ToInt64()); if (num == 0L) { diff --git a/Questionable/Questionable.Controller.Utils/PartyWatchDog.cs b/Questionable/Questionable.Controller.Utils/PartyWatchDog.cs index 0ae0983..c5767af 100644 --- a/Questionable/Questionable.Controller.Utils/PartyWatchDog.cs +++ b/Questionable/Questionable.Controller.Utils/PartyWatchDog.cs @@ -4,24 +4,32 @@ using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.Group; using LLib.GameData; using Microsoft.Extensions.Logging; +using Questionable.Data; +using Questionable.Model.Questing; namespace Questionable.Controller.Utils; -internal sealed class PartyWatchDog : IDisposable +internal sealed class PartyWatchdog : IDisposable { private readonly QuestController _questController; + private readonly Configuration _configuration; + + private readonly TerritoryData _territoryData; + private readonly IClientState _clientState; private readonly IChatGui _chatGui; - private readonly ILogger _logger; + private readonly ILogger _logger; private ushort? _uncheckedTeritoryId; - public PartyWatchDog(QuestController questController, IClientState clientState, IChatGui chatGui, ILogger logger) + public PartyWatchdog(QuestController questController, Configuration configuration, TerritoryData territoryData, IClientState clientState, IChatGui chatGui, ILogger logger) { _questController = questController; + _configuration = configuration; + _territoryData = territoryData; _clientState = clientState; _chatGui = chatGui; _logger = logger; @@ -30,92 +38,116 @@ internal sealed class PartyWatchDog : IDisposable private unsafe void TerritoryChanged(ushort newTerritoryId) { - switch ((ETerritoryIntendedUse)GameMain.Instance()->CurrentTerritoryIntendedUseId) + if (!_configuration.Advanced.DisablePartyWatchdog) { - case ETerritoryIntendedUse.Gaol: - case ETerritoryIntendedUse.Frontline: - case ETerritoryIntendedUse.LordOfVerminion: - case ETerritoryIntendedUse.Diadem: - case ETerritoryIntendedUse.CrystallineConflict: - case ETerritoryIntendedUse.DeepDungeon: - case ETerritoryIntendedUse.TreasureMapDuty: - case ETerritoryIntendedUse.Battlehall: - case ETerritoryIntendedUse.CrystallineConflict2: - case ETerritoryIntendedUse.Diadem2: - case ETerritoryIntendedUse.RivalWings: - case ETerritoryIntendedUse.Eureka: - case ETerritoryIntendedUse.LeapOfFaith: - case ETerritoryIntendedUse.OceanFishing: - case ETerritoryIntendedUse.Diadem3: - case ETerritoryIntendedUse.Bozja: - case ETerritoryIntendedUse.Battlehall2: - case ETerritoryIntendedUse.Battlehall3: - case ETerritoryIntendedUse.LargeScaleRaid: - case ETerritoryIntendedUse.LargeScaleSavageRaid: - case ETerritoryIntendedUse.Blunderville: - StopIfRunning($"Unsupported Area entered ({newTerritoryId})"); - break; - case ETerritoryIntendedUse.Dungeon: - case ETerritoryIntendedUse.VariantDungeon: - case ETerritoryIntendedUse.AllianceRaid: - case ETerritoryIntendedUse.Trial: - case ETerritoryIntendedUse.Raid: - case ETerritoryIntendedUse.Raid2: - case ETerritoryIntendedUse.SeasonalEvent: - case ETerritoryIntendedUse.SeasonalEvent2: - case ETerritoryIntendedUse.CriterionDuty: - case ETerritoryIntendedUse.CriterionSavageDuty: - _uncheckedTeritoryId = newTerritoryId; - _logger.LogInformation("Will check territory {TerritoryId} after loading", newTerritoryId); - break; - case ETerritoryIntendedUse.StartingArea: - case ETerritoryIntendedUse.QuestArea: - case ETerritoryIntendedUse.QuestBattle: - case (ETerritoryIntendedUse)11: - case ETerritoryIntendedUse.QuestArea2: - case ETerritoryIntendedUse.ResidentialArea: - case ETerritoryIntendedUse.HousingInstances: - case ETerritoryIntendedUse.QuestArea3: - case (ETerritoryIntendedUse)19: - case ETerritoryIntendedUse.ChocoboSquare: - case ETerritoryIntendedUse.RestorationEvent: - case ETerritoryIntendedUse.Sanctum: - case ETerritoryIntendedUse.GoldSaucer: - case (ETerritoryIntendedUse)24: - case ETerritoryIntendedUse.HallOfTheNovice: - case ETerritoryIntendedUse.QuestBattle2: - case ETerritoryIntendedUse.Barracks: - case ETerritoryIntendedUse.SeasonalEventDuty: - case (ETerritoryIntendedUse)36: - case ETerritoryIntendedUse.Unknown1: - case (ETerritoryIntendedUse)42: - case ETerritoryIntendedUse.MaskedCarnivale: - case ETerritoryIntendedUse.IslandSanctuary: - case ETerritoryIntendedUse.QuestArea4: - case (ETerritoryIntendedUse)55: - case ETerritoryIntendedUse.TribalInstance: - break; + switch ((ETerritoryIntendedUse)GameMain.Instance()->CurrentTerritoryIntendedUseId) + { + case ETerritoryIntendedUse.Gaol: + case ETerritoryIntendedUse.Frontline: + case ETerritoryIntendedUse.LordOfVerminion: + case ETerritoryIntendedUse.Diadem: + case ETerritoryIntendedUse.CrystallineConflict: + case ETerritoryIntendedUse.DeepDungeon: + case ETerritoryIntendedUse.TreasureMapDuty: + case ETerritoryIntendedUse.Battlehall: + case ETerritoryIntendedUse.CrystallineConflict2: + case ETerritoryIntendedUse.Diadem2: + case ETerritoryIntendedUse.RivalWings: + case ETerritoryIntendedUse.Eureka: + case ETerritoryIntendedUse.LeapOfFaith: + case ETerritoryIntendedUse.OceanFishing: + case ETerritoryIntendedUse.Diadem3: + case ETerritoryIntendedUse.Bozja: + case ETerritoryIntendedUse.Battlehall2: + case ETerritoryIntendedUse.Battlehall3: + case ETerritoryIntendedUse.LargeScaleRaid: + case ETerritoryIntendedUse.LargeScaleSavageRaid: + case ETerritoryIntendedUse.Blunderville: + StopIfRunning($"Unsupported Area entered ({newTerritoryId})"); + break; + case ETerritoryIntendedUse.Dungeon: + case ETerritoryIntendedUse.VariantDungeon: + case ETerritoryIntendedUse.AllianceRaid: + case ETerritoryIntendedUse.Trial: + case ETerritoryIntendedUse.Raid: + case ETerritoryIntendedUse.Raid2: + case ETerritoryIntendedUse.SeasonalEvent: + case ETerritoryIntendedUse.SeasonalEvent2: + case ETerritoryIntendedUse.CriterionDuty: + case ETerritoryIntendedUse.CriterionSavageDuty: + _uncheckedTeritoryId = newTerritoryId; + _logger.LogInformation("Will check territory {TerritoryId} after loading", newTerritoryId); + break; + case ETerritoryIntendedUse.StartingArea: + case ETerritoryIntendedUse.QuestArea: + case ETerritoryIntendedUse.QuestBattle: + case (ETerritoryIntendedUse)11: + case ETerritoryIntendedUse.QuestArea2: + case ETerritoryIntendedUse.ResidentialArea: + case ETerritoryIntendedUse.HousingInstances: + case ETerritoryIntendedUse.QuestArea3: + case (ETerritoryIntendedUse)19: + case ETerritoryIntendedUse.ChocoboSquare: + case ETerritoryIntendedUse.RestorationEvent: + case ETerritoryIntendedUse.Sanctum: + case ETerritoryIntendedUse.GoldSaucer: + case (ETerritoryIntendedUse)24: + case ETerritoryIntendedUse.HallOfTheNovice: + case ETerritoryIntendedUse.QuestBattle2: + case ETerritoryIntendedUse.Barracks: + case ETerritoryIntendedUse.SeasonalEventDuty: + case (ETerritoryIntendedUse)36: + case ETerritoryIntendedUse.Unknown1: + case (ETerritoryIntendedUse)42: + case ETerritoryIntendedUse.MaskedCarnivale: + case ETerritoryIntendedUse.IslandSanctuary: + case ETerritoryIntendedUse.QuestArea4: + case (ETerritoryIntendedUse)55: + case ETerritoryIntendedUse.TribalInstance: + break; + } } } public unsafe void Update() { - if (_uncheckedTeritoryId != _clientState.TerritoryType || GameMain.Instance()->TerritoryLoadState != 2) + if (_configuration.Advanced.DisablePartyWatchdog || _uncheckedTeritoryId != _clientState.TerritoryType || GameMain.Instance()->TerritoryLoadState != 2) { return; } GroupManager* ptr = GroupManager.Instance(); - if (ptr != null) + if (ptr == null) { - byte memberCount = ptr->MainGroup.MemberCount; - bool isAlliance = ptr->MainGroup.IsAlliance; - _logger.LogDebug("Territory {TerritoryId} with {MemberCount} members, alliance: {IsInAlliance}", _uncheckedTeritoryId, memberCount, isAlliance); - if (memberCount > 1 || isAlliance) + return; + } + byte memberCount = ptr->MainGroup.MemberCount; + bool isAlliance = ptr->MainGroup.IsAlliance; + _logger.LogDebug("Territory {TerritoryId} with {MemberCount} members, alliance: {IsInAlliance}", _uncheckedTeritoryId, memberCount, isAlliance); + if (memberCount > 1 || isAlliance) + { + if (!IsDutyConfiguredForParty(_uncheckedTeritoryId.Value)) { StopIfRunning("Other party members present"); } - _uncheckedTeritoryId = null; + else + { + _logger.LogInformation("Party detected but duty is configured for Unsync (Party) mode, continuing"); + } } + _uncheckedTeritoryId = null; + } + + private bool IsDutyConfiguredForParty(ushort territoryId) + { + if (!_territoryData.TryGetContentFinderConditionIdForTerritory(territoryId, out var cfcId)) + { + return false; + } + if (_configuration.Duties.DutyModeOverrides.TryGetValue(cfcId, out var value)) + { + return value == EDutyMode.UnsyncParty; + } + return _configuration.Duties.DefaultDutyMode == EDutyMode.UnsyncParty; } private void StopIfRunning(string reason) diff --git a/Questionable/Questionable.Controller/QuestController.cs b/Questionable/Questionable.Controller/QuestController.cs index c0f2935..8f29938 100644 --- a/Questionable/Questionable.Controller/QuestController.cs +++ b/Questionable/Questionable.Controller/QuestController.cs @@ -361,6 +361,13 @@ internal sealed class QuestController : MiniTaskController if (_configuration.Stop.Enabled && _startedQuest != null) { string text = _startedQuest.Quest.Id.ToString(); + if (_configuration.Stop.LevelToStopAfter && IsRunning && _objectTable[0] is IPlayerCharacter playerCharacter && playerCharacter.Level >= _configuration.Stop.TargetLevel) + { + _logger.LogInformation("Reached level stop condition (current: {CurrentLevel}, target: {TargetLevel})", playerCharacter.Level, _configuration.Stop.TargetLevel); + _chatGui.Print($"Character level {playerCharacter.Level} reached target level {_configuration.Stop.TargetLevel}.", "Questionable", 576); + Stop($"Level stop condition reached [{playerCharacter.Level}]"); + return; + } if (_configuration.Stop.QuestSequences.TryGetValue(text, out var value) && value.HasValue) { int sequence = _startedQuest.Sequence; @@ -395,17 +402,17 @@ internal sealed class QuestController : MiniTaskController if (step == 0 || step == 255) { flag2 = true; - goto IL_054c; + goto IL_0691; } } flag2 = false; - goto IL_054c; + goto IL_0691; } - goto IL_0550; - IL_054c: + goto IL_0695; + IL_0691: flag = flag2; - goto IL_0550; - IL_0550: + goto IL_0695; + IL_0695: if (flag && DateTime.Now >= CurrentQuest.StepProgress.StartedAt.AddSeconds(15.0)) { lock (_progressLock) @@ -958,8 +965,11 @@ internal sealed class QuestController : MiniTaskController { using (_logger.BeginScope("Q/" + label)) { - AutomationType = EAutomationType.Automatic; - ExecuteNextStep(); + if (!CheckAndBlockForStopConditions()) + { + AutomationType = EAutomationType.Automatic; + ExecuteNextStep(); + } } } @@ -967,8 +977,11 @@ internal sealed class QuestController : MiniTaskController { using (_logger.BeginScope("GQ/" + label)) { - AutomationType = EAutomationType.GatheringOnly; - ExecuteNextStep(); + if (!CheckAndBlockForStopConditions()) + { + AutomationType = EAutomationType.GatheringOnly; + ExecuteNextStep(); + } } } @@ -976,8 +989,11 @@ internal sealed class QuestController : MiniTaskController { using (_logger.BeginScope("SQ/" + label)) { - AutomationType = EAutomationType.SingleQuestA; - ExecuteNextStep(); + if (!CheckAndBlockForStopConditions()) + { + AutomationType = EAutomationType.SingleQuestA; + ExecuteNextStep(); + } } } @@ -990,6 +1006,65 @@ internal sealed class QuestController : MiniTaskController } } + private bool CheckAndBlockForStopConditions() + { + if (!_configuration.Stop.Enabled) + { + return false; + } + if (_configuration.Stop.LevelToStopAfter && _objectTable[0] is IPlayerCharacter playerCharacter && playerCharacter.Level >= _configuration.Stop.TargetLevel) + { + _logger.LogInformation("Blocking start: Level stop condition already met (current: {CurrentLevel}, target: {TargetLevel})", playerCharacter.Level, _configuration.Stop.TargetLevel); + _chatGui.Print($"Cannot start: Character level {playerCharacter.Level} has reached target level {_configuration.Stop.TargetLevel}.", "Questionable", 576); + return true; + } + foreach (ElementId item in _configuration.Stop.QuestsToStopAfter) + { + string key = item.ToString(); + if (_configuration.Stop.QuestSequences.TryGetValue(key, out var value) && value.HasValue) + { + if (!_questFunctions.IsQuestAccepted(item)) + { + continue; + } + QuestProgressInfo questProgressInfo = _questFunctions.GetQuestProgressInfo(item); + if (questProgressInfo != null && questProgressInfo.Sequence >= value.Value) + { + if (_questRegistry.TryGetQuest(item, out Quest quest)) + { + _logger.LogInformation("Blocking start: Quest '{QuestName}' is at sequence {CurrentSequence}, stop sequence is {StopSequence}", quest.Info.Name, questProgressInfo.Sequence, value.Value); + _chatGui.Print($"Cannot start: Quest '{quest.Info.Name}' is at sequence {questProgressInfo.Sequence}, configured stop sequence is {value.Value}.", "Questionable", 576); + } + return true; + } + } + else if (_questFunctions.IsQuestComplete(item)) + { + if (_questRegistry.TryGetQuest(item, out Quest quest2)) + { + _logger.LogInformation("Blocking start: Quest '{QuestName}' is already complete and configured as a stop condition", quest2.Info.Name); + _chatGui.Print("Cannot start: Quest '" + quest2.Info.Name + "' is complete and configured as a stopping point.", "Questionable", 576); + } + return true; + } + } + if (_configuration.Stop.SequenceToStopAfter && _startedQuest != null) + { + string key2 = _startedQuest.Quest.Id.ToString(); + if (!_configuration.Stop.QuestSequences.ContainsKey(key2)) + { + int sequence = _startedQuest.Sequence; + if (sequence >= _configuration.Stop.TargetSequence) + { + _logger.LogInformation("Blocking start: Global sequence stop condition already met (current: {CurrentSequence}, target: {TargetSequence})", sequence, _configuration.Stop.TargetSequence); + _chatGui.Print($"Cannot start: Quest sequence {sequence} has reached target sequence {_configuration.Stop.TargetSequence}.", "Questionable", 576); + return true; + } + } + } + return false; + } + private void ExecuteNextStep() { ClearTasksInternal(); diff --git a/Questionable/Questionable.Data/ChangelogData.cs b/Questionable/Questionable.Data/ChangelogData.cs index 8235f58..b11ca41 100644 --- a/Questionable/Questionable.Data/ChangelogData.cs +++ b/Questionable/Questionable.Data/ChangelogData.cs @@ -11,401 +11,395 @@ internal static class ChangelogData static ChangelogData() { - int num = 50; + int num = 51; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); int num2 = 0; ref ChangelogEntry reference = ref span[num2]; - DateOnly releaseDate = new DateOnly(2025, 12, 22); - int num3 = 1; + DateOnly releaseDate = new DateOnly(2025, 12, 23); + int num3 = 2; List list2 = new List(num3); CollectionsMarshal.SetCount(list2, num3); Span span2 = CollectionsMarshal.AsSpan(list2); - int index = 0; - ref ChangeEntry reference2 = ref span2[index]; - int num4 = 2; - List list3 = new List(num4); - CollectionsMarshal.SetCount(list3, num4); + int num4 = 0; + ref ChangeEntry reference2 = ref span2[num4]; + int num5 = 1; + List list3 = new List(num5); + CollectionsMarshal.SetCount(list3, num5); Span span3 = CollectionsMarshal.AsSpan(list3); - int num5 = 0; - span3[num5] = "Dive adjustments"; - num5++; - span3[num5] = "Logging message adjustments"; - reference2 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list3); - reference = new ChangelogEntry("7.4.5", releaseDate, list2); - num2++; - ref ChangelogEntry reference3 = ref span[num2]; - DateOnly releaseDate2 = new DateOnly(2025, 12, 21); + int index = 0; + span3[index] = "Added Cinema Mode to not skip cutscenes"; + reference2 = new ChangeEntry(EChangeCategory.Added, "Major Features", list3); + num4++; + ref ChangeEntry reference3 = ref span2[num4]; index = 2; - List list4 = new List(index); + List list4 = new List(index); CollectionsMarshal.SetCount(list4, index); - Span span4 = CollectionsMarshal.AsSpan(list4); - num3 = 0; - ref ChangeEntry reference4 = ref span4[num3]; - num5 = 1; - List list5 = new List(num5); - CollectionsMarshal.SetCount(list5, num5); - Span span5 = CollectionsMarshal.AsSpan(list5); - num4 = 0; - span5[num4] = "Changelog only shows once per update now"; - reference4 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list5); - num3++; - ref ChangeEntry reference5 = ref span4[num3]; - num4 = 1; - List list6 = new List(num4); - CollectionsMarshal.SetCount(list6, num4); - Span span6 = CollectionsMarshal.AsSpan(list6); + Span span4 = CollectionsMarshal.AsSpan(list4); num5 = 0; - span6[num5] = "Fixed gathering paths loading"; - reference5 = new ChangeEntry(EChangeCategory.Fixed, "Fixes", list6); - reference3 = new ChangelogEntry("7.4.4", releaseDate2, list4); + span4[num5] = "Added handling for Unsync (Party) to Party Watchdog and configuration to disable if in party"; + num5++; + span4[num5] = "Stop conditions now act as a true stop"; + reference3 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list4); + reference = new ChangelogEntry("7.4.6", releaseDate, list2); + num2++; + ref ChangelogEntry reference4 = ref span[num2]; + DateOnly releaseDate2 = new DateOnly(2025, 12, 22); + num4 = 1; + List list5 = new List(num4); + CollectionsMarshal.SetCount(list5, num4); + Span span5 = CollectionsMarshal.AsSpan(list5); + num3 = 0; + ref ChangeEntry reference5 = ref span5[num3]; + num5 = 2; + List list6 = new List(num5); + CollectionsMarshal.SetCount(list6, num5); + Span span6 = CollectionsMarshal.AsSpan(list6); + index = 0; + span6[index] = "Dive adjustments"; + index++; + span6[index] = "Logging message adjustments"; + reference5 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list6); + reference4 = new ChangelogEntry("7.4.5", releaseDate2, list5); num2++; ref ChangelogEntry reference6 = ref span[num2]; DateOnly releaseDate3 = new DateOnly(2025, 12, 21); - num3 = 1; + num3 = 2; List list7 = new List(num3); CollectionsMarshal.SetCount(list7, num3); Span span7 = CollectionsMarshal.AsSpan(list7); - index = 0; - ref ChangeEntry reference7 = ref span7[index]; - num5 = 1; - List list8 = new List(num5); - CollectionsMarshal.SetCount(list8, num5); + num4 = 0; + ref ChangeEntry reference7 = ref span7[num4]; + index = 1; + List list8 = new List(index); + CollectionsMarshal.SetCount(list8, index); Span span8 = CollectionsMarshal.AsSpan(list8); - num4 = 0; - span8[num4] = "Fixed changelog version checks"; - reference7 = new ChangeEntry(EChangeCategory.Fixed, "Fixes", list8); - reference6 = new ChangelogEntry("7.4.3", releaseDate3, list7); - num2++; - ref ChangelogEntry reference8 = ref span[num2]; - DateOnly releaseDate4 = new DateOnly(2025, 12, 20); - index = 2; - List list9 = new List(index); - CollectionsMarshal.SetCount(list9, index); - Span span9 = CollectionsMarshal.AsSpan(list9); - num3 = 0; - ref ChangeEntry reference9 = ref span9[num3]; - num4 = 1; - List list10 = new List(num4); - CollectionsMarshal.SetCount(list10, num4); - Span span10 = CollectionsMarshal.AsSpan(list10); num5 = 0; - span10[num5] = "Add 7.4 Starlight Celebration (2025) quest"; - reference9 = new ChangeEntry(EChangeCategory.QuestUpdates, "New Quest Paths", list10); - num3++; - ref ChangeEntry reference10 = ref span9[num3]; + span8[num5] = "Changelog only shows once per update now"; + reference7 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list8); + num4++; + ref ChangeEntry reference8 = ref span7[num4]; num5 = 1; - List list11 = new List(num5); - CollectionsMarshal.SetCount(list11, num5); + List list9 = new List(num5); + CollectionsMarshal.SetCount(list9, num5); + Span span9 = CollectionsMarshal.AsSpan(list9); + index = 0; + span9[index] = "Fixed gathering paths loading"; + reference8 = new ChangeEntry(EChangeCategory.Fixed, "Fixes", list9); + reference6 = new ChangelogEntry("7.4.4", releaseDate3, list7); + num2++; + ref ChangelogEntry reference9 = ref span[num2]; + DateOnly releaseDate4 = new DateOnly(2025, 12, 21); + num4 = 1; + List list10 = new List(num4); + CollectionsMarshal.SetCount(list10, num4); + Span span10 = CollectionsMarshal.AsSpan(list10); + num3 = 0; + ref ChangeEntry reference10 = ref span10[num3]; + index = 1; + List list11 = new List(index); + CollectionsMarshal.SetCount(list11, index); Span span11 = CollectionsMarshal.AsSpan(list11); - num4 = 0; - span11[num4] = "Fixed 7.4 MSQ"; + num5 = 0; + span11[num5] = "Fixed changelog version checks"; reference10 = new ChangeEntry(EChangeCategory.Fixed, "Fixes", list11); - reference8 = new ChangelogEntry("7.4.2", releaseDate4, list9); + reference9 = new ChangelogEntry("7.4.3", releaseDate4, list10); num2++; ref ChangelogEntry reference11 = ref span[num2]; - DateOnly releaseDate5 = new DateOnly(2025, 12, 19); - num3 = 1; + DateOnly releaseDate5 = new DateOnly(2025, 12, 20); + num3 = 2; List list12 = new List(num3); CollectionsMarshal.SetCount(list12, num3); Span span12 = CollectionsMarshal.AsSpan(list12); - index = 0; - ref ChangeEntry reference12 = ref span12[index]; - num4 = 2; - List list13 = new List(num4); - CollectionsMarshal.SetCount(list13, num4); + num4 = 0; + ref ChangeEntry reference12 = ref span12[num4]; + num5 = 1; + List list13 = new List(num5); + CollectionsMarshal.SetCount(list13, num5); Span span13 = CollectionsMarshal.AsSpan(list13); - num5 = 0; - span13[num5] = "Add 7.4 MSQ"; - num5++; - span13[num5] = "Add 7.4 Arcadion Raid quests"; + index = 0; + span13[index] = "Add 7.4 Starlight Celebration (2025) quest"; reference12 = new ChangeEntry(EChangeCategory.QuestUpdates, "New Quest Paths", list13); - reference11 = new ChangelogEntry("7.4.1", releaseDate5, list12); - num2++; - ref ChangelogEntry reference13 = ref span[num2]; - DateOnly releaseDate6 = new DateOnly(2025, 12, 17); + num4++; + ref ChangeEntry reference13 = ref span12[num4]; index = 1; - List list14 = new List(index); + List list14 = new List(index); CollectionsMarshal.SetCount(list14, index); - Span span14 = CollectionsMarshal.AsSpan(list14); - num3 = 0; - span14[num3] = new ChangeEntry(EChangeCategory.Changed, "Api 14 update"); - reference13 = new ChangelogEntry("7.4.0", releaseDate6, list14); + Span span14 = CollectionsMarshal.AsSpan(list14); + num5 = 0; + span14[num5] = "Fixed 7.4 MSQ"; + reference13 = new ChangeEntry(EChangeCategory.Fixed, "Fixes", list14); + reference11 = new ChangelogEntry("7.4.2", releaseDate5, list12); num2++; ref ChangelogEntry reference14 = ref span[num2]; - DateOnly releaseDate7 = new DateOnly(2025, 12, 6); - num3 = 2; - List list15 = new List(num3); - CollectionsMarshal.SetCount(list15, num3); + DateOnly releaseDate6 = new DateOnly(2025, 12, 19); + num4 = 1; + List list15 = new List(num4); + CollectionsMarshal.SetCount(list15, num4); Span span15 = CollectionsMarshal.AsSpan(list15); - index = 0; - ref ChangeEntry reference15 = ref span15[index]; - num5 = 4; + num3 = 0; + ref ChangeEntry reference15 = ref span15[num3]; + num5 = 2; List list16 = new List(num5); CollectionsMarshal.SetCount(list16, num5); Span span16 = CollectionsMarshal.AsSpan(list16); - num4 = 0; - span16[num4] = "Added reloading and rebuilding to movement system"; - num4++; - span16[num4] = "Improved interrupts and refresh states to allow continuation of questing"; - num4++; - span16[num4] = "Added player input detection to stop automation when manually moving character"; - num4++; - span16[num4] = "Added various missing quest sequences"; - reference15 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list16); + index = 0; + span16[index] = "Add 7.4 MSQ"; index++; - ref ChangeEntry reference16 = ref span15[index]; - num4 = 1; - List list17 = new List(num4); - CollectionsMarshal.SetCount(list17, num4); - Span span17 = CollectionsMarshal.AsSpan(list17); - num5 = 0; - span17[num5] = "Fixed reset task state to prevent stuck interactions after interruption"; - reference16 = new ChangeEntry(EChangeCategory.Fixed, "Fixes", list17); - reference14 = new ChangelogEntry("7.38.9", releaseDate7, list15); + span16[index] = "Add 7.4 Arcadion Raid quests"; + reference15 = new ChangeEntry(EChangeCategory.QuestUpdates, "New Quest Paths", list16); + reference14 = new ChangelogEntry("7.4.1", releaseDate6, list15); + num2++; + ref ChangelogEntry reference16 = ref span[num2]; + DateOnly releaseDate7 = new DateOnly(2025, 12, 17); + num3 = 1; + List list17 = new List(num3); + CollectionsMarshal.SetCount(list17, num3); + Span span17 = CollectionsMarshal.AsSpan(list17); + num4 = 0; + span17[num4] = new ChangeEntry(EChangeCategory.Changed, "Api 14 update"); + reference16 = new ChangelogEntry("7.4.0", releaseDate7, list17); num2++; ref ChangelogEntry reference17 = ref span[num2]; - DateOnly releaseDate8 = new DateOnly(2025, 11, 29); - index = 2; - List list18 = new List(index); - CollectionsMarshal.SetCount(list18, index); + DateOnly releaseDate8 = new DateOnly(2025, 12, 6); + num4 = 2; + List list18 = new List(num4); + CollectionsMarshal.SetCount(list18, num4); Span span18 = CollectionsMarshal.AsSpan(list18); num3 = 0; ref ChangeEntry reference18 = ref span18[num3]; - num5 = 3; - List list19 = new List(num5); - CollectionsMarshal.SetCount(list19, num5); + index = 4; + List list19 = new List(index); + CollectionsMarshal.SetCount(list19, index); Span span19 = CollectionsMarshal.AsSpan(list19); - num4 = 0; - span19[num4] = "Movement update with automatic retrying if character can't reach target position"; - num4++; - span19[num4] = "Added Hunt mob data"; - num4++; - span19[num4] = "Refactored commands"; + num5 = 0; + span19[num5] = "Added reloading and rebuilding to movement system"; + num5++; + span19[num5] = "Improved interrupts and refresh states to allow continuation of questing"; + num5++; + span19[num5] = "Added player input detection to stop automation when manually moving character"; + num5++; + span19[num5] = "Added various missing quest sequences"; reference18 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list19); num3++; ref ChangeEntry reference19 = ref span18[num3]; - num4 = 3; - List list20 = new List(num4); - CollectionsMarshal.SetCount(list20, num4); + num5 = 1; + List list20 = new List(num5); + CollectionsMarshal.SetCount(list20, num5); Span span20 = CollectionsMarshal.AsSpan(list20); - num5 = 0; - span20[num5] = "Fixed quest (Way of the Archer)"; - num5++; - span20[num5] = "Fixed quest (Spirithold Broken)"; - num5++; - span20[num5] = "Fixed quest (It's Probably Not Pirates)"; - reference19 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list20); - reference17 = new ChangelogEntry("7.38.8", releaseDate8, list18); + index = 0; + span20[index] = "Fixed reset task state to prevent stuck interactions after interruption"; + reference19 = new ChangeEntry(EChangeCategory.Fixed, "Fixes", list20); + reference17 = new ChangelogEntry("7.38.9", releaseDate8, list18); num2++; ref ChangelogEntry reference20 = ref span[num2]; - DateOnly releaseDate9 = new DateOnly(2025, 11, 25); + DateOnly releaseDate9 = new DateOnly(2025, 11, 29); num3 = 2; List list21 = new List(num3); CollectionsMarshal.SetCount(list21, num3); Span span21 = CollectionsMarshal.AsSpan(list21); - index = 0; - ref ChangeEntry reference21 = ref span21[index]; - num5 = 2; - List list22 = new List(num5); - CollectionsMarshal.SetCount(list22, num5); - Span span22 = CollectionsMarshal.AsSpan(list22); num4 = 0; - span22[num4] = "Added individual sequence stop condition for each quest"; - num4++; - span22[num4] = "Added Trials to Duties tab in config"; - reference21 = new ChangeEntry(EChangeCategory.Added, "Major features", list22); - index++; - ref ChangeEntry reference22 = ref span21[index]; - num4 = 1; - List list23 = new List(num4); - CollectionsMarshal.SetCount(list23, num4); - Span span23 = CollectionsMarshal.AsSpan(list23); + ref ChangeEntry reference21 = ref span21[num4]; + index = 3; + List list22 = new List(index); + CollectionsMarshal.SetCount(list22, index); + Span span22 = CollectionsMarshal.AsSpan(list22); num5 = 0; - span23[num5] = "Added IPC for stop conditions: GetQuestSequenceStopCondition, SetQuestSequenceStopCondition, RemoveQuestSequenceStopCondition, GetAllQuestSequenceStopConditions"; - reference22 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list23); - reference20 = new ChangelogEntry("7.38.7", releaseDate9, list21); + span22[num5] = "Movement update with automatic retrying if character can't reach target position"; + num5++; + span22[num5] = "Added Hunt mob data"; + num5++; + span22[num5] = "Refactored commands"; + reference21 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list22); + num4++; + ref ChangeEntry reference22 = ref span21[num4]; + num5 = 3; + List list23 = new List(num5); + CollectionsMarshal.SetCount(list23, num5); + Span span23 = CollectionsMarshal.AsSpan(list23); + index = 0; + span23[index] = "Fixed quest (Way of the Archer)"; + index++; + span23[index] = "Fixed quest (Spirithold Broken)"; + index++; + span23[index] = "Fixed quest (It's Probably Not Pirates)"; + reference22 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list23); + reference20 = new ChangelogEntry("7.38.8", releaseDate9, list21); num2++; ref ChangelogEntry reference23 = ref span[num2]; DateOnly releaseDate10 = new DateOnly(2025, 11, 25); - index = 3; - List list24 = new List(index); - CollectionsMarshal.SetCount(list24, index); + num4 = 2; + List list24 = new List(num4); + CollectionsMarshal.SetCount(list24, num4); Span span24 = CollectionsMarshal.AsSpan(list24); num3 = 0; ref ChangeEntry reference24 = ref span24[num3]; - num5 = 2; - List list25 = new List(num5); - CollectionsMarshal.SetCount(list25, num5); + index = 2; + List list25 = new List(index); + CollectionsMarshal.SetCount(list25, index); Span span25 = CollectionsMarshal.AsSpan(list25); - num4 = 0; - span25[num4] = "Updated Allied Society journal text"; - num4++; - span25[num4] = "Improved Allied Society rank handling"; - reference24 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list25); + num5 = 0; + span25[num5] = "Added individual sequence stop condition for each quest"; + num5++; + span25[num5] = "Added Trials to Duties tab in config"; + reference24 = new ChangeEntry(EChangeCategory.Added, "Major features", list25); num3++; ref ChangeEntry reference25 = ref span24[num3]; - num4 = 1; - List list26 = new List(num4); - CollectionsMarshal.SetCount(list26, num4); + num5 = 1; + List list26 = new List(num5); + CollectionsMarshal.SetCount(list26, num5); Span span26 = CollectionsMarshal.AsSpan(list26); - num5 = 0; - span26[num5] = "Added IPC for Allied Society: AddAlliedSocietyOptimalQuests, GetAlliedSocietyOptimalQuests"; - reference25 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list26); - num3++; - ref ChangeEntry reference26 = ref span24[num3]; - num5 = 1; - List list27 = new List(num5); - CollectionsMarshal.SetCount(list27, num5); - Span span27 = CollectionsMarshal.AsSpan(list27); - num4 = 0; - span27[num4] = "Fixed quest (We Come in Peace)"; - reference26 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list27); - reference23 = new ChangelogEntry("7.38.6", releaseDate10, list24); - num2++; - ref ChangelogEntry reference27 = ref span[num2]; - DateOnly releaseDate11 = new DateOnly(2025, 11, 24); - num3 = 2; - List list28 = new List(num3); - CollectionsMarshal.SetCount(list28, num3); - Span span28 = CollectionsMarshal.AsSpan(list28); index = 0; - ref ChangeEntry reference28 = ref span28[index]; - num4 = 1; - List list29 = new List(num4); - CollectionsMarshal.SetCount(list29, num4); - Span span29 = CollectionsMarshal.AsSpan(list29); - num5 = 0; - span29[num5] = "Added Allied Society daily allowance tracker with bulk quest adding buttons"; - reference28 = new ChangeEntry(EChangeCategory.Added, "Major features", list29); - index++; - ref ChangeEntry reference29 = ref span28[index]; - num5 = 1; - List list30 = new List(num5); - CollectionsMarshal.SetCount(list30, num5); - Span span30 = CollectionsMarshal.AsSpan(list30); + span26[index] = "Added IPC for stop conditions: GetQuestSequenceStopCondition, SetQuestSequenceStopCondition, RemoveQuestSequenceStopCondition, GetAllQuestSequenceStopConditions"; + reference25 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list26); + reference23 = new ChangelogEntry("7.38.7", releaseDate10, list24); + num2++; + ref ChangelogEntry reference26 = ref span[num2]; + DateOnly releaseDate11 = new DateOnly(2025, 11, 25); + num3 = 3; + List list27 = new List(num3); + CollectionsMarshal.SetCount(list27, num3); + Span span27 = CollectionsMarshal.AsSpan(list27); num4 = 0; - span30[num4] = "Added IPC for Allied Society: GetRemainingAllowances, GetTimeUntilReset, GetAvailableQuestIds, GetAllAvailableQuestCounts, IsMaxRank, GetCurrentRank, GetSocietiesWithAvailableQuests"; - reference29 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list30); - reference27 = new ChangelogEntry("7.38.5", releaseDate11, list28); + ref ChangeEntry reference27 = ref span27[num4]; + index = 2; + List list28 = new List(index); + CollectionsMarshal.SetCount(list28, index); + Span span28 = CollectionsMarshal.AsSpan(list28); + num5 = 0; + span28[num5] = "Updated Allied Society journal text"; + num5++; + span28[num5] = "Improved Allied Society rank handling"; + reference27 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list28); + num4++; + ref ChangeEntry reference28 = ref span27[num4]; + num5 = 1; + List list29 = new List(num5); + CollectionsMarshal.SetCount(list29, num5); + Span span29 = CollectionsMarshal.AsSpan(list29); + index = 0; + span29[index] = "Added IPC for Allied Society: AddAlliedSocietyOptimalQuests, GetAlliedSocietyOptimalQuests"; + reference28 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list29); + num4++; + ref ChangeEntry reference29 = ref span27[num4]; + index = 1; + List list30 = new List(index); + CollectionsMarshal.SetCount(list30, index); + Span span30 = CollectionsMarshal.AsSpan(list30); + num5 = 0; + span30[num5] = "Fixed quest (We Come in Peace)"; + reference29 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list30); + reference26 = new ChangelogEntry("7.38.6", releaseDate11, list27); num2++; ref ChangelogEntry reference30 = ref span[num2]; - DateOnly releaseDate12 = new DateOnly(2025, 11, 23); - index = 2; - List list31 = new List(index); - CollectionsMarshal.SetCount(list31, index); + DateOnly releaseDate12 = new DateOnly(2025, 11, 24); + num4 = 2; + List list31 = new List(num4); + CollectionsMarshal.SetCount(list31, num4); Span span31 = CollectionsMarshal.AsSpan(list31); num3 = 0; ref ChangeEntry reference31 = ref span31[num3]; - num4 = 1; - List list32 = new List(num4); - CollectionsMarshal.SetCount(list32, num4); + num5 = 1; + List list32 = new List(num5); + CollectionsMarshal.SetCount(list32, num5); Span span32 = CollectionsMarshal.AsSpan(list32); - num5 = 0; - span32[num5] = "Explicitly declare support for BMR singleplayer duty (The Rematch)"; - reference31 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list32); + index = 0; + span32[index] = "Added Allied Society daily allowance tracker with bulk quest adding buttons"; + reference31 = new ChangeEntry(EChangeCategory.Added, "Major features", list32); num3++; ref ChangeEntry reference32 = ref span31[num3]; - num5 = 8; - List list33 = new List(num5); - CollectionsMarshal.SetCount(list33, num5); + index = 1; + List list33 = new List(index); + CollectionsMarshal.SetCount(list33, index); Span span33 = CollectionsMarshal.AsSpan(list33); - num4 = 0; - span33[num4] = "Fixed quest (Microbrewing) to not get stuck near ramp"; - num4++; - span33[num4] = "Fixed quest (The Illuminated Land) where pathing would kill the player due to fall damage"; - num4++; - span33[num4] = "Fixed quest (It's Probably Not Pirates) improper pathing and removed unneeded step"; - num4++; - span33[num4] = "Fixed quest (The Black Wolf's Ultimatum) not exiting landing area"; - num4++; - span33[num4] = "Fixed quest (Magiteknical Failure) from not interacting with NPC due to being mounted"; - num4++; - span33[num4] = "Fixed quest (We Come in Peace) shortcut navigation"; - num4++; - span33[num4] = "Fixed quest (Poisoned Hearts) where incorrect pathing caused the player to die"; - num4++; - span33[num4] = "Fixed quests (Savage Snares) and (An Apple a Day) not detecting kills"; - reference32 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list33); - reference30 = new ChangelogEntry("7.38.4", releaseDate12, list31); + num5 = 0; + span33[num5] = "Added IPC for Allied Society: GetRemainingAllowances, GetTimeUntilReset, GetAvailableQuestIds, GetAllAvailableQuestCounts, IsMaxRank, GetCurrentRank, GetSocietiesWithAvailableQuests"; + reference32 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list33); + reference30 = new ChangelogEntry("7.38.5", releaseDate12, list31); num2++; ref ChangelogEntry reference33 = ref span[num2]; DateOnly releaseDate13 = new DateOnly(2025, 11, 23); - num3 = 3; + num3 = 2; List list34 = new List(num3); CollectionsMarshal.SetCount(list34, num3); Span span34 = CollectionsMarshal.AsSpan(list34); - index = 0; - ref ChangeEntry reference34 = ref span34[index]; - num4 = 2; - List list35 = new List(num4); - CollectionsMarshal.SetCount(list35, num4); + num4 = 0; + ref ChangeEntry reference34 = ref span34[num4]; + num5 = 1; + List list35 = new List(num5); + CollectionsMarshal.SetCount(list35, num5); Span span35 = CollectionsMarshal.AsSpan(list35); - num5 = 0; - span35[num5] = "Added RequireHq to crafting InteractionType"; - num5++; - span35[num5] = "Mark GC quests as Locked if rank not achieved"; + index = 0; + span35[index] = "Explicitly declare support for BMR singleplayer duty (The Rematch)"; reference34 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list35); - index++; - ref ChangeEntry reference35 = ref span34[index]; - num5 = 2; - List list36 = new List(num5); - CollectionsMarshal.SetCount(list36, num5); + num4++; + ref ChangeEntry reference35 = ref span34[num4]; + index = 8; + List list36 = new List(index); + CollectionsMarshal.SetCount(list36, index); Span span36 = CollectionsMarshal.AsSpan(list36); - num4 = 0; - span36[num4] = "Added IPC for stop conditions: GetStopConditionsEnabled, SetStopConditionsEnabled, GetStopQuestList, AddStopQuest, RemoveStopQuest, ClearStopQuests, GetLevelStopCondition, SetLevelStopCondition, GetSequenceStopCondition, SetSequenceStopCondition"; - num4++; - span36[num4] = "Added IPC for priority quests: GetPriorityQuests, RemovePriorityQuest, ReorderPriorityQuest, GetAvailablePresets, GetPresetQuests, AddPresetToPriority, IsPresetAvailable, IsQuestInPriority, GetQuestPriorityIndex, HasAvailablePriorityQuests"; - reference35 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list36); - index++; - ref ChangeEntry reference36 = ref span34[index]; - num4 = 3; - List list37 = new List(num4); - CollectionsMarshal.SetCount(list37, num4); - Span span37 = CollectionsMarshal.AsSpan(list37); num5 = 0; - span37[num5] = "Fixed line breaks not working in dialog strings"; + span36[num5] = "Fixed quest (Microbrewing) to not get stuck near ramp"; num5++; - span37[num5] = "Fixed quest (Labor of Love)"; + span36[num5] = "Fixed quest (The Illuminated Land) where pathing would kill the player due to fall damage"; num5++; - span37[num5] = "Fixed quest (Sea of Sorrow)"; - reference36 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list37); - reference33 = new ChangelogEntry("7.38.3", releaseDate13, list34); + span36[num5] = "Fixed quest (It's Probably Not Pirates) improper pathing and removed unneeded step"; + num5++; + span36[num5] = "Fixed quest (The Black Wolf's Ultimatum) not exiting landing area"; + num5++; + span36[num5] = "Fixed quest (Magiteknical Failure) from not interacting with NPC due to being mounted"; + num5++; + span36[num5] = "Fixed quest (We Come in Peace) shortcut navigation"; + num5++; + span36[num5] = "Fixed quest (Poisoned Hearts) where incorrect pathing caused the player to die"; + num5++; + span36[num5] = "Fixed quests (Savage Snares) and (An Apple a Day) not detecting kills"; + reference35 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list36); + reference33 = new ChangelogEntry("7.38.4", releaseDate13, list34); num2++; - ref ChangelogEntry reference37 = ref span[num2]; - DateOnly releaseDate14 = new DateOnly(2025, 11, 18); - index = 3; - List list38 = new List(index); - CollectionsMarshal.SetCount(list38, index); - Span span38 = CollectionsMarshal.AsSpan(list38); - num3 = 0; - ref ChangeEntry reference38 = ref span38[num3]; - num5 = 2; - List list39 = new List(num5); - CollectionsMarshal.SetCount(list39, num5); - Span span39 = CollectionsMarshal.AsSpan(list39); - num4 = 0; - span39[num4] = "Auto Duty unsync options for each duty (Duty Support, Unsync Solo, Unsync Party)"; - num4++; - span39[num4] = "Added Auto Duty unsync options to quest schema and updated quests using old unsync method"; - reference38 = new ChangeEntry(EChangeCategory.Added, "Major features", list39); - num3++; - ref ChangeEntry reference39 = ref span38[num3]; + ref ChangelogEntry reference36 = ref span[num2]; + DateOnly releaseDate14 = new DateOnly(2025, 11, 23); num4 = 3; - List list40 = new List(num4); - CollectionsMarshal.SetCount(list40, num4); - Span span40 = CollectionsMarshal.AsSpan(list40); - num5 = 0; - span40[num5] = "Added IPC for duty sync handling: GetDefaultDutyMode, SetDefaultDutyMode"; - num5++; - span40[num5] = "Added IPC for duty mode overrides: GetDutyModeOverride, SetDutyModeOverride"; - num5++; - span40[num5] = "Added IPC for clearing overrides: ClearDutyModeOverride, ClearAllDutyModeOverrides"; - reference39 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list40); + List list37 = new List(num4); + CollectionsMarshal.SetCount(list37, num4); + Span span37 = CollectionsMarshal.AsSpan(list37); + num3 = 0; + ref ChangeEntry reference37 = ref span37[num3]; + num5 = 2; + List list38 = new List(num5); + CollectionsMarshal.SetCount(list38, num5); + Span span38 = CollectionsMarshal.AsSpan(list38); + index = 0; + span38[index] = "Added RequireHq to crafting InteractionType"; + index++; + span38[index] = "Mark GC quests as Locked if rank not achieved"; + reference37 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list38); num3++; - span38[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest (Constant Cravings)"); - reference37 = new ChangelogEntry("7.38.2", releaseDate14, list38); + ref ChangeEntry reference38 = ref span37[num3]; + index = 2; + List list39 = new List(index); + CollectionsMarshal.SetCount(list39, index); + Span span39 = CollectionsMarshal.AsSpan(list39); + num5 = 0; + span39[num5] = "Added IPC for stop conditions: GetStopConditionsEnabled, SetStopConditionsEnabled, GetStopQuestList, AddStopQuest, RemoveStopQuest, ClearStopQuests, GetLevelStopCondition, SetLevelStopCondition, GetSequenceStopCondition, SetSequenceStopCondition"; + num5++; + span39[num5] = "Added IPC for priority quests: GetPriorityQuests, RemovePriorityQuest, ReorderPriorityQuest, GetAvailablePresets, GetPresetQuests, AddPresetToPriority, IsPresetAvailable, IsQuestInPriority, GetQuestPriorityIndex, HasAvailablePriorityQuests"; + reference38 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list39); + num3++; + ref ChangeEntry reference39 = ref span37[num3]; + num5 = 3; + List list40 = new List(num5); + CollectionsMarshal.SetCount(list40, num5); + Span span40 = CollectionsMarshal.AsSpan(list40); + index = 0; + span40[index] = "Fixed line breaks not working in dialog strings"; + index++; + span40[index] = "Fixed quest (Labor of Love)"; + index++; + span40[index] = "Fixed quest (Sea of Sorrow)"; + reference39 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list40); + reference36 = new ChangelogEntry("7.38.3", releaseDate14, list37); num2++; ref ChangelogEntry reference40 = ref span[num2]; DateOnly releaseDate15 = new DateOnly(2025, 11, 18); @@ -413,608 +407,642 @@ internal static class ChangelogData List list41 = new List(num3); CollectionsMarshal.SetCount(list41, num3); Span span41 = CollectionsMarshal.AsSpan(list41); - index = 0; - ref ChangeEntry reference41 = ref span41[index]; - num5 = 1; - List list42 = new List(num5); - CollectionsMarshal.SetCount(list42, num5); + num4 = 0; + ref ChangeEntry reference41 = ref span41[num4]; + index = 2; + List list42 = new List(index); + CollectionsMarshal.SetCount(list42, index); Span span42 = CollectionsMarshal.AsSpan(list42); - num4 = 0; - span42[num4] = "Added new fields to quest schema"; - reference41 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list42); - index++; - ref ChangeEntry reference42 = ref span41[index]; - num4 = 3; - List list43 = new List(num4); - CollectionsMarshal.SetCount(list43, num4); - Span span43 = CollectionsMarshal.AsSpan(list43); num5 = 0; - span43[num5] = "A Faerie Tale Come True"; + span42[num5] = "Auto Duty unsync options for each duty (Duty Support, Unsync Solo, Unsync Party)"; num5++; - span43[num5] = "Constant Cravings"; - num5++; - span43[num5] = "A Bridge Too Full"; - reference42 = new ChangeEntry(EChangeCategory.QuestUpdates, "Added new quest paths", list43); - index++; - ref ChangeEntry reference43 = ref span41[index]; + span42[num5] = "Added Auto Duty unsync options to quest schema and updated quests using old unsync method"; + reference41 = new ChangeEntry(EChangeCategory.Added, "Major features", list42); + num4++; + ref ChangeEntry reference42 = ref span41[num4]; num5 = 3; - List list44 = new List(num5); - CollectionsMarshal.SetCount(list44, num5); - Span span44 = CollectionsMarshal.AsSpan(list44); - num4 = 0; - span44[num4] = "Fixed various quest schemas"; + List list43 = new List(num5); + CollectionsMarshal.SetCount(list43, num5); + Span span43 = CollectionsMarshal.AsSpan(list43); + index = 0; + span43[index] = "Added IPC for duty sync handling: GetDefaultDutyMode, SetDefaultDutyMode"; + index++; + span43[index] = "Added IPC for duty mode overrides: GetDutyModeOverride, SetDutyModeOverride"; + index++; + span43[index] = "Added IPC for clearing overrides: ClearDutyModeOverride, ClearAllDutyModeOverrides"; + reference42 = new ChangeEntry(EChangeCategory.Added, "IPC changes", list43); num4++; - span44[num4] = "Fixed changelog bullet point encoding"; - num4++; - span44[num4] = "Fixed item use to wait until item is used before next action"; - reference43 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list44); - reference40 = new ChangelogEntry("7.38.1", releaseDate15, list41); + span41[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest (Constant Cravings)"); + reference40 = new ChangelogEntry("7.38.2", releaseDate15, list41); num2++; - ref ChangelogEntry reference44 = ref span[num2]; - DateOnly releaseDate16 = new DateOnly(2025, 11, 17); - index = 5; - List list45 = new List(index); - CollectionsMarshal.SetCount(list45, index); - Span span45 = CollectionsMarshal.AsSpan(list45); - num3 = 0; - ref ChangeEntry reference45 = ref span45[num3]; - num4 = 2; - List list46 = new List(num4); - CollectionsMarshal.SetCount(list46, num4); - Span span46 = CollectionsMarshal.AsSpan(list46); - num5 = 0; - span46[num5] = "Quest sequence window to show expected sequences in each quest (with quest searching)"; - num5++; - span46[num5] = "Changelog"; - reference45 = new ChangeEntry(EChangeCategory.Added, "Major features", list46); - num3++; - ref ChangeEntry reference46 = ref span45[num3]; - num5 = 2; - List list47 = new List(num5); - CollectionsMarshal.SetCount(list47, num5); - Span span47 = CollectionsMarshal.AsSpan(list47); - num4 = 0; - span47[num4] = "Updated quest schemas"; - num4++; - span47[num4] = "Added search bar to preferred mounts and capitalization to mirror game mount names"; - reference46 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list47); - num3++; - ref ChangeEntry reference47 = ref span45[num3]; + ref ChangelogEntry reference43 = ref span[num2]; + DateOnly releaseDate16 = new DateOnly(2025, 11, 18); num4 = 3; - List list48 = new List(num4); - CollectionsMarshal.SetCount(list48, num4); - Span span48 = CollectionsMarshal.AsSpan(list48); - num5 = 0; - span48[num5] = "Renamed IsQuestCompleted → IsQuestComplete"; - num5++; - span48[num5] = "Renamed IsQuestAvailable → IsReadyToAcceptQuest"; - num5++; - span48[num5] = "Added GetCurrentTask IPC"; - reference47 = new ChangeEntry(EChangeCategory.Changed, "IPC changes", list48); - num3++; - span45[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added all Hildibrand quests"); - num3++; - span45[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed credits/cutscenes playback"); - reference44 = new ChangelogEntry("7.38.0", releaseDate16, list45); - num2++; - ref ChangelogEntry reference48 = ref span[num2]; - DateOnly releaseDate17 = new DateOnly(2025, 11, 8); - num3 = 1; - List list49 = new List(num3); - CollectionsMarshal.SetCount(list49, num3); - Span span49 = CollectionsMarshal.AsSpan(list49); - index = 0; - span49[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Fall Guys quest (Just Crowning Around)"); - reference48 = new ChangelogEntry("6.38", releaseDate17, list49); - num2++; - ref ChangelogEntry reference49 = ref span[num2]; - DateOnly releaseDate18 = new DateOnly(2025, 11, 8); - index = 1; - List list50 = new List(index); - CollectionsMarshal.SetCount(list50, index); - Span span50 = CollectionsMarshal.AsSpan(list50); + List list44 = new List(num4); + CollectionsMarshal.SetCount(list44, num4); + Span span44 = CollectionsMarshal.AsSpan(list44); num3 = 0; - span50[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Cosmic Exploration and various unlock quests"); - reference49 = new ChangelogEntry("6.37", releaseDate18, list50); - num2++; - ref ChangelogEntry reference50 = ref span[num2]; - DateOnly releaseDate19 = new DateOnly(2025, 11, 2); - num3 = 1; - List list51 = new List(num3); - CollectionsMarshal.SetCount(list51, num3); - Span span51 = CollectionsMarshal.AsSpan(list51); + ref ChangeEntry reference44 = ref span44[num3]; + index = 1; + List list45 = new List(index); + CollectionsMarshal.SetCount(list45, index); + Span span45 = CollectionsMarshal.AsSpan(list45); + num5 = 0; + span45[num5] = "Added new fields to quest schema"; + reference44 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list45); + num3++; + ref ChangeEntry reference45 = ref span44[num3]; + num5 = 3; + List list46 = new List(num5); + CollectionsMarshal.SetCount(list46, num5); + Span span46 = CollectionsMarshal.AsSpan(list46); index = 0; - span51[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 6 quest (With High Spirits)"); - reference50 = new ChangelogEntry("6.36", releaseDate19, list51); + span46[index] = "A Faerie Tale Come True"; + index++; + span46[index] = "Constant Cravings"; + index++; + span46[index] = "A Bridge Too Full"; + reference45 = new ChangeEntry(EChangeCategory.QuestUpdates, "Added new quest paths", list46); + num3++; + ref ChangeEntry reference46 = ref span44[num3]; + index = 3; + List list47 = new List(index); + CollectionsMarshal.SetCount(list47, index); + Span span47 = CollectionsMarshal.AsSpan(list47); + num5 = 0; + span47[num5] = "Fixed various quest schemas"; + num5++; + span47[num5] = "Fixed changelog bullet point encoding"; + num5++; + span47[num5] = "Fixed item use to wait until item is used before next action"; + reference46 = new ChangeEntry(EChangeCategory.Fixed, "Bug fixes", list47); + reference43 = new ChangelogEntry("7.38.1", releaseDate16, list44); + num2++; + ref ChangelogEntry reference47 = ref span[num2]; + DateOnly releaseDate17 = new DateOnly(2025, 11, 17); + num3 = 5; + List list48 = new List(num3); + CollectionsMarshal.SetCount(list48, num3); + Span span48 = CollectionsMarshal.AsSpan(list48); + num4 = 0; + ref ChangeEntry reference48 = ref span48[num4]; + num5 = 2; + List list49 = new List(num5); + CollectionsMarshal.SetCount(list49, num5); + Span span49 = CollectionsMarshal.AsSpan(list49); + index = 0; + span49[index] = "Quest sequence window to show expected sequences in each quest (with quest searching)"; + index++; + span49[index] = "Changelog"; + reference48 = new ChangeEntry(EChangeCategory.Added, "Major features", list49); + num4++; + ref ChangeEntry reference49 = ref span48[num4]; + index = 2; + List list50 = new List(index); + CollectionsMarshal.SetCount(list50, index); + Span span50 = CollectionsMarshal.AsSpan(list50); + num5 = 0; + span50[num5] = "Updated quest schemas"; + num5++; + span50[num5] = "Added search bar to preferred mounts and capitalization to mirror game mount names"; + reference49 = new ChangeEntry(EChangeCategory.Changed, "Improvements", list50); + num4++; + ref ChangeEntry reference50 = ref span48[num4]; + num5 = 3; + List list51 = new List(num5); + CollectionsMarshal.SetCount(list51, num5); + Span span51 = CollectionsMarshal.AsSpan(list51); + index = 0; + span51[index] = "Renamed IsQuestCompleted → IsQuestComplete"; + index++; + span51[index] = "Renamed IsQuestAvailable → IsReadyToAcceptQuest"; + index++; + span51[index] = "Added GetCurrentTask IPC"; + reference50 = new ChangeEntry(EChangeCategory.Changed, "IPC changes", list51); + num4++; + span48[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added all Hildibrand quests"); + num4++; + span48[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed credits/cutscenes playback"); + reference47 = new ChangelogEntry("7.38.0", releaseDate17, list48); num2++; ref ChangelogEntry reference51 = ref span[num2]; - DateOnly releaseDate20 = new DateOnly(2025, 10, 28); - index = 1; - List list52 = new List(index); - CollectionsMarshal.SetCount(list52, index); + DateOnly releaseDate18 = new DateOnly(2025, 11, 8); + num4 = 1; + List list52 = new List(num4); + CollectionsMarshal.SetCount(list52, num4); Span span52 = CollectionsMarshal.AsSpan(list52); num3 = 0; - span52[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed level 3 MSQ handling if character started on non-XP buff world"); - reference51 = new ChangelogEntry("6.35", releaseDate20, list52); + span52[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Fall Guys quest (Just Crowning Around)"); + reference51 = new ChangelogEntry("6.38", releaseDate18, list52); num2++; ref ChangelogEntry reference52 = ref span[num2]; - DateOnly releaseDate21 = new DateOnly(2025, 10, 23); - num3 = 2; + DateOnly releaseDate19 = new DateOnly(2025, 11, 8); + num3 = 1; List list53 = new List(num3); CollectionsMarshal.SetCount(list53, num3); Span span53 = CollectionsMarshal.AsSpan(list53); - index = 0; - span53[index] = new ChangeEntry(EChangeCategory.Added, "Added clear priority quests on logout and on completion config settings"); - index++; - span53[index] = new ChangeEntry(EChangeCategory.Fixed, "Fixed priority quest importing to respect import order"); - reference52 = new ChangelogEntry("6.34", releaseDate21, list53); + num4 = 0; + span53[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Cosmic Exploration and various unlock quests"); + reference52 = new ChangelogEntry("6.37", releaseDate19, list53); num2++; ref ChangelogEntry reference53 = ref span[num2]; - DateOnly releaseDate22 = new DateOnly(2025, 10, 23); - index = 1; - List list54 = new List(index); - CollectionsMarshal.SetCount(list54, index); + DateOnly releaseDate20 = new DateOnly(2025, 11, 2); + num4 = 1; + List list54 = new List(num4); + CollectionsMarshal.SetCount(list54, num4); Span span54 = CollectionsMarshal.AsSpan(list54); num3 = 0; - span54[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed RSR combat module"); - reference53 = new ChangelogEntry("6.33", releaseDate22, list54); + span54[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 6 quest (With High Spirits)"); + reference53 = new ChangelogEntry("6.36", releaseDate20, list54); num2++; ref ChangelogEntry reference54 = ref span[num2]; - DateOnly releaseDate23 = new DateOnly(2025, 10, 23); + DateOnly releaseDate21 = new DateOnly(2025, 10, 28); num3 = 1; List list55 = new List(num3); CollectionsMarshal.SetCount(list55, num3); Span span55 = CollectionsMarshal.AsSpan(list55); - index = 0; - span55[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 5 quest (Forged in Corn)"); - reference54 = new ChangelogEntry("6.32", releaseDate23, list55); + num4 = 0; + span55[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed level 3 MSQ handling if character started on non-XP buff world"); + reference54 = new ChangelogEntry("6.35", releaseDate21, list55); num2++; ref ChangelogEntry reference55 = ref span[num2]; - DateOnly releaseDate24 = new DateOnly(2025, 10, 21); - index = 1; - List list56 = new List(index); - CollectionsMarshal.SetCount(list56, index); + DateOnly releaseDate22 = new DateOnly(2025, 10, 23); + num4 = 2; + List list56 = new List(num4); + CollectionsMarshal.SetCount(list56, num4); Span span56 = CollectionsMarshal.AsSpan(list56); num3 = 0; - span56[num3] = new ChangeEntry(EChangeCategory.Changed, "Added checks for moogle and allied society quests when using add all available quests"); - reference55 = new ChangelogEntry("6.31", releaseDate24, list56); + span56[num3] = new ChangeEntry(EChangeCategory.Added, "Added clear priority quests on logout and on completion config settings"); + num3++; + span56[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed priority quest importing to respect import order"); + reference55 = new ChangelogEntry("6.34", releaseDate22, list56); num2++; ref ChangelogEntry reference56 = ref span[num2]; - DateOnly releaseDate25 = new DateOnly(2025, 10, 21); + DateOnly releaseDate23 = new DateOnly(2025, 10, 23); num3 = 1; List list57 = new List(num3); CollectionsMarshal.SetCount(list57, num3); Span span57 = CollectionsMarshal.AsSpan(list57); - index = 0; - span57[index] = new ChangeEntry(EChangeCategory.Added, "Added button to journal that allows adding all available quests to priority"); - reference56 = new ChangelogEntry("6.30", releaseDate25, list57); + num4 = 0; + span57[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed RSR combat module"); + reference56 = new ChangelogEntry("6.33", releaseDate23, list57); num2++; ref ChangelogEntry reference57 = ref span[num2]; - DateOnly releaseDate26 = new DateOnly(2025, 10, 20); - index = 2; - List list58 = new List(index); - CollectionsMarshal.SetCount(list58, index); + DateOnly releaseDate24 = new DateOnly(2025, 10, 23); + num4 = 1; + List list58 = new List(num4); + CollectionsMarshal.SetCount(list58, num4); Span span58 = CollectionsMarshal.AsSpan(list58); num3 = 0; - ref ChangeEntry reference58 = ref span58[num3]; - num5 = 2; - List list59 = new List(num5); - CollectionsMarshal.SetCount(list59, num5); - Span span59 = CollectionsMarshal.AsSpan(list59); + span58[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy Rank 5 quest (Forged in Corn)"); + reference57 = new ChangelogEntry("6.32", releaseDate24, list58); + num2++; + ref ChangelogEntry reference58 = ref span[num2]; + DateOnly releaseDate25 = new DateOnly(2025, 10, 21); + num3 = 1; + List list59 = new List(num3); + CollectionsMarshal.SetCount(list59, num3); + Span span59 = CollectionsMarshal.AsSpan(list59); num4 = 0; - span59[num4] = "Added item count to combat handling rework"; - num4++; - span59[num4] = "Updated Pandora conflicting features"; - reference58 = new ChangeEntry(EChangeCategory.Changed, "Combat handling improvements", list59); - num3++; - span58[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest to purchase Gysahl Greens if not in inventory"); - reference57 = new ChangelogEntry("6.29", releaseDate26, list58); + span59[num4] = new ChangeEntry(EChangeCategory.Changed, "Added checks for moogle and allied society quests when using add all available quests"); + reference58 = new ChangelogEntry("6.31", releaseDate25, list59); num2++; ref ChangelogEntry reference59 = ref span[num2]; - DateOnly releaseDate27 = new DateOnly(2025, 10, 19); - num3 = 1; - List list60 = new List(num3); - CollectionsMarshal.SetCount(list60, num3); + DateOnly releaseDate26 = new DateOnly(2025, 10, 21); + num4 = 1; + List list60 = new List(num4); + CollectionsMarshal.SetCount(list60, num4); Span span60 = CollectionsMarshal.AsSpan(list60); - index = 0; - span60[index] = new ChangeEntry(EChangeCategory.Changed, "Reworked kill count combat handling - combat and enemy kills are now processed instantly"); - reference59 = new ChangelogEntry("6.28", releaseDate27, list60); + num3 = 0; + span60[num3] = new ChangeEntry(EChangeCategory.Added, "Added button to journal that allows adding all available quests to priority"); + reference59 = new ChangelogEntry("6.30", releaseDate26, list60); num2++; ref ChangelogEntry reference60 = ref span[num2]; - DateOnly releaseDate28 = new DateOnly(2025, 10, 18); - index = 2; - List list61 = new List(index); - CollectionsMarshal.SetCount(list61, index); + DateOnly releaseDate27 = new DateOnly(2025, 10, 20); + num3 = 2; + List list61 = new List(num3); + CollectionsMarshal.SetCount(list61, num3); Span span61 = CollectionsMarshal.AsSpan(list61); - num3 = 0; - span61[num3] = new ChangeEntry(EChangeCategory.Changed, "Improved Aether Current checking logic"); - num3++; - span61[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Chocobo Taxi Stand CheckSkip error and Patch 7.3 Fantasia unlock quest date/time"); - reference60 = new ChangelogEntry("6.27", releaseDate28, list61); - num2++; - ref ChangelogEntry reference61 = ref span[num2]; - DateOnly releaseDate29 = new DateOnly(2025, 10, 18); - num3 = 1; - List list62 = new List(num3); - CollectionsMarshal.SetCount(list62, num3); - Span span62 = CollectionsMarshal.AsSpan(list62); - index = 0; - span62[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests"); - reference61 = new ChangelogEntry("6.26", releaseDate29, list62); + num4 = 0; + ref ChangeEntry reference61 = ref span61[num4]; + index = 2; + List list62 = new List(index); + CollectionsMarshal.SetCount(list62, index); + Span span62 = CollectionsMarshal.AsSpan(list62); + num5 = 0; + span62[num5] = "Added item count to combat handling rework"; + num5++; + span62[num5] = "Updated Pandora conflicting features"; + reference61 = new ChangeEntry(EChangeCategory.Changed, "Combat handling improvements", list62); + num4++; + span61[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest to purchase Gysahl Greens if not in inventory"); + reference60 = new ChangelogEntry("6.29", releaseDate27, list61); num2++; ref ChangelogEntry reference62 = ref span[num2]; - DateOnly releaseDate30 = new DateOnly(2025, 10, 17); - index = 1; - List list63 = new List(index); - CollectionsMarshal.SetCount(list63, index); + DateOnly releaseDate28 = new DateOnly(2025, 10, 19); + num4 = 1; + List list63 = new List(num4); + CollectionsMarshal.SetCount(list63, num4); Span span63 = CollectionsMarshal.AsSpan(list63); num3 = 0; - span63[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added All Saints' Wake 2025 quests and 7.35 Yok Huy rank 4 quests"); - reference62 = new ChangelogEntry("6.25", releaseDate30, list63); + span63[num3] = new ChangeEntry(EChangeCategory.Changed, "Reworked kill count combat handling - combat and enemy kills are now processed instantly"); + reference62 = new ChangelogEntry("6.28", releaseDate28, list63); num2++; ref ChangelogEntry reference63 = ref span[num2]; - DateOnly releaseDate31 = new DateOnly(2025, 10, 16); - num3 = 1; + DateOnly releaseDate29 = new DateOnly(2025, 10, 18); + num3 = 2; List list64 = new List(num3); CollectionsMarshal.SetCount(list64, num3); Span span64 = CollectionsMarshal.AsSpan(list64); - index = 0; - span64[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests and Deep Dungeon quest"); - reference63 = new ChangelogEntry("6.24", releaseDate31, list64); + num4 = 0; + span64[num4] = new ChangeEntry(EChangeCategory.Changed, "Improved Aether Current checking logic"); + num4++; + span64[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Chocobo Taxi Stand CheckSkip error and Patch 7.3 Fantasia unlock quest date/time"); + reference63 = new ChangelogEntry("6.27", releaseDate29, list64); num2++; ref ChangelogEntry reference64 = ref span[num2]; - DateOnly releaseDate32 = new DateOnly(2025, 10, 13); - index = 1; - List list65 = new List(index); - CollectionsMarshal.SetCount(list65, index); + DateOnly releaseDate30 = new DateOnly(2025, 10, 18); + num4 = 1; + List list65 = new List(num4); + CollectionsMarshal.SetCount(list65, num4); Span span65 = CollectionsMarshal.AsSpan(list65); num3 = 0; - span65[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quest (Larder Logistics)"); - reference64 = new ChangelogEntry("6.23", releaseDate32, list65); + span65[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests"); + reference64 = new ChangelogEntry("6.26", releaseDate30, list65); num2++; ref ChangelogEntry reference65 = ref span[num2]; - DateOnly releaseDate33 = new DateOnly(2025, 10, 12); - num3 = 3; + DateOnly releaseDate31 = new DateOnly(2025, 10, 17); + num3 = 1; List list66 = new List(num3); CollectionsMarshal.SetCount(list66, num3); Span span66 = CollectionsMarshal.AsSpan(list66); - index = 0; - span66[index] = new ChangeEntry(EChangeCategory.Changed, "Prevent disabled or Locked quests from being started as 'Start as next quest'"); - index++; - span66[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); - index++; - span66[index] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Yok Huy quest and journal quest chain priority issues"); - reference65 = new ChangelogEntry("6.22", releaseDate33, list66); + num4 = 0; + span66[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added All Saints' Wake 2025 quests and 7.35 Yok Huy rank 4 quests"); + reference65 = new ChangelogEntry("6.25", releaseDate31, list66); num2++; ref ChangelogEntry reference66 = ref span[num2]; - DateOnly releaseDate34 = new DateOnly(2025, 10, 12); - index = 2; - List list67 = new List(index); - CollectionsMarshal.SetCount(list67, index); + DateOnly releaseDate32 = new DateOnly(2025, 10, 16); + num4 = 1; + List list67 = new List(num4); + CollectionsMarshal.SetCount(list67, num4); Span span67 = CollectionsMarshal.AsSpan(list67); num3 = 0; - span67[num3] = new ChangeEntry(EChangeCategory.Added, "Added expansion abbreviation to journal window"); - num3++; - span67[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); - reference66 = new ChangelogEntry("6.21", releaseDate34, list67); + span67[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 4 quests and Deep Dungeon quest"); + reference66 = new ChangelogEntry("6.24", releaseDate32, list67); num2++; ref ChangelogEntry reference67 = ref span[num2]; - DateOnly releaseDate35 = new DateOnly(2025, 10, 10); - num3 = 2; + DateOnly releaseDate33 = new DateOnly(2025, 10, 13); + num3 = 1; List list68 = new List(num3); CollectionsMarshal.SetCount(list68, num3); Span span68 = CollectionsMarshal.AsSpan(list68); - index = 0; - span68[index] = new ChangeEntry(EChangeCategory.Changed, "Allow completed repeatable quests to be used with 'Add quest and requirements to priority' feature"); - index++; - span68[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 quest (A Work of Cart)"); - reference67 = new ChangelogEntry("6.20", releaseDate35, list68); + num4 = 0; + span68[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quest (Larder Logistics)"); + reference67 = new ChangelogEntry("6.23", releaseDate33, list68); num2++; ref ChangelogEntry reference68 = ref span[num2]; - DateOnly releaseDate36 = new DateOnly(2025, 10, 9); - index = 3; - List list69 = new List(index); - CollectionsMarshal.SetCount(list69, index); + DateOnly releaseDate34 = new DateOnly(2025, 10, 12); + num4 = 3; + List list69 = new List(num4); + CollectionsMarshal.SetCount(list69, num4); Span span69 = CollectionsMarshal.AsSpan(list69); num3 = 0; - span69[num3] = new ChangeEntry(EChangeCategory.Added, "Added config to batch Allied Society quest turn-ins"); + span69[num3] = new ChangeEntry(EChangeCategory.Changed, "Prevent disabled or Locked quests from being started as 'Start as next quest'"); num3++; - span69[num3] = new ChangeEntry(EChangeCategory.Changed, "Repeatable quests now show correct availability state in journal"); + span69[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); num3++; - span69[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 2 quests"); - reference68 = new ChangelogEntry("6.19", releaseDate36, list69); + span69[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Yok Huy quest and journal quest chain priority issues"); + reference68 = new ChangelogEntry("6.22", releaseDate34, list69); num2++; ref ChangelogEntry reference69 = ref span[num2]; - DateOnly releaseDate37 = new DateOnly(2025, 10, 9); + DateOnly releaseDate35 = new DateOnly(2025, 10, 12); num3 = 2; List list70 = new List(num3); CollectionsMarshal.SetCount(list70, num3); Span span70 = CollectionsMarshal.AsSpan(list70); - index = 0; - span70[index] = new ChangeEntry(EChangeCategory.Changed, "Show once completed quests with improved state display"); - index++; - span70[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy daily quest and improvements to various Yok Huy quests"); - reference69 = new ChangelogEntry("6.18", releaseDate37, list70); + num4 = 0; + span70[num4] = new ChangeEntry(EChangeCategory.Added, "Added expansion abbreviation to journal window"); + num4++; + span70[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 3 quests"); + reference69 = new ChangelogEntry("6.21", releaseDate35, list70); num2++; ref ChangelogEntry reference70 = ref span[num2]; - DateOnly releaseDate38 = new DateOnly(2025, 10, 8); - index = 1; - List list71 = new List(index); - CollectionsMarshal.SetCount(list71, index); + DateOnly releaseDate36 = new DateOnly(2025, 10, 10); + num4 = 2; + List list71 = new List(num4); + CollectionsMarshal.SetCount(list71, num4); Span span71 = CollectionsMarshal.AsSpan(list71); num3 = 0; - span71[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 and rank 2 quests"); - reference70 = new ChangelogEntry("6.17", releaseDate38, list71); + span71[num3] = new ChangeEntry(EChangeCategory.Changed, "Allow completed repeatable quests to be used with 'Add quest and requirements to priority' feature"); + num3++; + span71[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 quest (A Work of Cart)"); + reference70 = new ChangelogEntry("6.20", releaseDate36, list71); num2++; ref ChangelogEntry reference71 = ref span[num2]; - DateOnly releaseDate39 = new DateOnly(2025, 10, 8); - num3 = 1; + DateOnly releaseDate37 = new DateOnly(2025, 10, 9); + num3 = 3; List list72 = new List(num3); CollectionsMarshal.SetCount(list72, num3); Span span72 = CollectionsMarshal.AsSpan(list72); - index = 0; - span72[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon quest (Faerie Tale)"); - reference71 = new ChangelogEntry("6.16", releaseDate39, list72); + num4 = 0; + span72[num4] = new ChangeEntry(EChangeCategory.Added, "Added config to batch Allied Society quest turn-ins"); + num4++; + span72[num4] = new ChangeEntry(EChangeCategory.Changed, "Repeatable quests now show correct availability state in journal"); + num4++; + span72[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 2 quests"); + reference71 = new ChangelogEntry("6.19", releaseDate37, list72); num2++; ref ChangelogEntry reference72 = ref span[num2]; - DateOnly releaseDate40 = new DateOnly(2025, 10, 8); - index = 2; - List list73 = new List(index); - CollectionsMarshal.SetCount(list73, index); + DateOnly releaseDate38 = new DateOnly(2025, 10, 9); + num4 = 2; + List list73 = new List(num4); + CollectionsMarshal.SetCount(list73, num4); Span span73 = CollectionsMarshal.AsSpan(list73); num3 = 0; - span73[num3] = new ChangeEntry(EChangeCategory.Changed, "Dalamud cleanup"); + span73[num3] = new ChangeEntry(EChangeCategory.Changed, "Show once completed quests with improved state display"); num3++; - span73[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest level requirement check log spam"); - reference72 = new ChangelogEntry("6.15", releaseDate40, list73); + span73[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy daily quest and improvements to various Yok Huy quests"); + reference72 = new ChangelogEntry("6.18", releaseDate38, list73); num2++; ref ChangelogEntry reference73 = ref span[num2]; - DateOnly releaseDate41 = new DateOnly(2025, 10, 8); + DateOnly releaseDate39 = new DateOnly(2025, 10, 8); num3 = 1; List list74 = new List(num3); CollectionsMarshal.SetCount(list74, num3); Span span74 = CollectionsMarshal.AsSpan(list74); - index = 0; - span74[index] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check logic if quest were MSQ"); - reference73 = new ChangelogEntry("6.14", releaseDate41, list74); + num4 = 0; + span74[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Yok Huy rank 1 and rank 2 quests"); + reference73 = new ChangelogEntry("6.17", releaseDate39, list74); num2++; ref ChangelogEntry reference74 = ref span[num2]; - DateOnly releaseDate42 = new DateOnly(2025, 10, 8); - index = 2; - List list75 = new List(index); - CollectionsMarshal.SetCount(list75, index); + DateOnly releaseDate40 = new DateOnly(2025, 10, 8); + num4 = 1; + List list75 = new List(num4); + CollectionsMarshal.SetCount(list75, num4); Span span75 = CollectionsMarshal.AsSpan(list75); num3 = 0; - ref ChangeEntry reference75 = ref span75[num3]; - num4 = 3; - List list76 = new List(num4); - CollectionsMarshal.SetCount(list76, num4); - Span span76 = CollectionsMarshal.AsSpan(list76); - num5 = 0; - span76[num5] = "Context menu option to add required quests and their chain to priority list"; - num5++; - span76[num5] = "AetheryteShortcut to multiple quests"; - num5++; - span76[num5] = "Artisan as a recommended plugin/dependency"; - reference75 = new ChangeEntry(EChangeCategory.Added, "Quest improvements", list76); - num3++; - span75[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check and priority list issues"); - reference74 = new ChangelogEntry("6.13", releaseDate42, list75); + span75[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon quest (Faerie Tale)"); + reference74 = new ChangelogEntry("6.16", releaseDate40, list75); + num2++; + ref ChangelogEntry reference75 = ref span[num2]; + DateOnly releaseDate41 = new DateOnly(2025, 10, 8); + num3 = 2; + List list76 = new List(num3); + CollectionsMarshal.SetCount(list76, num3); + Span span76 = CollectionsMarshal.AsSpan(list76); + num4 = 0; + span76[num4] = new ChangeEntry(EChangeCategory.Changed, "Dalamud cleanup"); + num4++; + span76[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed quest level requirement check log spam"); + reference75 = new ChangelogEntry("6.15", releaseDate41, list76); num2++; ref ChangelogEntry reference76 = ref span[num2]; - DateOnly releaseDate43 = new DateOnly(2025, 10, 7); - num3 = 4; - List list77 = new List(num3); - CollectionsMarshal.SetCount(list77, num3); + DateOnly releaseDate42 = new DateOnly(2025, 10, 8); + num4 = 1; + List list77 = new List(num4); + CollectionsMarshal.SetCount(list77, num4); Span span77 = CollectionsMarshal.AsSpan(list77); - index = 0; - ref ChangeEntry reference77 = ref span77[index]; - num5 = 4; - List list78 = new List(num5); - CollectionsMarshal.SetCount(list78, num5); - Span span78 = CollectionsMarshal.AsSpan(list78); + num3 = 0; + span77[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check logic if quest were MSQ"); + reference76 = new ChangelogEntry("6.14", releaseDate42, list77); + num2++; + ref ChangelogEntry reference77 = ref span[num2]; + DateOnly releaseDate43 = new DateOnly(2025, 10, 8); + num3 = 2; + List list78 = new List(num3); + CollectionsMarshal.SetCount(list78, num3); + Span span78 = CollectionsMarshal.AsSpan(list78); num4 = 0; - span78[num4] = "FATE combat handling with auto level syncing"; - num4++; - span78[num4] = "Start accepted quests from journal with 'Start as next quest'"; - num4++; - span78[num4] = "Update quest tracking when quests are hidden or prioritised in game"; - num4++; - span78[num4] = "QuestMap as a recommended plugin/dependency"; - reference77 = new ChangeEntry(EChangeCategory.Added, "FATE and quest tracking", list78); - index++; - ref ChangeEntry reference78 = ref span77[index]; - num4 = 3; - List list79 = new List(num4); - CollectionsMarshal.SetCount(list79, num4); + ref ChangeEntry reference78 = ref span78[num4]; + num5 = 3; + List list79 = new List(num5); + CollectionsMarshal.SetCount(list79, num5); Span span79 = CollectionsMarshal.AsSpan(list79); - num5 = 0; - span79[num5] = "Always prioritise next quest during teleportation/zone transitions"; - num5++; - span79[num5] = "Improved accepted quest logic with abandoned quest detection"; - num5++; - span79[num5] = "Show quests without quest paths as Locked"; - reference78 = new ChangeEntry(EChangeCategory.Changed, "Quest prioritisation improvements", list79); + index = 0; + span79[index] = "Context menu option to add required quests and their chain to priority list"; index++; - span77[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon, Hildibrand, Yok Huy, Monster Hunter Wilds Collab, and Doman Enclave quests"); + span79[index] = "AetheryteShortcut to multiple quests"; index++; - span77[index] = new ChangeEntry(EChangeCategory.Fixed, "Fixed accepted/active quest display and Hildibrand quest issues"); - reference76 = new ChangelogEntry("6.12", releaseDate43, list77); + span79[index] = "Artisan as a recommended plugin/dependency"; + reference78 = new ChangeEntry(EChangeCategory.Added, "Quest improvements", list79); + num4++; + span78[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed abandoned quest check and priority list issues"); + reference77 = new ChangelogEntry("6.13", releaseDate43, list78); num2++; ref ChangelogEntry reference79 = ref span[num2]; - DateOnly releaseDate44 = new DateOnly(2025, 10, 3); - index = 1; - List list80 = new List(index); - CollectionsMarshal.SetCount(list80, index); + DateOnly releaseDate44 = new DateOnly(2025, 10, 7); + num4 = 4; + List list80 = new List(num4); + CollectionsMarshal.SetCount(list80, num4); Span span80 = CollectionsMarshal.AsSpan(list80); num3 = 0; - span80[num3] = new ChangeEntry(EChangeCategory.Changed, "Added remaining checks for quest priority to prevent infinite teleport looping"); - reference79 = new ChangelogEntry("6.11", releaseDate44, list80); - num2++; - ref ChangelogEntry reference80 = ref span[num2]; - DateOnly releaseDate45 = new DateOnly(2025, 10, 2); - num3 = 1; - List list81 = new List(num3); - CollectionsMarshal.SetCount(list81, num3); - Span span81 = CollectionsMarshal.AsSpan(list81); - index = 0; - ref ChangeEntry reference81 = ref span81[index]; - num5 = 2; + ref ChangeEntry reference80 = ref span80[num3]; + index = 4; + List list81 = new List(index); + CollectionsMarshal.SetCount(list81, index); + Span span81 = CollectionsMarshal.AsSpan(list81); + num5 = 0; + span81[num5] = "FATE combat handling with auto level syncing"; + num5++; + span81[num5] = "Start accepted quests from journal with 'Start as next quest'"; + num5++; + span81[num5] = "Update quest tracking when quests are hidden or prioritised in game"; + num5++; + span81[num5] = "QuestMap as a recommended plugin/dependency"; + reference80 = new ChangeEntry(EChangeCategory.Added, "FATE and quest tracking", list81); + num3++; + ref ChangeEntry reference81 = ref span80[num3]; + num5 = 3; List list82 = new List(num5); CollectionsMarshal.SetCount(list82, num5); Span span82 = CollectionsMarshal.AsSpan(list82); - num4 = 0; - span82[num4] = "Don't show quests as available if player doesn't meet level requirements"; - num4++; - span82[num4] = "Updated 'required for MSQ' text in Crystal Tower quest preset window"; - reference81 = new ChangeEntry(EChangeCategory.Changed, "Quest window improvements", list82); - reference80 = new ChangelogEntry("6.10", releaseDate45, list81); + index = 0; + span82[index] = "Always prioritise next quest during teleportation/zone transitions"; + index++; + span82[index] = "Improved accepted quest logic with abandoned quest detection"; + index++; + span82[index] = "Show quests without quest paths as Locked"; + reference81 = new ChangeEntry(EChangeCategory.Changed, "Quest prioritisation improvements", list82); + num3++; + span80[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.35 Deep Dungeon, Hildibrand, Yok Huy, Monster Hunter Wilds Collab, and Doman Enclave quests"); + num3++; + span80[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed accepted/active quest display and Hildibrand quest issues"); + reference79 = new ChangelogEntry("6.12", releaseDate44, list80); num2++; ref ChangelogEntry reference82 = ref span[num2]; - DateOnly releaseDate46 = new DateOnly(2025, 9, 21); - index = 5; - List list83 = new List(index); - CollectionsMarshal.SetCount(list83, index); + DateOnly releaseDate45 = new DateOnly(2025, 10, 3); + num3 = 1; + List list83 = new List(num3); + CollectionsMarshal.SetCount(list83, num3); Span span83 = CollectionsMarshal.AsSpan(list83); - num3 = 0; - ref ChangeEntry reference83 = ref span83[num3]; - num4 = 4; - List list84 = new List(num4); + num4 = 0; + span83[num4] = new ChangeEntry(EChangeCategory.Changed, "Added remaining checks for quest priority to prevent infinite teleport looping"); + reference82 = new ChangelogEntry("6.11", releaseDate45, list83); + num2++; + ref ChangelogEntry reference83 = ref span[num2]; + DateOnly releaseDate46 = new DateOnly(2025, 10, 2); + num4 = 1; + List list84 = new List(num4); CollectionsMarshal.SetCount(list84, num4); - Span span84 = CollectionsMarshal.AsSpan(list84); - num5 = 0; - span84[num5] = "Reworked event quest handling - automatically displays when events are active"; - num5++; - span84[num5] = "Reworked journal system with improved filtering and display"; - num5++; - span84[num5] = "Reworked Priority Quests tab (Manual Priority and Quest Presets)"; - num5++; - span84[num5] = "Quest path viewer site (https://wigglymuffin.github.io/FFXIV-Tools/)"; - reference83 = new ChangeEntry(EChangeCategory.Added, "Major system reworks", list84); - num3++; - ref ChangeEntry reference84 = ref span83[num3]; - num5 = 4; - List list85 = new List(num5); - CollectionsMarshal.SetCount(list85, num5); - Span span85 = CollectionsMarshal.AsSpan(list85); - num4 = 0; - span85[num4] = "Questionable.IsQuestCompleted"; - num4++; - span85[num4] = "Questionable.IsQuestAvailable"; - num4++; - span85[num4] = "Questionable.IsQuestAccepted"; - num4++; - span85[num4] = "Questionable.IsQuestUnobtainable"; - reference84 = new ChangeEntry(EChangeCategory.Added, "New IPC commands", list85); - num3++; - ref ChangeEntry reference85 = ref span83[num3]; - num4 = 5; - List list86 = new List(num4); - CollectionsMarshal.SetCount(list86, num4); - Span span86 = CollectionsMarshal.AsSpan(list86); - num5 = 0; - span86[num5] = "Improved JSON quest validation with specific error reasons"; - num5++; - span86[num5] = "Added stop at sequence stop condition"; - num5++; - span86[num5] = "Improved Pandora plugin conflict detection"; - num5++; - span86[num5] = "Improved DialogueChoices regex matching"; - num5++; - span86[num5] = "Improved refresh checker for all quest states"; - reference85 = new ChangeEntry(EChangeCategory.Changed, "Various improvements", list86); - num3++; - span83[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.31 Occult Crescent quests"); - num3++; - span83[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed cutscene crashes, Single Player Duty triggers, and various quest issues"); - reference82 = new ChangelogEntry("6.9", releaseDate46, list83); - num2++; - ref ChangelogEntry reference86 = ref span[num2]; - DateOnly releaseDate47 = new DateOnly(2025, 9, 2); - num3 = 4; - List list87 = new List(num3); - CollectionsMarshal.SetCount(list87, num3); - Span span87 = CollectionsMarshal.AsSpan(list87); - index = 0; - ref ChangeEntry reference87 = ref span87[index]; - num5 = 4; - List list88 = new List(num5); - CollectionsMarshal.SetCount(list88, num5); - Span span88 = CollectionsMarshal.AsSpan(list88); - num4 = 0; - span88[num4] = "Help commands and priority quest command"; - num4++; - span88[num4] = "Prevent 'CompleteQuest' step setting"; - num4++; - span88[num4] = "Duty counts and controls in 'Quest Battles' tab"; - num4++; - span88[num4] = "'Refresh quest timer' setting (WIP)"; - reference87 = new ChangeEntry(EChangeCategory.Added, "Command and UI improvements", list88); - index++; - span87[index] = new ChangeEntry(EChangeCategory.Changed, "Improved 'Clear All' buttons to require CTRL being held"); - index++; - span87[index] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Zodiac quests and 7.31 Cosmic/Occult Crescent quests"); - index++; - span87[index] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Fishing for Friendship and Cosmic Exploration quests"); - reference86 = new ChangelogEntry("6.8", releaseDate47, list87); - num2++; - ref ChangelogEntry reference88 = ref span[num2]; - DateOnly releaseDate48 = new DateOnly(2025, 8, 27); - index = 4; - List list89 = new List(index); - CollectionsMarshal.SetCount(list89, index); - Span span89 = CollectionsMarshal.AsSpan(list89); + Span span84 = CollectionsMarshal.AsSpan(list84); num3 = 0; - ref ChangeEntry reference89 = ref span89[num3]; - num4 = 2; - List list90 = new List(num4); - CollectionsMarshal.SetCount(list90, num4); - Span span90 = CollectionsMarshal.AsSpan(list90); - num5 = 0; - span90[num5] = "Icon to 'Clear All' button in stop conditions"; - num5++; - span90[num5] = "Duty counts and 'Enable All' button in 'Duties' tab"; - reference89 = new ChangeEntry(EChangeCategory.Added, "UI improvements", list90); - num3++; - span89[num3] = new ChangeEntry(EChangeCategory.Changed, "Renamed 'Clear' button to 'Clear All' in priority window"); - num3++; - span89[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Rising 2025 Event Quests"); - num3++; - span89[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed clipboard assigning blacklist to whitelist in 'Duties' tab"); - reference88 = new ChangelogEntry("6.7", releaseDate48, list89); - num2++; - ref ChangelogEntry reference90 = ref span[num2]; - DateOnly releaseDate49 = new DateOnly(2025, 8, 25); - num3 = 2; - List list91 = new List(num3); - CollectionsMarshal.SetCount(list91, num3); - Span span91 = CollectionsMarshal.AsSpan(list91); - index = 0; - ref ChangeEntry reference91 = ref span91[index]; - num5 = 2; - List list92 = new List(num5); - CollectionsMarshal.SetCount(list92, num5); - Span span92 = CollectionsMarshal.AsSpan(list92); - num4 = 0; - span92[num4] = "Missing emotes to schema and emote handler"; - num4++; - span92[num4] = "Improved stop conditions with 'Clear All' button"; - reference91 = new ChangeEntry(EChangeCategory.Added, "Emote support and stop conditions", list92); - index++; - span91[index] = new ChangeEntry(EChangeCategory.Changed, "Stop at level functionality"); - reference90 = new ChangelogEntry("6.6", releaseDate49, list91); - num2++; - ref ChangelogEntry reference92 = ref span[num2]; - DateOnly releaseDate50 = new DateOnly(2025, 8, 25); + ref ChangeEntry reference84 = ref span84[num3]; index = 2; - List list93 = new List(index); - CollectionsMarshal.SetCount(list93, index); - Span span93 = CollectionsMarshal.AsSpan(list93); + List list85 = new List(index); + CollectionsMarshal.SetCount(list85, index); + Span span85 = CollectionsMarshal.AsSpan(list85); + num5 = 0; + span85[num5] = "Don't show quests as available if player doesn't meet level requirements"; + num5++; + span85[num5] = "Updated 'required for MSQ' text in Crystal Tower quest preset window"; + reference84 = new ChangeEntry(EChangeCategory.Changed, "Quest window improvements", list85); + reference83 = new ChangelogEntry("6.10", releaseDate46, list84); + num2++; + ref ChangelogEntry reference85 = ref span[num2]; + DateOnly releaseDate47 = new DateOnly(2025, 9, 21); + num3 = 5; + List list86 = new List(num3); + CollectionsMarshal.SetCount(list86, num3); + Span span86 = CollectionsMarshal.AsSpan(list86); + num4 = 0; + ref ChangeEntry reference86 = ref span86[num4]; + num5 = 4; + List list87 = new List(num5); + CollectionsMarshal.SetCount(list87, num5); + Span span87 = CollectionsMarshal.AsSpan(list87); + index = 0; + span87[index] = "Reworked event quest handling - automatically displays when events are active"; + index++; + span87[index] = "Reworked journal system with improved filtering and display"; + index++; + span87[index] = "Reworked Priority Quests tab (Manual Priority and Quest Presets)"; + index++; + span87[index] = "Quest path viewer site (https://wigglymuffin.github.io/FFXIV-Tools/)"; + reference86 = new ChangeEntry(EChangeCategory.Added, "Major system reworks", list87); + num4++; + ref ChangeEntry reference87 = ref span86[num4]; + index = 4; + List list88 = new List(index); + CollectionsMarshal.SetCount(list88, index); + Span span88 = CollectionsMarshal.AsSpan(list88); + num5 = 0; + span88[num5] = "Questionable.IsQuestCompleted"; + num5++; + span88[num5] = "Questionable.IsQuestAvailable"; + num5++; + span88[num5] = "Questionable.IsQuestAccepted"; + num5++; + span88[num5] = "Questionable.IsQuestUnobtainable"; + reference87 = new ChangeEntry(EChangeCategory.Added, "New IPC commands", list88); + num4++; + ref ChangeEntry reference88 = ref span86[num4]; + num5 = 5; + List list89 = new List(num5); + CollectionsMarshal.SetCount(list89, num5); + Span span89 = CollectionsMarshal.AsSpan(list89); + index = 0; + span89[index] = "Improved JSON quest validation with specific error reasons"; + index++; + span89[index] = "Added stop at sequence stop condition"; + index++; + span89[index] = "Improved Pandora plugin conflict detection"; + index++; + span89[index] = "Improved DialogueChoices regex matching"; + index++; + span89[index] = "Improved refresh checker for all quest states"; + reference88 = new ChangeEntry(EChangeCategory.Changed, "Various improvements", list89); + num4++; + span86[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added 7.31 Occult Crescent quests"); + num4++; + span86[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed cutscene crashes, Single Player Duty triggers, and various quest issues"); + reference85 = new ChangelogEntry("6.9", releaseDate47, list86); + num2++; + ref ChangelogEntry reference89 = ref span[num2]; + DateOnly releaseDate48 = new DateOnly(2025, 9, 2); + num4 = 4; + List list90 = new List(num4); + CollectionsMarshal.SetCount(list90, num4); + Span span90 = CollectionsMarshal.AsSpan(list90); num3 = 0; - span93[num3] = new ChangeEntry(EChangeCategory.Fixed, "Potential fix to single/solo duties softlocking"); + ref ChangeEntry reference90 = ref span90[num3]; + index = 4; + List list91 = new List(index); + CollectionsMarshal.SetCount(list91, index); + Span span91 = CollectionsMarshal.AsSpan(list91); + num5 = 0; + span91[num5] = "Help commands and priority quest command"; + num5++; + span91[num5] = "Prevent 'CompleteQuest' step setting"; + num5++; + span91[num5] = "Duty counts and controls in 'Quest Battles' tab"; + num5++; + span91[num5] = "'Refresh quest timer' setting (WIP)"; + reference90 = new ChangeEntry(EChangeCategory.Added, "Command and UI improvements", list91); num3++; - span93[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added San d'Oria: The Second Walk and various side quests"); - reference92 = new ChangelogEntry("6.5", releaseDate50, list93); + span90[num3] = new ChangeEntry(EChangeCategory.Changed, "Improved 'Clear All' buttons to require CTRL being held"); + num3++; + span90[num3] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Zodiac quests and 7.31 Cosmic/Occult Crescent quests"); + num3++; + span90[num3] = new ChangeEntry(EChangeCategory.Fixed, "Fixed Fishing for Friendship and Cosmic Exploration quests"); + reference89 = new ChangelogEntry("6.8", releaseDate48, list90); + num2++; + ref ChangelogEntry reference91 = ref span[num2]; + DateOnly releaseDate49 = new DateOnly(2025, 8, 27); + num3 = 4; + List list92 = new List(num3); + CollectionsMarshal.SetCount(list92, num3); + Span span92 = CollectionsMarshal.AsSpan(list92); + num4 = 0; + ref ChangeEntry reference92 = ref span92[num4]; + num5 = 2; + List list93 = new List(num5); + CollectionsMarshal.SetCount(list93, num5); + Span span93 = CollectionsMarshal.AsSpan(list93); + index = 0; + span93[index] = "Icon to 'Clear All' button in stop conditions"; + index++; + span93[index] = "Duty counts and 'Enable All' button in 'Duties' tab"; + reference92 = new ChangeEntry(EChangeCategory.Added, "UI improvements", list93); + num4++; + span92[num4] = new ChangeEntry(EChangeCategory.Changed, "Renamed 'Clear' button to 'Clear All' in priority window"); + num4++; + span92[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added Rising 2025 Event Quests"); + num4++; + span92[num4] = new ChangeEntry(EChangeCategory.Fixed, "Fixed clipboard assigning blacklist to whitelist in 'Duties' tab"); + reference91 = new ChangelogEntry("6.7", releaseDate49, list92); + num2++; + ref ChangelogEntry reference93 = ref span[num2]; + DateOnly releaseDate50 = new DateOnly(2025, 8, 25); + num4 = 2; + List list94 = new List(num4); + CollectionsMarshal.SetCount(list94, num4); + Span span94 = CollectionsMarshal.AsSpan(list94); + num3 = 0; + ref ChangeEntry reference94 = ref span94[num3]; + index = 2; + List list95 = new List(index); + CollectionsMarshal.SetCount(list95, index); + Span span95 = CollectionsMarshal.AsSpan(list95); + num5 = 0; + span95[num5] = "Missing emotes to schema and emote handler"; + num5++; + span95[num5] = "Improved stop conditions with 'Clear All' button"; + reference94 = new ChangeEntry(EChangeCategory.Added, "Emote support and stop conditions", list95); + num3++; + span94[num3] = new ChangeEntry(EChangeCategory.Changed, "Stop at level functionality"); + reference93 = new ChangelogEntry("6.6", releaseDate50, list94); + num2++; + ref ChangelogEntry reference95 = ref span[num2]; + DateOnly releaseDate51 = new DateOnly(2025, 8, 25); + num3 = 2; + List list96 = new List(num3); + CollectionsMarshal.SetCount(list96, num3); + Span span96 = CollectionsMarshal.AsSpan(list96); + num4 = 0; + span96[num4] = new ChangeEntry(EChangeCategory.Fixed, "Potential fix to single/solo duties softlocking"); + num4++; + span96[num4] = new ChangeEntry(EChangeCategory.QuestUpdates, "Added San d'Oria: The Second Walk and various side quests"); + reference95 = new ChangelogEntry("6.5", releaseDate51, list96); Changelogs = list; } } diff --git a/Questionable/Questionable.Data/TerritoryData.cs b/Questionable/Questionable.Data/TerritoryData.cs index 38d6d54..d9e748c 100644 --- a/Questionable/Questionable.Data/TerritoryData.cs +++ b/Questionable/Questionable.Data/TerritoryData.cs @@ -33,6 +33,8 @@ internal sealed class TerritoryData private readonly ImmutableDictionary _contentFinderConditions; + private readonly ImmutableDictionary _territoryToContentFinderCondition; + private readonly ImmutableDictionary<(ElementId QuestId, byte Index), uint> _questBattlesToContentFinderCondition; public TerritoryData(IDataManager dataManager) @@ -67,6 +69,9 @@ internal sealed class TerritoryData return flag && x.ContentType.RowId != 6; }) select new ContentFinderConditionData(x, dataManager.Language)).ToImmutableDictionary((ContentFinderConditionData x) => x.ContentFinderConditionId, (ContentFinderConditionData x) => x); + _territoryToContentFinderCondition = (from x in dataManager.GetExcelSheet() + where x.RowId != 0 && x.TerritoryType.RowId != 0 + group x by x.TerritoryType.RowId).ToImmutableDictionary((IGrouping g) => g.Key, (IGrouping g) => g.First().RowId); _questBattlesToContentFinderCondition = (from x in (from x in dataManager.GetExcelSheet() where x.RowId != 0 && x.IssuerLocation.RowId != 0 select x).SelectMany(GetQuestBattles) @@ -138,6 +143,11 @@ internal sealed class TerritoryData return false; } + public bool TryGetContentFinderConditionIdForTerritory(ushort territoryId, out uint cfcId) + { + return _territoryToContentFinderCondition.TryGetValue(territoryId, out cfcId); + } + public IEnumerable<(ElementId QuestId, byte Index, ContentFinderConditionData Data)> GetAllQuestsWithQuestBattles() { return _questBattlesToContentFinderCondition.Select, (ElementId, byte, ContentFinderConditionData)>((KeyValuePair<(ElementId QuestId, byte Index), uint> x) => (QuestId: x.Key.QuestId, Index: x.Key.Index, _contentFinderConditions[x.Value])); diff --git a/Questionable/Questionable.External/TextAdvanceIpc.cs b/Questionable/Questionable.External/TextAdvanceIpc.cs index 573a68a..6a66e89 100644 --- a/Questionable/Questionable.External/TextAdvanceIpc.cs +++ b/Questionable/Questionable.External/TextAdvanceIpc.cs @@ -1,4 +1,5 @@ using System; +using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Services; @@ -10,31 +11,37 @@ internal sealed class TextAdvanceIpc : IDisposable { public sealed class ExternalTerritoryConfig { - public bool? EnableQuestAccept = true; + public bool? EnableQuestAccept; - public bool? EnableQuestComplete = true; + public bool? EnableQuestComplete; - public bool? EnableRewardPick = true; + public bool? EnableRewardPick; - public bool? EnableRequestHandin = true; + public bool? EnableRequestHandin; - public bool? EnableCutsceneEsc = true; + public bool? EnableCutsceneEsc; - public bool? EnableCutsceneSkipConfirm = true; + public bool? EnableCutsceneSkipConfirm; - public bool? EnableTalkSkip = true; + public bool? EnableTalkSkip; - public bool? EnableRequestFill = true; + public bool? EnableRequestFill; - public bool? EnableAutoInteract = false; + public bool? EnableAutoInteract; } private bool _isExternalControlActivated; + private bool _lastCinemaModeState; + + private bool _lastInCutsceneState; + private readonly QuestController _questController; private readonly Configuration _configuration; + private readonly ICondition _condition; + private readonly IFramework _framework; private readonly ICallGateSubscriber _isInExternalControl; @@ -45,13 +52,12 @@ internal sealed class TextAdvanceIpc : IDisposable private readonly string _pluginName; - private readonly ExternalTerritoryConfig _externalTerritoryConfig = new ExternalTerritoryConfig(); - - public TextAdvanceIpc(IDalamudPluginInterface pluginInterface, IFramework framework, QuestController questController, Configuration configuration) + public TextAdvanceIpc(IDalamudPluginInterface pluginInterface, IFramework framework, QuestController questController, Configuration configuration, ICondition condition) { _framework = framework; _questController = questController; _configuration = configuration; + _condition = condition; _isInExternalControl = pluginInterface.GetIpcSubscriber("TextAdvance.IsInExternalControl"); _enableExternalControl = pluginInterface.GetIpcSubscriber("TextAdvance.EnableExternalControl"); _disableExternalControl = pluginInterface.GetIpcSubscriber("TextAdvance.DisableExternalControl"); @@ -71,16 +77,53 @@ internal sealed class TextAdvanceIpc : IDisposable private void OnUpdate(IFramework framework) { bool flag = _questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual; - if (_configuration.General.ConfigureTextAdvance && flag) + if (!_configuration.General.ConfigureTextAdvance || !flag) { - if (!_isInExternalControl.InvokeFunc() && _enableExternalControl.InvokeFunc(_pluginName, _externalTerritoryConfig)) + if (_isExternalControlActivated && (_disableExternalControl.InvokeFunc(_pluginName) || !_isInExternalControl.InvokeFunc())) { - _isExternalControlActivated = true; + _isExternalControlActivated = false; + } + return; + } + bool cinemaMode = _configuration.General.CinemaMode; + bool flag2 = _condition[ConditionFlag.OccupiedInCutSceneEvent] || _condition[ConditionFlag.WatchingCutscene] || _condition[ConditionFlag.WatchingCutscene78]; + bool flag3 = cinemaMode != _lastCinemaModeState || (cinemaMode && flag2 != _lastInCutsceneState); + if (!_isExternalControlActivated) + { + if (!_isInExternalControl.InvokeFunc()) + { + ExternalTerritoryConfig arg = CreateExternalTerritoryConfig(cinemaMode, flag2); + if (_enableExternalControl.InvokeFunc(_pluginName, arg)) + { + _isExternalControlActivated = true; + _lastCinemaModeState = cinemaMode; + _lastInCutsceneState = flag2; + } } } - else if (_isExternalControlActivated && (_disableExternalControl.InvokeFunc(_pluginName) || !_isInExternalControl.InvokeFunc())) + else if (flag3) { - _isExternalControlActivated = false; + ExternalTerritoryConfig arg2 = CreateExternalTerritoryConfig(cinemaMode, flag2); + _enableExternalControl.InvokeFunc(_pluginName, arg2); + _lastCinemaModeState = cinemaMode; + _lastInCutsceneState = flag2; } } + + private static ExternalTerritoryConfig CreateExternalTerritoryConfig(bool cinemaMode, bool inCutscene) + { + bool flag = cinemaMode && inCutscene; + return new ExternalTerritoryConfig + { + EnableQuestAccept = true, + EnableQuestComplete = true, + EnableRewardPick = true, + EnableRequestHandin = true, + EnableCutsceneEsc = !cinemaMode, + EnableCutsceneSkipConfirm = !cinemaMode, + EnableTalkSkip = !flag, + EnableRequestFill = true, + EnableAutoInteract = false + }; + } } diff --git a/Questionable/Questionable.Windows.ConfigComponents/DebugConfigComponent.cs b/Questionable/Questionable.Windows.ConfigComponents/DebugConfigComponent.cs index f5a4f8b..bab710a 100644 --- a/Questionable/Questionable.Windows.ConfigComponents/DebugConfigComponent.cs +++ b/Questionable/Questionable.Windows.ConfigComponents/DebugConfigComponent.cs @@ -52,15 +52,23 @@ internal sealed class DebugConfigComponent : ConfigComponent base.Configuration.Advanced.AdditionalStatusInformation = v4; Save(); } + bool v5 = base.Configuration.Advanced.DisablePartyWatchdog; + if (ImGui.Checkbox("Disable Party Watchdog", ref v5)) + { + base.Configuration.Advanced.DisablePartyWatchdog = v5; + Save(); + } + ImGui.SameLine(); + ImGuiComponents.HelpMarker("The Party Watchdog stops Questionable when entering certain zones with other party members, or when entering unsupported content. Disabling this allows Questionable to continue working while in a party, but may cause unexpected behavior in group content."); ImGui.Separator(); ImGui.Text("AutoDuty Settings"); using (ImRaii.PushIndent()) { ImGui.AlignTextToFramePadding(); - bool v5 = base.Configuration.Advanced.DisableAutoDutyBareMode; - if (ImGui.Checkbox("Use Pre-Loop/Loop/Post-Loop settings", ref v5)) + bool v6 = base.Configuration.Advanced.DisableAutoDutyBareMode; + if (ImGui.Checkbox("Use Pre-Loop/Loop/Post-Loop settings", ref v6)) { - base.Configuration.Advanced.DisableAutoDutyBareMode = v5; + base.Configuration.Advanced.DisableAutoDutyBareMode = v6; Save(); } ImGui.SameLine(); @@ -70,42 +78,42 @@ internal sealed class DebugConfigComponent : ConfigComponent ImGui.Text("Quest/Interaction Skips"); using (ImRaii.PushIndent()) { - bool v6 = base.Configuration.Advanced.SkipAetherCurrents; - if (ImGui.Checkbox("Don't pick up aether currents/aether current quests", ref v6)) + bool v7 = base.Configuration.Advanced.SkipAetherCurrents; + if (ImGui.Checkbox("Don't pick up aether currents/aether current quests", ref v7)) { - base.Configuration.Advanced.SkipAetherCurrents = v6; + base.Configuration.Advanced.SkipAetherCurrents = v7; Save(); } ImGui.SameLine(); ImGuiComponents.HelpMarker("If not done during the MSQ by Questionable, you have to manually pick up any missed aether currents/quests. There is no way to automatically pick up all missing aether currents."); - bool v7 = base.Configuration.Advanced.SkipClassJobQuests; - if (ImGui.Checkbox("Don't pick up class/job/role quests", ref v7)) + bool v8 = base.Configuration.Advanced.SkipClassJobQuests; + if (ImGui.Checkbox("Don't pick up class/job/role quests", ref v8)) { - base.Configuration.Advanced.SkipClassJobQuests = v7; + base.Configuration.Advanced.SkipClassJobQuests = v8; Save(); } ImGui.SameLine(); ImGuiComponents.HelpMarker("Class and job skills for A Realm Reborn, Heavensward and (for the Lv70 skills) Stormblood are locked behind quests. Not recommended if you plan on queueing for instances with duty finder/party finder.\n\nNote: This setting is ignored for the first class/job quest if your character is not high enough level to start the level 4 MSQ."); - bool v8 = base.Configuration.Advanced.SkipARealmRebornHardModePrimals; - if (ImGui.Checkbox("Don't pick up ARR hard mode primal quests", ref v8)) + bool v9 = base.Configuration.Advanced.SkipARealmRebornHardModePrimals; + if (ImGui.Checkbox("Don't pick up ARR hard mode primal quests", ref v9)) { - base.Configuration.Advanced.SkipARealmRebornHardModePrimals = v8; + base.Configuration.Advanced.SkipARealmRebornHardModePrimals = v9; Save(); } ImGui.SameLine(); ImGuiComponents.HelpMarker("Hard mode Ifrit/Garuda/Titan are required for the Patch 2.5 quest 'Good Intentions' and to start Heavensward."); - bool v9 = base.Configuration.Advanced.SkipCrystalTowerRaids; - if (ImGui.Checkbox("Don't pick up Crystal Tower quests", ref v9)) + bool v10 = base.Configuration.Advanced.SkipCrystalTowerRaids; + if (ImGui.Checkbox("Don't pick up Crystal Tower quests", ref v10)) { - base.Configuration.Advanced.SkipCrystalTowerRaids = v9; + base.Configuration.Advanced.SkipCrystalTowerRaids = v10; Save(); } ImGui.SameLine(); ImGuiComponents.HelpMarker("Crystal Tower raids are required for the Patch 2.55 quest 'A Time to Every Purpose' and to start Heavensward."); - bool v10 = base.Configuration.Advanced.PreventQuestCompletion; - if (ImGui.Checkbox("Prevent quest completion", ref v10)) + bool v11 = base.Configuration.Advanced.PreventQuestCompletion; + if (ImGui.Checkbox("Prevent quest completion", ref v11)) { - base.Configuration.Advanced.PreventQuestCompletion = v10; + base.Configuration.Advanced.PreventQuestCompletion = v11; Save(); } ImGui.SameLine(); diff --git a/Questionable/Questionable.Windows.ConfigComponents/GeneralConfigComponent.cs b/Questionable/Questionable.Windows.ConfigComponents/GeneralConfigComponent.cs index 98e6dcd..674af38 100644 --- a/Questionable/Questionable.Windows.ConfigComponents/GeneralConfigComponent.cs +++ b/Questionable/Questionable.Windows.ConfigComponents/GeneralConfigComponent.cs @@ -43,6 +43,10 @@ internal sealed class GeneralConfigComponent : ConfigComponent private bool _mountComboJustOpened; + private string _classJobSearchText = string.Empty; + + private bool _classJobComboJustOpened; + public GeneralConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration, IDataManager dataManager, ClassJobUtils classJobUtils, QuestRegistry questRegistry, TerritoryData territoryData) : base(pluginInterface, configuration) { @@ -155,17 +159,54 @@ internal sealed class GeneralConfigComponent : ConfigComponent base.Configuration.General.GrandCompany = (FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany)currentItem2; Save(); } - int currentItem3 = Array.IndexOf(_classJobIds, base.Configuration.General.CombatJob); - if (currentItem3 == -1) + int num3 = Array.IndexOf(_classJobIds, base.Configuration.General.CombatJob); + if (num3 == -1) { base.Configuration.General.CombatJob = EClassJob.Adventurer; Save(); - currentItem3 = 0; + num3 = 0; } - if (ImGui.Combo((ImU8String)"Preferred Combat Job", ref currentItem3, (ReadOnlySpan)_classJobNames, _classJobNames.Length)) + string text2 = ((num3 >= 0 && num3 < _classJobNames.Length) ? _classJobNames[num3] : "Unknown"); + if (ImGui.BeginCombo("Preferred Combat Job", text2, ImGuiComboFlags.HeightLarge)) { - base.Configuration.General.CombatJob = _classJobIds[currentItem3]; - Save(); + if (!_classJobComboJustOpened) + { + ImGui.SetKeyboardFocusHere(); + _classJobComboJustOpened = true; + } + ImGui.SetNextItemWidth(-1f); + ImGui.InputTextWithHint("##CombatJobSearch", "Search combat jobs...", ref _classJobSearchText, 256); + ImGui.Separator(); + using (ImRaii.IEndObject endObject3 = ImRaii.Child("##CombatJobScrollArea", new Vector2(0f, 300f), border: false)) + { + if (endObject3) + { + string value2 = _classJobSearchText.ToUpperInvariant(); + for (int num4 = 0; num4 < _classJobNames.Length; num4++) + { + if (string.IsNullOrEmpty(_classJobSearchText) || _classJobNames[num4].ToUpperInvariant().Contains(value2, StringComparison.Ordinal)) + { + bool flag2 = num4 == num3; + if (ImGui.Selectable(_classJobNames[num4], flag2)) + { + base.Configuration.General.CombatJob = _classJobIds[num4]; + Save(); + _classJobSearchText = string.Empty; + ImGui.CloseCurrentPopup(); + } + if (flag2) + { + ImGui.SetItemDefaultFocus(); + } + } + } + } + } + ImGui.EndCombo(); + } + else + { + _classJobComboJustOpened = false; } ImGui.Separator(); ImGui.Text("UI"); @@ -212,16 +253,38 @@ internal sealed class GeneralConfigComponent : ConfigComponent ImGui.Text("Questing"); using (ImRaii.PushIndent()) { - bool v7 = base.Configuration.General.ConfigureTextAdvance; - if (ImGui.Checkbox("Automatically configure TextAdvance with the recommended settings", ref v7)) + bool v7 = base.Configuration.General.CinemaMode; + if (ImGui.Checkbox("Cinema Mode (watch cutscenes)", ref v7)) { - base.Configuration.General.ConfigureTextAdvance = v7; + base.Configuration.General.CinemaMode = v7; Save(); } - bool v8 = base.Configuration.General.SkipLowPriorityDuties; - if (ImGui.Checkbox("Unlock certain optional dungeons and raids (instead of waiting for completion)", ref v8)) + ImGui.SameLine(); + using (ImRaii.PushFont(UiBuilder.IconFont)) { - base.Configuration.General.SkipLowPriorityDuties = v8; + ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString()); + } + if (ImGui.IsItemHovered()) + { + using (ImRaii.Tooltip()) + { + ImGui.Text("When enabled, cutscenes will NOT be automatically skipped."); + ImGui.Text("This allows you to experience the story while Questionable"); + ImGui.Text("handles navigation, combat, and other gameplay automation."); + ImGui.Spacing(); + 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)) + { + base.Configuration.General.ConfigureTextAdvance = v8; + Save(); + } + bool v9 = base.Configuration.General.SkipLowPriorityDuties; + if (ImGui.Checkbox("Unlock certain optional dungeons and raids (instead of waiting for completion)", ref v9)) + { + base.Configuration.General.SkipLowPriorityDuties = v9; Save(); } ImGui.SameLine(); @@ -241,18 +304,18 @@ internal sealed class GeneralConfigComponent : ConfigComponent { if (_territoryData.TryGetContentFinderCondition(lowPriorityContentFinderConditionQuest.ContentFinderConditionId, out TerritoryData.ContentFinderConditionData contentFinderConditionData)) { - ImU8String text2 = new ImU8String(0, 1); - text2.AppendFormatted(contentFinderConditionData.Name); - ImGui.BulletText(text2); + ImU8String text3 = new ImU8String(0, 1); + text3.AppendFormatted(contentFinderConditionData.Name); + ImGui.BulletText(text3); } } } } ImGui.Spacing(); - bool v9 = base.Configuration.General.AutoStepRefreshEnabled; - if (ImGui.Checkbox("Automatically refresh quest steps when stuck", ref v9)) + bool v10 = base.Configuration.General.AutoStepRefreshEnabled; + if (ImGui.Checkbox("Automatically refresh quest steps when stuck", ref v10)) { - base.Configuration.General.AutoStepRefreshEnabled = v9; + base.Configuration.General.AutoStepRefreshEnabled = v10; Save(); } ImGui.SameLine(); @@ -268,37 +331,37 @@ internal sealed class GeneralConfigComponent : ConfigComponent ImGui.Text("This helps resume automated quest completion when interruptions occur."); } } - using (ImRaii.Disabled(!v9)) + using (ImRaii.Disabled(!v10)) { ImGui.Indent(); - int v10 = base.Configuration.General.AutoStepRefreshDelaySeconds; + int v11 = base.Configuration.General.AutoStepRefreshDelaySeconds; ImGui.SetNextItemWidth(150f); - if (ImGui.SliderInt("Refresh delay (seconds)", ref v10, 10, 180)) + if (ImGui.SliderInt("Refresh delay (seconds)", ref v11, 10, 180)) { - base.Configuration.General.AutoStepRefreshDelaySeconds = v10; + base.Configuration.General.AutoStepRefreshDelaySeconds = v11; Save(); } Vector4 col = new Vector4(0.7f, 0.7f, 0.7f, 1f); - ImU8String text3 = new ImU8String(77, 1); - text3.AppendLiteral("Quest steps will refresh automatically after "); - text3.AppendFormatted(v10); - text3.AppendLiteral(" seconds if no progress is made."); - ImGui.TextColored(in col, text3); + ImU8String text4 = new ImU8String(77, 1); + text4.AppendLiteral("Quest steps will refresh automatically after "); + text4.AppendFormatted(v11); + text4.AppendLiteral(" seconds if no progress is made."); + ImGui.TextColored(in col, text4); ImGui.Unindent(); } ImGui.Spacing(); ImGui.Separator(); ImGui.Text("Priority Quest Management"); - bool v11 = base.Configuration.General.ClearPriorityQuestsOnLogout; - if (ImGui.Checkbox("Clear priority quests on character logout", ref v11)) + bool v12 = base.Configuration.General.ClearPriorityQuestsOnLogout; + if (ImGui.Checkbox("Clear priority quests on character logout", ref v12)) { - base.Configuration.General.ClearPriorityQuestsOnLogout = v11; + base.Configuration.General.ClearPriorityQuestsOnLogout = v12; Save(); } - bool v12 = base.Configuration.General.ClearPriorityQuestsOnCompletion; - if (ImGui.Checkbox("Remove priority quests when completed", ref v12)) + bool v13 = base.Configuration.General.ClearPriorityQuestsOnCompletion; + if (ImGui.Checkbox("Remove priority quests when completed", ref v13)) { - base.Configuration.General.ClearPriorityQuestsOnCompletion = v12; + base.Configuration.General.ClearPriorityQuestsOnCompletion = v13; Save(); } ImGui.SameLine(); diff --git a/Questionable/Questionable.Windows.ConfigComponents/NotificationConfigComponent.cs b/Questionable/Questionable.Windows.ConfigComponents/NotificationConfigComponent.cs index 2269944..c39f0db 100644 --- a/Questionable/Questionable.Windows.ConfigComponents/NotificationConfigComponent.cs +++ b/Questionable/Questionable.Windows.ConfigComponents/NotificationConfigComponent.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Numerics; using Dalamud.Bindings.ImGui; using Dalamud.Game.Text; using Dalamud.Interface.Utility.Raii; @@ -10,9 +11,21 @@ namespace Questionable.Windows.ConfigComponents; internal sealed class NotificationConfigComponent : ConfigComponent { + private readonly XivChatType[] _xivChatTypes; + + private readonly string[] _chatTypeNames; + + private string _chatChannelSearchText = string.Empty; + + private bool _chatChannelComboJustOpened; + public NotificationConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration) : base(pluginInterface, configuration) { + _xivChatTypes = (from x in Enum.GetValues() + where x != XivChatType.StandardEmote + select x).ToArray(); + _chatTypeNames = _xivChatTypes.Select((XivChatType t) => t.GetAttribute()?.FancyName ?? t.ToString()).ToArray(); } public override void DrawTab() @@ -32,15 +45,52 @@ internal sealed class NotificationConfigComponent : ConfigComponent { using (ImRaii.PushIndent()) { - XivChatType[] array = (from x in Enum.GetValues() - where x != XivChatType.StandardEmote - select x).ToArray(); - int currentItem = Array.IndexOf(array, base.Configuration.Notifications.ChatType); - string[] array2 = array.Select((XivChatType t) => t.GetAttribute()?.FancyName ?? t.ToString()).ToArray(); - if (ImGui.Combo((ImU8String)"Chat channel", ref currentItem, (ReadOnlySpan)array2, array2.Length)) + int num = Array.IndexOf(_xivChatTypes, base.Configuration.Notifications.ChatType); + if (num == -1) { - base.Configuration.Notifications.ChatType = array[currentItem]; - Save(); + num = 0; + } + string text = ((num >= 0 && num < _chatTypeNames.Length) ? _chatTypeNames[num] : "Unknown"); + if (ImGui.BeginCombo("Chat channel", text, ImGuiComboFlags.HeightLarge)) + { + if (!_chatChannelComboJustOpened) + { + ImGui.SetKeyboardFocusHere(); + _chatChannelComboJustOpened = true; + } + ImGui.SetNextItemWidth(-1f); + ImGui.InputTextWithHint("##ChatChannelSearch", "Search chat channels...", ref _chatChannelSearchText, 256); + ImGui.Separator(); + using (ImRaii.IEndObject endObject2 = ImRaii.Child("##ChatChannelScrollArea", new Vector2(0f, 300f), border: false)) + { + if (endObject2) + { + string value = _chatChannelSearchText.ToUpperInvariant(); + for (int i = 0; i < _chatTypeNames.Length; i++) + { + if (string.IsNullOrEmpty(_chatChannelSearchText) || _chatTypeNames[i].ToUpperInvariant().Contains(value, StringComparison.Ordinal)) + { + bool flag = i == num; + if (ImGui.Selectable(_chatTypeNames[i], flag)) + { + base.Configuration.Notifications.ChatType = _xivChatTypes[i]; + Save(); + _chatChannelSearchText = string.Empty; + ImGui.CloseCurrentPopup(); + } + if (flag) + { + ImGui.SetItemDefaultFocus(); + } + } + } + } + } + ImGui.EndCombo(); + } + else + { + _chatChannelComboJustOpened = false; } } } diff --git a/Questionable/Questionable.Windows.Utils/QuestSelector.cs b/Questionable/Questionable.Windows.Utils/QuestSelector.cs index c969145..08aee3b 100644 --- a/Questionable/Questionable.Windows.Utils/QuestSelector.cs +++ b/Questionable/Questionable.Windows.Utils/QuestSelector.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; using Dalamud.Bindings.ImGui; +using Dalamud.Interface.Utility.Raii; using Questionable.Controller; using Questionable.Model; using Questionable.Model.Questing; @@ -12,6 +14,8 @@ internal sealed class QuestSelector(QuestRegistry questRegistry) { private string _searchString = string.Empty; + private bool _comboJustOpened; + public Predicate? SuggestionPredicate { private get; set; } public Predicate? DefaultPredicate { private get; set; } @@ -27,12 +31,18 @@ internal sealed class QuestSelector(QuestRegistry questRegistry) ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); if (ImGui.BeginCombo("##QuestSelection", "Add Quest...", ImGuiComboFlags.HeightLarge)) { - ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); - bool flag = ImGui.InputTextWithHint("", "Filter...", ref _searchString, 256, ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue); + if (!_comboJustOpened) + { + ImGui.SetKeyboardFocusHere(); + _comboJustOpened = true; + } + ImGui.SetNextItemWidth(-1f); + bool flag = ImGui.InputTextWithHint("##QuestSearch", "Search quests...", ref _searchString, 256, ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue); + ImGui.Separator(); IEnumerable enumerable; if (!string.IsNullOrEmpty(_searchString)) { - enumerable = Enumerable.Where(predicate: (!ElementId.TryFromString(_searchString, out ElementId elementId)) ? new Func(DefaultPredicate) : ((Func)((Quest x) => DefaultPredicate(x) || x.Id == elementId)), source: questRegistry.AllQuests.Where(delegate(Quest x) + enumerable = Enumerable.Where(predicate: (!ElementId.TryFromString(_searchString, out ElementId elementId)) ? new Func(SearchPredicate) : ((Func)((Quest x) => SearchPredicate(x) || x.Id == elementId)), source: questRegistry.AllQuests.Where(delegate(Quest x) { ElementId id = x.Id; return !(id is SatisfactionSupplyNpcId) && !(id is AlliedSocietyDailyId); @@ -40,24 +50,35 @@ internal sealed class QuestSelector(QuestRegistry questRegistry) } else { - enumerable = questRegistry.AllQuests.Where((Quest x) => this.DefaultPredicate?.Invoke(x) ?? true); + enumerable = questRegistry.AllQuests.Where((Quest x) => DefaultPredicate?.Invoke(x) ?? true); } - foreach (Quest item in enumerable) + using (ImRaii.IEndObject endObject = ImRaii.Child("##QuestScrollArea", new Vector2(0f, 300f), border: false)) { - if ((SuggestionPredicate == null || SuggestionPredicate(item)) && (ImGui.Selectable(item.Info.Name) || flag)) + if (endObject) { - QuestSelected(item); - if (flag) + foreach (Quest item in enumerable) { - ImGui.CloseCurrentPopup(); - flag = false; + if ((SuggestionPredicate == null || SuggestionPredicate(item)) && (ImGui.Selectable(item.Info.Name) || flag)) + { + QuestSelected(item); + _searchString = string.Empty; + if (flag) + { + ImGui.CloseCurrentPopup(); + flag = false; + } + } } } } ImGui.EndCombo(); } + else + { + _comboJustOpened = false; + } ImGui.Spacing(); - bool DefaultPredicate(Quest x) + bool SearchPredicate(Quest x) { return x.Info.Name.Contains(_searchString, StringComparison.CurrentCultureIgnoreCase); } diff --git a/Questionable/Questionable/Configuration.cs b/Questionable/Questionable/Configuration.cs index 63a58b3..e2dc621 100644 --- a/Questionable/Questionable/Configuration.cs +++ b/Questionable/Questionable/Configuration.cs @@ -32,6 +32,8 @@ internal sealed class Configuration : IPluginConfiguration public bool ConfigureTextAdvance { get; set; } = true; + public bool CinemaMode { get; set; } + public bool AutoStepRefreshEnabled { get; set; } = true; public int AutoStepRefreshDelaySeconds { get; set; } = 60; @@ -110,6 +112,8 @@ internal sealed class Configuration : IPluginConfiguration public bool AdditionalStatusInformation { get; set; } + public bool DisablePartyWatchdog { get; set; } + public bool DisableAutoDutyBareMode { get; set; } public bool SkipAetherCurrents { get; set; } diff --git a/Questionable/Questionable/DalamudInitializer.cs b/Questionable/Questionable/DalamudInitializer.cs index b1e9c83..9812b6a 100644 --- a/Questionable/Questionable/DalamudInitializer.cs +++ b/Questionable/Questionable/DalamudInitializer.cs @@ -33,11 +33,11 @@ internal sealed class DalamudInitializer : IDisposable private readonly Configuration _configuration; - private readonly PartyWatchDog _partyWatchDog; + private readonly PartyWatchdog _partyWatchdog; private readonly ILogger _logger; - public DalamudInitializer(IDalamudPluginInterface pluginInterface, IFramework framework, QuestController questController, MovementController movementController, WindowSystem windowSystem, OneTimeSetupWindow oneTimeSetupWindow, QuestWindow questWindow, DebugOverlay debugOverlay, ConfigWindow configWindow, QuestSelectionWindow questSelectionWindow, QuestSequenceWindow questSequenceWindow, QuestValidationWindow questValidationWindow, JournalProgressWindow journalProgressWindow, PriorityWindow priorityWindow, ChangelogWindow changelogWindow, IToastGui toastGui, Configuration configuration, PartyWatchDog partyWatchDog, ILogger logger) + public DalamudInitializer(IDalamudPluginInterface pluginInterface, IFramework framework, QuestController questController, MovementController movementController, WindowSystem windowSystem, OneTimeSetupWindow oneTimeSetupWindow, QuestWindow questWindow, DebugOverlay debugOverlay, ConfigWindow configWindow, QuestSelectionWindow questSelectionWindow, QuestSequenceWindow questSequenceWindow, QuestValidationWindow questValidationWindow, JournalProgressWindow journalProgressWindow, PriorityWindow priorityWindow, ChangelogWindow changelogWindow, IToastGui toastGui, Configuration configuration, PartyWatchdog partyWatchdog, ILogger logger) { _pluginInterface = pluginInterface; _framework = framework; @@ -49,7 +49,7 @@ internal sealed class DalamudInitializer : IDisposable _configWindow = configWindow; _toastGui = toastGui; _configuration = configuration; - _partyWatchDog = partyWatchDog; + _partyWatchdog = partyWatchdog; _logger = logger; _windowSystem.AddWindow(oneTimeSetupWindow); _windowSystem.AddWindow(questWindow); @@ -72,7 +72,7 @@ internal sealed class DalamudInitializer : IDisposable private void FrameworkUpdate(IFramework framework) { - _partyWatchDog.Update(); + _partyWatchdog.Update(); _questController.Update(); try { diff --git a/Questionable/Questionable/QuestionablePlugin.cs b/Questionable/Questionable/QuestionablePlugin.cs index 7035af0..840e9e2 100644 --- a/Questionable/Questionable/QuestionablePlugin.cs +++ b/Questionable/Questionable/QuestionablePlugin.cs @@ -213,7 +213,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin, IDisposable serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton();