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; 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; } } ExcelSheet questExSheet = dataManager.GetExcelSheet(); List list = new List(); list.AddRange(from x in dataManager.GetExcelSheet() where x.RowId != 0 where x.IssuerLocation.RowId != 0 select new QuestInfo(x, questExSheet.GetRow(x.RowId), 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 global::_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); span[0] = new AethernetQuestInfo(new AethernetId(1), "Limsa Lominsa"); span[1] = new AethernetQuestInfo(new AethernetId(2), "Gridania"); span[2] = new AethernetQuestInfo(new AethernetId(3), "Ul'dah"); span[3] = new AethernetQuestInfo(new AethernetId(4), "The Gold Saucer"); span[4] = new AethernetQuestInfo(new AethernetId(5), "Ishgard"); span[5] = new AethernetQuestInfo(new AethernetId(6), "Idyllshire"); span[6] = new AethernetQuestInfo(new AethernetId(7), "Rhalgr's Reach"); span[7] = new AethernetQuestInfo(new AethernetId(8), "Kugane"); span[8] = new AethernetQuestInfo(new AethernetId(9), "Doman Enclave"); span[9] = new AethernetQuestInfo(new AethernetId(10), "The Crystarium"); span[10] = new AethernetQuestInfo(new AethernetId(11), "Eulmore"); span[11] = new AethernetQuestInfo(new AethernetId(12), "Old Sharlayan"); span[12] = new AethernetQuestInfo(new AethernetId(13), "Radz-at-Han"); span[13] = new AethernetQuestInfo(new AethernetId(14), "Tuliyollal"); span[14] = 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 num = 1; List list43 = new List(num); CollectionsMarshal.SetCount(list43, num); CollectionsMarshal.AsSpan(list43)[0] = 63u; list2 = list43; break; } case EClassJob.Paladin: { int num = 3; List list42 = new List(num); CollectionsMarshal.SetCount(list42, num); Span span27 = CollectionsMarshal.AsSpan(list42); span27[0] = 72u; span27[1] = 73u; span27[2] = 74u; list2 = list42; break; } case EClassJob.Marauder: { int num = 1; List list41 = new List(num); CollectionsMarshal.SetCount(list41, num); CollectionsMarshal.AsSpan(list41)[0] = 64u; list2 = list41; break; } case EClassJob.Warrior: { int num = 3; List list40 = new List(num); CollectionsMarshal.SetCount(list40, num); Span span26 = CollectionsMarshal.AsSpan(list40); span26[0] = 76u; span26[1] = 77u; span26[2] = 78u; list2 = list40; break; } case EClassJob.Conjurer: { int num = 1; List list39 = new List(num); CollectionsMarshal.SetCount(list39, num); CollectionsMarshal.AsSpan(list39)[0] = 65u; list2 = list39; break; } case EClassJob.WhiteMage: { int num = 3; List list38 = new List(num); CollectionsMarshal.SetCount(list38, num); Span span25 = CollectionsMarshal.AsSpan(list38); span25[0] = 86u; span25[1] = 87u; span25[2] = 88u; list2 = list38; break; } case EClassJob.Arcanist: { int num = 1; List list37 = new List(num); CollectionsMarshal.SetCount(list37, num); CollectionsMarshal.AsSpan(list37)[0] = 66u; list2 = list37; break; } case EClassJob.Summoner: { int num = 3; List list36 = new List(num); CollectionsMarshal.SetCount(list36, num); Span span24 = CollectionsMarshal.AsSpan(list36); span24[0] = 127u; span24[1] = 128u; span24[2] = 129u; list2 = list36; break; } case EClassJob.Scholar: { int num = 3; List list35 = new List(num); CollectionsMarshal.SetCount(list35, num); Span span23 = CollectionsMarshal.AsSpan(list35); span23[0] = 90u; span23[1] = 91u; span23[2] = 92u; list2 = list35; break; } case EClassJob.Pugilist: { int num = 1; List list34 = new List(num); CollectionsMarshal.SetCount(list34, num); CollectionsMarshal.AsSpan(list34)[0] = 67u; list2 = list34; break; } case EClassJob.Monk: { int num = 3; List list33 = new List(num); CollectionsMarshal.SetCount(list33, num); Span span22 = CollectionsMarshal.AsSpan(list33); span22[0] = 98u; span22[1] = 99u; span22[2] = 100u; list2 = list33; break; } case EClassJob.Lancer: { int num = 1; List list32 = new List(num); CollectionsMarshal.SetCount(list32, num); CollectionsMarshal.AsSpan(list32)[0] = 68u; list2 = list32; break; } case EClassJob.Dragoon: { int num = 3; List list31 = new List(num); CollectionsMarshal.SetCount(list31, num); Span span21 = CollectionsMarshal.AsSpan(list31); span21[0] = 102u; span21[1] = 103u; span21[2] = 104u; list2 = list31; break; } case EClassJob.Rogue: { int num = 1; List list30 = new List(num); CollectionsMarshal.SetCount(list30, num); CollectionsMarshal.AsSpan(list30)[0] = 69u; list2 = list30; break; } case EClassJob.Ninja: { int num = 3; List list29 = new List(num); CollectionsMarshal.SetCount(list29, num); Span span20 = CollectionsMarshal.AsSpan(list29); span20[0] = 106u; span20[1] = 107u; span20[2] = 108u; list2 = list29; break; } case EClassJob.Archer: { int num = 1; List list28 = new List(num); CollectionsMarshal.SetCount(list28, num); CollectionsMarshal.AsSpan(list28)[0] = 70u; list2 = list28; break; } case EClassJob.Bard: { int num = 3; List list27 = new List(num); CollectionsMarshal.SetCount(list27, num); Span span19 = CollectionsMarshal.AsSpan(list27); span19[0] = 113u; span19[1] = 114u; span19[2] = 115u; list2 = list27; break; } case EClassJob.Thaumaturge: { int num = 1; List list26 = new List(num); CollectionsMarshal.SetCount(list26, num); CollectionsMarshal.AsSpan(list26)[0] = 71u; list2 = list26; break; } case EClassJob.BlackMage: { int num = 3; List list25 = new List(num); CollectionsMarshal.SetCount(list25, num); Span span18 = CollectionsMarshal.AsSpan(list25); span18[0] = 123u; span18[1] = 124u; span18[2] = 125u; list2 = list25; break; } case EClassJob.DarkKnight: { int num = 3; List list24 = new List(num); CollectionsMarshal.SetCount(list24, num); Span span17 = CollectionsMarshal.AsSpan(list24); span17[0] = 80u; span17[1] = 81u; span17[2] = 82u; list2 = list24; break; } case EClassJob.Astrologian: { int num = 3; List list23 = new List(num); CollectionsMarshal.SetCount(list23, num); Span span16 = CollectionsMarshal.AsSpan(list23); span16[0] = 94u; span16[1] = 95u; span16[2] = 96u; list2 = list23; break; } case EClassJob.Machinist: { int num = 3; List list22 = new List(num); CollectionsMarshal.SetCount(list22, num); Span span15 = CollectionsMarshal.AsSpan(list22); span15[0] = 117u; span15[1] = 118u; span15[2] = 119u; list2 = list22; break; } case EClassJob.Samurai: { int num = 2; List list21 = new List(num); CollectionsMarshal.SetCount(list21, num); Span span14 = CollectionsMarshal.AsSpan(list21); span14[0] = 110u; span14[1] = 111u; list2 = list21; break; } case EClassJob.RedMage: { int num = 2; List list20 = new List(num); CollectionsMarshal.SetCount(list20, num); Span span13 = CollectionsMarshal.AsSpan(list20); span13[0] = 131u; span13[1] = 132u; list2 = list20; break; } case EClassJob.BlueMage: { int num = 4; List list19 = new List(num); CollectionsMarshal.SetCount(list19, num); Span span12 = CollectionsMarshal.AsSpan(list19); span12[0] = 134u; span12[1] = 135u; span12[2] = 146u; span12[3] = 170u; list2 = list19; break; } case EClassJob.Gunbreaker: { int num = 1; List list18 = new List(num); CollectionsMarshal.SetCount(list18, num); CollectionsMarshal.AsSpan(list18)[0] = 84u; list2 = list18; break; } case EClassJob.Dancer: { int num = 1; List list17 = new List(num); CollectionsMarshal.SetCount(list17, num); CollectionsMarshal.AsSpan(list17)[0] = 121u; list2 = list17; break; } case EClassJob.Sage: { int num = 1; List list16 = new List(num); CollectionsMarshal.SetCount(list16, num); CollectionsMarshal.AsSpan(list16)[0] = 152u; list2 = list16; break; } case EClassJob.Reaper: { int num = 1; List list15 = new List(num); CollectionsMarshal.SetCount(list15, num); CollectionsMarshal.AsSpan(list15)[0] = 153u; list2 = list15; break; } case EClassJob.Viper: { int num = 1; List list14 = new List(num); CollectionsMarshal.SetCount(list14, num); CollectionsMarshal.AsSpan(list14)[0] = 176u; list2 = list14; break; } case EClassJob.Pictomancer: { int num = 1; List list13 = new List(num); CollectionsMarshal.SetCount(list13, num); CollectionsMarshal.AsSpan(list13)[0] = 177u; list2 = list13; break; } case EClassJob.Alchemist: { int num = 3; List list12 = new List(num); CollectionsMarshal.SetCount(list12, num); Span span11 = CollectionsMarshal.AsSpan(list12); span11[0] = 48u; span11[1] = 49u; span11[2] = 50u; list2 = list12; break; } case EClassJob.Armorer: { int num = 3; List list11 = new List(num); CollectionsMarshal.SetCount(list11, num); Span span10 = CollectionsMarshal.AsSpan(list11); span10[0] = 36u; span10[1] = 37u; span10[2] = 38u; list2 = list11; break; } case EClassJob.Blacksmith: { int num = 3; List list10 = new List(num); CollectionsMarshal.SetCount(list10, num); Span span9 = CollectionsMarshal.AsSpan(list10); span9[0] = 33u; span9[1] = 34u; span9[2] = 35u; list2 = list10; break; } case EClassJob.Carpenter: { int num = 3; List list9 = new List(num); CollectionsMarshal.SetCount(list9, num); Span span8 = CollectionsMarshal.AsSpan(list9); span8[0] = 30u; span8[1] = 31u; span8[2] = 32u; list2 = list9; break; } case EClassJob.Culinarian: { int num = 3; List list8 = new List(num); CollectionsMarshal.SetCount(list8, num); Span span7 = CollectionsMarshal.AsSpan(list8); span7[0] = 51u; span7[1] = 52u; span7[2] = 53u; list2 = list8; break; } case EClassJob.Goldsmith: { int num = 3; List list7 = new List(num); CollectionsMarshal.SetCount(list7, num); Span span6 = CollectionsMarshal.AsSpan(list7); span6[0] = 39u; span6[1] = 40u; span6[2] = 41u; list2 = list7; break; } case EClassJob.Leatherworker: { int num = 3; List list6 = new List(num); CollectionsMarshal.SetCount(list6, num); Span span5 = CollectionsMarshal.AsSpan(list6); span5[0] = 42u; span5[1] = 43u; span5[2] = 44u; list2 = list6; break; } case EClassJob.Weaver: { int num = 3; List list5 = new List(num); CollectionsMarshal.SetCount(list5, num); Span span4 = CollectionsMarshal.AsSpan(list5); span4[0] = 45u; span4[1] = 46u; span4[2] = 47u; list2 = list5; break; } case EClassJob.Miner: { int num = 3; List list4 = new List(num); CollectionsMarshal.SetCount(list4, num); Span span3 = CollectionsMarshal.AsSpan(list4); span3[0] = 54u; span3[1] = 55u; span3[2] = 56u; list2 = list4; break; } case EClassJob.Botanist: { int num = 3; List list3 = new List(num); CollectionsMarshal.SetCount(list3, num); Span span2 = CollectionsMarshal.AsSpan(list3); span2[0] = 57u; span2[1] = 58u; span2[2] = 59u; list2 = list3; break; } case EClassJob.Fisher: { int num = 3; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); span[0] = 60u; span[1] = 61u; span[2] = 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); ref List reference = ref span[0]; List list2; if (eClassJob != EClassJob.Gladiator) { int num2 = 2; list2 = new List(num2); CollectionsMarshal.SetCount(list2, num2); Span span2 = CollectionsMarshal.AsSpan(list2); span2[0] = 253; span2[1] = 261; } else { int num2 = 4; list2 = new List(num2); CollectionsMarshal.SetCount(list2, num2); Span span3 = CollectionsMarshal.AsSpan(list2); span3[0] = 177; span3[1] = 285; span3[2] = 286; span3[3] = 288; } reference = list2; ref List reference2 = ref span[1]; List list3; if (eClassJob != EClassJob.Pugilist) { int num2 = 2; list3 = new List(num2); CollectionsMarshal.SetCount(list3, num2); Span span4 = CollectionsMarshal.AsSpan(list3); span4[0] = 533; span4[1] = 555; } else { int num2 = 4; list3 = new List(num2); CollectionsMarshal.SetCount(list3, num2); Span span5 = CollectionsMarshal.AsSpan(list3); span5[0] = 178; span5[1] = 532; span5[2] = 553; span5[3] = 698; } reference2 = list3; ref List reference3 = ref span[2]; List list4; if (eClassJob != EClassJob.Marauder) { int num2 = 2; list4 = new List(num2); CollectionsMarshal.SetCount(list4, num2); Span span6 = CollectionsMarshal.AsSpan(list4); span6[0] = 311; span6[1] = 314; } else { int num2 = 4; list4 = new List(num2); CollectionsMarshal.SetCount(list4, num2); Span span7 = CollectionsMarshal.AsSpan(list4); span7[0] = 179; span7[1] = 310; span7[2] = 312; span7[3] = 315; } reference3 = list4; ref List reference4 = ref span[3]; List list5; if (eClassJob != EClassJob.Lancer) { int num2 = 2; list5 = new List(num2); CollectionsMarshal.SetCount(list5, num2); Span span8 = CollectionsMarshal.AsSpan(list5); span8[0] = 23; span8[1] = 35; } else { int num2 = 4; list5 = new List(num2); CollectionsMarshal.SetCount(list5, num2); Span span9 = CollectionsMarshal.AsSpan(list5); span9[0] = 180; span9[1] = 132; span9[2] = 218; span9[3] = 143; } reference4 = list5; ref List reference5 = ref span[4]; List list6; if (eClassJob != EClassJob.Archer) { int num2 = 2; list6 = new List(num2); CollectionsMarshal.SetCount(list6, num2); Span span10 = CollectionsMarshal.AsSpan(list6); span10[0] = 21; span10[1] = 67; } else { int num2 = 4; list6 = new List(num2); CollectionsMarshal.SetCount(list6, num2); Span span11 = CollectionsMarshal.AsSpan(list6); span11[0] = 181; span11[1] = 131; span11[2] = 219; span11[3] = 134; } reference5 = list6; ref List reference6 = ref span[5]; List list7; if (eClassJob != EClassJob.Conjurer) { int num2 = 2; list7 = new List(num2); CollectionsMarshal.SetCount(list7, num2); Span span12 = CollectionsMarshal.AsSpan(list7); span12[0] = 22; span12[1] = 91; } else { int num2 = 4; list7 = new List(num2); CollectionsMarshal.SetCount(list7, num2); Span span13 = CollectionsMarshal.AsSpan(list7); span13[0] = 182; span13[1] = 133; span13[2] = 211; span13[3] = 147; } reference6 = list7; ref List reference7 = ref span[6]; List list8; if (eClassJob != EClassJob.Thaumaturge) { int num2 = 2; list8 = new List(num2); CollectionsMarshal.SetCount(list8, num2); Span span14 = CollectionsMarshal.AsSpan(list8); span14[0] = 345; span14[1] = 348; } else { int num2 = 4; list8 = new List(num2); CollectionsMarshal.SetCount(list8, num2); Span span15 = CollectionsMarshal.AsSpan(list8); span15[0] = 183; span15[1] = 344; span15[2] = 346; span15[3] = 349; } reference7 = list8; ref List reference8 = ref span[7]; List list9; if (eClassJob != EClassJob.Arcanist) { int num2 = 2; list9 = new List(num2); CollectionsMarshal.SetCount(list9, num2); Span span16 = CollectionsMarshal.AsSpan(list9); span16[0] = 453; span16[1] = 456; } else { int num2 = 4; list9 = new List(num2); CollectionsMarshal.SetCount(list9, num2); Span span17 = CollectionsMarshal.AsSpan(list9); span17[0] = 451; span17[1] = 452; span17[2] = 454; span17[3] = 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 { _ = value is UnlockLinkQuestInfo; } } public void AddOrReplaceQuestInfo(IQuestInfo info) { ArgumentNullException.ThrowIfNull(info, "info"); _quests[info.QuestId] = info; } static QuestData() { Dictionary> dictionary = new Dictionary>(); int num = 4; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); span[0] = 1744; span[1] = 1759; span[2] = 1760; span[3] = 2111; dictionary.Add(397u, list); num = 4; List list2 = new List(num); CollectionsMarshal.SetCount(list2, num); Span span2 = CollectionsMarshal.AsSpan(list2); span2[0] = 1771; span2[1] = 1790; span2[2] = 1797; span2[3] = 1802; dictionary.Add(398u, list2); num = 4; List list3 = new List(num); CollectionsMarshal.SetCount(list3, num); Span span3 = CollectionsMarshal.AsSpan(list3); span3[0] = 1936; span3[1] = 1945; span3[2] = 1963; span3[3] = 1966; dictionary.Add(399u, list3); num = 4; List list4 = new List(num); CollectionsMarshal.SetCount(list4, num); Span span4 = CollectionsMarshal.AsSpan(list4); span4[0] = 1819; span4[1] = 1823; span4[2] = 1828; span4[3] = 1835; dictionary.Add(400u, list4); num = 4; List list5 = new List(num); CollectionsMarshal.SetCount(list5, num); Span span5 = CollectionsMarshal.AsSpan(list5); span5[0] = 1748; span5[1] = 1874; span5[2] = 1909; span5[3] = 1910; dictionary.Add(401u, list5); num = 4; List list6 = new List(num); CollectionsMarshal.SetCount(list6, num); Span span6 = CollectionsMarshal.AsSpan(list6); span6[0] = 2639; span6[1] = 2661; span6[2] = 2816; span6[3] = 2821; dictionary.Add(612u, list6); num = 4; List list7 = new List(num); CollectionsMarshal.SetCount(list7, num); Span span7 = CollectionsMarshal.AsSpan(list7); span7[0] = 2632; span7[1] = 2673; span7[2] = 2687; span7[3] = 2693; dictionary.Add(613u, list7); num = 4; List list8 = new List(num); CollectionsMarshal.SetCount(list8, num); Span span8 = CollectionsMarshal.AsSpan(list8); span8[0] = 2724; span8[1] = 2728; span8[2] = 2730; span8[3] = 2733; dictionary.Add(614u, list8); num = 4; List list9 = new List(num); CollectionsMarshal.SetCount(list9, num); Span span9 = CollectionsMarshal.AsSpan(list9); span9[0] = 2655; span9[1] = 2842; span9[2] = 2851; span9[3] = 2860; dictionary.Add(620u, list9); num = 4; List list10 = new List(num); CollectionsMarshal.SetCount(list10, num); Span span10 = CollectionsMarshal.AsSpan(list10); span10[0] = 2877; span10[1] = 2880; span10[2] = 2881; span10[3] = 2883; dictionary.Add(621u, list10); num = 4; List list11 = new List(num); CollectionsMarshal.SetCount(list11, num); Span span11 = CollectionsMarshal.AsSpan(list11); span11[0] = 2760; span11[1] = 2771; span11[2] = 2782; span11[3] = 2791; dictionary.Add(622u, list11); num = 4; List list12 = new List(num); CollectionsMarshal.SetCount(list12, num); Span span12 = CollectionsMarshal.AsSpan(list12); span12[0] = 3380; span12[1] = 3384; span12[2] = 3385; span12[3] = 3386; dictionary.Add(813u, list12); num = 4; List list13 = new List(num); CollectionsMarshal.SetCount(list13, num); Span span13 = CollectionsMarshal.AsSpan(list13); span13[0] = 3360; span13[1] = 3371; span13[2] = 3537; span13[3] = 3556; dictionary.Add(814u, list13); num = 4; List list14 = new List(num); CollectionsMarshal.SetCount(list14, num); Span span14 = CollectionsMarshal.AsSpan(list14); span14[0] = 3375; span14[1] = 3503; span14[2] = 3511; span14[3] = 3525; dictionary.Add(815u, list14); num = 4; List list15 = new List(num); CollectionsMarshal.SetCount(list15, num); Span span15 = CollectionsMarshal.AsSpan(list15); span15[0] = 3395; span15[1] = 3398; span15[2] = 3404; span15[3] = 3427; dictionary.Add(816u, list15); num = 4; List list16 = new List(num); CollectionsMarshal.SetCount(list16, num); Span span16 = CollectionsMarshal.AsSpan(list16); span16[0] = 3444; span16[1] = 3467; span16[2] = 3478; span16[3] = 3656; dictionary.Add(817u, list16); num = 4; List list17 = new List(num); CollectionsMarshal.SetCount(list17, num); Span span17 = CollectionsMarshal.AsSpan(list17); span17[0] = 3588; span17[1] = 3592; span17[2] = 3593; span17[3] = 3594; dictionary.Add(818u, list17); num = 4; List list18 = new List(num); CollectionsMarshal.SetCount(list18, num); Span span18 = CollectionsMarshal.AsSpan(list18); span18[0] = 4320; span18[1] = 4329; span18[2] = 4480; span18[3] = 4484; dictionary.Add(956u, list18); num = 4; List list19 = new List(num); CollectionsMarshal.SetCount(list19, num); Span span19 = CollectionsMarshal.AsSpan(list19); span19[0] = 4203; span19[1] = 4257; span19[2] = 4259; span19[3] = 4489; dictionary.Add(957u, list19); num = 4; List list20 = new List(num); CollectionsMarshal.SetCount(list20, num); Span span20 = CollectionsMarshal.AsSpan(list20); span20[0] = 4216; span20[1] = 4232; span20[2] = 4498; span20[3] = 4502; dictionary.Add(958u, list20); num = 4; List list21 = new List(num); CollectionsMarshal.SetCount(list21, num); Span span21 = CollectionsMarshal.AsSpan(list21); span21[0] = 4240; span21[1] = 4241; span21[2] = 4253; span21[3] = 4516; dictionary.Add(959u, list21); num = 4; List list22 = new List(num); CollectionsMarshal.SetCount(list22, num); Span span22 = CollectionsMarshal.AsSpan(list22); span22[0] = 4342; span22[1] = 4346; span22[2] = 4354; span22[3] = 4355; dictionary.Add(960u, list22); num = 4; List list23 = new List(num); CollectionsMarshal.SetCount(list23, num); Span span23 = CollectionsMarshal.AsSpan(list23); span23[0] = 4288; span23[1] = 4313; span23[2] = 4507; span23[3] = 4511; dictionary.Add(961u, list23); num = 4; List list24 = new List(num); CollectionsMarshal.SetCount(list24, num); Span span24 = CollectionsMarshal.AsSpan(list24); span24[0] = 5039; span24[1] = 5047; span24[2] = 5051; span24[3] = 5055; dictionary.Add(1187u, list24); num = 4; List list25 = new List(num); CollectionsMarshal.SetCount(list25, num); Span span25 = CollectionsMarshal.AsSpan(list25); span25[0] = 5064; span25[1] = 5074; span25[2] = 5081; span25[3] = 5085; dictionary.Add(1188u, list25); num = 4; List list26 = new List(num); CollectionsMarshal.SetCount(list26, num); Span span26 = CollectionsMarshal.AsSpan(list26); span26[0] = 5094; span26[1] = 5103; span26[2] = 5110; span26[3] = 5114; dictionary.Add(1189u, list26); num = 4; List list27 = new List(num); CollectionsMarshal.SetCount(list27, num); Span span27 = CollectionsMarshal.AsSpan(list27); span27[0] = 5130; span27[1] = 5138; span27[2] = 5140; span27[3] = 5144; dictionary.Add(1190u, list27); num = 4; List list28 = new List(num); CollectionsMarshal.SetCount(list28, num); Span span28 = CollectionsMarshal.AsSpan(list28); span28[0] = 5153; span28[1] = 5156; span28[2] = 5159; span28[3] = 5160; dictionary.Add(1191u, list28); num = 4; List list29 = new List(num); CollectionsMarshal.SetCount(list29, num); Span span29 = CollectionsMarshal.AsSpan(list29); span29[0] = 5174; span29[1] = 5176; span29[2] = 5178; span29[3] = 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) }); } }