Change to ExdSheets 2

This commit is contained in:
Asriel Camora
2024-08-06 11:53:03 -07:00
parent ff7d7693ad
commit fa45ac072e
16 changed files with 181 additions and 185 deletions
+1 -1
View File
@@ -20,7 +20,7 @@
<PackageReference Include="BenchmarkDotNet" Version="0.13.10" /> <PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.dotTrace" Version="0.13.10" /> <PackageReference Include="BenchmarkDotNet.Diagnostics.dotTrace" Version="0.13.10" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.10" /> <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.10" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.162"> <PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
+4 -3
View File
@@ -39,10 +39,11 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.13" /> <PackageReference Include="DalamudPackager" Version="2.1.13" />
<PackageReference Include="ExdSheets" Version="1.2.2" /> <PackageReference Include="ExdSheets" Version="2.1.0" />
<PackageReference Include="Lumina" Version="3.15.2" ExcludeAssets="all" /> <PackageReference Include="Lumina" Version="4.1.1" ExcludeAssets="all" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="9.0.0-preview.1.24081.5" ExcludeAssets="all" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" /> <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.162"> <PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
+4 -4
View File
@@ -290,7 +290,7 @@ internal static class ImGuiUtils
} }
} }
private sealed class SearchableComboData<T> where T : class private sealed class SearchableComboData<T> where T : IEquatable<T>
{ {
public readonly ImmutableArray<T> items; public readonly ImmutableArray<T> items;
public List<T> filteredItems; public List<T> filteredItems;
@@ -314,7 +314,7 @@ internal static class ImGuiUtils
public void SetItem(T selectedItem) public void SetItem(T selectedItem)
{ {
if (this.selectedItem != selectedItem) if (!this.selectedItem.Equals(selectedItem))
{ {
input = GetString(selectedItem); input = GetString(selectedItem);
this.selectedItem = selectedItem; this.selectedItem = selectedItem;
@@ -364,14 +364,14 @@ internal static class ImGuiUtils
} }
private static readonly Dictionary<uint, object> ComboData = []; private static readonly Dictionary<uint, object> ComboData = [];
private static SearchableComboData<T> GetComboData<T>(uint comboKey, IEnumerable<T> items, T selectedItem, Func<T, string> getString) where T : class => private static SearchableComboData<T> GetComboData<T>(uint comboKey, IEnumerable<T> items, T selectedItem, Func<T, string> getString) where T : IEquatable<T> =>
(SearchableComboData<T>)( (SearchableComboData<T>)(
ComboData.TryGetValue(comboKey, out var data) ComboData.TryGetValue(comboKey, out var data)
? data ? data
: ComboData[comboKey] = new SearchableComboData<T>(items, selectedItem, getString)); : ComboData[comboKey] = new SearchableComboData<T>(items, selectedItem, getString));
// https://github.com/ocornut/imgui/issues/718#issuecomment-1563162222 // https://github.com/ocornut/imgui/issues/718#issuecomment-1563162222
public static bool SearchableCombo<T>(string id, ref T selectedItem, IEnumerable<T> items, ImFontPtr selectableFont, float width, Func<T, string> getString, Func<T, string> getId, Action<T> draw) where T : class public static bool SearchableCombo<T>(string id, ref T selectedItem, IEnumerable<T> items, ImFontPtr selectableFont, float width, Func<T, string> getString, Func<T, string> getId, Action<T> draw) where T : IEquatable<T>
{ {
var comboKey = ImGui.GetID(id); var comboKey = ImGui.GetID(id);
var data = GetComboData(comboKey, items, selectedItem, getString); var data = GetComboData(comboKey, items, selectedItem, getString);
+19 -29
View File
@@ -1,37 +1,27 @@
using Dalamud.Game; using Dalamud.Utility;
using ExdSheets; using ExdSheets;
using Lumina.Excel; using ExdSheets.Sheets;
using System.Collections.Concurrent; using Lumina.Data;
namespace Craftimizer.Plugin; namespace Craftimizer.Plugin;
public static class LuminaSheets public static class LuminaSheets
{ {
public static readonly ExcelSheet<Recipe> RecipeSheet = Service.DataManager.GetExcelSheet<Recipe>()!; private static readonly Module Module = new(Service.DataManager.GameData, Service.DataManager.Language.ToLumina());
public static readonly ExcelSheet<Action> ActionSheet = Service.DataManager.GetExcelSheet<Action>()!;
public static readonly ExcelSheet<CraftAction> CraftActionSheet = Service.DataManager.GetExcelSheet<CraftAction>()!;
public static readonly ExcelSheet<Status> StatusSheet = Service.DataManager.GetExcelSheet<Status>()!;
public static readonly ExcelSheet<Addon> AddonSheet = Service.DataManager.GetExcelSheet<Addon>()!;
public static readonly ExcelSheet<ClassJob> ClassJobSheet = Service.DataManager.GetExcelSheet<ClassJob>()!;
public static readonly ExcelSheet<Item> ItemSheet = Service.DataManager.GetExcelSheet<Item>()!;
public static readonly ExcelSheet<Item> ItemSheetEnglish = Service.DataManager.GetExcelSheet<Item>(ClientLanguage.English)!;
public static readonly ExcelSheet<ENpcResident> ENpcResidentSheet = Service.DataManager.GetExcelSheet<ENpcResident>()!;
public static readonly ExcelSheet<Level> LevelSheet = Service.DataManager.GetExcelSheet<Level>()!;
public static readonly ExcelSheet<Quest> QuestSheet = Service.DataManager.GetExcelSheet<Quest>()!;
public static readonly ExcelSheet<Materia> MateriaSheet = Service.DataManager.GetExcelSheet<Materia>()!;
public static readonly ExcelSheet<BaseParam> BaseParamSheet = Service.DataManager.GetExcelSheet<BaseParam>()!;
public static readonly ExcelSheet<ItemFood> ItemFoodSheet = Service.DataManager.GetExcelSheet<ItemFood>()!;
public static readonly ExcelSheet<SatisfactionSupply> SatisfactionSupplySheet = Service.DataManager.GetExcelSheet<SatisfactionSupply>()!;
private static ConcurrentDictionary<(ExcelSheetImpl, uint), uint> SubRowCountCache { get; } = new(); public static readonly Sheet<Recipe> RecipeSheet = Module.GetSheet<Recipe>();
public static uint? GetSubRowCount<T>(this ExcelSheet<T> sheet, uint row) where T : ExcelRow public static readonly Sheet<Action> ActionSheet = Module.GetSheet<Action>();
{ public static readonly Sheet<CraftAction> CraftActionSheet = Module.GetSheet<CraftAction>();
if (SubRowCountCache.TryGetValue((sheet, row), out var count)) public static readonly Sheet<Status> StatusSheet = Module.GetSheet<Status>();
return count; public static readonly Sheet<Addon> AddonSheet = Module.GetSheet<Addon>();
var parser = sheet.GetRowParser(row); public static readonly Sheet<ClassJob> ClassJobSheet = Module.GetSheet<ClassJob>();
if (parser == null) public static readonly Sheet<Item> ItemSheet = Module.GetSheet<Item>();
return null; public static readonly Sheet<Item> ItemSheetEnglish = Module.GetSheet<Item>(Language.English)!;
SubRowCountCache.TryAdd((sheet, row), parser.RowCount); public static readonly Sheet<ENpcResident> ENpcResidentSheet = Module.GetSheet<ENpcResident>();
return parser.RowCount; public static readonly Sheet<Level> LevelSheet = Module.GetSheet<Level>();
} public static readonly Sheet<Quest> QuestSheet = Module.GetSheet<Quest>();
public static readonly Sheet<Materia> MateriaSheet = Module.GetSheet<Materia>();
public static readonly Sheet<BaseParam> BaseParamSheet = Module.GetSheet<BaseParam>();
public static readonly Sheet<ItemFood> ItemFoodSheet = Module.GetSheet<ItemFood>();
public static readonly Sheet<SatisfactionSupply> SatisfactionSupplySheet = Module.GetSheet<SatisfactionSupply>();
} }
+1 -1
View File
@@ -62,7 +62,7 @@ public sealed class Plugin : IDalamudPlugin
SynthHelperWindow = new(); SynthHelperWindow = new();
ListWindow = new(); ListWindow = new();
// Trigger static constructors so a huge hitch doesn't occur on first RecipeNote frame. // Trigger static constructors so a hitch doesn't occur on first RecipeNote frame.
FoodStatus.Initialize(); FoodStatus.Initialize();
ActionUtils.Initialize(); ActionUtils.Initialize();
+45 -51
View File
@@ -1,21 +1,19 @@
using Craftimizer.Simulator; using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions; using Craftimizer.Simulator.Actions;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.Game.UI;
using ExdSheets;
using System; using System;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Text; using System.Text;
using Action = ExdSheets.Action; using Action = ExdSheets.Sheets.Action;
using ActionType = Craftimizer.Simulator.Actions.ActionType; using ActionType = Craftimizer.Simulator.Actions.ActionType;
using ClassJob = Craftimizer.Simulator.ClassJob; using ClassJob = Craftimizer.Simulator.ClassJob;
using Condition = Craftimizer.Simulator.Condition; using Condition = Craftimizer.Simulator.Condition;
using Status = ExdSheets.Status; using Status = ExdSheets.Sheets.Status;
using Dalamud.Interface.Textures;
using Craftimizer.Utils; using Craftimizer.Utils;
using ExdSheets.Sheets;
using Lumina.Text.ReadOnly;
using Lumina.Text.Payloads;
namespace Craftimizer.Plugin; namespace Craftimizer.Plugin;
@@ -31,33 +29,33 @@ internal static class ActionUtils
foreach (var actionType in actionTypes) foreach (var actionType in actionTypes)
{ {
var actionId = actionType.Base().ActionId; var actionId = actionType.Base().ActionId;
if (LuminaSheets.CraftActionSheet.GetRow(actionId) is CraftAction baseCraftAction) if (LuminaSheets.CraftActionSheet.TryGetRow(actionId) is { } baseCraftAction)
{ {
foreach (var classJob in classJobs) foreach (var classJob in classJobs)
{ {
ActionRows[(int)actionType, (int)classJob] = (classJob switch ActionRows[(int)actionType, (int)classJob] = (classJob switch
{ {
ClassJob.Carpenter => baseCraftAction.CRP.Value!, ClassJob.Carpenter => baseCraftAction.CRP.Value,
ClassJob.Blacksmith => baseCraftAction.BSM.Value!, ClassJob.Blacksmith => baseCraftAction.BSM.Value,
ClassJob.Armorer => baseCraftAction.ARM.Value!, ClassJob.Armorer => baseCraftAction.ARM.Value,
ClassJob.Goldsmith => baseCraftAction.GSM.Value!, ClassJob.Goldsmith => baseCraftAction.GSM.Value,
ClassJob.Leatherworker => baseCraftAction.LTW.Value!, ClassJob.Leatherworker => baseCraftAction.LTW.Value,
ClassJob.Weaver => baseCraftAction.WVR.Value!, ClassJob.Weaver => baseCraftAction.WVR.Value,
ClassJob.Alchemist => baseCraftAction.ALC.Value!, ClassJob.Alchemist => baseCraftAction.ALC.Value,
ClassJob.Culinarian => baseCraftAction.CUL.Value!, ClassJob.Culinarian => baseCraftAction.CUL.Value,
_ => baseCraftAction _ => baseCraftAction
}, null); }, null);
} }
} }
if (LuminaSheets.ActionSheet.GetRow(actionId) is Action baseAction) if (LuminaSheets.ActionSheet.TryGetRow(actionId) is { } baseAction)
{ {
var possibleActions = LuminaSheets.ActionSheet.Where(r => var possibleActions = LuminaSheets.ActionSheet.Where(r =>
r.Icon == baseAction.Icon && r.Icon == baseAction.Icon &&
r.ActionCategory.Row == baseAction.ActionCategory.Row && r.ActionCategory.RowId == baseAction.ActionCategory.RowId &&
r.Name.RawString.Equals(baseAction.Name.RawString, StringComparison.Ordinal)); r.Name.Equals(baseAction.Name));
foreach (var classJob in classJobs) foreach (var classJob in classJobs)
ActionRows[(int)actionType, (int)classJob] = (null, possibleActions.First(r => r.ClassJobCategory.Value?.IsClassJob(classJob) ?? false)); ActionRows[(int)actionType, (int)classJob] = (null, possibleActions.First(r => r.ClassJobCategory.ValueNullable?.IsClassJob(classJob) ?? false));
} }
} }
} }
@@ -70,32 +68,20 @@ internal static class ActionUtils
public static uint GetId(this ActionType me, ClassJob classJob) public static uint GetId(this ActionType me, ClassJob classJob)
{ {
var (craftAction, action) = GetActionRow(me, classJob); var (craftAction, action) = GetActionRow(me, classJob);
if (craftAction != null) return craftAction?.RowId ?? action?.RowId ?? 0;
return craftAction.RowId;
if (action != null)
return action.RowId;
return 0;
} }
public static string GetName(this ActionType me, ClassJob classJob) public static string GetName(this ActionType me, ClassJob classJob)
{ {
var (craftAction, action) = GetActionRow(me, classJob); var (craftAction, action) = GetActionRow(me, classJob);
if (craftAction != null) return (craftAction?.Name ?? action?.Name)?.AsSpan().ExtractText() ?? "Unknown";
return craftAction.Name.ToDalamudString().TextValue;
if (action != null)
return action.Name.ToDalamudString().TextValue;
return "Unknown";
} }
public static ITextureIcon GetIcon(this ActionType me, ClassJob classJob) public static ITextureIcon GetIcon(this ActionType me, ClassJob classJob)
{ {
var (craftAction, action) = GetActionRow(me, classJob); var (craftAction, action) = GetActionRow(me, classJob);
if (craftAction != null) // 1953 = Old "Steady Hand" action icon
return Service.IconManager.GetIconCached(craftAction.Icon); return Service.IconManager.GetIconCached(craftAction?.Icon ?? action?.Icon ?? 1953);
if (action != null)
return Service.IconManager.GetIconCached(action.Icon);
// Old "Steady Hand" action icon
return Service.IconManager.GetIconCached(1953);
} }
public static ActionType? GetActionTypeFromId(uint actionId, ClassJob classJob, bool isCraftAction) public static ActionType? GetActionTypeFromId(uint actionId, ClassJob classJob, bool isCraftAction)
@@ -155,18 +141,18 @@ internal static class ClassJobUtils
PlayerState.Instance()->ClassJobLevels[me.GetExpArrayIdx()]; PlayerState.Instance()->ClassJobLevels[me.GetExpArrayIdx()];
public static unsafe bool CanPlayerUseManipulation(this ClassJob me) => public static unsafe bool CanPlayerUseManipulation(this ClassJob me) =>
UIState.Instance()->IsUnlockLinkUnlockedOrQuestCompleted(ActionType.Manipulation.GetActionRow(me).Action!.UnlockLink.Row); UIState.Instance()->IsUnlockLinkUnlockedOrQuestCompleted(ActionType.Manipulation.GetActionRow(me).Action!.Value.UnlockLink.RowId);
public static string GetName(this ClassJob me) public static string GetName(this ClassJob me)
{ {
var job = LuminaSheets.ClassJobSheet.GetRow(me.GetClassJobIndex())!; var job = LuminaSheets.ClassJobSheet.GetRow(me.GetClassJobIndex());
return job.Name.ToDalamudString().TextValue.ToLowerInvariant(); return job.Name.ExtractText().ToLowerInvariant();
} }
public static string GetNameArticle(this ClassJob me) public static string GetNameArticle(this ClassJob me)
{ {
var job = LuminaSheets.ClassJobSheet.GetRow(me.GetClassJobIndex())!; var job = LuminaSheets.ClassJobSheet.GetRow(me.GetClassJobIndex());
if (job.SheetLanguage == Lumina.Data.Language.English) if (LuminaSheets.ClassJobSheet.Language == Lumina.Data.Language.English)
{ {
if (me is ClassJob.Alchemist or ClassJob.Armorer) if (me is ClassJob.Alchemist or ClassJob.Armorer)
return "an"; return "an";
@@ -176,12 +162,12 @@ internal static class ClassJobUtils
public static string GetAbbreviation(this ClassJob me) public static string GetAbbreviation(this ClassJob me)
{ {
var job = LuminaSheets.ClassJobSheet.GetRow(me.GetClassJobIndex())!; var job = LuminaSheets.ClassJobSheet.GetRow(me.GetClassJobIndex());
return job.Abbreviation.ToDalamudString().TextValue; return job.Abbreviation.ExtractText();
} }
public static Quest GetUnlockQuest(this ClassJob me) => public static Quest GetUnlockQuest(this ClassJob me) =>
LuminaSheets.QuestSheet.GetRow(65720 + (uint)me) ?? throw new ArgumentException($"Could not get unlock quest for {me}", nameof(me)); LuminaSheets.QuestSheet.GetRow(65720 + (uint)me);
public static ushort GetIconId(this ClassJob me) => public static ushort GetIconId(this ClassJob me) =>
(ushort)(62000 + me.GetClassJobIndex()); (ushort)(62000 + me.GetClassJobIndex());
@@ -295,15 +281,23 @@ internal static class ConditionUtils
} }
public static string Name(this Condition me) => public static string Name(this Condition me) =>
LuminaSheets.AddonSheet.GetRow(me.AddonIds().Name)!.Text.ToDalamudString().TextValue; LuminaSheets.AddonSheet.GetRow(me.AddonIds().Name).Text.ExtractText();
public static string Description(this Condition me, bool isRelic) public static string Description(this Condition me, bool isRelic)
{ {
var text = LuminaSheets.AddonSheet.GetRow(me.AddonIds().Description)!.Text.ToDalamudString(); var text = LuminaSheets.AddonSheet.GetRow(me.AddonIds().Description).Text;
for (var i = 0; i < text.Payloads.Count; ++i) if (!text.Any(p => p is { Type: ReadOnlySePayloadType.Macro, MacroCode: MacroCode.Float }))
if (text.Payloads[i] is RawPayload) return text.ExtractText();
text.Payloads[i] = new TextPayload(isRelic ? "1.75" : "1.5");
return text.TextValue; ReadOnlySeString finalText = new();
foreach (var payload in text)
{
if (payload is { Type: ReadOnlySePayloadType.Macro, MacroCode: MacroCode.Float })
finalText += new ReadOnlySePayload(ReadOnlySePayloadType.Text, default, Encoding.UTF8.GetBytes(isRelic ? "1.75" : "1.5"));
else
finalText += payload;
}
return finalText.ExtractText();
} }
} }
@@ -349,7 +343,7 @@ internal static class EffectUtils
{ {
var status = me.Status(); var status = me.Status();
var name = new StringBuilder(); var name = new StringBuilder();
name.Append(status.Name.ToDalamudString().TextValue); name.Append(status.Name.ExtractText());
if (status.MaxStacks != 0) if (status.MaxStacks != 0)
name.Append($" {strength}"); name.Append($" {strength}");
if (!status.IsPermanent) if (!status.IsPermanent)
+10 -11
View File
@@ -1,5 +1,5 @@
using Craftimizer.Plugin; using Craftimizer.Plugin;
using ExdSheets; using ExdSheets.Sheets;
using System.Collections.Frozen; using System.Collections.Frozen;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
@@ -25,28 +25,27 @@ public static class FoodStatus
var medicines = new Dictionary<uint, Food>(); var medicines = new Dictionary<uint, Food>();
foreach (var item in LuminaSheets.ItemSheet) foreach (var item in LuminaSheets.ItemSheet)
{ {
var isFood = item.ItemUICategory.Row == 46; var isFood = item.ItemUICategory.RowId == 46;
var isMedicine = item.ItemUICategory.Row == 44; var isMedicine = item.ItemUICategory.RowId == 44;
if (!isFood && !isMedicine) if (!isFood && !isMedicine)
continue; continue;
if (item.ItemAction.Value == null) if (item.ItemAction.ValueNullable is not { } itemAction)
continue; continue;
if (!(item.ItemAction.Value.Type is 844 or 845 or 846)) if (itemAction.Type is not (844 or 845 or 846))
continue; continue;
var itemFood = LuminaSheets.ItemFoodSheet.GetRow(item.ItemAction.Value.Data[1]); if (LuminaSheets.ItemFoodSheet.TryGetRow(itemAction.Data[1]) is not { } itemFood)
if (itemFood == null)
continue; continue;
FoodStat? craftsmanship = null, control = null, cp = null; FoodStat? craftsmanship = null, control = null, cp = null;
foreach (var stat in itemFood.Params) foreach (var stat in itemFood.Params)
{ {
if (stat.BaseParam.Row == 0) if (stat.BaseParam.RowId == 0)
continue; continue;
var foodStat = new FoodStat(stat.IsRelative, stat.Value, stat.Max, stat.ValueHQ, stat.MaxHQ); var foodStat = new FoodStat(stat.IsRelative, stat.Value, stat.Max, stat.ValueHQ, stat.MaxHQ);
switch (stat.BaseParam.Row) switch (stat.BaseParam.RowId)
{ {
case Gearsets.ParamCraftsmanship: craftsmanship = foodStat; break; case Gearsets.ParamCraftsmanship: craftsmanship = foodStat; break;
case Gearsets.ParamControl: control = foodStat; break; case Gearsets.ParamControl: control = foodStat; break;
@@ -71,8 +70,8 @@ public static class FoodStatus
FoodItems = foods.ToFrozenDictionary(); FoodItems = foods.ToFrozenDictionary();
MedicineItems = medicines.ToFrozenDictionary(); MedicineItems = medicines.ToFrozenDictionary();
FoodOrder = FoodItems.OrderByDescending(a => a.Value.Item.LevelItem.Row).Select(a => a.Key).ToImmutableArray(); FoodOrder = FoodItems.OrderByDescending(a => a.Value.Item.LevelItem.RowId).Select(a => a.Key).ToImmutableArray();
MedicineOrder = MedicineItems.OrderByDescending(a => a.Value.Item.LevelItem.Row).Select(a => a.Key).ToImmutableArray(); MedicineOrder = MedicineItems.OrderByDescending(a => a.Value.Item.LevelItem.RowId).Select(a => a.Key).ToImmutableArray();
} }
public static void Initialize() { } public static void Initialize() { }
+8 -8
View File
@@ -3,7 +3,7 @@ using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Misc; using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using ExdSheets; using ExdSheets.Sheets;
using System; using System;
using System.Linq; using System.Linq;
using Craftimizer.Plugin; using Craftimizer.Plugin;
@@ -62,10 +62,10 @@ public static unsafe class Gearsets
} }
foreach (var statIncrease in item.BaseParam.Zip(item.BaseParamValue)) foreach (var statIncrease in item.BaseParam.Zip(item.BaseParamValue))
IncreaseStat(statIncrease.First.Row, statIncrease.Second); IncreaseStat(statIncrease.First.RowId, statIncrease.Second);
if (gearsetItem.IsHq) if (gearsetItem.IsHq)
foreach (var statIncrease in item.BaseParamSpecial.Zip(item.BaseParamValueSpecial)) foreach (var statIncrease in item.BaseParamSpecial.Zip(item.BaseParamValueSpecial))
IncreaseStat(statIncrease.First.Row, statIncrease.Second); IncreaseStat(statIncrease.First.RowId, statIncrease.Second);
foreach (var gearsetMateria in gearsetItem.Materia) foreach (var gearsetMateria in gearsetItem.Materia)
{ {
@@ -73,7 +73,7 @@ public static unsafe class Gearsets
continue; continue;
var materia = LuminaSheets.MateriaSheet.GetRow(gearsetMateria.Type)!; var materia = LuminaSheets.MateriaSheet.GetRow(gearsetMateria.Type)!;
IncreaseStat(materia.BaseParam.Row, materia.Value[gearsetMateria.Grade]); IncreaseStat(materia.BaseParam.RowId, materia.Value[gearsetMateria.Grade]);
} }
cp = Math.Min(cp, CalculateParamCap(item, ParamCP)); cp = Math.Min(cp, CalculateParamCap(item, ParamCP));
@@ -126,16 +126,16 @@ public static unsafe class Gearsets
var luminaItem = LuminaSheets.ItemSheet.GetRow(item.ItemId)!; var luminaItem = LuminaSheets.ItemSheet.GetRow(item.ItemId)!;
// Soul Crystal ItemUICategory DoH Category // Soul Crystal ItemUICategory DoH Category
return luminaItem.ItemUICategory.Row == 62 && luminaItem.ClassJobUse.Value!.ClassJobCategory.Row == 33; return luminaItem.ItemUICategory.RowId == 62 && luminaItem.ClassJobUse.Value.ClassJobCategory.RowId == 33;
} }
public static bool IsSplendorousTool(GearsetItem item) => public static bool IsSplendorousTool(GearsetItem item) =>
LuminaSheets.ItemSheetEnglish.GetRow(item.ItemId)!.Description.ToDalamudString().TextValue.Contains("Increases to quality are 1.75 times higher than normal when material condition is Good.", StringComparison.Ordinal); LuminaSheets.ItemSheetEnglish.GetRow(item.ItemId).Description.ExtractText().Contains("Increases to quality are 1.75 times higher than normal when material condition is Good.", StringComparison.Ordinal);
// https://github.com/ffxiv-teamcraft/ffxiv-teamcraft/blob/24d0db2d9676f264edf53651b21005305267c84c/apps/client/src/app/modules/gearsets/materia.service.ts#L265 // https://github.com/ffxiv-teamcraft/ffxiv-teamcraft/blob/24d0db2d9676f264edf53651b21005305267c84c/apps/client/src/app/modules/gearsets/materia.service.ts#L265
private static int CalculateParamCap(Item item, uint paramId) private static int CalculateParamCap(Item item, uint paramId)
{ {
var ilvl = item.LevelItem.Value!; var ilvl = item.LevelItem.Value;
var param = LuminaSheets.BaseParamSheet.GetRow(paramId)!; var param = LuminaSheets.BaseParamSheet.GetRow(paramId)!;
var baseValue = paramId switch var baseValue = paramId switch
@@ -146,7 +146,7 @@ public static unsafe class Gearsets
_ => 0 _ => 0
}; };
// https://github.com/ffxiv-teamcraft/ffxiv-teamcraft/blob/24d0db2d9676f264edf53651b21005305267c84c/apps/data-extraction/src/extractors/items.extractor.ts#L6 // https://github.com/ffxiv-teamcraft/ffxiv-teamcraft/blob/24d0db2d9676f264edf53651b21005305267c84c/apps/data-extraction/src/extractors/items.extractor.ts#L6
var slotMod = item.EquipSlotCategory.Row switch var slotMod = item.EquipSlotCategory.RowId switch
{ {
1 => param.OneHandWeaponPercent, // column 4 1 => param.OneHandWeaponPercent, // column 4
2 => param.OffHandPercent, // column 5 2 => param.OffHandPercent, // column 5
+22 -28
View File
@@ -1,7 +1,6 @@
using Craftimizer.Plugin; using Craftimizer.Plugin;
using Craftimizer.Simulator; using Craftimizer.Simulator;
using ExdSheets; using ExdSheets.Sheets;
using Lumina.Excel;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -18,7 +17,7 @@ public sealed record RecipeData
public ClassJob ClassJob { get; } public ClassJob ClassJob { get; }
public RecipeInfo RecipeInfo { get; } public RecipeInfo RecipeInfo { get; }
public bool IsCollectable => Recipe.ItemResult.Value?.AlwaysCollectable ?? false; public bool IsCollectable => Recipe.ItemResult.ValueNullable?.AlwaysCollectable ?? false;
public IReadOnlyList<int?>? CollectableThresholds { 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; }
@@ -28,11 +27,11 @@ public sealed record RecipeData
{ {
RecipeId = recipeId; RecipeId = recipeId;
Recipe = LuminaSheets.RecipeSheet.GetRow(recipeId) ?? Recipe = LuminaSheets.RecipeSheet.TryGetRow(recipeId) ??
throw new ArgumentException($"Invalid recipe id {recipeId}", nameof(recipeId)); throw new ArgumentException($"Invalid recipe id {recipeId}", nameof(recipeId));
Table = Recipe.RecipeLevelTable.Value!; Table = Recipe.RecipeLevelTable.Value;
ClassJob = (ClassJob)Recipe.CraftType.Row; ClassJob = (ClassJob)Recipe.CraftType.RowId;
RecipeInfo = new() RecipeInfo = new()
{ {
IsExpert = Recipe.IsExpert, IsExpert = Recipe.IsExpert,
@@ -48,49 +47,44 @@ public sealed record RecipeData
}; };
int[]? thresholds = null; int[]? thresholds = null;
if (Recipe.CollectableMetadata is LazyRow<CollectablesShopRefine> { Value: { } row }) if (Recipe.CollectableMetadata.TryGetValue<CollectablesShopRefine>() is { } row)
thresholds = [row.LowCollectability, row.MidCollectability, row.HighCollectability]; thresholds = [row.LowCollectability, row.MidCollectability, row.HighCollectability];
else if (Recipe.CollectableMetadata is LazyRow<HWDCrafterSupply> { Value: { } row2 }) else if (Recipe.CollectableMetadata.TryGetValue<HWDCrafterSupply>() is { } row2)
{ {
foreach (var entry in row2.HWDCrafterSupplyParams) foreach (var entry in row2.HWDCrafterSupplyParams)
{ {
if (entry.ItemTradeIn.Row == Recipe.ItemResult.Row) if (entry.ItemTradeIn.RowId == Recipe.ItemResult.RowId)
{ {
thresholds = [entry.BaseCollectableRating, entry.MidCollectableRating, entry.HighCollectableRating]; thresholds = [entry.BaseCollectableRating, entry.MidCollectableRating, entry.HighCollectableRating];
break; break;
} }
} }
} }
else if (Recipe.CollectableMetadata is LazyRow<SatisfactionSupply> { } row4) else if (Recipe.CollectableMetadata.TryGetValue<SatisfactionSupply>() is { } row3)
{ {
var subRowCount = LuminaSheets.SatisfactionSupplySheet.GetSubRowCount(row4.Row); var subrowCount = LuminaSheets.SatisfactionSupplySheet.GetSubrowCount(row3.RowId);
if (subRowCount is { } subRowValue) for (ushort i = 0; i < subrowCount; ++i)
{ {
for (uint i = 0; i < subRowValue; ++i) var subrow = LuminaSheets.SatisfactionSupplySheet.GetRow(row3.RowId, i);
if (subrow.Item.RowId == Recipe.ItemResult.RowId)
{ {
var subRow = LuminaSheets.SatisfactionSupplySheet.GetRow(row4.Row, i); thresholds = [subrow.CollectabilityLow, subrow.CollectabilityMid, subrow.CollectabilityHigh];
if (subRow == null)
continue;
if (subRow.Item.Row == Recipe.ItemResult.Row)
{
thresholds = [subRow.CollectabilityLow, subRow.CollectabilityMid, subRow.CollectabilityHigh];
break; break;
} }
} }
} }
} else if (Recipe.CollectableMetadata.TryGetValue<SharlayanCraftWorksSupply>() is { } row5)
else if (Recipe.CollectableMetadata is LazyRow<SharlayanCraftWorksSupply> { Value: { } row5 })
{ {
foreach (var item in row5.Item) foreach (var item in row5.Item)
{ {
if (item.ItemId.Row == Recipe.ItemResult.Row) if (item.ItemId.RowId == Recipe.ItemResult.RowId)
{ {
thresholds = [0, item.CollectabilityMid, item.CollectabilityHigh]; thresholds = [0, item.CollectabilityMid, item.CollectabilityHigh];
break; break;
} }
} }
} }
else if (Recipe.CollectableMetadata is LazyRow<CollectablesRefine> { Value: { } row6 }) else if (Recipe.CollectableMetadata.TryGetValue<CollectablesRefine>() is { } row6)
{ {
if (row6.CollectabilityHigh != 0) if (row6.CollectabilityHigh != 0)
thresholds = [row6.CollectabilityLow, row6.CollectabilityMid, row6.CollectabilityHigh]; thresholds = [row6.CollectabilityLow, row6.CollectabilityMid, row6.CollectabilityHigh];
@@ -102,12 +96,12 @@ public sealed record RecipeData
Ingredients = Recipe.Ingredient.Zip(Recipe.AmountIngredient) Ingredients = Recipe.Ingredient.Zip(Recipe.AmountIngredient)
.Take(6) .Take(6)
.Where(i => i.First.Value != null) .Where(i => i.First.IsValid)
.Select(i => (i.First.Value!, (int)i.Second)) .Select(i => (i.First.Value, (int)i.Second))
.ToList(); .ToList();
MaxStartingQuality = (int)Math.Floor(Recipe.MaterialQualityFactor * RecipeInfo.MaxQuality / 100f); MaxStartingQuality = (int)Math.Floor(Recipe.MaterialQualityFactor * RecipeInfo.MaxQuality / 100f);
TotalHqILvls = (int)Ingredients.Where(i => i.Item.CanBeHq).Sum(i => i.Item.LevelItem.Row * i.Amount); TotalHqILvls = (int)Ingredients.Where(i => i.Item.CanBeHq).Sum(i => i.Item.LevelItem.RowId * i.Amount);
} }
public int CalculateItemStartingQuality(int itemIdx, int amount) public int CalculateItemStartingQuality(int itemIdx, int amount)
@@ -120,7 +114,7 @@ public sealed record RecipeData
if (!ingredient.Item.CanBeHq) if (!ingredient.Item.CanBeHq)
return 0; return 0;
var iLvls = ingredient.Item.LevelItem.Row * amount; var iLvls = ingredient.Item.LevelItem.RowId * amount;
return (int)Math.Floor((float)iLvls / TotalHqILvls * MaxStartingQuality); return (int)Math.Floor((float)iLvls / TotalHqILvls * MaxStartingQuality);
} }
@@ -129,7 +123,7 @@ public sealed record RecipeData
if (TotalHqILvls == 0) if (TotalHqILvls == 0)
return 0; return 0;
var iLvls = Ingredients.Zip(hqQuantities).Sum(i => i.First.Item.LevelItem.Row * i.Second); var iLvls = Ingredients.Zip(hqQuantities).Sum(i => i.First.Item.LevelItem.RowId * i.Second);
return (int)Math.Floor((float)iLvls / TotalHqILvls * MaxStartingQuality); return (int)Math.Floor((float)iLvls / TotalHqILvls * MaxStartingQuality);
} }
+25 -15
View File
@@ -12,7 +12,6 @@ using Dalamud.Interface.ManagedFontAtlas;
using Dalamud.Interface.Utility; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -23,6 +22,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Sim = Craftimizer.Simulator.Simulator; using Sim = Craftimizer.Simulator.Simulator;
using SimNoRandom = Craftimizer.Simulator.SimulatorNoRandom; using SimNoRandom = Craftimizer.Simulator.SimulatorNoRandom;
using Recipe = ExdSheets.Sheets.Recipe;
namespace Craftimizer.Windows; namespace Craftimizer.Windows;
@@ -376,7 +376,7 @@ public sealed class MacroEditor : Window, IDisposable
} }
ImGui.SameLine(0, 5); ImGui.SameLine(0, 5);
{ {
var manipLevel = ActionType.Manipulation.GetActionRow(RecipeData.ClassJob).Action!.ClassJobLevel; var manipLevel = ActionType.Manipulation.GetActionRow(RecipeData.ClassJob).Action!.Value.ClassJobLevel;
using (var d = ImRaii.Disabled(manipLevel > CharacterStats.Level)) using (var d = ImRaii.Disabled(manipLevel > CharacterStats.Level))
{ {
var v = CharacterStats.CanUseManipulation && manipLevel <= CharacterStats.Level; var v = CharacterStats.CanUseManipulation && manipLevel <= CharacterStats.Level;
@@ -586,7 +586,7 @@ public sealed class MacroEditor : Window, IDisposable
if (input.ItemId == 0) if (input.ItemId == 0)
return "None"; return "None";
var name = LuminaSheets.ItemSheet.GetRow(input.ItemId)?.Name.ToDalamudString().ToString() ?? $"Unknown ({input.ItemId})"; var name = LuminaSheets.ItemSheet.TryGetRow(input.ItemId)?.Name.ExtractText() ?? $"Unknown ({input.ItemId})";
return input.IsHQ ? $"{name} (HQ)" : name; return input.IsHQ ? $"{name} (HQ)" : name;
} }
@@ -727,6 +727,16 @@ public sealed class MacroEditor : Window, IDisposable
return (int)Math.Ceiling((y - b) / (c + 1)); return (int)Math.Ceiling((y - b) / (c + 1));
} }
private readonly struct RecipeWrapper(Recipe recipe) : IEquatable<RecipeWrapper>
{
public readonly Recipe Recipe = recipe;
public bool Equals(RecipeWrapper other) =>
Recipe.RowId == other.Recipe.RowId;
}
private readonly List<RecipeWrapper> searchableRecipes = LuminaSheets.RecipeSheet.Where(r => r.RecipeLevelTable.RowId != 0 && r.ItemResult.RowId != 0).Select(r => new RecipeWrapper(r)).ToList();
private bool DrawRecipeParams() private bool DrawRecipeParams()
{ {
var oldStartingQuality = StartingQuality; var oldStartingQuality = StartingQuality;
@@ -752,29 +762,29 @@ public sealed class MacroEditor : Window, IDisposable
(isExpert ? badgeSize.X + 3 : 0); (isExpert ? badgeSize.X + 3 : 0);
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
ImGui.Image(Service.IconManager.GetIconCached(RecipeData.Recipe.ItemResult.Value!.Icon).ImGuiHandle, new Vector2(imageSize)); ImGui.Image(Service.IconManager.GetIconCached(RecipeData.Recipe.ItemResult.Value.Icon).ImGuiHandle, new Vector2(imageSize));
ImGui.SameLine(0, 5); ImGui.SameLine(0, 5);
ushort? newRecipe = null; ushort? newRecipe = null;
{ {
var recipe = RecipeData.Recipe; var recipe = new RecipeWrapper(RecipeData.Recipe);
using var lockedFontHandle = AxisFont.Available ? AxisFont.Lock() : null; using var lockedFontHandle = AxisFont.Available ? AxisFont.Lock() : null;
var fontHandle = lockedFontHandle?.ImFont ?? ImGui.GetFont(); var fontHandle = lockedFontHandle?.ImFont ?? ImGui.GetFont();
if (ImGuiUtils.SearchableCombo( if (ImGuiUtils.SearchableCombo(
"combo", "combo",
ref recipe, ref recipe,
LuminaSheets.RecipeSheet.Where(r => r.RecipeLevelTable.Row != 0 && r.ItemResult.Row != 0), searchableRecipes,
fontHandle, fontHandle,
ImGui.GetContentRegionAvail().X - rightSideWidth, ImGui.GetContentRegionAvail().X - rightSideWidth,
r => r.ItemResult.Value!.Name.ToDalamudString().ToString(), r => r.Recipe.ItemResult.Value.Name.ExtractText(),
r => r.RowId.ToString(), r => r.Recipe.RowId.ToString(),
r => r =>
{ {
ImGui.TextUnformatted($"{r.ItemResult.Value!.Name.ToDalamudString()}"); ImGui.TextUnformatted($"{r.Recipe.ItemResult.Value.Name.ExtractText()}");
var classJob = (ClassJob)r.CraftType.Row; var classJob = (ClassJob)r.Recipe.CraftType.RowId;
var textLevel = SqText.LevelPrefix.ToIconChar() + SqText.ToLevelString(r.RecipeLevelTable.Value!.ClassJobLevel); var textLevel = SqText.LevelPrefix.ToIconChar() + SqText.ToLevelString(r.Recipe.RecipeLevelTable.Value!.ClassJobLevel);
var textLevelSize = ImGui.CalcTextSize(textLevel); var textLevelSize = ImGui.CalcTextSize(textLevel);
ImGui.SameLine(); ImGui.SameLine();
@@ -796,7 +806,7 @@ public sealed class MacroEditor : Window, IDisposable
ImGui.TextUnformatted(textLevel); ImGui.TextUnformatted(textLevel);
})) }))
{ {
newRecipe = (ushort)recipe.RowId; newRecipe = (ushort)recipe.Recipe.RowId;
} }
} }
@@ -923,10 +933,10 @@ public sealed class MacroEditor : Window, IDisposable
{ {
var perItem = RecipeData.CalculateItemStartingQuality(idx, 1); var perItem = RecipeData.CalculateItemStartingQuality(idx, 1);
var total = RecipeData.CalculateItemStartingQuality(idx, hqCount); var total = RecipeData.CalculateItemStartingQuality(idx, hqCount);
ImGuiUtils.Tooltip($"{ingredient.Item.Name.ToDalamudString()} {SeIconChar.HighQuality.ToIconString()}\n+{perItem} Quality/Item{(total > 0 ? $"\n+{total} Quality" : "")}"); ImGuiUtils.Tooltip($"{ingredient.Item.Name.ExtractText()} {SeIconChar.HighQuality.ToIconString()}\n+{perItem} Quality/Item{(total > 0 ? $"\n+{total} Quality" : "")}");
} }
else if (ingredient.Amount != 0) else if (ingredient.Amount != 0)
ImGuiUtils.Tooltip($"{ingredient.Item.Name.ToDalamudString()}"); ImGuiUtils.Tooltip($"{ingredient.Item.Name.ExtractText()}");
} }
ImGui.SameLine(0, 5); ImGui.SameLine(0, 5);
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - (5 + ImGui.CalcTextSize("/").X + 5 + ImGui.CalcTextSize($"99").X)); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - (5 + ImGui.CalcTextSize("/").X + 5 + ImGui.CalcTextSize($"99").X));
@@ -1137,7 +1147,7 @@ public sealed class MacroEditor : Window, IDisposable
{ {
var status = effect.Status(); var status = effect.Status();
using var _reset = ImRaii.DefaultFont(); using var _reset = ImRaii.DefaultFont();
ImGuiUtils.Tooltip($"{status.Name.ToDalamudString()}\n{status.Description.ToDalamudString()}"); ImGuiUtils.Tooltip($"{status.Name.ExtractText()}\n{status.Description.ExtractText()}");
} }
ImGui.SameLine(); ImGui.SameLine();
} }
+13 -13
View File
@@ -527,7 +527,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
ImGuiUtils.TextCentered($"You do not have {RecipeData.ClassJob.GetName()} unlocked."); ImGuiUtils.TextCentered($"You do not have {RecipeData.ClassJob.GetName()} unlocked.");
ImGui.Separator(); ImGui.Separator();
var unlockQuest = RecipeData.ClassJob.GetUnlockQuest(); var unlockQuest = RecipeData.ClassJob.GetUnlockQuest();
var (questGiver, questTerritory, questLocation, mapPayload) = ResolveLevelData(unlockQuest.IssuerLocation.Row); var (questGiver, questTerritory, questLocation, mapPayload) = ResolveLevelData(unlockQuest.IssuerLocation.RowId);
var unlockText = $"Unlock it from {questGiver}"; var unlockText = $"Unlock it from {questGiver}";
ImGuiUtils.AlignCentered(ImGui.CalcTextSize(unlockText).X + 5 + ImGui.GetFrameHeight()); ImGuiUtils.AlignCentered(ImGui.CalcTextSize(unlockText).X + 5 + ImGui.GetFrameHeight());
@@ -580,7 +580,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
case CraftableStatus.RequiredItem: case CraftableStatus.RequiredItem:
{ {
var item = RecipeData.Recipe.ItemRequired.Value!; var item = RecipeData.Recipe.ItemRequired.Value!;
var itemName = item.Name.ToDalamudString().ToString(); var itemName = item.Name.ExtractText();
var imageSize = ImGui.GetFrameHeight(); var imageSize = ImGui.GetFrameHeight();
ImGuiUtils.TextCentered($"You are missing the required equipment."); ImGuiUtils.TextCentered($"You are missing the required equipment.");
@@ -594,7 +594,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
case CraftableStatus.RequiredStatus: case CraftableStatus.RequiredStatus:
{ {
var status = RecipeData.Recipe.StatusRequired.Value!; var status = RecipeData.Recipe.StatusRequired.Value!;
var statusName = status.Name.ToDalamudString().ToString(); var statusName = status.Name.ExtractText();
var statusIcon = Service.IconManager.GetIconCached(status.Icon); var statusIcon = Service.IconManager.GetIconCached(status.Icon);
var imageSize = new Vector2(ImGui.GetFrameHeight() * (statusIcon.AspectRatio ?? 1), ImGui.GetFrameHeight()); var imageSize = new Vector2(ImGui.GetFrameHeight() * (statusIcon.AspectRatio ?? 1), ImGui.GetFrameHeight());
@@ -1073,16 +1073,16 @@ public sealed unsafe class RecipeNote : Window, IDisposable
return CraftableStatus.SpecialistRequired; return CraftableStatus.SpecialistRequired;
var itemRequired = RecipeData.Recipe.ItemRequired; var itemRequired = RecipeData.Recipe.ItemRequired;
if (itemRequired.Row != 0 && itemRequired.Value != null) if (itemRequired.RowId != 0 && itemRequired.IsValid)
{ {
if (!gearItems.Any(i => Gearsets.IsItem(i, itemRequired.Row))) if (!gearItems.Any(i => Gearsets.IsItem(i, itemRequired.RowId)))
return CraftableStatus.RequiredItem; return CraftableStatus.RequiredItem;
} }
var statusRequired = RecipeData.Recipe.StatusRequired; var statusRequired = RecipeData.Recipe.StatusRequired;
if (statusRequired.Row != 0 && statusRequired.Value != null) if (statusRequired.RowId != 0 && statusRequired.IsValid)
{ {
if (!Service.ClientState.LocalPlayer!.StatusList.Any(s => s.StatusId == statusRequired.Row)) if (!Service.ClientState.LocalPlayer!.StatusList.Any(s => s.StatusId == statusRequired.RowId))
return CraftableStatus.RequiredStatus; return CraftableStatus.RequiredStatus;
} }
@@ -1097,24 +1097,24 @@ public sealed unsafe class RecipeNote : Window, IDisposable
private static (string NpcName, string Territory, Vector2 MapLocation, MapLinkPayload Payload) ResolveLevelData(uint levelRowId) private static (string NpcName, string Territory, Vector2 MapLocation, MapLinkPayload Payload) ResolveLevelData(uint levelRowId)
{ {
var level = LuminaSheets.LevelSheet.GetRow(levelRowId) ?? var level = LuminaSheets.LevelSheet.TryGetRow(levelRowId) ??
throw new ArgumentNullException(nameof(levelRowId), $"Invalid level row {levelRowId}"); throw new ArgumentNullException(nameof(levelRowId), $"Invalid level row {levelRowId}");
var territory = level.Territory.Value!.PlaceName.Value!.Name.ToDalamudString().ToString(); var territory = level.Territory.Value.PlaceName.Value.Name.ExtractText();
var location = WorldToMap2(new(level.X, level.Z), level.Map.Value!); var location = WorldToMap2(new(level.X, level.Z), level.Map.Value!);
return (ResolveNpcResidentName(level.Object.Row), territory, location, new(level.Territory.Row, level.Map.Row, location.X, location.Y)); return (ResolveNpcResidentName(level.Object.RowId), territory, location, new(level.Territory.RowId, level.Map.RowId, location.X, location.Y));
} }
private static Vector2 WorldToMap2(Vector2 worldCoordinates, ExdSheets.Map map) private static Vector2 WorldToMap2(Vector2 worldCoordinates, ExdSheets.Sheets.Map map)
{ {
return MapUtil.WorldToMap(worldCoordinates, map.OffsetX, map.OffsetY, map.SizeFactor); return MapUtil.WorldToMap(worldCoordinates, map.OffsetX, map.OffsetY, map.SizeFactor);
} }
private static string ResolveNpcResidentName(uint npcRowId) private static string ResolveNpcResidentName(uint npcRowId)
{ {
var resident = LuminaSheets.ENpcResidentSheet.GetRow(npcRowId) ?? var resident = LuminaSheets.ENpcResidentSheet.TryGetRow(npcRowId) ??
throw new ArgumentNullException(nameof(npcRowId), $"Invalid npc row {npcRowId}"); throw new ArgumentNullException(nameof(npcRowId), $"Invalid npc row {npcRowId}");
return resident.Singular.ToDalamudString().ToString(); return resident.Singular.ExtractText();
} }
private static int? GetGearsetForJob(ClassJob job) private static int? GetGearsetForJob(ClassJob job)
+1 -2
View File
@@ -10,7 +10,6 @@ using Dalamud.Interface.ManagedFontAtlas;
using Dalamud.Interface.Utility; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
@@ -382,7 +381,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
{ {
var status = effect.Status(); var status = effect.Status();
using var _reset = ImRaii.DefaultFont(); using var _reset = ImRaii.DefaultFont();
ImGuiUtils.Tooltip($"{status.Name.ToDalamudString()}\n{status.Description.ToDalamudString()}"); ImGuiUtils.Tooltip($"{status.Name.ExtractText()}\n{status.Description.ExtractText()}");
} }
ImGui.SameLine(); ImGui.SameLine();
} }
+22 -13
View File
@@ -10,18 +10,21 @@
}, },
"ExdSheets": { "ExdSheets": {
"type": "Direct", "type": "Direct",
"requested": "[1.2.2, )", "requested": "[2.1.0, )",
"resolved": "1.2.2", "resolved": "2.1.0",
"contentHash": "oS1oUBhlOpUWY1Wc3SwOLzfAMuSRzBn54I8p84euVUHrUEOzRZwA9vuNKNMAIY66eT1dpc/DxT+C7LNH0nK0jg==", "contentHash": "SfvLFyL8LYsW4AzPLFVfFwtKPl9xegGraIe9oFar3IlWW8Z4kf5dkM+1CiSr/J+PQt4xt2QZc/ydZ4ibs3RosA==",
"dependencies": { "dependencies": {
"Lumina": "3.15.2" "Lumina": "4.1.1"
} }
}, },
"Lumina": { "Lumina": {
"type": "Direct", "type": "Direct",
"requested": "[3.15.2, )", "requested": "[4.1.1, )",
"resolved": "3.15.2", "resolved": "4.1.1",
"contentHash": "EnoxYEYMepcvAoXdZhaFJiv2aiDBIPjgkgzxR/+ArOxlrALzCgheTsb5yD39a9sxNIi2tNECT93ulZvYjx8fZg==" "contentHash": "Hd+iTtdaPACTpViXaJ/+sQ3ZQ8MEpApCSD+mxTXnUTYDSZOAipuC4LsZqhAkLMeQHSK/R/jiXEXaXS7e0mTXyA==",
"dependencies": {
"Microsoft.Extensions.ObjectPool": "9.0.0-preview.1.24081.5"
}
}, },
"MathNet.Numerics": { "MathNet.Numerics": {
"type": "Direct", "type": "Direct",
@@ -31,14 +34,20 @@
}, },
"Meziantou.Analyzer": { "Meziantou.Analyzer": {
"type": "Direct", "type": "Direct",
"requested": "[2.0.162, )", "requested": "[2.0.163, )",
"resolved": "2.0.162", "resolved": "2.0.163",
"contentHash": "lU5ZkiNx6Jj++yYhkUkn2qsgl+PSfAy+BDFc0IkoVVeSCnmUOGBa0Eb1XzGLAeyAuIoz6vYN4J97Q/uiGdIkhw==" "contentHash": "vN0YmOkuvPLukMsefLHYCWYaLPzpc6SfoR74aPwuLeK8QdxgxkavywQ1q/II0shLEEaN1RhlMjmL1RxMPW853w=="
},
"Microsoft.Extensions.ObjectPool": {
"type": "Direct",
"requested": "[9.0.0-preview.1.24081.5, )",
"resolved": "9.0.0-preview.1.24081.5",
"contentHash": "aAR7YW+pUUdvHk3vj7GtAi71dWGDIuY9270lsmQ6lKw23zzY+r8pLP3cGNbJdlnA9VWl+S+gnIVkBCqj2ROlEg=="
}, },
"DotNext": { "DotNext": {
"type": "Transitive", "type": "Transitive",
"resolved": "5.8.0", "resolved": "5.11.0",
"contentHash": "5PwF7lUwgJKMcQRrMnFo8ilqrFq9OyaQ5Lq/zFHn0LahhLriNeySCPs08Zd15FdBV0G0KpZvPHBC8Rp1LIsrhg==", "contentHash": "aLWtURne05gwWFFsOg9/X1g4V5yHyuWHX5paQIN7pJIDLCbaCDHcQlLeRRvzvksjAflZJ7tTHkowN/Xi1NXPrA==",
"dependencies": { "dependencies": {
"System.IO.Hashing": "8.0.0" "System.IO.Hashing": "8.0.0"
} }
@@ -55,7 +64,7 @@
"type": "Project", "type": "Project",
"dependencies": { "dependencies": {
"Craftimizer.Simulator": "[1.0.0, )", "Craftimizer.Simulator": "[1.0.0, )",
"DotNext": "[5.8.0, )" "DotNext": "[5.11.0, )"
} }
} }
} }
+1 -1
View File
@@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.162"> <PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
+2 -2
View File
@@ -10,8 +10,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DotNext" Version="5.8.0" /> <PackageReference Include="DotNext" Version="5.11.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.162"> <PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
+1 -1
View File
@@ -11,7 +11,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.162"> <PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>