From: Liza Carvelli Date: Mon, 10 Mar 2025 16:54:19 +0000 (+0100) Subject: Add GatheringLocation ExtraQuestItems to configure extra items that aren't in the... X-Git-Tag: v4.25~3 X-Git-Url: https://git.jacobcasper.com/?a=commitdiff_plain;h=cd18f0dc3fd433926f88d234b80800110cd317e1;p=Questionable.git Add GatheringLocation ExtraQuestItems to configure extra items that aren't in the sheets --- diff --git a/GatheringPaths/gatheringlocation-v1.json b/GatheringPaths/gatheringlocation-v1.json index 0a821158..3c781fbe 100644 --- a/GatheringPaths/gatheringlocation-v1.json +++ b/GatheringPaths/gatheringlocation-v1.json @@ -31,6 +31,14 @@ "type": "boolean", "default": true }, + "ExtraQuestItems": { + "description": "Some quests (such as Ixal) add quest items to gathering nodes, but there's no clear connection between the item and the node in the sheets", + "type": "array", + "items": { + "type": "integer", + "minimum": 2000000 + } + }, "Groups": { "type": "array", "items": { diff --git a/QuestPathGenerator/GatheringSourceGenerator.cs b/QuestPathGenerator/GatheringSourceGenerator.cs index cf1dd6f0..cefc63e7 100644 --- a/QuestPathGenerator/GatheringSourceGenerator.cs +++ b/QuestPathGenerator/GatheringSourceGenerator.cs @@ -164,6 +164,7 @@ public class GatheringSourceGenerator : ISourceGenerator Assignment(nameof(GatheringRoot.FlyBetweenNodes), root.FlyBetweenNodes, emptyRoot.FlyBetweenNodes) .AsSyntaxNodeOrToken(), + AssignmentList(nameof(GatheringRoot.ExtraQuestItems), root.ExtraQuestItems).AsSyntaxNodeOrToken(), AssignmentList(nameof(GatheringRoot.Groups), root.Groups).AsSyntaxNodeOrToken())))); } catch (Exception e) diff --git a/Questionable.Model/Gathering/GatheringRoot.cs b/Questionable.Model/Gathering/GatheringRoot.cs index 52da35eb..77383d6d 100644 --- a/Questionable.Model/Gathering/GatheringRoot.cs +++ b/Questionable.Model/Gathering/GatheringRoot.cs @@ -14,5 +14,6 @@ public sealed class GatheringRoot public List Steps { get; set; } = []; public bool? FlyBetweenNodes { get; set; } + public List ExtraQuestItems { get; set; } = []; public List Groups { get; set; } = []; } diff --git a/Questionable/Controller/ContextMenuController.cs b/Questionable/Controller/ContextMenuController.cs index 153dc2bf..68b982ba 100644 --- a/Questionable/Controller/ContextMenuController.cs +++ b/Questionable/Controller/ContextMenuController.cs @@ -21,6 +21,7 @@ internal sealed class ContextMenuController : IDisposable { private readonly IContextMenu _contextMenu; private readonly QuestController _questController; + private readonly GatheringPointRegistry _gatheringPointRegistry; private readonly GatheringData _gatheringData; private readonly QuestRegistry _questRegistry; private readonly QuestData _questData; @@ -34,6 +35,7 @@ internal sealed class ContextMenuController : IDisposable public ContextMenuController( IContextMenu contextMenu, QuestController questController, + GatheringPointRegistry gatheringPointRegistry, GatheringData gatheringData, QuestRegistry questRegistry, QuestData questData, @@ -46,6 +48,7 @@ internal sealed class ContextMenuController : IDisposable { _contextMenu = contextMenu; _questController = questController; + _gatheringPointRegistry = gatheringPointRegistry; _gatheringData = gatheringData; _questRegistry = questRegistry; _questData = questData; @@ -112,7 +115,7 @@ internal sealed class ContextMenuController : IDisposable if (classJob != currentClassJob && currentClassJob is EClassJob.Miner or EClassJob.Botanist) return; - if (!_gatheringData.TryGetGatheringPointId(itemId, classJob, out _)) + if (!_gatheringPointRegistry.TryGetGatheringPointId(itemId, classJob, out _)) { _logger.LogInformation("No gathering point found for {ClassJob}.", classJob); return; diff --git a/Questionable/Controller/GameUi/InteractionUiController.cs b/Questionable/Controller/GameUi/InteractionUiController.cs index 74b5fd4a..950f7059 100644 --- a/Questionable/Controller/GameUi/InteractionUiController.cs +++ b/Questionable/Controller/GameUi/InteractionUiController.cs @@ -37,7 +37,6 @@ internal sealed class InteractionUiController : IDisposable private readonly AetheryteFunctions _aetheryteFunctions; private readonly ExcelFunctions _excelFunctions; private readonly QuestController _questController; - private readonly GatheringData _gatheringData; private readonly GatheringPointRegistry _gatheringPointRegistry; private readonly QuestRegistry _questRegistry; private readonly QuestData _questData; @@ -61,7 +60,6 @@ internal sealed class InteractionUiController : IDisposable AetheryteFunctions aetheryteFunctions, ExcelFunctions excelFunctions, QuestController questController, - GatheringData gatheringData, GatheringPointRegistry gatheringPointRegistry, QuestRegistry questRegistry, QuestData questData, @@ -81,7 +79,6 @@ internal sealed class InteractionUiController : IDisposable _aetheryteFunctions = aetheryteFunctions; _excelFunctions = excelFunctions; _questController = questController; - _gatheringData = gatheringData; _gatheringPointRegistry = gatheringPointRegistry; _questRegistry = questRegistry; _questData = questData; @@ -791,7 +788,7 @@ internal sealed class InteractionUiController : IDisposable if (step != null && (step.TerritoryId != _clientState.TerritoryType || step.TargetTerritoryId == null) && step.InteractionType == EInteractionType.Gather) { - if (_gatheringData.TryGetGatheringPointId(step.ItemsToGather[0].ItemId, + if (_gatheringPointRegistry.TryGetGatheringPointId(step.ItemsToGather[0].ItemId, (EClassJob?)_clientState.LocalPlayer?.ClassJob.RowId ?? EClassJob.Adventurer, out GatheringPointId? gatheringPointId) && _gatheringPointRegistry.TryGetGatheringPoint(gatheringPointId, out GatheringRoot? root)) diff --git a/Questionable/Controller/GatheringPointRegistry.cs b/Questionable/Controller/GatheringPointRegistry.cs index 82042151..86043020 100644 --- a/Questionable/Controller/GatheringPointRegistry.cs +++ b/Questionable/Controller/GatheringPointRegistry.cs @@ -3,9 +3,12 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Linq; using System.Text.Json; using Dalamud.Plugin; +using LLib.GameData; using Microsoft.Extensions.Logging; +using Questionable.Data; using Questionable.GatheringPaths; using Questionable.Model; using Questionable.Model.Gathering; @@ -16,15 +19,19 @@ internal sealed class GatheringPointRegistry : IDisposable { private readonly IDalamudPluginInterface _pluginInterface; private readonly QuestRegistry _questRegistry; + private readonly GatheringData _gatheringData; private readonly ILogger _logger; private readonly Dictionary _gatheringPoints = new(); - public GatheringPointRegistry(IDalamudPluginInterface pluginInterface, QuestRegistry questRegistry, + public GatheringPointRegistry(IDalamudPluginInterface pluginInterface, + QuestRegistry questRegistry, + GatheringData gatheringData, ILogger logger) { _pluginInterface = pluginInterface; _questRegistry = questRegistry; + _gatheringData = gatheringData; _logger = logger; _questRegistry.Reloaded += OnReloaded; @@ -141,6 +148,38 @@ internal sealed class GatheringPointRegistry : IDisposable public bool TryGetGatheringPoint(GatheringPointId gatheringPointId, [NotNullWhen(true)] out GatheringRoot? gatheringRoot) => _gatheringPoints.TryGetValue(gatheringPointId, out gatheringRoot); + public bool TryGetGatheringPointId(uint itemId, EClassJob classJobId, + [NotNullWhen(true)] out GatheringPointId? gatheringPointId) + { + if (classJobId == EClassJob.Miner) + { + if (_gatheringData.TryGetMinerGatheringPointByItemId(itemId, out gatheringPointId)) + return true; + + gatheringPointId = _gatheringPoints + .Where(x => x.Value.ExtraQuestItems.Contains(itemId)) + .Select(x => x.Key) + .FirstOrDefault(x => _gatheringData.MinerGatheringPoints.Contains(x)); + return gatheringPointId != null; + } + else if (classJobId == EClassJob.Botanist) + { + if (_gatheringData.TryGetBotanistGatheringPointByItemId(itemId, out gatheringPointId)) + return true; + + gatheringPointId = _gatheringPoints + .Where(x => x.Value.ExtraQuestItems.Contains(itemId)) + .Select(x => x.Key) + .FirstOrDefault(x => _gatheringData.BotanistGatheringPoints.Contains(x)); + return gatheringPointId != null; + } + else + { + gatheringPointId = null; + return false; + } + } + public void Dispose() { _questRegistry.Reloaded -= OnReloaded; diff --git a/Questionable/Controller/Steps/Shared/Gather.cs b/Questionable/Controller/Steps/Shared/Gather.cs index 45c007c4..bc546559 100644 --- a/Questionable/Controller/Steps/Shared/Gather.cs +++ b/Questionable/Controller/Steps/Shared/Gather.cs @@ -38,7 +38,6 @@ internal static class Gather } internal sealed class DelayedGatheringExecutor( - GatheringData gatheringData, GatheringPointRegistry gatheringPointRegistry, TerritoryData territoryData, IClientState clientState, @@ -52,7 +51,7 @@ internal static class Gather public IEnumerable CreateExtraTasks() { EClassJob currentClassJob = (EClassJob)clientState.LocalPlayer!.ClassJob.RowId; - if (!gatheringData.TryGetGatheringPointId(Task.GatheredItem.ItemId, currentClassJob, + if (!gatheringPointRegistry.TryGetGatheringPointId(Task.GatheredItem.ItemId, currentClassJob, out GatheringPointId? gatheringPointId)) throw new TaskException($"No gathering point found for item {Task.GatheredItem.ItemId}"); diff --git a/Questionable/Data/GatheringData.cs b/Questionable/Data/GatheringData.cs index 41a6631b..105911d5 100644 --- a/Questionable/Data/GatheringData.cs +++ b/Questionable/Data/GatheringData.cs @@ -62,19 +62,14 @@ internal sealed class GatheringData .ToDictionary(x => x.ItemId, x => x.NpcId); } - public bool TryGetGatheringPointId(uint itemId, EClassJob classJobId, - [NotNullWhen(true)] out GatheringPointId? gatheringPointId) - { - if (classJobId == EClassJob.Miner) - return _minerGatheringPoints.TryGetValue(itemId, out gatheringPointId); - else if (classJobId == EClassJob.Botanist) - return _botanistGatheringPoints.TryGetValue(itemId, out gatheringPointId); - else - { - gatheringPointId = null; - return false; - } - } + public IEnumerable MinerGatheringPoints => _minerGatheringPoints.Values; + public IEnumerable BotanistGatheringPoints => _botanistGatheringPoints.Values; + + public bool TryGetMinerGatheringPointByItemId(uint itemId, [NotNullWhen(true)] out GatheringPointId? gatheringPointId) + => _minerGatheringPoints.TryGetValue(itemId, out gatheringPointId); + + public bool TryGetBotanistGatheringPointByItemId(uint itemId, [NotNullWhen(true)] out GatheringPointId? gatheringPointId) + => _botanistGatheringPoints.TryGetValue(itemId, out gatheringPointId); public ushort GetRecommendedCollectability(uint itemId) => _itemIdToCollectability.GetValueOrDefault(itemId);