From be1e4ed2e621192653cc76bb3fdfc3574c12cbcd Mon Sep 17 00:00:00 2001 From: Liza Carvelli Date: Sat, 16 Nov 2024 21:53:37 +0100 Subject: [PATCH] partial API 11 updates --- .../GatheringPathRenderer.csproj | 2 +- LLib | 2 +- .../Controller/CombatModules/ItemUseModule.cs | 2 +- .../RotationSolverRebornModule.cs | 2 +- Questionable/Controller/CommandHandler.cs | 5 +- .../Controller/ContextMenuController.cs | 2 +- .../GameUi/InteractionUiController.cs | 16 ++--- .../Controller/GatheringController.cs | 2 +- Questionable/Controller/MiniTaskController.cs | 2 +- Questionable/Controller/QuestController.cs | 6 -- .../Controller/Steps/Gathering/DoGather.cs | 2 +- .../Steps/Gathering/DoGatherCollectable.cs | 2 +- .../Steps/Interactions/EquipItem.cs | 17 ++--- .../Steps/Interactions/EquipRecommended.cs | 2 +- Questionable/Controller/Steps/Shared/Craft.cs | 38 +++++------ .../Controller/Steps/Shared/Gather.cs | 2 +- .../Controller/Steps/Shared/MoveTo.cs | 3 +- .../Controller/Steps/Shared/SkipCondition.cs | 2 +- .../Controller/Steps/Shared/SwitchClassJob.cs | 2 +- Questionable/Data/AetherCurrentData.cs | 10 +-- Questionable/Data/AetheryteData.cs | 16 ++--- Questionable/Data/GatheringData.cs | 35 +++++----- Questionable/Data/JournalData.cs | 35 ++++++---- Questionable/Data/QuestData.cs | 46 ++++++------- Questionable/Data/Sheets/QuestEx.cs | 45 +++++++++++++ Questionable/Data/TerritoryData.cs | 26 +++---- Questionable/Functions/AetheryteFunctions.cs | 11 ++- Questionable/Functions/ChatFunctions.cs | 14 ++-- Questionable/Functions/ExcelFunctions.cs | 39 +++++------ Questionable/Functions/GameFunctions.cs | 26 +++---- Questionable/Functions/QuestFunctions.cs | 12 ++-- Questionable/Model/LeveInfo.cs | 12 ++-- Questionable/Model/QuestInfo.cs | 37 +++++----- Questionable/Model/QuestInfoUtils.cs | 15 +++-- Questionable/Model/SatisfactionSupplyInfo.cs | 10 +-- Questionable/Questionable.csproj | 2 +- Questionable/Windows/ConfigWindow.cs | 5 +- .../GatheringJournalComponent.cs | 67 ++++++++++--------- .../QuestJournalComponent.cs | 2 +- Questionable/Windows/QuestWindow.cs | 2 +- vendor/ECommons | 2 +- 41 files changed, 314 insertions(+), 266 deletions(-) create mode 100644 Questionable/Data/Sheets/QuestEx.cs diff --git a/GatheringPathRenderer/GatheringPathRenderer.csproj b/GatheringPathRenderer/GatheringPathRenderer.csproj index fc157f20..6009a518 100644 --- a/GatheringPathRenderer/GatheringPathRenderer.csproj +++ b/GatheringPathRenderer/GatheringPathRenderer.csproj @@ -1,4 +1,4 @@ - + diff --git a/LLib b/LLib index fde09c70..538329a1 160000 --- a/LLib +++ b/LLib @@ -1 +1 @@ -Subproject commit fde09c705b648f03c287814191a554f0a4b92cc4 +Subproject commit 538329a1e80acbcd09e28bd6dd459c35b5563c0a diff --git a/Questionable/Controller/CombatModules/ItemUseModule.cs b/Questionable/Controller/CombatModules/ItemUseModule.cs index 91b4ca1d..ec9adfa1 100644 --- a/Questionable/Controller/CombatModules/ItemUseModule.cs +++ b/Questionable/Controller/CombatModules/ItemUseModule.cs @@ -142,7 +142,7 @@ internal sealed class ItemUseModule : ICombatModule { BattleChara* battleChara = (BattleChara*)gameObject.Address; if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.Incapacitated) - return (battleChara->Flags2 & 128u) != 0; + return (battleChara->CombatTagType & 128u) != 0; // FIXME 7.1 if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.HealthPercent) return (100f * battleChara->Health / battleChara->MaxHealth) < _combatData.CombatItemUse.Value; diff --git a/Questionable/Controller/CombatModules/RotationSolverRebornModule.cs b/Questionable/Controller/CombatModules/RotationSolverRebornModule.cs index a0b43b2f..581e07a9 100644 --- a/Questionable/Controller/CombatModules/RotationSolverRebornModule.cs +++ b/Questionable/Controller/CombatModules/RotationSolverRebornModule.cs @@ -82,7 +82,7 @@ internal sealed class RotationSolverRebornModule : ICombatModule, IDisposable float hitboxOffset = player.HitboxRadius + gameObject.HitboxRadius; float actualDistance = Vector3.Distance(player.Position, gameObject.Position); - float maxDistance = player.ClassJob.GameData?.Role is 3 or 4 ? 20f : 2.9f; + float maxDistance = player.ClassJob.ValueNullable?.Role is 3 or 4 ? 20f : 2.9f; if (actualDistance - hitboxOffset >= maxDistance) { if (actualDistance - hitboxOffset <= 5) diff --git a/Questionable/Controller/CommandHandler.cs b/Questionable/Controller/CommandHandler.cs index 42759d99..c6085a18 100644 --- a/Questionable/Controller/CommandHandler.cs +++ b/Questionable/Controller/CommandHandler.cs @@ -3,11 +3,10 @@ using System.Linq; using Dalamud.Game.ClientState.Objects; using Dalamud.Game.Command; using Dalamud.Plugin.Services; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Questionable.Functions; using Questionable.Model.Questing; using Questionable.Windows; -using Questionable.Windows.QuestComponents; using Quest = Questionable.Model.Quest; namespace Questionable.Controller; @@ -240,7 +239,7 @@ internal sealed class CommandHandler : IDisposable ushort? mountId = _gameFunctions.GetMountId(); if (mountId != null) { - var row = _dataManager.GetExcelSheet()!.GetRow(mountId.Value); + var row = _dataManager.GetExcelSheet().GetRowOrDefault(mountId.Value); _chatGui.Print( $"Mount ID: {mountId}, Name: {row?.Singular}, Obtainable: {(row?.Order == -1 ? "No" : "Yes")}", MessageTag, TagColor); diff --git a/Questionable/Controller/ContextMenuController.cs b/Questionable/Controller/ContextMenuController.cs index c3d6c4c5..fca77dd8 100644 --- a/Questionable/Controller/ContextMenuController.cs +++ b/Questionable/Controller/ContextMenuController.cs @@ -79,7 +79,7 @@ internal sealed class ContextMenuController : IDisposable private void AddContextMenuEntry(IMenuOpenedArgs args, uint itemId, uint npcId, EExtendedClassJob extendedClassJob, string verb) { - EClassJob currentClassJob = (EClassJob)_clientState.LocalPlayer!.ClassJob.Id; + EClassJob currentClassJob = (EClassJob)_clientState.LocalPlayer!.ClassJob.RowId; EClassJob classJob = ClassJobUtils.AsIndividualJobs(extendedClassJob).Single(); if (classJob != currentClassJob && currentClassJob is EClassJob.Miner or EClassJob.Botanist) return; diff --git a/Questionable/Controller/GameUi/InteractionUiController.cs b/Questionable/Controller/GameUi/InteractionUiController.cs index 698d24dd..797093dd 100644 --- a/Questionable/Controller/GameUi/InteractionUiController.cs +++ b/Questionable/Controller/GameUi/InteractionUiController.cs @@ -16,7 +16,7 @@ using FFXIVClientStructs.FFXIV.Component.GUI; using LLib; using LLib.GameData; using LLib.GameUI; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps.Interactions; using Questionable.Data; @@ -90,7 +90,7 @@ internal sealed class InteractionUiController : IDisposable _shopController = shopController; _logger = logger; - _returnRegex = _dataManager.GetExcelSheet()!.GetRow(196)!.GetRegex(addon => addon.Text, pluginLog)!; + _returnRegex = _dataManager.GetExcelSheet().GetRow(196).GetRegex(addon => addon.Text, pluginLog)!; _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectString", SelectStringPostSetup); _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "CutSceneSelectString", CutsceneSelectStringPostSetup); @@ -713,7 +713,7 @@ internal sealed class InteractionUiController : IDisposable step.InteractionType == EInteractionType.Gather) { if (_gatheringData.TryGetGatheringPointId(step.ItemsToGather[0].ItemId, - (EClassJob?)_clientState.LocalPlayer?.ClassJob.Id ?? EClassJob.Adventurer, + (EClassJob?)_clientState.LocalPlayer?.ClassJob.RowId ?? EClassJob.Adventurer, out GatheringPointId? gatheringPointId) && _gatheringPointRegistry.TryGetGatheringPoint(gatheringPointId, out GatheringRoot? root)) { @@ -757,19 +757,19 @@ internal sealed class InteractionUiController : IDisposable [NotNullWhen(true)] out string? warpText) { var warps = _dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0 && x.TerritoryType.Row == targetTerritoryId); + .Where(x => x.RowId > 0 && x.TerritoryType.RowId == targetTerritoryId); foreach (var entry in warps) { - string? excelName = entry.Name?.ToString(); - string? excelQuestion = entry.Question?.ToString(); + string? excelName = entry.Name.ToString(); + string? excelQuestion = entry.Question.ToString(); - if (excelQuestion != null && GameFunctions.GameStringEquals(excelQuestion, actualPrompt)) + if (!string.IsNullOrEmpty(excelQuestion) && GameFunctions.GameStringEquals(excelQuestion, actualPrompt)) { warpId = entry.RowId; warpText = excelQuestion; return true; } - else if (excelName != null && GameFunctions.GameStringEquals(excelName, actualPrompt)) + else if (!string.IsNullOrEmpty(excelName) && GameFunctions.GameStringEquals(excelName, actualPrompt)) { warpId = entry.RowId; warpText = excelName; diff --git a/Questionable/Controller/GatheringController.cs b/Questionable/Controller/GatheringController.cs index 8c7dedd4..bbe6d2e4 100644 --- a/Questionable/Controller/GatheringController.cs +++ b/Questionable/Controller/GatheringController.cs @@ -12,7 +12,7 @@ using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.Event; using FFXIVClientStructs.FFXIV.Client.Game.UI; using LLib; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps; using Questionable.Controller.Steps.Gathering; diff --git a/Questionable/Controller/MiniTaskController.cs b/Questionable/Controller/MiniTaskController.cs index dfa0bfc9..06850818 100644 --- a/Questionable/Controller/MiniTaskController.cs +++ b/Questionable/Controller/MiniTaskController.cs @@ -5,7 +5,7 @@ using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Plugin.Services; using LLib; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps; diff --git a/Questionable/Controller/QuestController.cs b/Questionable/Controller/QuestController.cs index 0fbd79fe..d6ae32a8 100644 --- a/Questionable/Controller/QuestController.cs +++ b/Questionable/Controller/QuestController.cs @@ -8,20 +8,14 @@ using Dalamud.Game.Gui.Toast; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; -using LLib; -using LLib.GameData; -using Lumina.Excel.GeneratedSheets; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps; -using Questionable.Controller.Steps.Interactions; using Questionable.Controller.Steps.Shared; -using Questionable.Data; using Questionable.External; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Questing; using Quest = Questionable.Model.Quest; -using Mount = Questionable.Controller.Steps.Common.Mount; namespace Questionable.Controller; diff --git a/Questionable/Controller/Steps/Gathering/DoGather.cs b/Questionable/Controller/Steps/Gathering/DoGather.cs index 701f8534..0f4c8c7f 100644 --- a/Questionable/Controller/Steps/Gathering/DoGather.cs +++ b/Questionable/Controller/Steps/Gathering/DoGather.cs @@ -225,7 +225,7 @@ internal static class DoGather private EAction PickAction(EAction minerAction, EAction botanistAction) { - if ((EClassJob?)clientState.LocalPlayer?.ClassJob.Id == EClassJob.Miner) + if ((EClassJob?)clientState.LocalPlayer?.ClassJob.RowId == EClassJob.Miner) return minerAction; else return botanistAction; diff --git a/Questionable/Controller/Steps/Gathering/DoGatherCollectable.cs b/Questionable/Controller/Steps/Gathering/DoGatherCollectable.cs index 16740943..2b91f353 100644 --- a/Questionable/Controller/Steps/Gathering/DoGatherCollectable.cs +++ b/Questionable/Controller/Steps/Gathering/DoGatherCollectable.cs @@ -193,7 +193,7 @@ internal static class DoGatherCollectable private EAction PickAction(EAction minerAction, EAction botanistAction) { - if ((EClassJob?)clientState.LocalPlayer?.ClassJob.Id == EClassJob.Miner) + if ((EClassJob?)clientState.LocalPlayer?.ClassJob.RowId == EClassJob.Miner) return minerAction; else return botanistAction; diff --git a/Questionable/Controller/Steps/Interactions/EquipItem.cs b/Questionable/Controller/Steps/Interactions/EquipItem.cs index c8159247..f5cd4e11 100644 --- a/Questionable/Controller/Steps/Interactions/EquipItem.cs +++ b/Questionable/Controller/Steps/Interactions/EquipItem.cs @@ -5,8 +5,7 @@ using Dalamud.Game.Text.SeStringHandling; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using LLib; -using Lumina.Excel.GeneratedSheets; -using Microsoft.Extensions.DependencyInjection; +using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Functions; using Questionable.Model.Questing; @@ -63,13 +62,13 @@ internal static class EquipItem ]; private int _attempts; - private Item _item = null!; + private Item? _item; private List _targetSlots = null!; private DateTime _continueAt = DateTime.MaxValue; protected override bool Start() { - _item = dataManager.GetExcelSheet()!.GetRow(Task.ItemId) ?? + _item = dataManager.GetExcelSheet().GetRowOrDefault(Task.ItemId) ?? throw new ArgumentOutOfRangeException(nameof(Task.ItemId)); _targetSlots = GetEquipSlot(_item) ?? throw new InvalidOperationException("Not a piece of equipment"); @@ -118,7 +117,7 @@ internal static class EquipItem var itemSlot = equippedContainer->GetInventorySlot(slot); if (itemSlot != null && itemSlot->ItemId == Task.ItemId) { - logger.LogInformation("Already equipped {Item}, skipping step", _item.Name?.ToString()); + logger.LogInformation("Already equipped {Item}, skipping step", _item?.Name.ToString()); return; } } @@ -162,11 +161,13 @@ internal static class EquipItem throw new TaskException($"Could not equip item {Task.ItemId}."); } - private static List? GetEquipSlot(Item item) + private static List? GetEquipSlot(Item? item) { - return item.EquipSlotCategory.Row switch + if (item == null) + return []; + return item.Value.EquipSlotCategory.RowId switch { - >= 1 and <= 11 => [(ushort)(item.EquipSlotCategory.Row - 1)], + >= 1 and <= 11 => [(ushort)(item.Value.EquipSlotCategory.RowId - 1)], 12 => [11, 12], // rings 13 => [0], 17 => [13], // soul crystal diff --git a/Questionable/Controller/Steps/Interactions/EquipRecommended.cs b/Questionable/Controller/Steps/Interactions/EquipRecommended.cs index cd4f7982..b923c237 100644 --- a/Questionable/Controller/Steps/Interactions/EquipRecommended.cs +++ b/Questionable/Controller/Steps/Interactions/EquipRecommended.cs @@ -45,7 +45,7 @@ internal static class EquipRecommended protected override bool Start() { - RecommendEquipModule.Instance()->SetupForClassJob((byte)clientState.LocalPlayer!.ClassJob.Id); + RecommendEquipModule.Instance()->SetupForClassJob((byte)clientState.LocalPlayer!.ClassJob.RowId); return true; } diff --git a/Questionable/Controller/Steps/Shared/Craft.cs b/Questionable/Controller/Steps/Shared/Craft.cs index ad474fe2..26493ca0 100644 --- a/Questionable/Controller/Steps/Shared/Craft.cs +++ b/Questionable/Controller/Steps/Shared/Craft.cs @@ -6,7 +6,7 @@ using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; using LLib.GameData; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.External; using Questionable.Model.Questing; @@ -55,20 +55,20 @@ internal static class Craft return false; } - RecipeLookup? recipeLookup = dataManager.GetExcelSheet()!.GetRow(Task.ItemId); + RecipeLookup? recipeLookup = dataManager.GetExcelSheet().GetRowOrDefault(Task.ItemId); if (recipeLookup == null) throw new TaskException($"Item {Task.ItemId} is not craftable"); - uint recipeId = (EClassJob)clientState.LocalPlayer!.ClassJob.Id switch + uint recipeId = (EClassJob)clientState.LocalPlayer!.ClassJob.RowId switch { - EClassJob.Carpenter => recipeLookup.CRP.Row, - EClassJob.Blacksmith => recipeLookup.BSM.Row, - EClassJob.Armorer => recipeLookup.ARM.Row, - EClassJob.Goldsmith => recipeLookup.GSM.Row, - EClassJob.Leatherworker => recipeLookup.LTW.Row, - EClassJob.Weaver => recipeLookup.WVR.Row, - EClassJob.Alchemist => recipeLookup.ALC.Row, - EClassJob.Culinarian => recipeLookup.CUL.Row, + EClassJob.Carpenter => recipeLookup.Value.CRP.RowId, + EClassJob.Blacksmith => recipeLookup.Value.BSM.RowId, + EClassJob.Armorer => recipeLookup.Value.ARM.RowId, + EClassJob.Goldsmith => recipeLookup.Value.GSM.RowId, + EClassJob.Leatherworker => recipeLookup.Value.LTW.RowId, + EClassJob.Weaver => recipeLookup.Value.WVR.RowId, + EClassJob.Alchemist => recipeLookup.Value.ALC.RowId, + EClassJob.Culinarian => recipeLookup.Value.CUL.RowId, _ => 0 }; @@ -76,14 +76,14 @@ internal static class Craft { recipeId = new[] { - recipeLookup.CRP.Row, - recipeLookup.BSM.Row, - recipeLookup.ARM.Row, - recipeLookup.GSM.Row, - recipeLookup.LTW.Row, - recipeLookup.WVR.Row, - recipeLookup.ALC.Row, - recipeLookup.WVR.Row + recipeLookup.Value.CRP.RowId, + recipeLookup.Value.BSM.RowId, + recipeLookup.Value.ARM.RowId, + recipeLookup.Value.GSM.RowId, + recipeLookup.Value.LTW.RowId, + recipeLookup.Value.WVR.RowId, + recipeLookup.Value.ALC.RowId, + recipeLookup.Value.WVR.RowId } .FirstOrDefault(x => x != 0); } diff --git a/Questionable/Controller/Steps/Shared/Gather.cs b/Questionable/Controller/Steps/Shared/Gather.cs index 5724a209..13671d8d 100644 --- a/Questionable/Controller/Steps/Shared/Gather.cs +++ b/Questionable/Controller/Steps/Shared/Gather.cs @@ -35,7 +35,7 @@ internal static class Gather foreach (var itemToGather in step.ItemsToGather) { - EClassJob currentClassJob = (EClassJob)clientState.LocalPlayer!.ClassJob.Id; + EClassJob currentClassJob = (EClassJob)clientState.LocalPlayer!.ClassJob.RowId; if (!gatheringData.TryGetGatheringPointId(itemToGather.ItemId, currentClassJob, out GatheringPointId? gatheringPointId)) throw new TaskException($"No gathering point found for item {itemToGather.ItemId}"); diff --git a/Questionable/Controller/Steps/Shared/MoveTo.cs b/Questionable/Controller/Steps/Shared/MoveTo.cs index eaead8ef..4df2870f 100644 --- a/Questionable/Controller/Steps/Shared/MoveTo.cs +++ b/Questionable/Controller/Steps/Shared/MoveTo.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Numerics; using Dalamud.Game.ClientState.Conditions; @@ -10,7 +9,7 @@ using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.Character; using LLib; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps.Common; using Questionable.Data; diff --git a/Questionable/Controller/Steps/Shared/SkipCondition.cs b/Questionable/Controller/Steps/Shared/SkipCondition.cs index 2951d8d8..68297c4e 100644 --- a/Questionable/Controller/Steps/Shared/SkipCondition.cs +++ b/Questionable/Controller/Steps/Shared/SkipCondition.cs @@ -239,7 +239,7 @@ internal static class SkipCondition { List expectedJobs = step.RequiredCurrentJob.SelectMany(ClassJobUtils.AsIndividualJobs).ToList(); - EClassJob currentJob = (EClassJob)clientState.LocalPlayer!.ClassJob.Id; + EClassJob currentJob = (EClassJob)clientState.LocalPlayer!.ClassJob.RowId; logger.LogInformation("Checking current job {CurrentJob} against {ExpectedJobs}", currentJob, string.Join(",", expectedJobs)); if (!expectedJobs.Contains(currentJob)) diff --git a/Questionable/Controller/Steps/Shared/SwitchClassJob.cs b/Questionable/Controller/Steps/Shared/SwitchClassJob.cs index 48b153c3..59477fec 100644 --- a/Questionable/Controller/Steps/Shared/SwitchClassJob.cs +++ b/Questionable/Controller/Steps/Shared/SwitchClassJob.cs @@ -31,7 +31,7 @@ internal static class SwitchClassJob { protected override unsafe bool StartInternal() { - if (clientState.LocalPlayer!.ClassJob.Id == (uint)Task.ClassJob) + if (clientState.LocalPlayer!.ClassJob.RowId == (uint)Task.ClassJob) return false; var gearsetModule = RaptureGearsetModule.Instance(); diff --git a/Questionable/Data/AetherCurrentData.cs b/Questionable/Data/AetherCurrentData.cs index f83b99c0..04bb7c37 100644 --- a/Questionable/Data/AetherCurrentData.cs +++ b/Questionable/Data/AetherCurrentData.cs @@ -1,7 +1,7 @@ using System.Collections.Immutable; using System.Linq; using Dalamud.Plugin.Services; -using Lumina.Excel.GeneratedSheets2; +using Lumina.Excel.Sheets; namespace Questionable.Data; @@ -13,12 +13,12 @@ internal sealed class AetherCurrentData { _overworldCurrents = dataManager.GetExcelSheet()! .Where(x => x.RowId > 0) - .Where(x => x.Territory.Value != null) + .Where(x => x.Territory.IsValid) .ToImmutableDictionary( - x => (ushort)x.Territory.Row, + x => (ushort)x.Territory.RowId, x => x.AetherCurrents - .Where(y => y.Row > 0 && y.Value?.Quest.Row == 0) - .Select(y => y.Row) + .Where(y => y.RowId > 0 && y.Value.Quest.RowId == 0) + .Select(y => y.RowId) .ToImmutableList()); } diff --git a/Questionable/Data/AetheryteData.cs b/Questionable/Data/AetheryteData.cs index f921972f..1e8f34c2 100644 --- a/Questionable/Data/AetheryteData.cs +++ b/Questionable/Data/AetheryteData.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Numerics; using Dalamud.Plugin.Services; using Dalamud.Utility; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Questionable.Model.Common; namespace Questionable.Data; @@ -29,19 +29,19 @@ internal sealed class AetheryteData void ConfigureAetheryteWithPlaceName(EAetheryteLocation aetheryteLocation, uint placeNameId, ushort territoryId) { ConfigureAetheryte(aetheryteLocation, - dataManager.GetExcelSheet()!.GetRow(placeNameId)!.Name.ToDalamudString().TextValue, + dataManager.GetExcelSheet().GetRow(placeNameId).Name.ToDalamudString().TextValue, territoryId, (ushort)((int)aetheryteLocation / 100)); } - foreach (var aetheryte in dataManager.GetExcelSheet()!.Where(x => x.RowId > 0)) + foreach (var aetheryte in dataManager.GetExcelSheet().Where(x => x.RowId > 0)) { - string? aethernetName = aetheryte.AethernetName?.Value?.Name.ToString(); + string? aethernetName = aetheryte.AethernetName.ValueNullable?.Name.ToString(); if (!string.IsNullOrEmpty(aethernetName)) aethernetNames[(EAetheryteLocation)aetheryte.RowId] = aethernetName; - if (aetheryte.Territory != null && aetheryte.Territory.Row > 0) - territoryIds[(EAetheryteLocation)aetheryte.RowId] = (ushort)aetheryte.Territory.Row; + if (aetheryte.Territory.RowId > 0) + territoryIds[(EAetheryteLocation)aetheryte.RowId] = (ushort)aetheryte.Territory.RowId; if (aetheryte.AethernetGroup > 0) aethernetGroups[(EAetheryteLocation)aetheryte.RowId] = aetheryte.AethernetGroup; @@ -62,8 +62,8 @@ internal sealed class AetheryteData TerritoryIds = territoryIds.AsReadOnly(); AethernetGroups = aethernetGroups.AsReadOnly(); - TownTerritoryIds = dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0 && !string.IsNullOrEmpty(x.Name) && x.TerritoryIntendedUse == 0) + TownTerritoryIds = dataManager.GetExcelSheet() + .Where(x => x.RowId > 0 && !string.IsNullOrEmpty(x.Name.ToString()) && x.TerritoryIntendedUse.RowId == 0) .Select(x => (ushort)x.RowId) .ToList(); } diff --git a/Questionable/Data/GatheringData.cs b/Questionable/Data/GatheringData.cs index c231f004..1d11a1ba 100644 --- a/Questionable/Data/GatheringData.cs +++ b/Questionable/Data/GatheringData.cs @@ -3,8 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Dalamud.Plugin.Services; using LLib.GameData; -using Lumina.Excel.GeneratedSheets; -using Microsoft.Extensions.Logging; +using Lumina.Excel.Sheets; using Questionable.Model.Gathering; namespace Questionable.Data; @@ -18,43 +17,45 @@ internal sealed class GatheringData public GatheringData(IDataManager dataManager) { - Dictionary gatheringItemToItem = dataManager.GetExcelSheet()! - .Where(x => x.RowId != 0 && x.Item != 0) - .ToDictionary(x => x.RowId, x => (uint)x.Item); + Dictionary gatheringItemToItem = dataManager.GetExcelSheet() + .Where(x => x.RowId != 0 && x.Item.RowId != 0) + .ToDictionary(x => x.RowId, x => x.Item.RowId); - foreach (var gatheringPointBase in dataManager.GetExcelSheet()!) + foreach (var gatheringPointBase in dataManager.GetExcelSheet()) { - foreach (var gatheringItemId in gatheringPointBase.Item.Where(x => x != 0)) + foreach (var gatheringItem in gatheringPointBase.Item.Where(x => x.RowId != 0)) { - if (gatheringItemToItem.TryGetValue((uint)gatheringItemId, out uint itemId)) + if (gatheringItemToItem.TryGetValue(gatheringItem.RowId, out uint itemId)) { - if (gatheringPointBase.GatheringType.Row is 0 or 1) + if (gatheringPointBase.GatheringType.RowId is 0 or 1) _minerGatheringPoints[itemId] = new GatheringPointId((ushort)gatheringPointBase.RowId); - else if (gatheringPointBase.GatheringType.Row is 2 or 3) + else if (gatheringPointBase.GatheringType.RowId is 2 or 3) _botanistGatheringPoints[itemId] = new GatheringPointId((ushort)gatheringPointBase.RowId); } } } - _itemIdToCollectability = dataManager.GetExcelSheet()! + _itemIdToCollectability = dataManager.GetSubrowExcelSheet() .Where(x => x.RowId > 0) + .SelectMany(x => x) .Where(x => x.Slot is 2) .Select(x => new { - ItemId = x.Item.Row, + ItemId = x.Item.RowId, Collectability = x.CollectabilityHigh, }) .Distinct() .ToDictionary(x => x.ItemId, x => x.Collectability); - _npcForCustomDeliveries = dataManager.GetExcelSheet()! + _npcForCustomDeliveries = dataManager.GetExcelSheet() .Where(x => x.RowId > 0) - .SelectMany(x => dataManager.GetExcelSheet()! - .Where(y => y.RowId == x.SupplyIndex.Last()) + .SelectMany(x => dataManager.GetSubrowExcelSheet() + .Where(y => y.RowId == x.SatisfactionNpcParams.Last().SupplyIndex) + .SelectMany(y => y) .Select(y => new { - ItemId = y.Item.Row, - NpcId = x.Npc.Row + ItemId = y.Item.RowId, + NpcId = x.Npc.RowId })) .Where(x => x.ItemId > 0) .Distinct() diff --git a/Questionable/Data/JournalData.cs b/Questionable/Data/JournalData.cs index fca04e82..f26f452a 100644 --- a/Questionable/Data/JournalData.cs +++ b/Questionable/Data/JournalData.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using System.Linq; using Dalamud.Plugin.Services; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; +using Microsoft.Extensions.Logging; using Questionable.Model; using Questionable.Model.Questing; @@ -9,28 +10,36 @@ namespace Questionable.Data; internal sealed class JournalData { - public JournalData(IDataManager dataManager, QuestData questData) + public JournalData(IDataManager dataManager, QuestData questData, ILogger logger) { - var genres = dataManager.GetExcelSheet()! + var genres = dataManager.GetExcelSheet() .Where(x => x.RowId > 0 && x.Icon > 0) .Select(x => new Genre(x, questData.GetAllByJournalGenre(x.RowId))) .ToList(); + foreach (var genre in genres) + { + logger.LogInformation("Genre {GenreId}: {GenreName} has {QuestCount} quests", + genre.Id, genre.Name, genre.QuestCount); + } + logger.LogInformation("Genre count: {GenreCount}", genres.Count); + var quest = questData.GetQuestInfo(new QuestId(5193)); + logger.LogInformation("Q: {N}, {A}, {B}", quest.Name, quest.JournalGenre, quest.IssuerDataId); - var limsaStart = dataManager.GetExcelSheet()!.GetRow(1)!; - var gridaniaStart = dataManager.GetExcelSheet()!.GetRow(2)!; - var uldahStart = dataManager.GetExcelSheet()!.GetRow(3)!; + var limsaStart = dataManager.GetExcelSheet().GetRow(1); + var gridaniaStart = dataManager.GetExcelSheet().GetRow(2); + var uldahStart = dataManager.GetExcelSheet().GetRow(3); var genreLimsa = new Genre(uint.MaxValue - 3, "Starting in Limsa Lominsa", 1, - new uint[] { 108, 109 }.Concat(limsaStart.Quest.Select(x => x.Row)) + new uint[] { 108, 109 }.Concat(limsaStart.QuestRedoParam.Select(x => x.Quest.RowId)) .Where(x => x != 0) .Select(x => questData.GetQuestInfo(new QuestId((ushort)(x & 0xFFFF)))) .ToList()); var genreGridania = new Genre(uint.MaxValue - 2, "Starting in Gridania", 1, - new uint[] { 85, 123, 124 }.Concat(gridaniaStart.Quest.Select(x => x.Row)) + new uint[] { 85, 123, 124 }.Concat(gridaniaStart.QuestRedoParam.Select(x => x.Quest.RowId)) .Where(x => x != 0) .Select(x => questData.GetQuestInfo(new QuestId((ushort)(x & 0xFFFF)))) .ToList()); var genreUldah = new Genre(uint.MaxValue - 1, "Starting in Ul'dah", 1, - new uint[] { 568, 569, 570 }.Concat(uldahStart.Quest.Select(x => x.Row)) + new uint[] { 568, 569, 570 }.Concat(uldahStart.QuestRedoParam.Select(x => x.Quest.RowId)) .Where(x => x != 0) .Select(x => questData.GetQuestInfo(new QuestId((ushort)(x & 0xFFFF)))) .ToList()); @@ -41,12 +50,12 @@ internal sealed class JournalData genreLimsa.Quests.Contains(x) || genreGridania.Quests.Contains(x) || genreUldah.Quests.Contains(x)); Genres = genres.AsReadOnly(); - Categories = dataManager.GetExcelSheet()! + Categories = dataManager.GetExcelSheet() .Where(x => x.RowId > 0) .Select(x => new Category(x, Genres.Where(y => y.CategoryId == x.RowId).ToList())) .ToList() .AsReadOnly(); - Sections = dataManager.GetExcelSheet()! + Sections = dataManager.GetExcelSheet() .Select(x => new Section(x, Categories.Where(y => y.SectionId == x.RowId).ToList())) .ToList(); } @@ -61,7 +70,7 @@ internal sealed class JournalData { Id = journalGenre.RowId; Name = journalGenre.Name.ToString(); - CategoryId = journalGenre.JournalCategory.Row; + CategoryId = journalGenre.JournalCategory.RowId; Quests = quests; } @@ -84,7 +93,7 @@ internal sealed class JournalData { public uint Id { get; } = journalCategory.RowId; public string Name { get; } = journalCategory.Name.ToString(); - public uint SectionId { get; } = journalCategory.JournalSection.Row; + public uint SectionId { get; } = journalCategory.JournalSection.RowId; public IReadOnlyList Genres { get; } = genres; public int QuestCount => Genres.Sum(x => x.QuestCount); } diff --git a/Questionable/Data/QuestData.cs b/Questionable/Data/QuestData.cs index e74f28e5..b055a7d7 100644 --- a/Questionable/Data/QuestData.cs +++ b/Questionable/Data/QuestData.cs @@ -5,11 +5,11 @@ using System.Linq; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.UI; using LLib.GameData; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; +using Questionable.Data.Sheets; using Questionable.Model; using Questionable.Model.Questing; -using Leve = Lumina.Excel.GeneratedSheets2.Leve; -using Quest = Lumina.Excel.GeneratedSheets2.Quest; +using Quest = Lumina.Excel.Sheets.Quest; namespace Questionable.Data; @@ -18,13 +18,13 @@ internal sealed class QuestData public static readonly IReadOnlyList CrystalTowerQuests = [new(1709), new(1200), new(1201), new(1202), new(1203), new(1474), new(494), new(495)]; - public static readonly IReadOnlyList TankRoleQuests = [136, 154, 178]; - public static readonly IReadOnlyList HealerRoleQuests = [137, 155, 179]; - public static readonly IReadOnlyList MeleeRoleQuests = [138, 156, 180]; - public static readonly IReadOnlyList PhysicalRangedRoleQuests = [138, 157, 181]; - public static readonly IReadOnlyList CasterRoleQuests = [139, 158, 182]; + public static readonly IReadOnlyList TankRoleQuests = [136, 154, 178]; + public static readonly IReadOnlyList HealerRoleQuests = [137, 155, 179]; + public static readonly IReadOnlyList MeleeRoleQuests = [138, 156, 180]; + public static readonly IReadOnlyList PhysicalRangedRoleQuests = [138, 157, 181]; + public static readonly IReadOnlyList CasterRoleQuests = [139, 158, 182]; - public static readonly IReadOnlyList> AllRoleQuestChapters = + public static readonly IReadOnlyList> AllRoleQuestChapters = [ TankRoleQuests, HealerRoleQuests, @@ -40,33 +40,33 @@ internal sealed class QuestData public QuestData(IDataManager dataManager) { - Dictionary questChapters = + Dictionary questChapters = dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0 && x.Quest.Row > 0) - .ToDictionary(x => x.Quest.Row, x => x.Redo); + .Where(x => x.RowId > 0 && x.Quest.RowId > 0) + .ToDictionary(x => x.Quest.RowId, x => x.Redo.RowId); Dictionary startingCities = new(); for (byte redoChapter = 1; redoChapter <= 3; ++redoChapter) { - var questRedo = dataManager.GetExcelSheet()!.GetRow(redoChapter)!; - foreach (var quest in questRedo.Quest.Where(x => x.Row > 0)) - startingCities[quest.Row] = redoChapter; + var questRedo = dataManager.GetExcelSheet().GetRow(redoChapter); + foreach (var quest in questRedo.QuestRedoParam.Where(x => x.Quest.IsValid)) + startingCities[quest.Quest.RowId] = redoChapter; } List quests = [ - ..dataManager.GetExcelSheet()! + ..dataManager.GetExcelSheet() .Where(x => x.RowId > 0) - .Where(x => x.IssuerLocation.Row > 0) + .Where(x => x.IssuerLocation.RowId > 0) .Select(x => new QuestInfo(x, questChapters.GetValueOrDefault(x.RowId), startingCities.GetValueOrDefault(x.RowId))) .Where(x => x.QuestId.Value != 1428), - ..dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0) + ..dataManager.GetExcelSheet() + .Where(x => x is { RowId: > 0, Npc.RowId: > 0 }) .Select(x => new SatisfactionSupplyInfo(x)), - ..dataManager.GetExcelSheet()! + ..dataManager.GetExcelSheet() .Where(x => x.RowId > 0) - .Where(x => x.LevelLevemete.Row != 0) + .Where(x => x.LevelLevemete.RowId != 0) .Select(x => new LeveInfo(x)), ]; _quests = quests.ToDictionary(x => x.QuestId, x => x); @@ -230,7 +230,7 @@ internal sealed class QuestData public List GetClassJobQuests(EClassJob classJob) { - List chapterIds = classJob switch + List chapterIds = classJob switch { EClassJob.Adventurer => throw new ArgumentOutOfRangeException(nameof(classJob)), @@ -308,7 +308,7 @@ internal sealed class QuestData return GetQuestsInNewGamePlusChapters(chapterIds); } - private List GetQuestsInNewGamePlusChapters(List chapterIds) + private List GetQuestsInNewGamePlusChapters(List chapterIds) { return _quests.Values .Where(x => x is QuestInfo) diff --git a/Questionable/Data/Sheets/QuestEx.cs b/Questionable/Data/Sheets/QuestEx.cs new file mode 100644 index 00000000..c4da0178 --- /dev/null +++ b/Questionable/Data/Sheets/QuestEx.cs @@ -0,0 +1,45 @@ +using Lumina.Excel; +using Lumina.Excel.Sheets; +using Lumina.Text.ReadOnly; + +namespace Questionable.Data.Sheets; + +// TODO Remove once fixed in dalamud +[Sheet("Quest", 0x1F8C7430)] +public readonly unsafe struct QuestEx(ExcelPage page, uint offset, uint row) : IExcelRow +{ + public uint RowId => row; + + public Quest Original { get; } = new(page, offset, row); + + public RowRef IssuerStart => RowRef.GetFirstValidRowOrUntyped(page.Module, page.ReadUInt32(offset + 2456), [typeof(EObjName), typeof(ENpcResident)], 882056187, page.Language); + public RowRef IssuerLocation => new(page.Module, page.ReadUInt32(offset + 2460), page.Language); + public RowRef JournalGenre => new(page.Module, page.ReadUInt32(offset + 2468), page.Language); + public ushort SortKey => page.ReadUInt16(offset + 2502); + public readonly RowRef Expansion => new(page.Module, (uint)page.ReadUInt8(offset + 2504), page.Language); + public readonly byte PreviousQuestJoin => page.ReadUInt8(offset + 2508); + public readonly RowRef ClassJobCategory0 => new(page.Module, (uint)page.ReadUInt8(offset + 2505), page.Language); + public readonly RowRef ClassJobCategory1 => new(page.Module, (uint)page.ReadUInt8(offset + 2507), page.Language); + public readonly RowRef Festival => new(page.Module, (uint)page.ReadUInt8(offset + 2517), page.Language); + public readonly byte Unknown7 => page.ReadUInt8(offset + 2509); + public readonly byte QuestLockJoin => page.ReadUInt8(offset + 2510); + public readonly RowRef GrandCompany => new(page.Module, (uint)page.ReadUInt8(offset + 2514), page.Language); + public readonly byte InstanceContentJoin => page.ReadUInt8(offset + 2516); + public readonly RowRef BeastTribe => new(page.Module, (uint)page.ReadUInt8(offset + 2520), page.Language); + public bool IsRepeatable => page.ReadPackedBool(offset + 2535, 1); + + public readonly Collection> PreviousQuest => new(page, offset, offset, &PreviousQuestCtor, 3); + private static RowRef PreviousQuestCtor(ExcelPage page, uint parentOffset, uint offset, uint i) => new(page.Module, page.ReadUInt32(offset + 2424 + i * 4), page.Language); + + public readonly Collection> QuestLock => new(page, offset, offset, &QuestLockCtor, 2); + private static RowRef QuestLockCtor(ExcelPage page, uint parentOffset, uint offset, uint i) => new(page.Module, page.ReadUInt32(offset + 2436 + i * 4), page.Language); + + public readonly Collection ClassJobLevel => new(page, offset, offset, &ClassJobLevelCtor, 2); + private static ushort ClassJobLevelCtor(ExcelPage page, uint parentOffset, uint offset, uint i) => page.ReadUInt16(offset + 2484 + i * 2); + + public Collection> InstanceContent => new(page, offset, offset, &InstanceContentCtor, 3); + private static RowRef InstanceContentCtor(ExcelPage page, uint parentOffset, uint offset, uint i) => new(page.Module, page.ReadUInt32(offset + 2444 + i * 4), page.Language); + + static QuestEx IExcelRow.Create(ExcelPage page, uint offset, uint row) => + new(page, offset, row); +} diff --git a/Questionable/Data/TerritoryData.cs b/Questionable/Data/TerritoryData.cs index e2d471c3..ee91f6b4 100644 --- a/Questionable/Data/TerritoryData.cs +++ b/Questionable/Data/TerritoryData.cs @@ -4,7 +4,7 @@ using System.Globalization; using System.Linq; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.Character; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; namespace Questionable.Data; @@ -13,37 +13,37 @@ internal sealed class TerritoryData private readonly ImmutableDictionary _territoryNames; private readonly ImmutableHashSet _territoriesWithMount; private readonly ImmutableDictionary _dutyTerritories; - private readonly ImmutableDictionary _instanceNames; + private readonly ImmutableDictionary _instanceNames; private readonly ImmutableDictionary _contentFinderConditionNames; public TerritoryData(IDataManager dataManager) { - _territoryNames = dataManager.GetExcelSheet()! + _territoryNames = dataManager.GetExcelSheet() .Where(x => x.RowId > 0) .Select(x => new { x.RowId, - Name = x.PlaceName.Value?.Name?.ToString() ?? x.PlaceNameZone?.Value?.Name?.ToString(), + Name = x.PlaceName.ValueNullable?.Name.ToString() ?? x.PlaceNameZone.ValueNullable?.Name.ToString(), }) .Where(x => !string.IsNullOrEmpty(x.Name)) .ToImmutableDictionary(x => x.RowId, x => x.Name!); - _territoriesWithMount = dataManager.GetExcelSheet()! + _territoriesWithMount = dataManager.GetExcelSheet() .Where(x => x.RowId > 0 && x.Mount) .Select(x => (ushort)x.RowId) .ToImmutableHashSet(); - _dutyTerritories = dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0 && x.ContentFinderCondition.Row != 0) - .ToImmutableDictionary(x => (ushort)x.RowId, x => x.ContentFinderCondition.Value!.ContentType.Row); + _dutyTerritories = dataManager.GetExcelSheet() + .Where(x => x.RowId > 0 && x.ContentFinderCondition.RowId != 0) + .ToImmutableDictionary(x => (ushort)x.RowId, x => x.ContentFinderCondition.Value.ContentType.RowId); - _instanceNames = dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6) - .ToImmutableDictionary(x => x.Content, x => x.Name.ToString()); + _instanceNames = dataManager.GetExcelSheet() + .Where(x => x.RowId > 0 && x.Content.RowId != 0 && x.ContentLinkType == 1 && x.ContentType.RowId != 6) + .ToImmutableDictionary(x => x.Content.RowId, x => x.Name.ToString()); - _contentFinderConditionNames = dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6) + _contentFinderConditionNames = dataManager.GetExcelSheet() + .Where(x => x.RowId > 0 && x.Content.RowId != 0 && x.ContentLinkType == 1 && x.ContentType.RowId != 6) .ToImmutableDictionary(x => x.RowId, x => x.Name.ToString()); } diff --git a/Questionable/Functions/AetheryteFunctions.cs b/Questionable/Functions/AetheryteFunctions.cs index afdedf4d..65b075d0 100644 --- a/Questionable/Functions/AetheryteFunctions.cs +++ b/Questionable/Functions/AetheryteFunctions.cs @@ -1,14 +1,12 @@ using System; -using System.Linq; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.UI; -using Lumina.Excel.GeneratedSheets; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Questionable.Model.Common; using Questionable.Model.Questing; -using Action = Lumina.Excel.GeneratedSheets.Action; +using Action = Lumina.Excel.Sheets.Action; namespace Questionable.Functions; @@ -57,9 +55,10 @@ internal sealed unsafe class AetheryteFunctions public bool IsTeleportUnlocked() { - uint unlockLink = _dataManager.GetExcelSheet()! - .GetRow(5)! - .UnlockLink; + uint unlockLink = _dataManager.GetExcelSheet() + .GetRow(5) + .UnlockLink + .RowId; return UIState.Instance()->IsUnlockLinkUnlocked(unlockLink); } diff --git a/Questionable/Functions/ChatFunctions.cs b/Questionable/Functions/ChatFunctions.cs index 5c31e4d8..d53ed9be 100644 --- a/Questionable/Functions/ChatFunctions.cs +++ b/Questionable/Functions/ChatFunctions.cs @@ -12,7 +12,7 @@ using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.System.Framework; using FFXIVClientStructs.FFXIV.Client.System.Memory; using FFXIVClientStructs.FFXIV.Client.System.String; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Model.Questing; @@ -41,11 +41,11 @@ internal sealed unsafe class ChatFunctions _sanitiseString = (delegate* unmanaged)sigScanner.ScanText(Signatures.SanitiseString); - _emoteCommands = dataManager.GetExcelSheet()! + _emoteCommands = dataManager.GetExcelSheet() .Where(x => x.RowId > 0) - .Where(x => x.TextCommand != null && x.TextCommand.Value != null) - .Select(x => (x.RowId, Command: x.TextCommand.Value!.Command?.ToString())) - .Where(x => x.Command != null && x.Command.StartsWith('/')) + .Where(x => x.TextCommand.IsValid) + .Select(x => (x.RowId, Command: x.TextCommand.Value.Command.ToString())) + .Where(x => !string.IsNullOrEmpty(x.Command) && x.Command.StartsWith('/')) .ToDictionary(x => (EEmote)x.RowId, x => x.Command!) .AsReadOnly(); } @@ -156,8 +156,8 @@ internal sealed unsafe class ChatFunctions private static class Signatures { - internal const string SendChat = "48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9"; - internal const string SanitiseString = "E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 0F B6 F0 E8 ?? ?? ?? ?? 48 8D 4D C0"; + internal const string SendChat = "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F2 48 8B F9 45 84 C9"; + internal const string SanitiseString = "E8 ?? ?? ?? ?? EB 0A 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8D AE"; } [StructLayout(LayoutKind.Explicit)] diff --git a/Questionable/Functions/ExcelFunctions.cs b/Questionable/Functions/ExcelFunctions.cs index e1278a59..2043c5a6 100644 --- a/Questionable/Functions/ExcelFunctions.cs +++ b/Questionable/Functions/ExcelFunctions.cs @@ -3,13 +3,13 @@ using System.Linq; using Dalamud.Plugin.Services; using Dalamud.Utility; using LLib; -using Lumina.Excel.CustomSheets; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Lumina.Text; +using Lumina.Text.ReadOnly; using Microsoft.Extensions.Logging; using Questionable.Model; using Quest = Questionable.Model.Quest; -using GimmickYesNo = Lumina.Excel.GeneratedSheets2.GimmickYesNo; +using GimmickYesNo = Lumina.Excel.Sheets.GimmickYesNo; namespace Questionable.Functions; @@ -33,12 +33,12 @@ internal sealed class ExcelFunctions return new StringOrRegex(seString?.ToDalamudString().ToString()); } - public SeString? GetRawDialogueText(Quest? currentQuest, string? excelSheetName, string key) + public ReadOnlySeString? GetRawDialogueText(Quest? currentQuest, string? excelSheetName, string key) { if (currentQuest != null && excelSheetName == null) { var questRow = - _dataManager.GetExcelSheet()!.GetRow((uint)currentQuest.Id.Value + + _dataManager.GetExcelSheet().GetRowOrDefault((uint)currentQuest.Id.Value + 0x10000); if (questRow == null) { @@ -46,18 +46,13 @@ internal sealed class ExcelFunctions return null; } - excelSheetName = $"quest/{(currentQuest.Id.Value / 100):000}/{questRow.Id}"; + excelSheetName = $"quest/{(currentQuest.Id.Value / 100):000}/{questRow.Value.RowId}"; } ArgumentNullException.ThrowIfNull(excelSheetName); - var excelSheet = _dataManager.Excel.GetSheet(excelSheetName); - if (excelSheet == null) - { - _logger.LogError("Unknown excel sheet '{SheetName}'", excelSheetName); - return null; - } - - return excelSheet.FirstOrDefault(x => x.Key == key)?.Value; + var excelSheet = _dataManager.GetExcelSheet(name: excelSheetName); + return excelSheet.Cast() + .FirstOrDefault(x => x!.Value.Key == key)?.Value; } public StringOrRegex GetDialogueTextByRowId(string? excelSheet, uint rowId, bool isRegex) @@ -69,36 +64,36 @@ internal sealed class ExcelFunctions return new StringOrRegex(seString?.ToDalamudString().ToString()); } - public SeString? GetRawDialogueTextByRowId(string? excelSheet, uint rowId) + public ReadOnlySeString? GetRawDialogueTextByRowId(string? excelSheet, uint rowId) { if (excelSheet == "GimmickYesNo") { - var questRow = _dataManager.GetExcelSheet()!.GetRow(rowId); + var questRow = _dataManager.GetExcelSheet().GetRowOrDefault(rowId); return questRow?.Unknown0; } else if (excelSheet == "Warp") { - var questRow = _dataManager.GetExcelSheet()!.GetRow(rowId); + var questRow = _dataManager.GetExcelSheet().GetRowOrDefault(rowId); return questRow?.Name; } else if (excelSheet is "Addon") { - var questRow = _dataManager.GetExcelSheet()!.GetRow(rowId); + var questRow = _dataManager.GetExcelSheet().GetRowOrDefault(rowId); return questRow?.Text; } else if (excelSheet is "EventPathMove") { - var questRow = _dataManager.GetExcelSheet()!.GetRow(rowId); - return questRow?.Unknown10; + var questRow = _dataManager.GetExcelSheet().GetRowOrDefault(rowId); + return questRow?.Unknown0; } else if (excelSheet is "GilShop") { - var questRow = _dataManager.GetExcelSheet()!.GetRow(rowId); + var questRow = _dataManager.GetExcelSheet().GetRowOrDefault(rowId); return questRow?.Name; } else if (excelSheet is "ContentTalk" or null) { - var questRow = _dataManager.GetExcelSheet()!.GetRow(rowId); + var questRow = _dataManager.GetExcelSheet().GetRowOrDefault(rowId); return questRow?.Text; } else diff --git a/Questionable/Functions/GameFunctions.cs b/Questionable/Functions/GameFunctions.cs index bb0313ae..d4a7e692 100644 --- a/Questionable/Functions/GameFunctions.cs +++ b/Questionable/Functions/GameFunctions.cs @@ -14,23 +14,22 @@ using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; using LLib.GameUI; +using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Model; -using Questionable.Model.Common; using Questionable.Model.Questing; -using Action = Lumina.Excel.GeneratedSheets2.Action; +using Action = Lumina.Excel.Sheets.Action; using BattleChara = FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara; -using ContentFinderCondition = Lumina.Excel.GeneratedSheets.ContentFinderCondition; +using ContentFinderCondition = Lumina.Excel.Sheets.ContentFinderCondition; using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind; using Quest = Questionable.Model.Quest; -using TerritoryType = Lumina.Excel.GeneratedSheets.TerritoryType; namespace Questionable.Functions; internal sealed unsafe class GameFunctions { private readonly ReadOnlyDictionary _territoryToAetherCurrentCompFlgSet; - private readonly ReadOnlyDictionary _contentFinderConditionToContentId; + private readonly ReadOnlyDictionary _contentFinderConditionToContentId; private readonly QuestFunctions _questFunctions; private readonly IDataManager _dataManager; @@ -63,14 +62,15 @@ internal sealed unsafe class GameFunctions _configuration = configuration; _logger = logger; - _territoryToAetherCurrentCompFlgSet = dataManager.GetExcelSheet()! + _territoryToAetherCurrentCompFlgSet = dataManager.GetExcelSheet() .Where(x => x.RowId > 0) - .Where(x => x.Unknown32 > 0) - .ToDictionary(x => (ushort)x.RowId, x => x.Unknown32) + .Where(x => x.Unknown3 > 0) + .ToDictionary(x => (ushort)x.RowId, x => x.Unknown4) .AsReadOnly(); - _contentFinderConditionToContentId = dataManager.GetExcelSheet()! - .Where(x => x.RowId > 0 && x.Content > 0) - .ToDictionary(x => x.RowId, x => x.Content) + _territoryToAetherCurrentCompFlgSet = new Dictionary().AsReadOnly(); + _contentFinderConditionToContentId = dataManager.GetExcelSheet() + .Where(x => x.RowId > 0 && x.Content.RowId > 0) + .ToDictionary(x => x.RowId, x => x.Content.RowId) .AsReadOnly(); } @@ -220,7 +220,7 @@ internal sealed unsafe class GameFunctions public bool UseAction(IGameObject gameObject, EAction action, bool checkCanUse = true) { - var actionRow = _dataManager.GetExcelSheet()!.GetRow((uint)action)!; + var actionRow = _dataManager.GetExcelSheet().GetRow((uint)action); if (checkCanUse && !ActionManager.CanUseActionOnTarget((uint)action, (GameObject*)gameObject.Address)) { _logger.LogWarning("Can not use action {Action} on target {Target}", action, gameObject); @@ -378,7 +378,7 @@ internal sealed unsafe class GameFunctions public void OpenDutyFinder(uint contentFinderConditionId) { - if (_contentFinderConditionToContentId.TryGetValue(contentFinderConditionId, out ushort contentId)) + if (_contentFinderConditionToContentId.TryGetValue(contentFinderConditionId, out uint contentId)) { if (UIState.IsInstanceContentUnlocked(contentId)) AgentContentsFinder.Instance()->OpenRegularDuty(contentFinderConditionId); diff --git a/Questionable/Functions/QuestFunctions.cs b/Questionable/Functions/QuestFunctions.cs index b0a92395..9211514d 100644 --- a/Questionable/Functions/QuestFunctions.cs +++ b/Questionable/Functions/QuestFunctions.cs @@ -11,7 +11,7 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; using LLib.GameData; using LLib.GameUI; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Questionable.Controller; using Questionable.Controller.Steps.Interactions; using Questionable.Data; @@ -311,8 +311,8 @@ internal sealed unsafe class QuestFunctions ..QuestData.CrystalTowerQuests ]; - EClassJob classJob = (EClassJob?)_clientState.LocalPlayer?.ClassJob.Id ?? EClassJob.Adventurer; - ushort[] shadowbringersRoleQuestChapters = QuestData.AllRoleQuestChapters.Select(x => x[0]).ToArray(); + EClassJob classJob = (EClassJob?)_clientState.LocalPlayer?.ClassJob.RowId ?? EClassJob.Adventurer; + uint[] shadowbringersRoleQuestChapters = QuestData.AllRoleQuestChapters.Select(x => x[0]).ToArray(); if (classJob != EClassJob.Adventurer) { priorityQuests.AddRange(_questRegistry.GetKnownClassJobQuests(classJob) @@ -460,7 +460,7 @@ internal sealed unsafe class QuestFunctions // this only checks for the current class IQuestInfo questInfo = _questData.GetQuestInfo(leveId); - if (!questInfo.ClassJobs.Contains((EClassJob)_clientState.LocalPlayer!.ClassJob.Id) || + if (!questInfo.ClassJobs.Contains((EClassJob)_clientState.LocalPlayer!.ClassJob.RowId) || questInfo.Level > _clientState.LocalPlayer.Level) return true; @@ -597,7 +597,7 @@ internal sealed unsafe class QuestFunctions public bool IsClassJobUnlocked(EClassJob classJob) { var classJobRow = _dataManager.GetExcelSheet()!.GetRow((uint)classJob)!; - var questId = (ushort)classJobRow.UnlockQuest.Row; + var questId = (ushort)classJobRow.UnlockQuest.RowId; if (questId != 0) return IsQuestComplete(new QuestId(questId)); @@ -608,7 +608,7 @@ internal sealed unsafe class QuestFunctions public bool IsJobUnlocked(EClassJob classJob) { var classJobRow = _dataManager.GetExcelSheet()!.GetRow((uint)classJob)!; - return IsClassJobUnlocked((EClassJob)classJobRow.ClassJobParent.Row); + return IsClassJobUnlocked((EClassJob)classJobRow.ClassJobParent.RowId); } public GrandCompany GetGrandCompany() diff --git a/Questionable/Model/LeveInfo.cs b/Questionable/Model/LeveInfo.cs index 14878f71..21eaf552 100644 --- a/Questionable/Model/LeveInfo.cs +++ b/Questionable/Model/LeveInfo.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using LLib.GameData; -using Lumina.Excel.GeneratedSheets2; +using Lumina.Excel.Sheets; using Questionable.Model.Questing; namespace Questionable.Model; @@ -11,13 +11,13 @@ internal sealed class LeveInfo : IQuestInfo public LeveInfo(Leve leve) { QuestId = new LeveId((ushort)leve.RowId); - Name = leve.Name; + Name = leve.Name.ToString(); Level = leve.ClassJobLevel; - JournalGenre = leve.JournalGenre.Row; + JournalGenre = leve.JournalGenre.RowId; SortKey = QuestId.Value; - IssuerDataId = leve.LevelLevemete.Value!.Object.Row; - ClassJobs = QuestInfoUtils.AsList(leve.ClassJobCategory.Value!); - Expansion = (EExpansionVersion)leve.LevelLevemete.Value.Territory.Value!.ExVersion.Row; + IssuerDataId = leve.LevelLevemete.Value.Object.RowId; + ClassJobs = QuestInfoUtils.AsList(leve.ClassJobCategory.Value); + Expansion = (EExpansionVersion)leve.LevelLevemete.Value.Territory.Value.ExVersion.RowId; } public ElementId QuestId { get; } diff --git a/Questionable/Model/QuestInfo.cs b/Questionable/Model/QuestInfo.cs index 6149209a..cca29890 100644 --- a/Questionable/Model/QuestInfo.cs +++ b/Questionable/Model/QuestInfo.cs @@ -3,16 +3,15 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using FFXIVClientStructs.FFXIV.Client.UI.Agent; -using JetBrains.Annotations; using LLib.GameData; +using Questionable.Data.Sheets; using Questionable.Model.Questing; -using ExcelQuest = Lumina.Excel.GeneratedSheets2.Quest; namespace Questionable.Model; internal sealed class QuestInfo : IQuestInfo { - public QuestInfo(ExcelQuest quest, ushort newGamePlusChapter, byte startingCity) + public QuestInfo(QuestEx quest, uint newGamePlusChapter, byte startingCity) { QuestId = new QuestId((ushort)(quest.RowId & 0xFFFF)); @@ -34,38 +33,38 @@ internal sealed class QuestInfo : IQuestInfo _ => "", }; - Name = $"{quest.Name}{suffix}"; + Name = $"{quest.Original.Name}{suffix}"; Level = quest.ClassJobLevel[0]; - IssuerDataId = quest.IssuerStart.Row; + IssuerDataId = quest.IssuerStart.RowId; IsRepeatable = quest.IsRepeatable; PreviousQuests = new List { - new(new QuestId((ushort)(quest.PreviousQuest[0].Row & 0xFFFF)), quest.Unknown7), - new(new QuestId((ushort)(quest.PreviousQuest[1].Row & 0xFFFF))), - new(new QuestId((ushort)(quest.PreviousQuest[2].Row & 0xFFFF))) + new(new QuestId((ushort)(quest.PreviousQuest[0].RowId & 0xFFFF)), quest.Unknown7), + new(new QuestId((ushort)(quest.PreviousQuest[1].RowId & 0xFFFF))), + new(new QuestId((ushort)(quest.PreviousQuest[2].RowId & 0xFFFF))) } .Where(x => x.QuestId.Value != 0) .ToImmutableList(); PreviousQuestJoin = (EQuestJoin)quest.PreviousQuestJoin; QuestLocks = quest.QuestLock - .Select(x => new QuestId((ushort)(x.Row & 0xFFFFF))) + .Select(x => new QuestId((ushort)(x.RowId & 0xFFFFF))) .Where(x => x.Value != 0) .ToImmutableList(); QuestLockJoin = (EQuestJoin)quest.QuestLockJoin; - JournalGenre = quest.JournalGenre?.Row; + JournalGenre = quest.JournalGenre.ValueNullable?.RowId; SortKey = quest.SortKey; - IsMainScenarioQuest = quest.JournalGenre?.Value?.JournalCategory?.Value?.JournalSection?.Row is 0 or 1; - CompletesInstantly = quest.TodoParams[0].ToDoCompleteSeq == 0; - PreviousInstanceContent = quest.InstanceContent.Select(x => (ushort)x.Row).Where(x => x != 0).ToList(); + IsMainScenarioQuest = quest.JournalGenre.ValueNullable?.JournalCategory.ValueNullable?.JournalSection.ValueNullable?.RowId is 0 or 1; + CompletesInstantly = quest.Original.TodoParams[0].ToDoCompleteSeq == 0; + PreviousInstanceContent = quest.InstanceContent.Select(x => (ushort)x.RowId).Where(x => x != 0).ToList(); PreviousInstanceContentJoin = (EQuestJoin)quest.InstanceContentJoin; - GrandCompany = (GrandCompany)quest.GrandCompany.Row; - AlliedSociety = (EAlliedSociety)quest.BeastTribe.Row; - ClassJobs = QuestInfoUtils.AsList(quest.ClassJobCategory0.Value!); - IsSeasonalEvent = quest.Festival.Row != 0; + GrandCompany = (GrandCompany)quest.GrandCompany.RowId; + AlliedSociety = (EAlliedSociety)quest.BeastTribe.RowId; + ClassJobs = QuestInfoUtils.AsList(quest.ClassJobCategory0.ValueNullable!); + IsSeasonalEvent = quest.Festival.RowId != 0; NewGamePlusChapter = newGamePlusChapter; StartingCity = startingCity; - Expansion = (EExpansionVersion)quest.Expansion.Row; + Expansion = (EExpansionVersion)quest.Expansion.RowId; } @@ -88,7 +87,7 @@ internal sealed class QuestInfo : IQuestInfo public EAlliedSociety AlliedSociety { get; } public IReadOnlyList ClassJobs { get; } public bool IsSeasonalEvent { get; } - public ushort NewGamePlusChapter { get; } + public uint NewGamePlusChapter { get; } public byte StartingCity { get; set; } public EExpansionVersion Expansion { get; } diff --git a/Questionable/Model/QuestInfoUtils.cs b/Questionable/Model/QuestInfoUtils.cs index 4f44fd4a..c22415bf 100644 --- a/Questionable/Model/QuestInfoUtils.cs +++ b/Questionable/Model/QuestInfoUtils.cs @@ -1,7 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using LLib.GameData; -using Lumina.Excel.GeneratedSheets2; +using Lumina.Excel.Sheets; namespace Questionable.Model; @@ -9,8 +10,12 @@ internal static class QuestInfoUtils { private static readonly Dictionary> CachedClassJobs = new(); - internal static IReadOnlyList AsList(ClassJobCategory classJobCategory) + internal static IReadOnlyList AsList(ClassJobCategory? optionalClassJobCategory) { + if (optionalClassJobCategory == null) + return Enum.GetValues(); + + ClassJobCategory classJobCategory = optionalClassJobCategory.Value; if (CachedClassJobs.TryGetValue(classJobCategory.RowId, out IReadOnlyList? classJobs)) return classJobs; @@ -57,8 +62,8 @@ internal static class QuestInfoUtils { EClassJob.Dancer, classJobCategory.DNC }, { EClassJob.Reaper, classJobCategory.RPR }, { EClassJob.Sage, classJobCategory.SGE }, - { EClassJob.Viper, classJobCategory.Unknown1 }, - { EClassJob.Pictomancer, classJobCategory.Unknown2 } + { EClassJob.Viper, classJobCategory.VPR }, + { EClassJob.Pictomancer, classJobCategory.PCT } } .Where(y => y.Value) .Select(y => y.Key) diff --git a/Questionable/Model/SatisfactionSupplyInfo.cs b/Questionable/Model/SatisfactionSupplyInfo.cs index 41f6d5e2..e2c25ad8 100644 --- a/Questionable/Model/SatisfactionSupplyInfo.cs +++ b/Questionable/Model/SatisfactionSupplyInfo.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using LLib.GameData; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Questionable.Model.Questing; namespace Questionable.Model; @@ -11,12 +11,12 @@ internal sealed class SatisfactionSupplyInfo : IQuestInfo public SatisfactionSupplyInfo(SatisfactionNpc npc) { QuestId = new SatisfactionSupplyNpcId((ushort)npc.RowId); - Name = npc.Npc.Value!.Singular; - IssuerDataId = npc.Npc.Row; + Name = npc.Npc.Value.Singular.ToString(); + IssuerDataId = npc.Npc.RowId; Level = npc.LevelUnlock; SortKey = QuestId.Value; - Expansion = (EExpansionVersion)npc.QuestRequired.Value!.Expansion.Row; - PreviousQuests = [new PreviousQuestInfo(new QuestId((ushort)(npc.QuestRequired.Row & 0xFFFF)))]; + Expansion = (EExpansionVersion)npc.QuestRequired.Value!.Expansion.RowId; + PreviousQuests = [new PreviousQuestInfo(new QuestId((ushort)(npc.QuestRequired.RowId & 0xFFFF)))]; } public ElementId QuestId { get; } diff --git a/Questionable/Questionable.csproj b/Questionable/Questionable.csproj index 64df5619..6d44ba06 100644 --- a/Questionable/Questionable.csproj +++ b/Questionable/Questionable.csproj @@ -1,4 +1,4 @@ - + dist $(SolutionDir)=X:\ diff --git a/Questionable/Windows/ConfigWindow.cs b/Questionable/Windows/ConfigWindow.cs index 7bcd7681..97847de5 100644 --- a/Questionable/Windows/ConfigWindow.cs +++ b/Questionable/Windows/ConfigWindow.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Dalamud.Game.Text; @@ -10,7 +11,7 @@ using Dalamud.Plugin.Services; using Dalamud.Utility; using ImGuiNET; using LLib.ImGui; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Questionable.External; using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany; @@ -36,7 +37,7 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig _notificationMasterIpc = notificationMasterIpc; _configuration = configuration; - var mounts = dataManager.GetExcelSheet()! + var mounts = dataManager.GetExcelSheet() .Where(x => x is { RowId: > 0, Icon: > 0 }) .Select(x => (MountId: x.RowId, Name: x.Singular.ToString())) .Where(x => !string.IsNullOrEmpty(x.Name)) diff --git a/Questionable/Windows/JournalComponents/GatheringJournalComponent.cs b/Questionable/Windows/JournalComponents/GatheringJournalComponent.cs index 81588465..53b1576e 100644 --- a/Questionable/Windows/JournalComponents/GatheringJournalComponent.cs +++ b/Questionable/Windows/JournalComponents/GatheringJournalComponent.cs @@ -10,7 +10,7 @@ using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using ImGuiNET; using LLib.GameData; -using Lumina.Excel.GeneratedSheets; +using Lumina.Excel.Sheets; using Questionable.Controller; using Questionable.Model; using Questionable.Model.Gathering; @@ -44,24 +44,24 @@ internal sealed class GatheringJournalComponent _gatheringPointRegistry = gatheringPointRegistry; // TODO some of the logic here would be better suited elsewhere, in particular the [item] → [gathering item] → [location] lookup - var routeToGatheringPoint = dataManager.GetExcelSheet()! - .Where(x => x.UnkData0[0].GatheringPoint != 0) - .SelectMany(x => x.UnkData0 - .Where(y => y.GatheringPoint != 0) + var routeToGatheringPoint = dataManager.GetExcelSheet() + .Where(x => x.GatheringPoint[0].RowId != 0) + .SelectMany(x => x.GatheringPoint + .Where(y => y.RowId != 0) .Select(y => new { RouteId = x.RowId, - GatheringPointId = y.GatheringPoint + GatheringPointId = y.RowId })) .GroupBy(x => x.RouteId) .ToDictionary(x => x.Key, x => x.Select(y => y.GatheringPointId).ToList()); - var gatheringLeveSheet = dataManager.GetExcelSheet()!; - var territoryTypeSheet = dataManager.GetExcelSheet()!; - var gatheringPointToLeve = dataManager.GetExcelSheet()! + var gatheringLeveSheet = dataManager.GetExcelSheet(); + var territoryTypeSheet = dataManager.GetExcelSheet(); + var gatheringPointToLeve = dataManager.GetExcelSheet() .Where(x => x.RowId > 0) .Select(x => { - uint startZonePlaceName = x.PlaceNameStartZone.Row; + uint startZonePlaceName = x.PlaceNameStartZone.RowId; startZonePlaceName = startZonePlaceName switch { 27 => 28, // limsa @@ -71,16 +71,17 @@ internal sealed class GatheringJournalComponent _ => startZonePlaceName }; - var territoryType = territoryTypeSheet.FirstOrDefault(y => startZonePlaceName == y.PlaceName.Row) + var territoryType = territoryTypeSheet.Cast() + .FirstOrDefault(y => startZonePlaceName == y!.Value.PlaceName.RowId) ?? throw new InvalidOperationException($"Unable to use {startZonePlaceName}"); return new { LeveId = x.RowId, LeveName = x.Name.ToString(), TerritoryType = (ushort)territoryType.RowId, - TerritoryName = territoryType.PlaceName.Value?.Name.ToString(), - Expansion = (EExpansionVersion)territoryType.ExVersion.Row, - GatheringLeve = gatheringLeveSheet.GetRow((uint)x.DataId), + TerritoryName = territoryType.PlaceName.ValueNullable?.Name.ToString(), + Expansion = (EExpansionVersion)territoryType.ExVersion.RowId, + GatheringLeve = gatheringLeveSheet.GetRowOrDefault(x.DataId.RowId), }; }) .Where(x => x.GatheringLeve != null) @@ -91,9 +92,9 @@ internal sealed class GatheringJournalComponent x.TerritoryType, x.TerritoryName, x.Expansion, - GatheringPoints = x.GatheringLeve!.Route - .Where(y => y.Row != 0) - .SelectMany(y => routeToGatheringPoint[y.Row]), + GatheringPoints = x.GatheringLeve!.Value.Route + .Where(y => y.RowId != 0) + .SelectMany(y => routeToGatheringPoint[y.RowId]), }) .SelectMany(x => x.GatheringPoints.Select(y => new { @@ -110,40 +111,40 @@ internal sealed class GatheringJournalComponent var itemSheet = dataManager.GetExcelSheet()!; _gatheringItems = dataManager.GetExcelSheet()! - .Where(x => x.RowId != 0 && x.GatheringItemLevel.Row != 0) + .Where(x => x.RowId != 0 && x.GatheringItemLevel.RowId != 0) .Select(x => new { GatheringItemId = (int)x.RowId, - Name = itemSheet.GetRow((uint)x.Item)?.Name.ToString() + Name = itemSheet.GetRowOrDefault(x.Item.RowId)?.Name.ToString() }) .Where(x => !string.IsNullOrEmpty(x.Name)) .ToDictionary(x => x.GatheringItemId, x => x.Name!); _gatheringPointsByExpansion = dataManager.GetExcelSheet()! - .Where(x => x.GatheringPointBase.Row != 0) - .Where(x => x.GatheringPointBase.Row is < 653 or > 680) // exclude ishgard restoration phase 1 - .DistinctBy(x => x.GatheringPointBase.Row) + .Where(x => x.GatheringPointBase.RowId != 0) + .Where(x => x.GatheringPointBase.RowId is < 653 or > 680) // exclude ishgard restoration phase 1 + .DistinctBy(x => x.GatheringPointBase.RowId) .Select(x => new { GatheringPointId = x.RowId, - Point = new DefaultGatheringPoint(new GatheringPointId((ushort)x.GatheringPointBase.Row), - x.GatheringPointBase.Value!.GatheringType.Row switch + Point = new DefaultGatheringPoint(new GatheringPointId((ushort)x.GatheringPointBase.RowId), + x.GatheringPointBase.Value!.GatheringType.RowId switch { 0 or 1 => EClassJob.Miner, 2 or 3 => EClassJob.Botanist, _ => EClassJob.Fisher }, x.GatheringPointBase.Value.GatheringLevel, - x.GatheringPointBase.Value.Item.Where(y => y != 0).Select(y => (ushort)y).ToList(), - (EExpansionVersion?)x.TerritoryType.Value?.ExVersion.Row ?? (EExpansionVersion)byte.MaxValue, - (ushort)x.TerritoryType.Row, - x.TerritoryType.Value?.PlaceName.Value?.Name.ToString(), - $"{x.GatheringPointBase.Row} - {x.PlaceName.Value?.Name}") + x.GatheringPointBase.Value.Item.Where(y => y.RowId != 0).Select(y => (ushort)y.RowId).ToList(), + (EExpansionVersion?)x.TerritoryType.ValueNullable?.ExVersion.RowId ?? (EExpansionVersion)byte.MaxValue, + (ushort)x.TerritoryType.RowId, + x.TerritoryType.ValueNullable?.PlaceName.ValueNullable?.Name.ToString(), + $"{x.GatheringPointBase.RowId} - {x.PlaceName.ValueNullable?.Name}") }) .Where(x => x.Point.ClassJob != EClassJob.Fisher) .Select(x => { - if (gatheringPointToLeve.TryGetValue((int)x.GatheringPointId, out var leve)) + if (gatheringPointToLeve.TryGetValue(x.GatheringPointId, out var leve)) { // it's a leve return x.Point with @@ -161,9 +162,9 @@ internal sealed class GatheringJournalComponent var territoryType = territoryTypeSheet.GetRow(gatheringRoot.Steps.Last().TerritoryId)!; return x.Point with { - Expansion = (EExpansionVersion)territoryType.ExVersion.Row, + Expansion = (EExpansionVersion)territoryType.ExVersion.RowId, TerritoryType = (ushort)territoryType.RowId, - TerritoryName = territoryType.PlaceName.Value?.Name.ToString(), + TerritoryName = territoryType.PlaceName.ValueNullable?.Name.ToString(), }; } else @@ -429,7 +430,7 @@ internal sealed class GatheringJournalComponent } } - public void ClearCounts() + public void ClearCounts(int type, int code) { foreach (var expansion in _gatheringPointsByExpansion) { diff --git a/Questionable/Windows/JournalComponents/QuestJournalComponent.cs b/Questionable/Windows/JournalComponents/QuestJournalComponent.cs index f273b00d..36565fdf 100644 --- a/Questionable/Windows/JournalComponents/QuestJournalComponent.cs +++ b/Questionable/Windows/JournalComponents/QuestJournalComponent.cs @@ -368,7 +368,7 @@ internal sealed class QuestJournalComponent } } - internal void ClearCounts() + internal void ClearCounts(int type, int code) { foreach (var genreCount in _genreCounts.ToList()) _genreCounts[genreCount.Key] = genreCount.Value with { Completed = 0 }; diff --git a/Questionable/Windows/QuestWindow.cs b/Questionable/Windows/QuestWindow.cs index 1deaf934..4c100a1b 100644 --- a/Questionable/Windows/QuestWindow.cs +++ b/Questionable/Windows/QuestWindow.cs @@ -67,7 +67,7 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig #endif SizeConstraints = new WindowSizeConstraints { - MinimumSize = new Vector2(200, 30), + MinimumSize = new Vector2(230, 30), MaximumSize = default }; RespectCloseHotkey = false; diff --git a/vendor/ECommons b/vendor/ECommons index 147e12e9..71ee09f7 160000 --- a/vendor/ECommons +++ b/vendor/ECommons @@ -1 +1 @@ -Subproject commit 147e12e95f2fb781f2c8ddac31d948700ed9051c +Subproject commit 71ee09f7cc2230a73503b945422760da1368405c