Include gearset slot to upgrade (relevant for rings) with IPC recommendations

This commit is contained in:
Liza 2024-08-28 21:01:00 +02:00
parent 18c62ba0b7
commit 49e16ab278
Signed by: liza
GPG Key ID: 7199F8D727D55F67
5 changed files with 62 additions and 36 deletions

View File

@ -27,7 +27,7 @@ public class GearsetterIpcTestPlugin : IDalamudPlugin
{ {
int currentGearsetIndex = RaptureGearsetModule.Instance()->CurrentGearsetIndex; int currentGearsetIndex = RaptureGearsetModule.Instance()->CurrentGearsetIndex;
var recommendations = _pluginInterface var recommendations = _pluginInterface
.GetIpcSubscriber<byte, List<(uint ItemId, InventoryType? SourceInventory, byte? SourceInventorySlot)>>( .GetIpcSubscriber<byte, List<(uint ItemId, InventoryType? SourceInventory, byte? SourceInventorySlot, RaptureGearsetModule.GearsetItemIndex TargetSlot)>>(
"Gearsetter.GetRecommendationsForGearset").InvokeFunc((byte)currentGearsetIndex); "Gearsetter.GetRecommendationsForGearset").InvokeFunc((byte)currentGearsetIndex);
if (recommendations.Count == 0) if (recommendations.Count == 0)
_chatGui.Print($"No recommendations for gearset #{currentGearsetIndex}."); _chatGui.Print($"No recommendations for gearset #{currentGearsetIndex}.");
@ -35,7 +35,7 @@ public class GearsetterIpcTestPlugin : IDalamudPlugin
{ {
foreach (var recommendation in recommendations) foreach (var recommendation in recommendations)
_chatGui.Print( _chatGui.Print(
$"Recommendation: Equip item {recommendation.ItemId} from {recommendation.SourceInventory} (slot {recommendation.SourceInventorySlot})"); $"Recommendation: Equip item {recommendation.ItemId} from {recommendation.SourceInventory} (slot {recommendation.SourceInventorySlot}) as {recommendation.TargetSlot}");
} }
} }

View File

@ -17,7 +17,8 @@ internal sealed class GearsetterIpc : IDisposable
private readonly IPluginLog _pluginLog; private readonly IPluginLog _pluginLog;
private readonly ICallGateProvider<byte, private readonly ICallGateProvider<byte,
List<(uint ItemId, InventoryType? SourceInventory, int? SourceInventorySlot)>> List<(uint ItemId, InventoryType? SourceInventory, int? SourceInventorySlot,
RaptureGearsetModule.GearsetItemIndex TargetSlot)>>
_getRecommendationsForGearset; _getRecommendationsForGearset;
public GearsetterIpc(GearsetterPlugin plugin, IDalamudPluginInterface pluginInterface, IPluginLog pluginLog) public GearsetterIpc(GearsetterPlugin plugin, IDalamudPluginInterface pluginInterface, IPluginLog pluginLog)
@ -25,11 +26,15 @@ internal sealed class GearsetterIpc : IDisposable
_plugin = plugin; _plugin = plugin;
_pluginLog = pluginLog; _pluginLog = pluginLog;
_getRecommendationsForGearset = _getRecommendationsForGearset =
pluginInterface.GetIpcProvider<byte, List<(uint, InventoryType?, int?)>>(IpcGetRecommendationsForGearset); pluginInterface
.GetIpcProvider<byte,
List<(uint, InventoryType?, int?, RaptureGearsetModule.GearsetItemIndex TargetSlot)>>(
IpcGetRecommendationsForGearset);
_getRecommendationsForGearset.RegisterFunc(GetRecommendationsForGearset); _getRecommendationsForGearset.RegisterFunc(GetRecommendationsForGearset);
} }
private unsafe List<(uint ItemId, InventoryType? SourceInventory, int? SourceInventorySlot)> private unsafe List<(uint ItemId, InventoryType? SourceInventory, int? SourceInventorySlot,
RaptureGearsetModule.GearsetItemIndex TargetSlot)>
GetRecommendationsForGearset(byte gearsetId) GetRecommendationsForGearset(byte gearsetId)
{ {
if (gearsetId > 100) if (gearsetId > 100)
@ -48,7 +53,7 @@ internal sealed class GearsetterIpc : IDisposable
_pluginLog.Verbose($"Checking for gearset upgrades for gearset {gearset->Id}."); _pluginLog.Verbose($"Checking for gearset upgrades for gearset {gearset->Id}.");
return _plugin.GetRecommendedUpgrades(gearset) return _plugin.GetRecommendedUpgrades(gearset)
.Select(x => (x.ItemId, x.SourceInventory, x.SourceInventorySlot)) .Select(x => (x.ItemId, x.SourceInventory, x.SourceInventorySlot, x.TargetSlot))
.ToList(); .ToList();
} }

View File

@ -1,6 +1,6 @@
<Project Sdk="Dalamud.NET.Sdk/9.0.2"> <Project Sdk="Dalamud.NET.Sdk/9.0.2">
<PropertyGroup> <PropertyGroup>
<Version>1.2</Version> <Version>1.3</Version>
<OutputPath>dist</OutputPath> <OutputPath>dist</OutputPath>
</PropertyGroup> </PropertyGroup>

View File

@ -189,7 +189,8 @@ public sealed class GearsetterPlugin : IDalamudPlugin
private List<RecommendedItemChange> GetRecommendedUpgrades(GearsetData gearset, private List<RecommendedItemChange> GetRecommendedUpgrades(GearsetData gearset,
Dictionary<(uint ItemId, bool Hql), List<MateriaStats>> inventoryItems, byte? level) Dictionary<(uint ItemId, bool Hql), List<MateriaStats>> inventoryItems, byte? level)
{ {
List<RecommendedItemChange> Handle(string label, EquipmentItem?[] gearsetItems, List<RecommendedItemChange> Handle(string label,
(EquipmentItem?, RaptureGearsetModule.GearsetItemIndex)[] gearsetItems,
EEquipSlotCategory category) EEquipSlotCategory category)
{ {
return HandleGearsetItem(label, gearset, gearsetItems, inventoryItems, category, level); return HandleGearsetItem(label, gearset, gearsetItems, inventoryItems, category, level);
@ -197,20 +198,25 @@ public sealed class GearsetterPlugin : IDalamudPlugin
List<List<RecommendedItemChange>> upgrades = new() List<List<RecommendedItemChange>> upgrades = new()
{ {
Handle("Main Hand", [gearset.MainHand], EEquipSlotCategory.None), Handle("Main Hand", [(gearset.MainHand, RaptureGearsetModule.GearsetItemIndex.MainHand)],
EEquipSlotCategory.None),
HandleOffHand(gearset, inventoryItems, level), HandleOffHand(gearset, inventoryItems, level),
Handle("Head", [gearset.Head], EEquipSlotCategory.Head), Handle("Head", [(gearset.Head, RaptureGearsetModule.GearsetItemIndex.Head)], EEquipSlotCategory.Head),
Handle("Body", [gearset.Body], EEquipSlotCategory.Body), Handle("Body", [(gearset.Body, RaptureGearsetModule.GearsetItemIndex.Body)], EEquipSlotCategory.Body),
Handle("Hands", [gearset.Hands], EEquipSlotCategory.Hands), Handle("Hands", [(gearset.Hands, RaptureGearsetModule.GearsetItemIndex.Hands)], EEquipSlotCategory.Hands),
Handle("Legs", [gearset.Legs], EEquipSlotCategory.Legs), Handle("Legs", [(gearset.Legs, RaptureGearsetModule.GearsetItemIndex.Legs)], EEquipSlotCategory.Legs),
Handle("Feet", [gearset.Feet], EEquipSlotCategory.Feet), Handle("Feet", [(gearset.Feet, RaptureGearsetModule.GearsetItemIndex.Feet)], EEquipSlotCategory.Feet),
Handle("Ears", [gearset.Ears], EEquipSlotCategory.Ears), Handle("Ears", [(gearset.Ears, RaptureGearsetModule.GearsetItemIndex.Ears)], EEquipSlotCategory.Ears),
Handle("Neck", [gearset.Neck], EEquipSlotCategory.Neck), Handle("Neck", [(gearset.Neck, RaptureGearsetModule.GearsetItemIndex.Neck)], EEquipSlotCategory.Neck),
Handle("Wrists", [gearset.Wrists], EEquipSlotCategory.Wrists), Handle("Wrists", [(gearset.Wrists, RaptureGearsetModule.GearsetItemIndex.Wrists)],
EEquipSlotCategory.Wrists),
Handle("Rings", Handle("Rings",
[gearset.RingLeft, gearset.RingRight], [
(gearset.RingLeft, RaptureGearsetModule.GearsetItemIndex.RingLeft),
(gearset.RingRight, RaptureGearsetModule.GearsetItemIndex.RingRight)
],
EEquipSlotCategory.Rings), EEquipSlotCategory.Rings),
}; };
@ -251,17 +257,18 @@ public sealed class GearsetterPlugin : IDalamudPlugin
=> gearset->NameString.Split((char)0)[0]; => gearset->NameString.Split((char)0)[0];
private List<RecommendedItemChange> HandleGearsetItem(string label, GearsetData gearset, private List<RecommendedItemChange> HandleGearsetItem(string label, GearsetData gearset,
EquipmentItem?[] gearsetItems, (EquipmentItem? Item, RaptureGearsetModule.GearsetItemIndex Slot)[] 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 = gearset.ClassJob; EClassJob classJob = gearset.ClassJob;
List<RaptureGearsetModule.GearsetItemIndex> availableGearsetSlots = gearsetItems.Select(x => x.Slot).ToList();
var itemLists = _gameDataHolder.GetItemLists(classJob); var itemLists = _gameDataHolder.GetItemLists(classJob);
if (equipSlotCategory == EEquipSlotCategory.None && gearsetItems.Any(x => x != null)) if (equipSlotCategory == EEquipSlotCategory.None && gearsetItems.Any(x => x.Item != null))
{ {
var firstEquippedItem = gearsetItems.First(x => x != null); var firstEquippedItem = gearsetItems.First(x => x.Item != null);
equipSlotCategory = firstEquippedItem!.EquipSlotCategory; equipSlotCategory = firstEquippedItem.Item!.EquipSlotCategory;
} }
if (equipSlotCategory == EEquipSlotCategory.None) if (equipSlotCategory == EEquipSlotCategory.None)
@ -270,15 +277,16 @@ public sealed class GearsetterPlugin : IDalamudPlugin
return []; return [];
} }
BaseItem?[] currentItems = gearsetItems (BaseItem? Item, RaptureGearsetModule.GearsetItemIndex Slot)[] currentItems = gearsetItems
.Select(x => .Select(x =>
{ {
if (x == null) if (x.Item == null)
return null; return (null, x.Slot);
return itemLists var baseItem = itemLists
.SelectMany(y => y.Items.Where(z => x.ItemId == z.ItemId && x.Hq == z.Hq)) .SelectMany(y => y.Items.Where(z => x.Item.ItemId == z.ItemId && x.Item.Hq == z.Hq))
.FirstOrDefault(); .FirstOrDefault();
return (baseItem, x.Slot);
}) })
.ToArray(); .ToArray();
@ -299,19 +307,28 @@ public sealed class GearsetterPlugin : IDalamudPlugin
.Take(gearsetItems.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.Item}, {x.Slot}"))}");
foreach (var currentItem in currentItems) foreach (var currentItem in currentItems)
{ {
var foundIndex = bestItems.FindIndex(x => var foundIndex = bestItems.FindIndex(x =>
currentItem != null && currentItem.ItemId == x.ItemId && currentItem.Hq == x.Hq); currentItem.Item != null && currentItem.Item.ItemId == x.ItemId && currentItem.Item.Hq == x.Hq);
if (foundIndex >= 0) if (foundIndex >= 0)
{
bestItems.RemoveAt(foundIndex); bestItems.RemoveAt(foundIndex);
availableGearsetSlots.Remove(currentItem.Slot);
}
} }
return bestItems return bestItems
.Select(x => ToItemRecommendation(x, .Select(x =>
new SeString(new TextPayload($"{label}: ")) {
.Append(SeString.CreateItemLink(x.ItemId, x.Hq)))) var slot = availableGearsetSlots[0];
availableGearsetSlots.RemoveAt(0);
return ToItemRecommendation(x, slot,
new SeString(new TextPayload($"{label}: "))
.Append(SeString.CreateItemLink(x.ItemId, x.Hq)));
})
.ToList(); .ToList();
} }
finally finally
@ -332,7 +349,8 @@ public sealed class GearsetterPlugin : IDalamudPlugin
if (equipSlotCategory != EEquipSlotCategory.OneHandedMainHand) if (equipSlotCategory != EEquipSlotCategory.OneHandedMainHand)
return []; return [];
return HandleGearsetItem("Off Hand", gearset, [gearset.OffHand], return HandleGearsetItem("Off Hand", gearset,
[(gearset.OffHand, RaptureGearsetModule.GearsetItemIndex.OffHand)],
inventoryItems, inventoryItems,
EEquipSlotCategory.Shield, level); EEquipSlotCategory.Shield, level);
} }
@ -341,7 +359,8 @@ public sealed class GearsetterPlugin : IDalamudPlugin
=> RaptureGearsetModule.Instance()->EquipGearset((byte)commandId); => RaptureGearsetModule.Instance()->EquipGearset((byte)commandId);
private unsafe RecommendedItemChange ToItemRecommendation(BaseItem baseItem, SeString text) private unsafe RecommendedItemChange ToItemRecommendation(BaseItem baseItem,
RaptureGearsetModule.GearsetItemIndex targetSlot, SeString text)
{ {
InventoryManager* inventoryManager = InventoryManager.Instance(); InventoryManager* inventoryManager = InventoryManager.Instance();
foreach (var inventoryType in _gameDataHolder.DefaultInventoryTypes) foreach (var inventoryType in _gameDataHolder.DefaultInventoryTypes)
@ -357,12 +376,12 @@ public sealed class GearsetterPlugin : IDalamudPlugin
MateriaStats actualMateriaStats = FetchMateriaStats(item); MateriaStats actualMateriaStats = FetchMateriaStats(item);
if (expectedMateriaStats == actualMateriaStats) if (expectedMateriaStats == actualMateriaStats)
return new RecommendedItemChange(item->ItemId, inventoryType, i, text); return new RecommendedItemChange(item->ItemId, inventoryType, i, targetSlot, text);
} }
} }
} }
return new RecommendedItemChange(baseItem.ItemId, null, null, text); return new RecommendedItemChange(baseItem.ItemId, null, null, targetSlot, text);
} }
internal unsafe Dictionary<(uint ItemId, bool Hq), List<MateriaStats>> GetAllInventoryItems() internal unsafe Dictionary<(uint ItemId, bool Hq), List<MateriaStats>> GetAllInventoryItems()

View File

@ -1,5 +1,6 @@
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
namespace Gearsetter.Model; namespace Gearsetter.Model;
@ -7,4 +8,5 @@ internal sealed record RecommendedItemChange(
uint ItemId, uint ItemId,
InventoryType? SourceInventory, InventoryType? SourceInventory,
int? SourceInventorySlot, int? SourceInventorySlot,
RaptureGearsetModule.GearsetItemIndex TargetSlot,
SeString Text); SeString Text);