From 12afada408c8191d1680205841f843c1b67c2b10 Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Thu, 24 Apr 2025 01:47:33 -0700 Subject: [PATCH] Add WKS level sync support --- Craftimizer/SimulatorUtils.cs | 16 ++++++++++++++++ Craftimizer/Utils/RecipeData.cs | 15 ++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Craftimizer/SimulatorUtils.cs b/Craftimizer/SimulatorUtils.cs index a84509d..0fa6995 100644 --- a/Craftimizer/SimulatorUtils.cs +++ b/Craftimizer/SimulatorUtils.cs @@ -14,6 +14,7 @@ using Craftimizer.Utils; using Lumina.Text.ReadOnly; using Lumina.Text.Payloads; using Lumina.Excel.Sheets; +using FFXIVClientStructs.FFXIV.Client.Game.Event; namespace Craftimizer.Plugin; @@ -140,6 +141,21 @@ internal static class ClassJobUtils public static unsafe short GetPlayerLevel(this ClassJob me) => PlayerState.Instance()->ClassJobLevels[me.GetExpArrayIdx()]; + public static unsafe ushort GetWKSSyncedLevel(this ClassJob me) + { + var jobLevel = (ushort)me.GetPlayerLevel(); + var handler = CSCraftEventHandler.Instance(); + if (handler != null) + { + for (var i = 0; i < 2; ++i) + { + if (handler->WKSClassJobs[i] == me.GetClassJobIndex()) + return Math.Min(jobLevel, handler->WKSClassLevels[i]); + } + } + return jobLevel; + } + public static unsafe bool CanPlayerUseManipulation(this ClassJob me) => UIState.Instance()->IsUnlockLinkUnlockedOrQuestCompleted(ActionType.Manipulation.GetActionRow(me).Action!.Value.UnlockLink.RowId); diff --git a/Craftimizer/Utils/RecipeData.cs b/Craftimizer/Utils/RecipeData.cs index 9a23e23..a91e12e 100644 --- a/Craftimizer/Utils/RecipeData.cs +++ b/Craftimizer/Utils/RecipeData.cs @@ -21,23 +21,32 @@ public sealed record RecipeData public IReadOnlyList? CollectableThresholds { get; } public IReadOnlyList<(Item Item, int Amount)> Ingredients { get; } public int MaxStartingQuality { get; } + public ushort? AdjustedJobLevel { get; } private int TotalHqILvls { get; } - public RecipeData(ushort recipeId) + public RecipeData(ushort recipeId, ushort? explicitlyAdjustedJobLevel = null) { RecipeId = recipeId; Recipe = LuminaSheets.RecipeSheet.GetRowOrDefault(recipeId) ?? throw new ArgumentException($"Invalid recipe id {recipeId}", nameof(recipeId)); - Table = Recipe.RecipeLevelTable.Value; ClassJob = (ClassJob)Recipe.CraftType.RowId; + + var resolvedLevelTableRow = Recipe.RecipeLevelTable.RowId; + if (Recipe.Unknown0 != 0) + { + AdjustedJobLevel = Math.Min(explicitlyAdjustedJobLevel ?? ClassJob.GetWKSSyncedLevel(), Recipe.Unknown0); + resolvedLevelTableRow = LuminaSheets.GathererCrafterLvAdjustTableSheet.GetRow(AdjustedJobLevel.Value).Unknown0; + } + Table = LuminaSheets.RecipeLevelTableSheet.GetRow(resolvedLevelTableRow); + RecipeInfo = new() { IsExpert = Recipe.IsExpert, ClassJobLevel = Table.ClassJobLevel, ConditionsFlag = Table.ConditionsFlag, - MaxDurability = Table.Durability * Recipe.DurabilityFactor / 100, + MaxDurability = (Recipe.Unknown0 != 0 ? 80 : Table.Durability) * Recipe.DurabilityFactor / 100, MaxQuality = (Recipe.CanHq || Recipe.IsExpert) ? (int)Table.Quality * Recipe.QualityFactor / 100 : 0, MaxProgress = Table.Difficulty * Recipe.DifficultyFactor / 100, QualityModifier = Table.QualityModifier,