From c7eb7e186211f49b7e81d74663b0015e35f9a0f6 Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Fri, 23 Feb 2024 06:15:24 -0800 Subject: [PATCH] Implement collectability thresholds in backend --- Craftimizer/LuminaSheets.cs | 68 +++++++++++++++++++++++++++++++++ Craftimizer/Utils/RecipeData.cs | 52 +++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/Craftimizer/LuminaSheets.cs b/Craftimizer/LuminaSheets.cs index 18301f2..8ccfbfe 100644 --- a/Craftimizer/LuminaSheets.cs +++ b/Craftimizer/LuminaSheets.cs @@ -1,6 +1,11 @@ using Dalamud; +using Lumina; +using Lumina.Data; using Lumina.Excel; using Lumina.Excel.GeneratedSheets; +using System; +using System.Collections.Concurrent; +using Action = Lumina.Excel.GeneratedSheets.Action; namespace Craftimizer.Plugin; @@ -22,4 +27,67 @@ public static class LuminaSheets public static readonly ExcelSheet MateriaSheet = Service.DataManager.GetExcelSheet()!; public static readonly ExcelSheet BaseParamSheet = Service.DataManager.GetExcelSheet()!; public static readonly ExcelSheet ItemFoodSheet = Service.DataManager.GetExcelSheet()!; + public static readonly ExcelSheet CollectablesShopRefineSheet = Service.DataManager.GetExcelSheet()!; + public static readonly ExcelSheet HWDCrafterSupplySheet = Service.DataManager.GetExcelSheet()!; + public static readonly ExcelSheet SatisfactionSupplySheet = Service.DataManager.GetExcelSheet()!; + public static readonly ExcelSheet SharlayanCraftWorksSupplySheet = Service.DataManager.GetExcelSheet()!; + + private static ConcurrentDictionary<(ExcelSheetImpl, uint), uint> SubRowCountCache { get; } = new(); + public static uint? GetSubRowCount(this ExcelSheet sheet, uint row) where T : ExcelRow + { + if (SubRowCountCache.TryGetValue((sheet, row), out var count)) + return count; + var parser = sheet.GetRowParser(row); + if (parser == null) + return null; + SubRowCountCache.TryAdd((sheet, row), parser.RowCount); + return parser.RowCount; + } } + +#nullable disable + +[Sheet("SharlayanCraftWorksSupply", columnHash: 0x903b128e)] +public class SharlayanCraftWorksSupply : ExcelRow +{ + public class ItemData + { + public byte Level { get; set; } + public LazyRow Item { get; set; } + public ushort CollectabilityMid { get; set; } + public ushort CollectabilityHigh { get; set; } + public uint XPReward { get; set; } + public byte HighXPMultiplier { get; set; } + public ushort GilReward { get; set; } + public byte HighGilMultiplier { get; set; } + public byte Unknown8 { get; set; } + public byte ScripReward { get; set; } + public byte HighScripMultiplier { get; set; } + } + + public ItemData[] Items { get; set; } + + public override void PopulateData(RowParser parser, GameData gameData, Language language) + { + base.PopulateData(parser, gameData, language); + + Items = new ItemData[4]; + for (var i = 0; i < 4; i++) + { + Items[i] = new ItemData(); + Items[i].Level = parser.ReadColumn(0 + (i * 11 + 0)); + Items[i].Item = new LazyRow(gameData, parser.ReadColumn(0 + (i * 11 + 1)), language); + Items[i].CollectabilityMid = parser.ReadColumn(0 + (i * 11 + 2)); + Items[i].CollectabilityHigh = parser.ReadColumn(0 + (i * 11 + 3)); + Items[i].XPReward = parser.ReadColumn(0 + (i * 11 + 4)); + Items[i].HighXPMultiplier = parser.ReadColumn(0 + (i * 11 + 5)); + Items[i].GilReward = parser.ReadColumn(0 + (i * 11 + 6)); + Items[i].HighGilMultiplier = parser.ReadColumn(0 + (i * 11 + 7)); + Items[i].Unknown8 = parser.ReadColumn(0 + (i * 11 + 8)); + Items[i].ScripReward = parser.ReadColumn(0 + (i * 11 + 9)); + Items[i].HighScripMultiplier = parser.ReadColumn(0 + (i * 11 + 10)); + } + } +} + +#nullable restore diff --git a/Craftimizer/Utils/RecipeData.cs b/Craftimizer/Utils/RecipeData.cs index 71d32b4..e97cbca 100644 --- a/Craftimizer/Utils/RecipeData.cs +++ b/Craftimizer/Utils/RecipeData.cs @@ -17,6 +17,7 @@ public sealed record RecipeData public ClassJob ClassJob { get; } public RecipeInfo RecipeInfo { get; } + public IReadOnlyList? CollectableThresholds { get; } public IReadOnlyList<(Item Item, int Amount)> Ingredients { get; } public int MaxStartingQuality { get; } private int TotalHqILvls { get; } @@ -45,6 +46,57 @@ public sealed record RecipeData ProgressDivider = Table.ProgressDivider, }; + CollectableThresholds = null; + switch (Recipe.Unknown45) + { + case 1: + var data1 = LuminaSheets.CollectablesShopRefineSheet.GetRow(Recipe.Unknown46); + if (data1 == null) + break; + CollectableThresholds = new int?[] { data1.LowCollectability, data1.MidCollectability, data1.HighCollectability }; + break; + case 2: + var data2 = LuminaSheets.HWDCrafterSupplySheet.GetRow(Recipe.Unknown46); + if (data2 == null) + break; + var idx = Array.FindIndex(data2.ItemTradeIn, i => i.Row == Recipe.ItemResult.Row); + if (idx == -1) + break; + CollectableThresholds = new int?[] { data2.BaseCollectableRating[idx], data2.MidCollectableRating[idx], data2.HighCollectableRating[idx] }; + break; + case 3: + var subRowCount = LuminaSheets.SatisfactionSupplySheet.GetSubRowCount(Recipe.Unknown46); + if (subRowCount is not { } subRowValue) + break; + for (uint i = 0; i < subRowValue; ++i) + { + var data3 = LuminaSheets.SatisfactionSupplySheet.GetRow(Recipe.Unknown46, i); + if (data3 == null) + continue; + if (data3.Item.Row == Recipe.ItemResult.Row) + { + CollectableThresholds = new int?[] { data3.CollectabilityLow, data3.CollectabilityMid, data3.CollectabilityHigh }; + break; + } + } + break; + case 4: + var data4 = LuminaSheets.SharlayanCraftWorksSupplySheet.GetRow(Recipe.Unknown46); + if (data4 == null) + goto default; + foreach (var item in data4.Items) + { + if (item.Item.Row == Recipe.ItemResult.Row) + { + CollectableThresholds = new int?[] { null, item.CollectabilityMid, item.CollectabilityHigh }; + break; + } + } + break; + default: + break; + } + Ingredients = Recipe.UnkData5.Take(6) .Where(i => i != null && i.ItemIngredient != 0) .Select(i => (LuminaSheets.ItemSheet.GetRow((uint)i.ItemIngredient)!, (int)i.AmountIngredient))