Calculate optimal gearset choice on a separate thread
This commit is contained in:
parent
ae706b0461
commit
1845ebf701
@ -1,6 +1,6 @@
|
||||
<Project Sdk="Dalamud.NET.Sdk/9.0.2">
|
||||
<PropertyGroup>
|
||||
<Version>1.0</Version>
|
||||
<Version>1.1</Version>
|
||||
<OutputPath>dist</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
@ -121,6 +122,7 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
|
||||
private unsafe void ShowUpgrades(byte? level = null)
|
||||
{
|
||||
DateTime start = DateTime.Now;
|
||||
var inventoryItems = GetAllInventoryItems();
|
||||
|
||||
var gearsetModule = RaptureGearsetModule.Instance();
|
||||
@ -131,7 +133,7 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
if (onlyCurrentJob)
|
||||
_chatGui.Print("Checking only gearsets for your current class/job...");
|
||||
|
||||
bool anyUpgrade = false;
|
||||
List<GearsetData> gearsets = new List<GearsetData>();
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
var gearset = gearsetModule->GetGearset(i);
|
||||
@ -140,44 +142,65 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
if (onlyCurrentJob && gearset->ClassJob != _clientState.LocalPlayer!.ClassJob.Id)
|
||||
continue;
|
||||
|
||||
anyUpgrade |= HandleGearset(gearset, inventoryItems, level);
|
||||
var gearsetData = PrepareGearset(gearset);
|
||||
if (gearsetData != null)
|
||||
gearsets.Add(gearsetData);
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyUpgrade)
|
||||
_chatGui.Print("All your gearsets are OK.");
|
||||
_pluginLog.Information($"Preparing gearsets took {DateTime.Now - start}");
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
start = DateTime.Now;
|
||||
bool anyUpgrade = false;
|
||||
foreach (GearsetData gearset in gearsets)
|
||||
anyUpgrade |= HandleGearset(gearset, inventoryItems, level);
|
||||
|
||||
if (!anyUpgrade)
|
||||
_chatGui.Print("All your gearsets are OK.");
|
||||
|
||||
_pluginLog.Information($"Evaluating gearsets took {DateTime.Now - start}");
|
||||
});
|
||||
}
|
||||
|
||||
private unsafe bool HandleGearset(RaptureGearsetModule.GearsetEntry* gearset,
|
||||
Dictionary<(uint ItemId, bool Hq), List<MateriaStats>> inventoryItems, byte? level)
|
||||
private unsafe GearsetData? PrepareGearset(RaptureGearsetModule.GearsetEntry* gearset)
|
||||
{
|
||||
string name = GetGearsetName(gearset);
|
||||
if (name.Contains('_', StringComparison.Ordinal) ||
|
||||
name.Contains("Eureka", StringComparison.OrdinalIgnoreCase) ||
|
||||
name.Contains("Bozja", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
return null;
|
||||
|
||||
List<SeString> Handle(string label, RaptureGearsetModule.GearsetItemIndex[] spanIds, EEquipSlotCategory category)
|
||||
return new GearsetData(_dataManager, gearset, name);
|
||||
}
|
||||
|
||||
private bool HandleGearset(GearsetData gearset,
|
||||
Dictionary<(uint ItemId, bool Hq), List<MateriaStats>> inventoryItems, byte? level)
|
||||
{
|
||||
List<SeString> Handle(string label, EquipmentItem?[] gearsetItems,
|
||||
EEquipSlotCategory category)
|
||||
{
|
||||
return HandleGearsetItem(label, gearset, spanIds.Select(x => gearset->GetItem(x)).ToArray(),
|
||||
inventoryItems, category, level);
|
||||
return HandleGearsetItem(label, gearset, gearsetItems, inventoryItems, category, level);
|
||||
}
|
||||
|
||||
List<List<SeString>> upgrades = new()
|
||||
{
|
||||
Handle("Main Hand", [RaptureGearsetModule.GearsetItemIndex.MainHand], EEquipSlotCategory.None),
|
||||
Handle("Main Hand", [gearset.MainHand], EEquipSlotCategory.None),
|
||||
HandleOffHand(gearset, inventoryItems, level),
|
||||
|
||||
Handle("Head", [RaptureGearsetModule.GearsetItemIndex.Head], EEquipSlotCategory.Head),
|
||||
Handle("Body", [RaptureGearsetModule.GearsetItemIndex.Body], EEquipSlotCategory.Body),
|
||||
Handle("Hands", [RaptureGearsetModule.GearsetItemIndex.Hands], EEquipSlotCategory.Hands),
|
||||
Handle("Legs", [RaptureGearsetModule.GearsetItemIndex.Legs], EEquipSlotCategory.Legs),
|
||||
Handle("Feet", [RaptureGearsetModule.GearsetItemIndex.Feet], EEquipSlotCategory.Feet),
|
||||
Handle("Head", [gearset.Head], EEquipSlotCategory.Head),
|
||||
Handle("Body", [gearset.Body], EEquipSlotCategory.Body),
|
||||
Handle("Hands", [gearset.Hands], EEquipSlotCategory.Hands),
|
||||
Handle("Legs", [gearset.Legs], EEquipSlotCategory.Legs),
|
||||
Handle("Feet", [gearset.Feet], EEquipSlotCategory.Feet),
|
||||
|
||||
Handle("Ears", [RaptureGearsetModule.GearsetItemIndex.Ears], EEquipSlotCategory.Ears),
|
||||
Handle("Neck", [RaptureGearsetModule.GearsetItemIndex.Neck], EEquipSlotCategory.Neck),
|
||||
Handle("Wrists", [RaptureGearsetModule.GearsetItemIndex.Wrists], EEquipSlotCategory.Wrists),
|
||||
Handle("Rings", [RaptureGearsetModule.GearsetItemIndex.RingLeft, RaptureGearsetModule.GearsetItemIndex.RingRight], EEquipSlotCategory.Rings),
|
||||
Handle("Ears", [gearset.Ears], EEquipSlotCategory.Ears),
|
||||
Handle("Neck", [gearset.Neck], EEquipSlotCategory.Neck),
|
||||
Handle("Wrists", [gearset.Wrists], EEquipSlotCategory.Wrists),
|
||||
Handle("Rings",
|
||||
[gearset.RingLeft, gearset.RingRight],
|
||||
EEquipSlotCategory.Rings),
|
||||
};
|
||||
|
||||
List<SeString> flatUpgrades = upgrades.SelectMany(x => x).ToList();
|
||||
@ -188,9 +211,9 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
new SeStringBuilder()
|
||||
.Append("Gearset ")
|
||||
.AddUiForeground(1)
|
||||
.Add(_linkPayloads[gearset->Id])
|
||||
.Append($"#{gearset->Id + 1}: ")
|
||||
.Append(name)
|
||||
.Add(_linkPayloads[gearset.Id])
|
||||
.Append($"#{gearset.Id + 1}: ")
|
||||
.Append(gearset.Name)
|
||||
.Add(RawPayload.LinkTerminator)
|
||||
.AddUiForegroundOff()
|
||||
.AddText(level != null ? $" at {level}" : "")
|
||||
@ -209,20 +232,18 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
private unsafe string GetGearsetName(RaptureGearsetModule.GearsetEntry* gearset)
|
||||
=> gearset->NameString.Split((char)0)[0];
|
||||
|
||||
private unsafe List<SeString> HandleGearsetItem(string label, RaptureGearsetModule.GearsetEntry* gearset,
|
||||
RaptureGearsetModule.GearsetItem[] gearsetItem,
|
||||
private List<SeString> HandleGearsetItem(string label, GearsetData gearset,
|
||||
EquipmentItem?[] gearsetItems,
|
||||
Dictionary<(uint ItemId, bool Hq), List<MateriaStats>> inventoryItems,
|
||||
EEquipSlotCategory equipSlotCategory, byte? level)
|
||||
{
|
||||
EClassJob classJob = (EClassJob)gearset->ClassJob;
|
||||
EClassJob classJob = gearset.ClassJob;
|
||||
var itemLists = _gameDataHolder.GetItemLists(classJob);
|
||||
|
||||
if (gearsetItem.Any(x => x.ItemId > 0))
|
||||
if (equipSlotCategory == EEquipSlotCategory.None && gearsetItems.Any(x => x != null))
|
||||
{
|
||||
var firstEquippedItem = gearsetItem.First(x => x.ItemId > 0);
|
||||
equipSlotCategory = (EEquipSlotCategory)(_dataManager.GetExcelSheet<Item>()!
|
||||
.GetRow(firstEquippedItem.ItemId % 1_000_000)
|
||||
?.EquipSlotCategory?.Row ?? 0);
|
||||
var firstEquippedItem = gearsetItems.First(x => x != null);
|
||||
equipSlotCategory = firstEquippedItem!.EquipSlotCategory;
|
||||
}
|
||||
|
||||
if (equipSlotCategory == EEquipSlotCategory.None)
|
||||
@ -231,14 +252,10 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
return new List<SeString>();
|
||||
}
|
||||
|
||||
BaseItem?[] currentItems = gearsetItem.Select(x => new
|
||||
{
|
||||
ItemId = x.ItemId % 1_000_000,
|
||||
Hq = x.ItemId > 1_000_000
|
||||
})
|
||||
BaseItem?[] currentItems = gearsetItems
|
||||
.Select(x =>
|
||||
{
|
||||
if (x.ItemId == 0)
|
||||
if (x == null)
|
||||
return null;
|
||||
|
||||
return itemLists
|
||||
@ -261,7 +278,7 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
var bestItems = availableList.Items
|
||||
.Where(x => x.Level <= level)
|
||||
.Where(x => x is Model.InventoryItem)
|
||||
.Take(gearsetItem.Length)
|
||||
.Take(gearsetItems.Length)
|
||||
.ToList();
|
||||
//_pluginLog.Debug(
|
||||
// $"{equipSlotCategory}: {string.Join(" ", currentItems.Select(x => $"{x?.ItemId}|{x?.Hq}"))}");
|
||||
@ -284,20 +301,20 @@ public sealed class GearsetterPlugin : IDalamudPlugin
|
||||
}
|
||||
|
||||
|
||||
private unsafe List<SeString> HandleOffHand(RaptureGearsetModule.GearsetEntry* gearset,
|
||||
private unsafe List<SeString> HandleOffHand(GearsetData gearset,
|
||||
Dictionary<(uint ItemId, bool Hq), List<MateriaStats>> inventoryItems, byte? level)
|
||||
{
|
||||
var mainHand = gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.MainHand);
|
||||
if (mainHand.ItemId == 0)
|
||||
var mainHand = gearset.MainHand;
|
||||
if (mainHand == null)
|
||||
return new List<SeString>();
|
||||
|
||||
// if it's a twohanded weapon, ignore it
|
||||
EEquipSlotCategory equipSlotCategory =
|
||||
(EEquipSlotCategory)(_dataManager.GetExcelSheet<Item>()!.GetRow(mainHand.ItemId % 1_000_000)?.RowId ?? 0);
|
||||
EEquipSlotCategory equipSlotCategory = mainHand.EquipSlotCategory;
|
||||
if (equipSlotCategory != EEquipSlotCategory.OneHandedMainHand)
|
||||
return new List<SeString>();
|
||||
|
||||
return HandleGearsetItem("Off Hand", gearset, [gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.OffHand)], inventoryItems,
|
||||
return HandleGearsetItem("Off Hand", gearset, [gearset.OffHand],
|
||||
inventoryItems,
|
||||
EEquipSlotCategory.Shield, level);
|
||||
}
|
||||
|
||||
|
56
Gearsetter/Model/GearsetData.cs
Normal file
56
Gearsetter/Model/GearsetData.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System.Collections.Generic;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
||||
using Gearsetter.GameData;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
|
||||
namespace Gearsetter.Model;
|
||||
|
||||
internal sealed class GearsetData
|
||||
{
|
||||
public unsafe GearsetData(IDataManager dataManager, RaptureGearsetModule.GearsetEntry* gearset, string name)
|
||||
{
|
||||
Id = gearset->Id;
|
||||
ClassJob = (EClassJob)gearset->ClassJob;
|
||||
Name = name;
|
||||
MainHand = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.MainHand);
|
||||
OffHand = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.OffHand);
|
||||
Head = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Head);
|
||||
Body = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Body);
|
||||
Hands = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Hands);
|
||||
Legs = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Legs);
|
||||
Feet = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Feet);
|
||||
Ears = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Ears);
|
||||
Neck = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Neck);
|
||||
Wrists = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.Wrists);
|
||||
RingLeft = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.RingLeft);
|
||||
RingRight = GetItem(dataManager, gearset, RaptureGearsetModule.GearsetItemIndex.RingRight);
|
||||
}
|
||||
|
||||
private static unsafe EquipmentItem? GetItem(IDataManager dataManager, RaptureGearsetModule.GearsetEntry* gearset,
|
||||
RaptureGearsetModule.GearsetItemIndex index)
|
||||
{
|
||||
var gearsetItem = gearset->GetItem(index);
|
||||
if (gearsetItem.ItemId == 0)
|
||||
return null;
|
||||
|
||||
var item = dataManager.GetExcelSheet<Item>()!.GetRow(gearsetItem.ItemId % 1_000_000)!;
|
||||
return new EquipmentItem(item, gearsetItem.ItemId > 1_000_000);
|
||||
}
|
||||
|
||||
public byte Id { get; }
|
||||
public EClassJob ClassJob { get; }
|
||||
public string Name { get; }
|
||||
public EquipmentItem? MainHand { get; }
|
||||
public EquipmentItem? OffHand { get; }
|
||||
public EquipmentItem? Head { get; }
|
||||
public EquipmentItem? Body { get; }
|
||||
public EquipmentItem? Hands { get; }
|
||||
public EquipmentItem? Legs { get; }
|
||||
public EquipmentItem? Feet { get; }
|
||||
public EquipmentItem? Ears { get; set; }
|
||||
public EquipmentItem? Neck { get; set; }
|
||||
public EquipmentItem? Wrists { get; }
|
||||
public EquipmentItem? RingLeft { get; }
|
||||
public EquipmentItem? RingRight { get; }
|
||||
}
|
@ -141,7 +141,8 @@ internal sealed class EquipmentBrowserWindow : LWindow
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
ImGui.PushStyleColor(ImGuiCol.HeaderHovered, hoverColor);
|
||||
foreach (var item in itemList.Items.DistinctBy(x => new { x.ItemId, x.Hq, Materia = x.MateriaStats?.GetHashCode() }))
|
||||
foreach (var item in itemList.Items.DistinctBy(x => new
|
||||
{ x.ItemId, x.Hq, Materia = x.MateriaStats?.GetHashCode() }))
|
||||
{
|
||||
if (item is not InventoryItem)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user