Add BonusItem API.

This commit is contained in:
Ottermandias 2024-08-10 11:52:12 +02:00
parent 9e06125092
commit 5971592217
7 changed files with 100 additions and 8 deletions

View file

@ -35,7 +35,8 @@ public sealed class IpcProviders : IDisposable, IApiService
(a, b, c, d, e, f) => (int)api.Items.SetItem(a, (ApiEquipSlot)b, c, [d], e, (ApplyFlag)f)),
new FuncProvider<string, byte, ulong, byte, uint, ulong, int>(pi, IpcSubscribers.Legacy.SetItemName.Label,
(a, b, c, d, e, f) => (int)api.Items.SetItemName(a, (ApiEquipSlot)b, c, [d], e, (ApplyFlag)f)),
IpcSubscribers.SetBonusItem.Provider(pi, api.Items),
IpcSubscribers.SetBonusItemName.Provider(pi, api.Items),
IpcSubscribers.GetState.Provider(pi, api.State),
IpcSubscribers.GetStateName.Provider(pi, api.State),
IpcSubscribers.GetStateBase64.Provider(pi, api.State),

View file

@ -57,6 +57,64 @@ public class ItemsApi(ApiHelpers helpers, ItemManager itemManager, StateManager
ApiHelpers.Lock(state, key, flags);
}
if (!anyFound)
return ApiHelpers.Return(GlamourerApiEc.ActorNotFound, args);
if (!anyHuman)
return ApiHelpers.Return(GlamourerApiEc.ActorNotHuman, args);
if (!anyUnlocked)
return ApiHelpers.Return(GlamourerApiEc.InvalidKey, args);
return ApiHelpers.Return(GlamourerApiEc.Success, args);
}
public GlamourerApiEc SetBonusItem(int objectIndex, ApiBonusSlot slot, ulong bonusItemId, uint key, ApplyFlag flags)
{
var args = ApiHelpers.Args("Index", objectIndex, "Slot", slot, "ID", bonusItemId, "Key", key, "Flags", flags);
if (!ResolveBonusItem(slot, bonusItemId, out var item))
return ApiHelpers.Return(GlamourerApiEc.ItemInvalid, args);
if (helpers.FindState(objectIndex) is not { } state)
return ApiHelpers.Return(GlamourerApiEc.ActorNotFound, args);
if (!state.ModelData.IsHuman)
return ApiHelpers.Return(GlamourerApiEc.ActorNotHuman, args);
if (!state.CanUnlock(key))
return ApiHelpers.Return(GlamourerApiEc.InvalidKey, args);
var settings = new ApplySettings(Source: flags.HasFlag(ApplyFlag.Once) ? StateSource.IpcManual : StateSource.IpcFixed, Key: key);
stateManager.ChangeBonusItem(state, item.Slot, item, settings);
ApiHelpers.Lock(state, key, flags);
return GlamourerApiEc.Success;
}
public GlamourerApiEc SetBonusItemName(string playerName, ApiBonusSlot slot, ulong bonusItemId, uint key, ApplyFlag flags)
{
var args = ApiHelpers.Args("Name", playerName, "Slot", slot, "ID", bonusItemId, "Key", key, "Flags", flags);
if (!ResolveBonusItem(slot, bonusItemId, out var item))
return ApiHelpers.Return(GlamourerApiEc.ItemInvalid, args);
var settings = new ApplySettings(Source: flags.HasFlag(ApplyFlag.Once) ? StateSource.IpcManual : StateSource.IpcFixed, Key: key);
var anyHuman = false;
var anyFound = false;
var anyUnlocked = false;
foreach (var state in helpers.FindStates(playerName))
{
anyFound = true;
if (!state.ModelData.IsHuman)
continue;
anyHuman = true;
if (!state.CanUnlock(key))
continue;
anyUnlocked = true;
stateManager.ChangeBonusItem(state, item.Slot, item, settings);
ApiHelpers.Lock(state, key, flags);
}
if (!anyFound)
return ApiHelpers.Return(GlamourerApiEc.ActorNotFound, args);
@ -79,4 +137,15 @@ public class ItemsApi(ApiHelpers helpers, ItemManager itemManager, StateManager
item = itemManager.Resolve(slot, id);
return item.Valid;
}
private bool ResolveBonusItem(ApiBonusSlot apiSlot, ulong itemId, out BonusItem item)
{
var slot = apiSlot switch
{
ApiBonusSlot.Glasses => BonusItemFlag.Glasses,
_ => BonusItemFlag.Unknown,
};
return itemManager.IsBonusItemValid(slot, (BonusItemId)itemId, out item);
}
}

View file

@ -91,6 +91,7 @@ public class GlamourerChangelog
.RegisterEntry("Glamourer now has a Support Info button akin to Penumbra's.")
.RegisterEntry("Glamourer now respects write protection on designs better.")
.RegisterEntry("The advanced dye window popup should now get focused when it is opening even in detached state.")
.RegisterEntry("Added API and IPC for bonus items, i.e. the Glasses slot.")
.RegisterHighlight("You can now display your characters height in Corgis or Olympic Swimming Pools.")
.RegisterEntry("Fixed some issues with advanced customizations and dyes applied via IPC. (1.2.3.2)")
.RegisterEntry(

View file

@ -19,7 +19,8 @@ public class ItemsIpcTester(IDalamudPluginInterface pluginInterface) : IUiServic
private ApplyFlag _flags = ApplyFlagEx.DesignDefault;
private CustomItemId _customItemId;
private StainId _stainId;
private EquipSlot _slot = EquipSlot.Head;
private EquipSlot _slot = EquipSlot.Head;
private BonusItemFlag _bonusSlot = BonusItemFlag.Glasses;
private GlamourerApiEc _lastError;
public void Draw()
@ -47,6 +48,16 @@ public class ItemsIpcTester(IDalamudPluginInterface pluginInterface) : IUiServic
if (ImGui.Button("Set##Name"))
_lastError = new SetItemName(pluginInterface).Invoke(_gameObjectName, (ApiEquipSlot)_slot, _customItemId.Id, [_stainId.Id], _key,
_flags);
IpcTesterHelpers.DrawIntro(SetBonusItem.Label);
if (ImGui.Button("Set##BonusIdx"))
_lastError = new SetBonusItem(pluginInterface).Invoke(_gameObjectIndex, ToApi(_bonusSlot), _customItemId.Id, _key,
_flags);
IpcTesterHelpers.DrawIntro(SetBonusItemName.Label);
if (ImGui.Button("Set##BonusName"))
_lastError = new SetBonusItemName(pluginInterface).Invoke(_gameObjectName, ToApi(_bonusSlot), _customItemId.Id, _key,
_flags);
}
private void DrawItemInput()
@ -57,6 +68,7 @@ public class ItemsIpcTester(IDalamudPluginInterface pluginInterface) : IUiServic
if (ImGuiUtil.InputUlong("Custom Item ID", ref tmp))
_customItemId = tmp;
EquipSlotCombo.Draw("Equip Slot", string.Empty, ref _slot, width);
BonusSlotCombo.Draw("Bonus Slot", string.Empty, ref _bonusSlot, width);
var value = (int)_stainId.Id;
ImGui.SetNextItemWidth(width);
if (ImGui.InputInt("Stain ID", ref value, 1, 3))
@ -65,4 +77,11 @@ public class ItemsIpcTester(IDalamudPluginInterface pluginInterface) : IUiServic
_stainId = (StainId)value;
}
}
private static ApiBonusSlot ToApi(BonusItemFlag slot)
=> slot switch
{
BonusItemFlag.Glasses => ApiBonusSlot.Glasses,
_ => ApiBonusSlot.Unknown,
};
}

View file

@ -7,6 +7,7 @@ using Glamourer.Services;
using Glamourer.Unlocks;
using ImGuiNET;
using OtterGui.Raii;
using OtterGui.Text;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using ImGuiClip = OtterGui.ImGuiClip;
@ -200,11 +201,12 @@ public class UnlockOverview(
using var tt = ImRaii.Tooltip();
if (size.X >= iconSize.X && size.Y >= iconSize.Y)
ImGui.Image(icon, size);
ImGui.TextUnformatted(item.Name);
ImGui.TextUnformatted($"{item.Slot.ToName()}");
ImGui.TextUnformatted($"{item.ModelId.Id}-{item.Variant.Id}");
ImUtf8.Text(item.Name);
ImUtf8.Text($"{item.Slot.ToName()}");
ImUtf8.Text($"{item.Id.Id}");
ImUtf8.Text($"{item.ModelId.Id}-{item.Variant.Id}");
// TODO
ImGui.TextUnformatted("Always Unlocked"); // : $"Unlocked on {time:g}" : "Not Unlocked.");
ImUtf8.Text("Always Unlocked"); // : $"Unlocked on {time:g}" : "Not Unlocked.");
// TODO
//tooltip.CreateTooltip(item, string.Empty, false);
}