Implement collectability thresholds in backend
This commit is contained in:
@@ -1,6 +1,11 @@
|
|||||||
using Dalamud;
|
using Dalamud;
|
||||||
|
using Lumina;
|
||||||
|
using Lumina.Data;
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Action = Lumina.Excel.GeneratedSheets.Action;
|
||||||
|
|
||||||
namespace Craftimizer.Plugin;
|
namespace Craftimizer.Plugin;
|
||||||
|
|
||||||
@@ -22,4 +27,67 @@ public static class LuminaSheets
|
|||||||
public static readonly ExcelSheet<Materia> MateriaSheet = Service.DataManager.GetExcelSheet<Materia>()!;
|
public static readonly ExcelSheet<Materia> MateriaSheet = Service.DataManager.GetExcelSheet<Materia>()!;
|
||||||
public static readonly ExcelSheet<BaseParam> BaseParamSheet = Service.DataManager.GetExcelSheet<BaseParam>()!;
|
public static readonly ExcelSheet<BaseParam> BaseParamSheet = Service.DataManager.GetExcelSheet<BaseParam>()!;
|
||||||
public static readonly ExcelSheet<ItemFood> ItemFoodSheet = Service.DataManager.GetExcelSheet<ItemFood>()!;
|
public static readonly ExcelSheet<ItemFood> ItemFoodSheet = Service.DataManager.GetExcelSheet<ItemFood>()!;
|
||||||
|
public static readonly ExcelSheet<CollectablesShopRefine> CollectablesShopRefineSheet = Service.DataManager.GetExcelSheet<CollectablesShopRefine>()!;
|
||||||
|
public static readonly ExcelSheet<HWDCrafterSupply> HWDCrafterSupplySheet = Service.DataManager.GetExcelSheet<HWDCrafterSupply>()!;
|
||||||
|
public static readonly ExcelSheet<SatisfactionSupply> SatisfactionSupplySheet = Service.DataManager.GetExcelSheet<SatisfactionSupply>()!;
|
||||||
|
public static readonly ExcelSheet<SharlayanCraftWorksSupply> SharlayanCraftWorksSupplySheet = Service.DataManager.GetExcelSheet<SharlayanCraftWorksSupply>()!;
|
||||||
|
|
||||||
|
private static ConcurrentDictionary<(ExcelSheetImpl, uint), uint> SubRowCountCache { get; } = new();
|
||||||
|
public static uint? GetSubRowCount<T>(this ExcelSheet<T> 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> 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<byte>(0 + (i * 11 + 0));
|
||||||
|
Items[i].Item = new LazyRow<Item>(gameData, parser.ReadColumn<uint>(0 + (i * 11 + 1)), language);
|
||||||
|
Items[i].CollectabilityMid = parser.ReadColumn<ushort>(0 + (i * 11 + 2));
|
||||||
|
Items[i].CollectabilityHigh = parser.ReadColumn<ushort>(0 + (i * 11 + 3));
|
||||||
|
Items[i].XPReward = parser.ReadColumn<uint>(0 + (i * 11 + 4));
|
||||||
|
Items[i].HighXPMultiplier = parser.ReadColumn<byte>(0 + (i * 11 + 5));
|
||||||
|
Items[i].GilReward = parser.ReadColumn<ushort>(0 + (i * 11 + 6));
|
||||||
|
Items[i].HighGilMultiplier = parser.ReadColumn<byte>(0 + (i * 11 + 7));
|
||||||
|
Items[i].Unknown8 = parser.ReadColumn<byte>(0 + (i * 11 + 8));
|
||||||
|
Items[i].ScripReward = parser.ReadColumn<byte>(0 + (i * 11 + 9));
|
||||||
|
Items[i].HighScripMultiplier = parser.ReadColumn<byte>(0 + (i * 11 + 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#nullable restore
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ public sealed record RecipeData
|
|||||||
|
|
||||||
public ClassJob ClassJob { get; }
|
public ClassJob ClassJob { get; }
|
||||||
public RecipeInfo RecipeInfo { get; }
|
public RecipeInfo RecipeInfo { get; }
|
||||||
|
public IReadOnlyList<int?>? CollectableThresholds { get; }
|
||||||
public IReadOnlyList<(Item Item, int Amount)> Ingredients { get; }
|
public IReadOnlyList<(Item Item, int Amount)> Ingredients { get; }
|
||||||
public int MaxStartingQuality { get; }
|
public int MaxStartingQuality { get; }
|
||||||
private int TotalHqILvls { get; }
|
private int TotalHqILvls { get; }
|
||||||
@@ -45,6 +46,57 @@ public sealed record RecipeData
|
|||||||
ProgressDivider = Table.ProgressDivider,
|
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)
|
Ingredients = Recipe.UnkData5.Take(6)
|
||||||
.Where(i => i != null && i.ItemIngredient != 0)
|
.Where(i => i != null && i.ItemIngredient != 0)
|
||||||
.Select(i => (LuminaSheets.ItemSheet.GetRow((uint)i.ItemIngredient)!, (int)i.AmountIngredient))
|
.Select(i => (LuminaSheets.ItemSheet.GetRow((uint)i.ItemIngredient)!, (int)i.AmountIngredient))
|
||||||
|
|||||||
Reference in New Issue
Block a user