using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.InteropServices; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.UI; using LLib.GameData; using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Model; using Questionable.Model.Questing; using Questionable.Windows.QuestComponents; namespace Questionable.Data; internal sealed class QuestData { public static readonly IReadOnlyList HardModePrimals = new global::_003C_003Ez__ReadOnlyArray(new QuestId[3] { new QuestId(1048), new QuestId(1157), new QuestId(1158) }); public static readonly IReadOnlyList CrystalTowerQuests = new global::_003C_003Ez__ReadOnlyArray(new QuestId[8] { new QuestId(1709), new QuestId(1200), new QuestId(1201), new QuestId(1202), new QuestId(1203), new QuestId(1474), new QuestId(494), new QuestId(495) }); public static readonly ImmutableDictionary> AetherCurrentQuestsByTerritory; private static readonly IReadOnlyList TankRoleQuestChapters; private static readonly IReadOnlyList HealerRoleQuestChapters; private static readonly IReadOnlyList MeleeRoleQuestChapters; private static readonly IReadOnlyList PhysicalRangedRoleQuestChapters; private static readonly IReadOnlyList CasterRoleQuestChapters; public static readonly IReadOnlyList> AllRoleQuestChapters; public static readonly IReadOnlyList FinalShadowbringersRoleQuests; private readonly Dictionary _quests; private readonly ILogger _logger; public static ImmutableHashSet AetherCurrentQuests { get; } public IReadOnlyList MainScenarioQuests { get; } public ImmutableHashSet RedeemableItems { get; } public QuestId LastMainScenarioQuestId { get; } public QuestData(IDataManager dataManager, ClassJobUtils classJobUtils, ILogger logger) { QuestData questData = this; _logger = logger ?? throw new ArgumentNullException("logger"); JournalGenreOverrides journalGenreOverrides = new JournalGenreOverrides { ARelicRebornQuests = dataManager.GetExcelSheet().GetRow(65742u).JournalGenre.RowId, RadzAtHanSideQuests = dataManager.GetExcelSheet().GetRow(69805u).JournalGenre.RowId, ThavnairSideQuests = dataManager.GetExcelSheet().GetRow(70025u).JournalGenre.RowId }; Dictionary questChapters = (from x in dataManager.GetExcelSheet() where x.RowId != 0 && x.Quest.RowId != 0 select x).ToDictionary((QuestChapter x) => x.Quest.RowId, (QuestChapter x) => x.Redo.RowId); Dictionary startingCities = new Dictionary(); for (byte b = 1; b <= 3; b++) { foreach (QuestRedo.QuestRedoParamStruct item in dataManager.GetExcelSheet().GetRow(b).QuestRedoParam.Where((QuestRedo.QuestRedoParamStruct x) => x.Quest.IsValid)) { startingCities[item.Quest.RowId] = b; } } List list = new List(); list.AddRange(from x in dataManager.GetExcelSheet() where x.RowId != 0 where x.IssuerLocation.RowId != 0 select new QuestInfo(x, questChapters.GetValueOrDefault(x.RowId), startingCities.GetValueOrDefault(x.RowId), journalGenreOverrides)); list.AddRange(from x in dataManager.GetExcelSheet() where x.RowId != 0 && x.Npc.RowId != 0 select new SatisfactionSupplyInfo(x)); List quests = list; quests.AddRange((from x in dataManager.GetExcelSheet() where x.RowId != 0 && !x.Name.IsEmpty select x).SelectMany(delegate(BeastTribe x) { if (!Enum.IsDefined(typeof(EAlliedSociety), (byte)x.RowId)) { questData._logger.LogWarning("Skipping unknown BeastTribe with RowId {RowId} (Name: {Name})", x.RowId, x.Name.ToString()); return Enumerable.Empty(); } if (x.RowId < 5) { List list3 = new List(); list3.Add(0); list3.AddRange((from QuestInfo y in quests.Where((IQuestInfo y) => (uint)y.AlliedSociety == (byte)x.RowId && y.IsRepeatable) select (byte)y.AlliedSocietyRank).Distinct()); return new _003C_003Ez__ReadOnlyList(list3).Select((byte rank) => new AlliedSocietyDailyInfo(x, rank, classJobUtils)); } return new global::_003C_003Ez__ReadOnlySingleElementList(new AlliedSocietyDailyInfo(x, 0, classJobUtils)); })); int num = 15; List list2 = new List(num); CollectionsMarshal.SetCount(list2, num); Span span = CollectionsMarshal.AsSpan(list2); int num2 = 0; span[num2] = new AethernetQuestInfo(new AethernetId(1), "Limsa Lominsa"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(2), "Gridania"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(3), "Ul'dah"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(4), "The Gold Saucer"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(5), "Ishgard"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(6), "Idyllshire"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(7), "Rhalgr's Reach"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(8), "Kugane"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(9), "Doman Enclave"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(10), "The Crystarium"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(11), "Eulmore"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(12), "Old Sharlayan"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(13), "Radz-at-Han"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(14), "Tuliyollal"); num2++; span[num2] = new AethernetQuestInfo(new AethernetId(15), "Solution Nine"); List collection = list2; List collection2 = new List(); quests.AddRange(collection); quests.AddRange(collection2); _quests = quests.ToDictionary((IQuestInfo x) => x.QuestId, (IQuestInfo x) => x); AddPreviousQuest(new QuestId(425), new QuestId(495)); AddPreviousQuest(new QuestId(1480), new QuestId(2373)); AddPreviousQuest(new QuestId(1717), new QuestId(1619)); AddPreviousQuest(new QuestId(2088), new QuestId(1619)); AddPreviousQuest(new QuestId(2062), new QuestId(1617)); AddPreviousQuest(new QuestId(2063), new QuestId(1619)); AddPreviousQuest(new QuestId(2257), new QuestId(1655)); AddPreviousQuest(new QuestId(2608), new QuestId(2534)); AddPreviousQuest(new QuestId(2600), new QuestId(2466)); AddPreviousQuest(new QuestId(2622), new QuestId(2490)); AddPreviousQuest(new QuestId(2624), new QuestId(2534)); AddPreviousQuest(new QuestId(2898), new QuestId(2490)); AddPreviousQuest(new QuestId(2974), new QuestId(2491)); AddPreviousQuest(new QuestId(2975), new QuestId(2630)); AddPreviousQuest(new QuestId(2912), new QuestId(2490)); AddPreviousQuest(new QuestId(2914), new QuestId(2537)); AddPreviousQuest(new QuestId(2919), new QuestId(2455)); AddPreviousQuest(new QuestId(2952), new QuestId(2518)); AddPreviousQuest(new QuestId(2904), new QuestId(2503)); AddPreviousQuest(new QuestId(3038), new QuestId(2534)); AddPreviousQuest(new QuestId(3087), new QuestId(100)); AddPreviousQuest(new QuestId(3246), new QuestId(3314)); AddPreviousQuest(new QuestId(3247), new QuestId(3320)); AddPreviousQuest(new QuestId(3270), new QuestId(3333)); AddPreviousQuest(new QuestId(3271), new QuestId(3634)); AddPreviousQuest(new QuestId(3264), new QuestId(2247)); AddPreviousQuest(new QuestId(3253), new QuestId(2247)); AddPreviousQuest(new QuestId(3254), new QuestId(2537)); AddPreviousQuest(new QuestId(3228), new QuestId(3320)); AddPreviousQuest(new QuestId(3234), new QuestId(3320)); AddPreviousQuest(new QuestId(3237), new QuestId(3320)); AddPreviousQuest(new QuestId(3238), new QuestId(3634)); AddPreviousQuest(new QuestId(3240), new QuestId(3320)); AddPreviousQuest(new QuestId(3241), new QuestId(3648)); AddPreviousQuest(new QuestId(3628), new QuestId(3301)); AddPreviousQuest(new QuestId(3655), new QuestId(2095)); AddPreviousQuest(new QuestId(3771), new QuestId(495)); AddPreviousQuest(new QuestId(4068), new QuestId(1658)); AddPreviousQuest(new QuestId(4078), new QuestId(1583)); AddPreviousQuest(new QuestId(4150), new QuestId(4417)); AddPreviousQuest(new QuestId(4155), new QuestId(4383)); AddPreviousQuest(new QuestId(4156), new QuestId(3326)); AddPreviousQuest(new QuestId(4158), new QuestId(4434)); AddPreviousQuest(new QuestId(4159), new QuestId(4464)); AddPreviousQuest(new QuestId(4163), new QuestId(4398)); AddPreviousQuest(new QuestId(4165), new QuestId(4438)); AddPreviousQuest(new QuestId(4473), new QuestId(2095)); AddPreviousQuest(new QuestId(4650), new QuestId(2374)); AddPreviousQuest(new QuestId(4662), new QuestId(3166)); AddPreviousQuest(new QuestId(4761), new QuestId(4032)); AddPreviousQuest(new QuestId(4812), new QuestId(4750)); AddPreviousQuest(new QuestId(4851), new QuestId(2446)); AddPreviousQuest(new QuestId(4856), new QuestId(1669)); AddPreviousQuest(new QuestId(4857), new QuestId(2553)); AddPreviousQuest(new QuestId(4979), new QuestId(4896)); AddPreviousQuest(new QuestId(4980), new QuestId(4911)); AddPreviousQuest(new QuestId(4985), new QuestId(4903)); AddPreviousQuest(new QuestId(4987), new QuestId(4912)); AddPreviousQuest(new QuestId(4988), new QuestId(4942)); AddPreviousQuest(new QuestId(4992), new QuestId(4912)); AddPreviousQuest(new QuestId(4999), new QuestId(4908)); AddPreviousQuest(new QuestId(4966), new QuestId(2095)); AddPreviousQuest(new QuestId(5000), new QuestId(4908)); AddPreviousQuest(new QuestId(5001), new QuestId(4912)); AddPreviousQuest(new QuestId(3629), new QuestId(3248)); AddPreviousQuest(new QuestId(3629), new QuestId(3272)); AddPreviousQuest(new QuestId(3629), new QuestId(3278)); AddPreviousQuest(new QuestId(3629), new QuestId(3628)); AddPreviousQuest(new QuestId(3986), new QuestId(2115)); AddPreviousQuest(new QuestId(3986), new QuestId(2116)); AddPreviousQuest(new QuestId(3986), new QuestId(2281)); AddPreviousQuest(new QuestId(3986), new QuestId(2333)); AddPreviousQuest(new QuestId(3986), new QuestId(2395)); AddPreviousQuest(new QuestId(3986), new QuestId(3985)); AddPreviousQuest(new QuestId(5188), new QuestId(4841)); AddPreviousQuest(new QuestId(5188), new QuestId(4847)); AddPreviousQuest(new QuestId(5188), new QuestId(4959)); ushort[] array = new ushort[20] { 107, 111, 112, 122, 663, 475, 472, 476, 470, 473, 474, 477, 486, 478, 479, 59, 400, 401, 693, 405 }; foreach (ushort value in array) { ((QuestInfo)_quests[new QuestId(value)]).StartingCity = 1; } array = new ushort[11] { 39, 1, 32, 34, 37, 172, 127, 130, 60, 220, 378 }; foreach (ushort value2 in array) { ((QuestInfo)_quests[new QuestId(value2)]).StartingCity = 2; } array = new ushort[19] { 594, 389, 390, 321, 304, 322, 388, 308, 326, 58, 687, 341, 504, 531, 506, 530, 573, 342, 505 }; foreach (ushort value3 in array) { ((QuestInfo)_quests[new QuestId(value3)]).StartingCity = 3; } AddGcFollowUpQuests(); MainScenarioQuests = _quests.Values.Where((IQuestInfo x) => x is QuestInfo questInfo && questInfo.IsMainScenarioQuest).Cast().ToList(); LastMainScenarioQuestId = (from x in MainScenarioQuests where !questData.MainScenarioQuests.Any((QuestInfo y) => y.PreviousQuests.Any((PreviousQuestInfo z) => z.QuestId == x.QuestId)) select (QuestId)x.QuestId).FirstOrDefault() ?? new QuestId(0); RedeemableItems = quests.Where((IQuestInfo x) => x is QuestInfo).Cast().SelectMany((QuestInfo x) => x.ItemRewards) .ToImmutableHashSet(); } private void AddPreviousQuest(QuestId questToUpdate, QuestId requiredQuestId) { if (_quests.TryGetValue(questToUpdate, out IQuestInfo value) && value is QuestInfo questInfo) { questInfo.AddPreviousQuest(new PreviousQuestInfo(requiredQuestId, 0)); } } private void AddGcFollowUpQuests() { QuestId[] array = new QuestId[3] { new QuestId(683), new QuestId(684), new QuestId(685) }; QuestId[] array2 = array; foreach (QuestId questId in array2) { ((QuestInfo)_quests[questId]).AddQuestLocks(EQuestJoin.AtLeastOne, array.Where((QuestId x) => x != questId).ToArray()); } } public IQuestInfo GetQuestInfo(ElementId elementId) { return _quests[elementId] ?? throw new ArgumentOutOfRangeException("elementId"); } public bool TryGetQuestInfo(ElementId elementId, [NotNullWhen(true)] out IQuestInfo? questInfo) { return _quests.TryGetValue(elementId, out questInfo); } public List GetAllByIssuerDataId(uint targetId) { return _quests.Values.Where((IQuestInfo x) => x.IssuerDataId == targetId).ToList(); } public bool IsIssuerOfAnyQuest(uint targetId) { return _quests.Values.Any((IQuestInfo x) => x.IssuerDataId == targetId); } public List GetAllByJournalGenre(uint journalGenre) { return (from x in _quests.Values where x.JournalGenre == journalGenre orderby x.SortKey, x.QuestId select x).ToList(); } public List GetAllByAlliedSociety(EAlliedSociety alliedSociety) { return (from QuestInfo x in _quests.Values.Where((IQuestInfo x) => x is QuestInfo) where x.AlliedSociety == alliedSociety orderby x.QuestId select x).ToList(); } public List GetClassJobQuests(EClassJob classJob, bool includeRoleQuests = false) { List list2; switch (classJob) { case EClassJob.Adventurer: throw new ArgumentOutOfRangeException("classJob"); case EClassJob.Gladiator: { int num2 = 1; List list43 = new List(num2); CollectionsMarshal.SetCount(list43, num2); Span span = CollectionsMarshal.AsSpan(list43); int num = 0; span[num] = 63u; list2 = list43; break; } case EClassJob.Paladin: { int num = 3; List list42 = new List(num); CollectionsMarshal.SetCount(list42, num); Span span = CollectionsMarshal.AsSpan(list42); int num2 = 0; span[num2] = 72u; num2++; span[num2] = 73u; num2++; span[num2] = 74u; list2 = list42; break; } case EClassJob.Marauder: { int num2 = 1; List list41 = new List(num2); CollectionsMarshal.SetCount(list41, num2); Span span = CollectionsMarshal.AsSpan(list41); int num = 0; span[num] = 64u; list2 = list41; break; } case EClassJob.Warrior: { int num = 3; List list40 = new List(num); CollectionsMarshal.SetCount(list40, num); Span span = CollectionsMarshal.AsSpan(list40); int num2 = 0; span[num2] = 76u; num2++; span[num2] = 77u; num2++; span[num2] = 78u; list2 = list40; break; } case EClassJob.Conjurer: { int num2 = 1; List list39 = new List(num2); CollectionsMarshal.SetCount(list39, num2); Span span = CollectionsMarshal.AsSpan(list39); int num = 0; span[num] = 65u; list2 = list39; break; } case EClassJob.WhiteMage: { int num = 3; List list38 = new List(num); CollectionsMarshal.SetCount(list38, num); Span span = CollectionsMarshal.AsSpan(list38); int num2 = 0; span[num2] = 86u; num2++; span[num2] = 87u; num2++; span[num2] = 88u; list2 = list38; break; } case EClassJob.Arcanist: { int num2 = 1; List list37 = new List(num2); CollectionsMarshal.SetCount(list37, num2); Span span = CollectionsMarshal.AsSpan(list37); int num = 0; span[num] = 66u; list2 = list37; break; } case EClassJob.Summoner: { int num = 3; List list36 = new List(num); CollectionsMarshal.SetCount(list36, num); Span span = CollectionsMarshal.AsSpan(list36); int num2 = 0; span[num2] = 127u; num2++; span[num2] = 128u; num2++; span[num2] = 129u; list2 = list36; break; } case EClassJob.Scholar: { int num2 = 3; List list35 = new List(num2); CollectionsMarshal.SetCount(list35, num2); Span span = CollectionsMarshal.AsSpan(list35); int num = 0; span[num] = 90u; num++; span[num] = 91u; num++; span[num] = 92u; list2 = list35; break; } case EClassJob.Pugilist: { int num = 1; List list34 = new List(num); CollectionsMarshal.SetCount(list34, num); Span span = CollectionsMarshal.AsSpan(list34); int num2 = 0; span[num2] = 67u; list2 = list34; break; } case EClassJob.Monk: { int num2 = 3; List list33 = new List(num2); CollectionsMarshal.SetCount(list33, num2); Span span = CollectionsMarshal.AsSpan(list33); int num = 0; span[num] = 98u; num++; span[num] = 99u; num++; span[num] = 100u; list2 = list33; break; } case EClassJob.Lancer: { int num = 1; List list32 = new List(num); CollectionsMarshal.SetCount(list32, num); Span span = CollectionsMarshal.AsSpan(list32); int num2 = 0; span[num2] = 68u; list2 = list32; break; } case EClassJob.Dragoon: { int num2 = 3; List list31 = new List(num2); CollectionsMarshal.SetCount(list31, num2); Span span = CollectionsMarshal.AsSpan(list31); int num = 0; span[num] = 102u; num++; span[num] = 103u; num++; span[num] = 104u; list2 = list31; break; } case EClassJob.Rogue: { int num = 1; List list30 = new List(num); CollectionsMarshal.SetCount(list30, num); Span span = CollectionsMarshal.AsSpan(list30); int num2 = 0; span[num2] = 69u; list2 = list30; break; } case EClassJob.Ninja: { int num2 = 3; List list29 = new List(num2); CollectionsMarshal.SetCount(list29, num2); Span span = CollectionsMarshal.AsSpan(list29); int num = 0; span[num] = 106u; num++; span[num] = 107u; num++; span[num] = 108u; list2 = list29; break; } case EClassJob.Archer: { int num = 1; List list28 = new List(num); CollectionsMarshal.SetCount(list28, num); Span span = CollectionsMarshal.AsSpan(list28); int num2 = 0; span[num2] = 70u; list2 = list28; break; } case EClassJob.Bard: { int num2 = 3; List list27 = new List(num2); CollectionsMarshal.SetCount(list27, num2); Span span = CollectionsMarshal.AsSpan(list27); int num = 0; span[num] = 113u; num++; span[num] = 114u; num++; span[num] = 115u; list2 = list27; break; } case EClassJob.Thaumaturge: { int num = 1; List list26 = new List(num); CollectionsMarshal.SetCount(list26, num); Span span = CollectionsMarshal.AsSpan(list26); int num2 = 0; span[num2] = 71u; list2 = list26; break; } case EClassJob.BlackMage: { int num2 = 3; List list25 = new List(num2); CollectionsMarshal.SetCount(list25, num2); Span span = CollectionsMarshal.AsSpan(list25); int num = 0; span[num] = 123u; num++; span[num] = 124u; num++; span[num] = 125u; list2 = list25; break; } case EClassJob.DarkKnight: { int num = 3; List list24 = new List(num); CollectionsMarshal.SetCount(list24, num); Span span = CollectionsMarshal.AsSpan(list24); int num2 = 0; span[num2] = 80u; num2++; span[num2] = 81u; num2++; span[num2] = 82u; list2 = list24; break; } case EClassJob.Astrologian: { int num2 = 3; List list23 = new List(num2); CollectionsMarshal.SetCount(list23, num2); Span span = CollectionsMarshal.AsSpan(list23); int num = 0; span[num] = 94u; num++; span[num] = 95u; num++; span[num] = 96u; list2 = list23; break; } case EClassJob.Machinist: { int num = 3; List list22 = new List(num); CollectionsMarshal.SetCount(list22, num); Span span = CollectionsMarshal.AsSpan(list22); int num2 = 0; span[num2] = 117u; num2++; span[num2] = 118u; num2++; span[num2] = 119u; list2 = list22; break; } case EClassJob.Samurai: { int num2 = 2; List list21 = new List(num2); CollectionsMarshal.SetCount(list21, num2); Span span = CollectionsMarshal.AsSpan(list21); int num = 0; span[num] = 110u; num++; span[num] = 111u; list2 = list21; break; } case EClassJob.RedMage: { int num = 2; List list20 = new List(num); CollectionsMarshal.SetCount(list20, num); Span span = CollectionsMarshal.AsSpan(list20); int num2 = 0; span[num2] = 131u; num2++; span[num2] = 132u; list2 = list20; break; } case EClassJob.BlueMage: { int num2 = 4; List list19 = new List(num2); CollectionsMarshal.SetCount(list19, num2); Span span = CollectionsMarshal.AsSpan(list19); int num = 0; span[num] = 134u; num++; span[num] = 135u; num++; span[num] = 146u; num++; span[num] = 170u; list2 = list19; break; } case EClassJob.Gunbreaker: { int num = 1; List list18 = new List(num); CollectionsMarshal.SetCount(list18, num); Span span = CollectionsMarshal.AsSpan(list18); int num2 = 0; span[num2] = 84u; list2 = list18; break; } case EClassJob.Dancer: { int num2 = 1; List list17 = new List(num2); CollectionsMarshal.SetCount(list17, num2); Span span = CollectionsMarshal.AsSpan(list17); int num = 0; span[num] = 121u; list2 = list17; break; } case EClassJob.Sage: { int num = 1; List list16 = new List(num); CollectionsMarshal.SetCount(list16, num); Span span = CollectionsMarshal.AsSpan(list16); int num2 = 0; span[num2] = 152u; list2 = list16; break; } case EClassJob.Reaper: { int num2 = 1; List list15 = new List(num2); CollectionsMarshal.SetCount(list15, num2); Span span = CollectionsMarshal.AsSpan(list15); int num = 0; span[num] = 153u; list2 = list15; break; } case EClassJob.Viper: { int num = 1; List list14 = new List(num); CollectionsMarshal.SetCount(list14, num); Span span = CollectionsMarshal.AsSpan(list14); int num2 = 0; span[num2] = 176u; list2 = list14; break; } case EClassJob.Pictomancer: { int num2 = 1; List list13 = new List(num2); CollectionsMarshal.SetCount(list13, num2); Span span = CollectionsMarshal.AsSpan(list13); int num = 0; span[num] = 177u; list2 = list13; break; } case EClassJob.Alchemist: { int num = 3; List list12 = new List(num); CollectionsMarshal.SetCount(list12, num); Span span = CollectionsMarshal.AsSpan(list12); int num2 = 0; span[num2] = 48u; num2++; span[num2] = 49u; num2++; span[num2] = 50u; list2 = list12; break; } case EClassJob.Armorer: { int num2 = 3; List list11 = new List(num2); CollectionsMarshal.SetCount(list11, num2); Span span = CollectionsMarshal.AsSpan(list11); int num = 0; span[num] = 36u; num++; span[num] = 37u; num++; span[num] = 38u; list2 = list11; break; } case EClassJob.Blacksmith: { int num = 3; List list10 = new List(num); CollectionsMarshal.SetCount(list10, num); Span span = CollectionsMarshal.AsSpan(list10); int num2 = 0; span[num2] = 33u; num2++; span[num2] = 34u; num2++; span[num2] = 35u; list2 = list10; break; } case EClassJob.Carpenter: { int num2 = 3; List list9 = new List(num2); CollectionsMarshal.SetCount(list9, num2); Span span = CollectionsMarshal.AsSpan(list9); int num = 0; span[num] = 30u; num++; span[num] = 31u; num++; span[num] = 32u; list2 = list9; break; } case EClassJob.Culinarian: { int num = 3; List list8 = new List(num); CollectionsMarshal.SetCount(list8, num); Span span = CollectionsMarshal.AsSpan(list8); int num2 = 0; span[num2] = 51u; num2++; span[num2] = 52u; num2++; span[num2] = 53u; list2 = list8; break; } case EClassJob.Goldsmith: { int num2 = 3; List list7 = new List(num2); CollectionsMarshal.SetCount(list7, num2); Span span = CollectionsMarshal.AsSpan(list7); int num = 0; span[num] = 39u; num++; span[num] = 40u; num++; span[num] = 41u; list2 = list7; break; } case EClassJob.Leatherworker: { int num = 3; List list6 = new List(num); CollectionsMarshal.SetCount(list6, num); Span span = CollectionsMarshal.AsSpan(list6); int num2 = 0; span[num2] = 42u; num2++; span[num2] = 43u; num2++; span[num2] = 44u; list2 = list6; break; } case EClassJob.Weaver: { int num2 = 3; List list5 = new List(num2); CollectionsMarshal.SetCount(list5, num2); Span span = CollectionsMarshal.AsSpan(list5); int num = 0; span[num] = 45u; num++; span[num] = 46u; num++; span[num] = 47u; list2 = list5; break; } case EClassJob.Miner: { int num = 3; List list4 = new List(num); CollectionsMarshal.SetCount(list4, num); Span span = CollectionsMarshal.AsSpan(list4); int num2 = 0; span[num2] = 54u; num2++; span[num2] = 55u; num2++; span[num2] = 56u; list2 = list4; break; } case EClassJob.Botanist: { int num2 = 3; List list3 = new List(num2); CollectionsMarshal.SetCount(list3, num2); Span span = CollectionsMarshal.AsSpan(list3); int num = 0; span[num] = 57u; num++; span[num] = 58u; num++; span[num] = 59u; list2 = list3; break; } case EClassJob.Fisher: { int num = 3; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); int num2 = 0; span[num2] = 60u; num2++; span[num2] = 61u; num2++; span[num2] = 62u; list2 = list; break; } default: throw new ArgumentOutOfRangeException("classJob"); } List list44 = list2; if (includeRoleQuests) { list44.AddRange(GetRoleQuestIds(classJob)); } return GetQuestsInNewGamePlusChapters(list44); } public List GetRoleQuests(EClassJob referenceClassJob) { return GetQuestsInNewGamePlusChapters(GetRoleQuestIds(referenceClassJob).ToList()); } private static IEnumerable GetRoleQuestIds(EClassJob classJob) { if (classJob.IsTank()) { return TankRoleQuestChapters; } if (classJob.IsHealer()) { return HealerRoleQuestChapters; } if (classJob.IsMelee()) { return MeleeRoleQuestChapters; } if (classJob.IsPhysicalRanged()) { return PhysicalRangedRoleQuestChapters; } if (classJob.IsCaster() && classJob != EClassJob.BlueMage) { return CasterRoleQuestChapters; } return Array.Empty(); } private List GetQuestsInNewGamePlusChapters(List chapterIds) { return (from QuestInfo x in _quests.Values.Where((IQuestInfo x) => x is QuestInfo) where chapterIds.Contains(x.NewGamePlusChapter) select x).ToList(); } public unsafe List GetLockedClassQuests() { PlayerState* ptr = PlayerState.Instance(); EClassJob eClassJob = (EClassJob)((ptr != null) ? ptr->FirstClass : 0); if (eClassJob == EClassJob.Adventurer) { return new List(); } int num = 8; List> list = new List>(num); CollectionsMarshal.SetCount(list, num); Span> span = CollectionsMarshal.AsSpan(list); int num2 = 0; ref List reference = ref span[num2]; List list2; if (eClassJob != EClassJob.Gladiator) { int num3 = 2; list2 = new List(num3); CollectionsMarshal.SetCount(list2, num3); Span span2 = CollectionsMarshal.AsSpan(list2); int num4 = 0; span2[num4] = 253; num4++; span2[num4] = 261; } else { int num4 = 4; list2 = new List(num4); CollectionsMarshal.SetCount(list2, num4); Span span2 = CollectionsMarshal.AsSpan(list2); int num3 = 0; span2[num3] = 177; num3++; span2[num3] = 285; num3++; span2[num3] = 286; num3++; span2[num3] = 288; } reference = list2; num2++; ref List reference2 = ref span[num2]; List list3; if (eClassJob != EClassJob.Pugilist) { int num3 = 2; list3 = new List(num3); CollectionsMarshal.SetCount(list3, num3); Span span2 = CollectionsMarshal.AsSpan(list3); int num4 = 0; span2[num4] = 533; num4++; span2[num4] = 555; } else { int num4 = 4; list3 = new List(num4); CollectionsMarshal.SetCount(list3, num4); Span span2 = CollectionsMarshal.AsSpan(list3); int num3 = 0; span2[num3] = 178; num3++; span2[num3] = 532; num3++; span2[num3] = 553; num3++; span2[num3] = 698; } reference2 = list3; num2++; ref List reference3 = ref span[num2]; List list4; if (eClassJob != EClassJob.Marauder) { int num3 = 2; list4 = new List(num3); CollectionsMarshal.SetCount(list4, num3); Span span2 = CollectionsMarshal.AsSpan(list4); int num4 = 0; span2[num4] = 311; num4++; span2[num4] = 314; } else { int num4 = 4; list4 = new List(num4); CollectionsMarshal.SetCount(list4, num4); Span span2 = CollectionsMarshal.AsSpan(list4); int num3 = 0; span2[num3] = 179; num3++; span2[num3] = 310; num3++; span2[num3] = 312; num3++; span2[num3] = 315; } reference3 = list4; num2++; ref List reference4 = ref span[num2]; List list5; if (eClassJob != EClassJob.Lancer) { int num3 = 2; list5 = new List(num3); CollectionsMarshal.SetCount(list5, num3); Span span2 = CollectionsMarshal.AsSpan(list5); int num4 = 0; span2[num4] = 23; num4++; span2[num4] = 35; } else { int num4 = 4; list5 = new List(num4); CollectionsMarshal.SetCount(list5, num4); Span span2 = CollectionsMarshal.AsSpan(list5); int num3 = 0; span2[num3] = 180; num3++; span2[num3] = 132; num3++; span2[num3] = 218; num3++; span2[num3] = 143; } reference4 = list5; num2++; ref List reference5 = ref span[num2]; List list6; if (eClassJob != EClassJob.Archer) { int num3 = 2; list6 = new List(num3); CollectionsMarshal.SetCount(list6, num3); Span span2 = CollectionsMarshal.AsSpan(list6); int num4 = 0; span2[num4] = 21; num4++; span2[num4] = 67; } else { int num4 = 4; list6 = new List(num4); CollectionsMarshal.SetCount(list6, num4); Span span2 = CollectionsMarshal.AsSpan(list6); int num3 = 0; span2[num3] = 181; num3++; span2[num3] = 131; num3++; span2[num3] = 219; num3++; span2[num3] = 134; } reference5 = list6; num2++; ref List reference6 = ref span[num2]; List list7; if (eClassJob != EClassJob.Conjurer) { int num3 = 2; list7 = new List(num3); CollectionsMarshal.SetCount(list7, num3); Span span2 = CollectionsMarshal.AsSpan(list7); int num4 = 0; span2[num4] = 22; num4++; span2[num4] = 91; } else { int num4 = 4; list7 = new List(num4); CollectionsMarshal.SetCount(list7, num4); Span span2 = CollectionsMarshal.AsSpan(list7); int num3 = 0; span2[num3] = 182; num3++; span2[num3] = 133; num3++; span2[num3] = 211; num3++; span2[num3] = 147; } reference6 = list7; num2++; ref List reference7 = ref span[num2]; List list8; if (eClassJob != EClassJob.Thaumaturge) { int num3 = 2; list8 = new List(num3); CollectionsMarshal.SetCount(list8, num3); Span span2 = CollectionsMarshal.AsSpan(list8); int num4 = 0; span2[num4] = 345; num4++; span2[num4] = 348; } else { int num4 = 4; list8 = new List(num4); CollectionsMarshal.SetCount(list8, num4); Span span2 = CollectionsMarshal.AsSpan(list8); int num3 = 0; span2[num3] = 183; num3++; span2[num3] = 344; num3++; span2[num3] = 346; num3++; span2[num3] = 349; } reference7 = list8; num2++; ref List reference8 = ref span[num2]; List list9; if (eClassJob != EClassJob.Arcanist) { int num3 = 2; list9 = new List(num3); CollectionsMarshal.SetCount(list9, num3); Span span2 = CollectionsMarshal.AsSpan(list9); int num4 = 0; span2[num4] = 453; num4++; span2[num4] = 456; } else { int num4 = 4; list9 = new List(num4); CollectionsMarshal.SetCount(list9, num4); Span span2 = CollectionsMarshal.AsSpan(list9); int num3 = 0; span2[num3] = 451; num3++; span2[num3] = 452; num3++; span2[num3] = 454; num3++; span2[num3] = 457; } reference8 = list9; return (from x in list.SelectMany((List x) => x) select new QuestId(x)).ToList(); } public void ApplySeasonalOverride(ElementId questId, bool isSeasonal, DateTime? expiry) { if (_quests.TryGetValue(questId, out IQuestInfo value) && value is QuestInfo questInfo) { DateTime? seasonalQuestExpiry = null; if (expiry.HasValue) { DateTime value2 = expiry.Value; seasonalQuestExpiry = ((!(value2.TimeOfDay == TimeSpan.Zero)) ? new DateTime?((value2.Kind == DateTimeKind.Utc) ? value2 : value2.ToUniversalTime()) : new DateTime?(EventInfoComponent.AtDailyReset(DateOnly.FromDateTime(value2)))); } questInfo.IsSeasonalQuest = isSeasonal; questInfo.SeasonalQuestExpiry = seasonalQuestExpiry; } else { _logger.LogWarning("ApplySeasonalOverride: Quest {QuestId} not found in QuestData (could not apply seasonal override)", questId); } } public void AddOrReplaceQuestInfo(IQuestInfo info) { ArgumentNullException.ThrowIfNull(info, "info"); _quests[info.QuestId] = info; _logger.LogDebug("Added or replaced QuestInfo for {QuestId} in QuestData", info.QuestId); } static QuestData() { Dictionary> dictionary = new Dictionary>(); int num = 4; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); int num2 = 0; span[num2] = 1744; num2++; span[num2] = 1759; num2++; span[num2] = 1760; num2++; span[num2] = 2111; dictionary.Add(397u, list); num2 = 4; List list2 = new List(num2); CollectionsMarshal.SetCount(list2, num2); span = CollectionsMarshal.AsSpan(list2); num = 0; span[num] = 1771; num++; span[num] = 1790; num++; span[num] = 1797; num++; span[num] = 1802; dictionary.Add(398u, list2); num = 4; List list3 = new List(num); CollectionsMarshal.SetCount(list3, num); span = CollectionsMarshal.AsSpan(list3); num2 = 0; span[num2] = 1936; num2++; span[num2] = 1945; num2++; span[num2] = 1963; num2++; span[num2] = 1966; dictionary.Add(399u, list3); num2 = 4; List list4 = new List(num2); CollectionsMarshal.SetCount(list4, num2); span = CollectionsMarshal.AsSpan(list4); num = 0; span[num] = 1819; num++; span[num] = 1823; num++; span[num] = 1828; num++; span[num] = 1835; dictionary.Add(400u, list4); num = 4; List list5 = new List(num); CollectionsMarshal.SetCount(list5, num); span = CollectionsMarshal.AsSpan(list5); num2 = 0; span[num2] = 1748; num2++; span[num2] = 1874; num2++; span[num2] = 1909; num2++; span[num2] = 1910; dictionary.Add(401u, list5); num2 = 4; List list6 = new List(num2); CollectionsMarshal.SetCount(list6, num2); span = CollectionsMarshal.AsSpan(list6); num = 0; span[num] = 2639; num++; span[num] = 2661; num++; span[num] = 2816; num++; span[num] = 2821; dictionary.Add(612u, list6); num = 4; List list7 = new List(num); CollectionsMarshal.SetCount(list7, num); span = CollectionsMarshal.AsSpan(list7); num2 = 0; span[num2] = 2632; num2++; span[num2] = 2673; num2++; span[num2] = 2687; num2++; span[num2] = 2693; dictionary.Add(613u, list7); num2 = 4; List list8 = new List(num2); CollectionsMarshal.SetCount(list8, num2); span = CollectionsMarshal.AsSpan(list8); num = 0; span[num] = 2724; num++; span[num] = 2728; num++; span[num] = 2730; num++; span[num] = 2733; dictionary.Add(614u, list8); num = 4; List list9 = new List(num); CollectionsMarshal.SetCount(list9, num); span = CollectionsMarshal.AsSpan(list9); num2 = 0; span[num2] = 2655; num2++; span[num2] = 2842; num2++; span[num2] = 2851; num2++; span[num2] = 2860; dictionary.Add(620u, list9); num2 = 4; List list10 = new List(num2); CollectionsMarshal.SetCount(list10, num2); span = CollectionsMarshal.AsSpan(list10); num = 0; span[num] = 2877; num++; span[num] = 2880; num++; span[num] = 2881; num++; span[num] = 2883; dictionary.Add(621u, list10); num = 4; List list11 = new List(num); CollectionsMarshal.SetCount(list11, num); span = CollectionsMarshal.AsSpan(list11); num2 = 0; span[num2] = 2760; num2++; span[num2] = 2771; num2++; span[num2] = 2782; num2++; span[num2] = 2791; dictionary.Add(622u, list11); num2 = 4; List list12 = new List(num2); CollectionsMarshal.SetCount(list12, num2); span = CollectionsMarshal.AsSpan(list12); num = 0; span[num] = 3380; num++; span[num] = 3384; num++; span[num] = 3385; num++; span[num] = 3386; dictionary.Add(813u, list12); num = 4; List list13 = new List(num); CollectionsMarshal.SetCount(list13, num); span = CollectionsMarshal.AsSpan(list13); num2 = 0; span[num2] = 3360; num2++; span[num2] = 3371; num2++; span[num2] = 3537; num2++; span[num2] = 3556; dictionary.Add(814u, list13); num2 = 4; List list14 = new List(num2); CollectionsMarshal.SetCount(list14, num2); span = CollectionsMarshal.AsSpan(list14); num = 0; span[num] = 3375; num++; span[num] = 3503; num++; span[num] = 3511; num++; span[num] = 3525; dictionary.Add(815u, list14); num = 4; List list15 = new List(num); CollectionsMarshal.SetCount(list15, num); span = CollectionsMarshal.AsSpan(list15); num2 = 0; span[num2] = 3395; num2++; span[num2] = 3398; num2++; span[num2] = 3404; num2++; span[num2] = 3427; dictionary.Add(816u, list15); num2 = 4; List list16 = new List(num2); CollectionsMarshal.SetCount(list16, num2); span = CollectionsMarshal.AsSpan(list16); num = 0; span[num] = 3444; num++; span[num] = 3467; num++; span[num] = 3478; num++; span[num] = 3656; dictionary.Add(817u, list16); num = 4; List list17 = new List(num); CollectionsMarshal.SetCount(list17, num); span = CollectionsMarshal.AsSpan(list17); num2 = 0; span[num2] = 3588; num2++; span[num2] = 3592; num2++; span[num2] = 3593; num2++; span[num2] = 3594; dictionary.Add(818u, list17); num2 = 4; List list18 = new List(num2); CollectionsMarshal.SetCount(list18, num2); span = CollectionsMarshal.AsSpan(list18); num = 0; span[num] = 4320; num++; span[num] = 4329; num++; span[num] = 4480; num++; span[num] = 4484; dictionary.Add(956u, list18); num = 4; List list19 = new List(num); CollectionsMarshal.SetCount(list19, num); span = CollectionsMarshal.AsSpan(list19); num2 = 0; span[num2] = 4203; num2++; span[num2] = 4257; num2++; span[num2] = 4259; num2++; span[num2] = 4489; dictionary.Add(957u, list19); num2 = 4; List list20 = new List(num2); CollectionsMarshal.SetCount(list20, num2); span = CollectionsMarshal.AsSpan(list20); num = 0; span[num] = 4216; num++; span[num] = 4232; num++; span[num] = 4498; num++; span[num] = 4502; dictionary.Add(958u, list20); num = 4; List list21 = new List(num); CollectionsMarshal.SetCount(list21, num); span = CollectionsMarshal.AsSpan(list21); num2 = 0; span[num2] = 4240; num2++; span[num2] = 4241; num2++; span[num2] = 4253; num2++; span[num2] = 4516; dictionary.Add(959u, list21); num2 = 4; List list22 = new List(num2); CollectionsMarshal.SetCount(list22, num2); span = CollectionsMarshal.AsSpan(list22); num = 0; span[num] = 4342; num++; span[num] = 4346; num++; span[num] = 4354; num++; span[num] = 4355; dictionary.Add(960u, list22); num = 4; List list23 = new List(num); CollectionsMarshal.SetCount(list23, num); span = CollectionsMarshal.AsSpan(list23); num2 = 0; span[num2] = 4288; num2++; span[num2] = 4313; num2++; span[num2] = 4507; num2++; span[num2] = 4511; dictionary.Add(961u, list23); num2 = 4; List list24 = new List(num2); CollectionsMarshal.SetCount(list24, num2); span = CollectionsMarshal.AsSpan(list24); num = 0; span[num] = 5039; num++; span[num] = 5047; num++; span[num] = 5051; num++; span[num] = 5055; dictionary.Add(1187u, list24); num = 4; List list25 = new List(num); CollectionsMarshal.SetCount(list25, num); span = CollectionsMarshal.AsSpan(list25); num2 = 0; span[num2] = 5064; num2++; span[num2] = 5074; num2++; span[num2] = 5081; num2++; span[num2] = 5085; dictionary.Add(1188u, list25); num2 = 4; List list26 = new List(num2); CollectionsMarshal.SetCount(list26, num2); span = CollectionsMarshal.AsSpan(list26); num = 0; span[num] = 5094; num++; span[num] = 5103; num++; span[num] = 5110; num++; span[num] = 5114; dictionary.Add(1189u, list26); num = 4; List list27 = new List(num); CollectionsMarshal.SetCount(list27, num); span = CollectionsMarshal.AsSpan(list27); num2 = 0; span[num2] = 5130; num2++; span[num2] = 5138; num2++; span[num2] = 5140; num2++; span[num2] = 5144; dictionary.Add(1190u, list27); num2 = 4; List list28 = new List(num2); CollectionsMarshal.SetCount(list28, num2); span = CollectionsMarshal.AsSpan(list28); num = 0; span[num] = 5153; num++; span[num] = 5156; num++; span[num] = 5159; num++; span[num] = 5160; dictionary.Add(1191u, list28); num = 4; List list29 = new List(num); CollectionsMarshal.SetCount(list29, num); span = CollectionsMarshal.AsSpan(list29); num2 = 0; span[num2] = 5174; num2++; span[num2] = 5176; num2++; span[num2] = 5178; num2++; span[num2] = 5179; dictionary.Add(1192u, list29); AetherCurrentQuestsByTerritory = dictionary.ToImmutableDictionary((KeyValuePair> x) => x.Key, (KeyValuePair> x) => x.Value.Select((ushort y) => new QuestId(y)).ToImmutableList()); AetherCurrentQuests = AetherCurrentQuestsByTerritory.Values.SelectMany((ImmutableList x) => x).ToImmutableHashSet(); TankRoleQuestChapters = new global::_003C_003Ez__ReadOnlyArray(new uint[3] { 136u, 154u, 178u }); HealerRoleQuestChapters = new global::_003C_003Ez__ReadOnlyArray(new uint[3] { 137u, 155u, 179u }); MeleeRoleQuestChapters = new global::_003C_003Ez__ReadOnlyArray(new uint[3] { 138u, 156u, 180u }); PhysicalRangedRoleQuestChapters = new global::_003C_003Ez__ReadOnlyArray(new uint[3] { 138u, 157u, 181u }); CasterRoleQuestChapters = new global::_003C_003Ez__ReadOnlyArray(new uint[3] { 139u, 158u, 182u }); AllRoleQuestChapters = new global::_003C_003Ez__ReadOnlyArray>(new IReadOnlyList[5] { TankRoleQuestChapters, HealerRoleQuestChapters, MeleeRoleQuestChapters, PhysicalRangedRoleQuestChapters, CasterRoleQuestChapters }); FinalShadowbringersRoleQuests = new global::_003C_003Ez__ReadOnlyArray(new QuestId[4] { new QuestId(3248), new QuestId(3272), new QuestId(3278), new QuestId(3628) }); } }