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