mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-13 12:14:18 +01:00
Remove BonusItem and replace with normal EquipItems everywhere.
This commit is contained in:
parent
415ac63767
commit
9d99d936aa
25 changed files with 112 additions and 118 deletions
|
|
@ -85,7 +85,7 @@ public class ItemsApi(ApiHelpers helpers, ItemManager itemManager, StateManager
|
||||||
return ApiHelpers.Return(GlamourerApiEc.InvalidKey, args);
|
return ApiHelpers.Return(GlamourerApiEc.InvalidKey, args);
|
||||||
|
|
||||||
var settings = new ApplySettings(Source: flags.HasFlag(ApplyFlag.Once) ? StateSource.IpcManual : StateSource.IpcFixed, Key: key);
|
var settings = new ApplySettings(Source: flags.HasFlag(ApplyFlag.Once) ? StateSource.IpcManual : StateSource.IpcFixed, Key: key);
|
||||||
stateManager.ChangeBonusItem(state, item.Slot, item, settings);
|
stateManager.ChangeBonusItem(state, item.Type.ToBonus(), item, settings);
|
||||||
ApiHelpers.Lock(state, key, flags);
|
ApiHelpers.Lock(state, key, flags);
|
||||||
return GlamourerApiEc.Success;
|
return GlamourerApiEc.Success;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +111,7 @@ public class ItemsApi(ApiHelpers helpers, ItemManager itemManager, StateManager
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
anyUnlocked = true;
|
anyUnlocked = true;
|
||||||
stateManager.ChangeBonusItem(state, item.Slot, item, settings);
|
stateManager.ChangeBonusItem(state, item.Type.ToBonus(), item, settings);
|
||||||
ApiHelpers.Lock(state, key, flags);
|
ApiHelpers.Lock(state, key, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ public class ItemsApi(ApiHelpers helpers, ItemManager itemManager, StateManager
|
||||||
return item.Valid;
|
return item.Valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ResolveBonusItem(ApiBonusSlot apiSlot, ulong itemId, out BonusItem item)
|
private bool ResolveBonusItem(ApiBonusSlot apiSlot, ulong itemId, out EquipItem item)
|
||||||
{
|
{
|
||||||
var slot = apiSlot switch
|
var slot = apiSlot switch
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ public class DesignBase
|
||||||
var item = _designData.BonusItem(slot);
|
var item = _designData.BonusItem(slot);
|
||||||
ret[slot.ToString()] = new JObject()
|
ret[slot.ToString()] = new JObject()
|
||||||
{
|
{
|
||||||
["BonusId"] = item.CustomId.Id,
|
["BonusId"] = item.Id.Id,
|
||||||
["Apply"] = DoApplyBonusItem(slot),
|
["Apply"] = DoApplyBonusItem(slot),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -443,7 +443,7 @@ public class DesignBase
|
||||||
if (json[slot.ToString()] is not JObject itemJson)
|
if (json[slot.ToString()] is not JObject itemJson)
|
||||||
{
|
{
|
||||||
design.Application.BonusItem &= ~slot;
|
design.Application.BonusItem &= ~slot;
|
||||||
design.GetDesignDataRef().SetBonusItem(slot, BonusItem.Empty(slot));
|
design.GetDesignDataRef().SetBonusItem(slot, EquipItem.BonusItemNothing(slot));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,12 +108,12 @@ public unsafe struct DesignData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly BonusItem BonusItem(BonusItemFlag slot)
|
public readonly EquipItem BonusItem(BonusItemFlag slot)
|
||||||
=> slot switch
|
=> slot switch
|
||||||
{
|
{
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
BonusItemFlag.Glasses => Penumbra.GameData.Structs.BonusItem.FromIds(_bonusIds[0], _iconIds[12], _bonusModelIds[0], _bonusVariants[0], BonusItemFlag.Glasses, _nameGlasses),
|
BonusItemFlag.Glasses => EquipItem.FromIds(_bonusIds[0], _iconIds[12], _bonusModelIds[0], 0, _bonusVariants[0], FullEquipType.Glasses, 0, _nameGlasses),
|
||||||
_ => Penumbra.GameData.Structs.BonusItem.Empty(slot),
|
_ => EquipItem.BonusItemNothing(slot),
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -191,15 +191,15 @@ public unsafe struct DesignData
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetBonusItem(BonusItemFlag slot, BonusItem item)
|
public bool SetBonusItem(BonusItemFlag slot, EquipItem item)
|
||||||
{
|
{
|
||||||
var index = slot.ToIndex();
|
var index = slot.ToIndex();
|
||||||
if (index > NumBonusItems)
|
if (index > NumBonusItems)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_iconIds[NumEquipment + NumWeapons + index] = item.Icon.Id;
|
_iconIds[NumEquipment + NumWeapons + index] = item.IconId.Id;
|
||||||
_bonusIds[index] = item.Id.Id;
|
_bonusIds[index] = item.Id.BonusItem.Id;
|
||||||
_bonusModelIds[index] = item.ModelId.Id;
|
_bonusModelIds[index] = item.PrimaryId.Id;
|
||||||
_bonusVariants[index] = item.Variant.Id;
|
_bonusVariants[index] = item.Variant.Id;
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
|
@ -330,7 +330,7 @@ public unsafe struct DesignData
|
||||||
public void SetDefaultBonusItems()
|
public void SetDefaultBonusItems()
|
||||||
{
|
{
|
||||||
foreach (var slot in BonusExtensions.AllFlags)
|
foreach (var slot in BonusExtensions.AllFlags)
|
||||||
SetBonusItem(slot, Penumbra.GameData.Structs.BonusItem.Empty(slot));
|
SetBonusItem(slot, EquipItem.BonusItemNothing(slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,10 +172,10 @@ public class DesignEditor(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void ChangeBonusItem(object data, BonusItemFlag slot, BonusItem item, ApplySettings settings = default)
|
public void ChangeBonusItem(object data, BonusItemFlag slot, EquipItem item, ApplySettings settings = default)
|
||||||
{
|
{
|
||||||
var design = (Design)data;
|
var design = (Design)data;
|
||||||
if (item.Slot != slot)
|
if (item.Type.ToBonus() != slot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var oldItem = design.DesignData.BonusItem(slot);
|
var oldItem = design.DesignData.BonusItem(slot);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public readonly record struct EquipTransaction(EquipSlot Slot, EquipItem Old, Eq
|
||||||
=> editor.ChangeItem(data, Slot, Old, ApplySettings.Manual);
|
=> editor.ChangeItem(data, Slot, Old, ApplySettings.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly record struct BonusItemTransaction(BonusItemFlag Slot, BonusItem Old, BonusItem New)
|
public readonly record struct BonusItemTransaction(BonusItemFlag Slot, EquipItem Old, EquipItem New)
|
||||||
: ITransaction
|
: ITransaction
|
||||||
{
|
{
|
||||||
public ITransaction? Merge(ITransaction older)
|
public ITransaction? Merge(ITransaction older)
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ public interface IDesignEditor
|
||||||
=> ChangeEquip(data, slot, item, null, settings);
|
=> ChangeEquip(data, slot, item, null, settings);
|
||||||
|
|
||||||
/// <summary> Change a bonus item. </summary>
|
/// <summary> Change a bonus item. </summary>
|
||||||
public void ChangeBonusItem(object data, BonusItemFlag slot, BonusItem item, ApplySettings settings = default);
|
public void ChangeBonusItem(object data, BonusItemFlag slot, EquipItem item, ApplySettings settings = default);
|
||||||
|
|
||||||
/// <summary> Change the stain for any equipment piece. </summary>
|
/// <summary> Change the stain for any equipment piece. </summary>
|
||||||
public void ChangeStains(object data, EquipSlot slot, StainIds stains, ApplySettings settings = default)
|
public void ChangeStains(object data, EquipSlot slot, StainIds stains, ApplySettings settings = default)
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,12 @@ using Glamourer.Gui;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Files;
|
||||||
|
|
||||||
namespace Glamourer;
|
namespace Glamourer;
|
||||||
|
|
||||||
|
|
@ -44,6 +47,15 @@ public class Glamourer : IDalamudPlugin
|
||||||
_services.GetService<CommandService>(); // initialize commands.
|
_services.GetService<CommandService>(); // initialize commands.
|
||||||
_services.GetService<IpcProviders>(); // initialize IPC.
|
_services.GetService<IpcProviders>(); // initialize IPC.
|
||||||
Log.Information($"Glamourer v{Version} loaded successfully.");
|
Log.Information($"Glamourer v{Version} loaded successfully.");
|
||||||
|
|
||||||
|
//var text = File.ReadAllBytes(@"C:\FFXIVMods\PBDTest\files\human.pbd");
|
||||||
|
//var pbd = new PbdFile(text);
|
||||||
|
//var roundtrip = pbd.Write();
|
||||||
|
//File.WriteAllBytes(@"C:\FFXIVMods\PBDTest\files\Vanilla resaved save.pbd", roundtrip);
|
||||||
|
//var deformer = pbd.Deformers.FirstOrDefault(d => d.GenderRace is GenderRace.RoegadynFemale)!.RacialDeformer;
|
||||||
|
//deformer.DeformMatrices["ya_fukubu_phys"] = deformer.DeformMatrices["j_kosi"];
|
||||||
|
//var aleks = pbd.Write();
|
||||||
|
//File.WriteAllBytes(@"C:\FFXIVMods\PBDTest\files\rue.pbd", aleks);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public struct BonusDrawData(BonusItemFlag slot, in DesignData designData)
|
||||||
public readonly bool IsState
|
public readonly bool IsState
|
||||||
=> _object is ActorState;
|
=> _object is ActorState;
|
||||||
|
|
||||||
public readonly void SetItem(BonusItem item)
|
public readonly void SetItem(EquipItem item)
|
||||||
=> _editor.ChangeBonusItem(_object, Slot, item, ApplySettings.Manual);
|
=> _editor.ChangeBonusItem(_object, Slot, item, ApplySettings.Manual);
|
||||||
|
|
||||||
public readonly void SetApplyItem(bool value)
|
public readonly void SetApplyItem(bool value)
|
||||||
|
|
@ -30,8 +30,8 @@ public struct BonusDrawData(BonusItemFlag slot, in DesignData designData)
|
||||||
manager.ChangeApplyBonusItem(design, Slot, value);
|
manager.ChangeApplyBonusItem(design, Slot, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BonusItem CurrentItem = designData.BonusItem(slot);
|
public EquipItem CurrentItem = designData.BonusItem(slot);
|
||||||
public BonusItem GameItem = default;
|
public EquipItem GameItem = default;
|
||||||
public bool CurrentApply;
|
public bool CurrentApply;
|
||||||
|
|
||||||
public static BonusDrawData FromDesign(DesignManager manager, Design design, BonusItemFlag slot)
|
public static BonusDrawData FromDesign(DesignManager manager, Design design, BonusItemFlag slot)
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Equipment;
|
namespace Glamourer.Gui.Equipment;
|
||||||
|
|
||||||
public sealed class BonusItemCombo : FilterComboCache<BonusItem>
|
public sealed class BonusItemCombo : FilterComboCache<EquipItem>
|
||||||
{
|
{
|
||||||
private readonly FavoriteManager _favorites;
|
private readonly FavoriteManager _favorites;
|
||||||
public readonly string Label;
|
public readonly string Label;
|
||||||
private BonusItemId _currentItem;
|
private CustomItemId _currentItem;
|
||||||
private float _innerWidth;
|
private float _innerWidth;
|
||||||
|
|
||||||
public PrimaryId CustomSetId { get; private set; }
|
public PrimaryId CustomSetId { get; private set; }
|
||||||
|
|
@ -75,14 +75,14 @@ public sealed class BonusItemCombo : FilterComboCache<BonusItem>
|
||||||
var ret = ImGui.Selectable(name, selected);
|
var ret = ImGui.Selectable(name, selected);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, 0xFF808080);
|
using var color = ImRaii.PushColor(ImGuiCol.Text, 0xFF808080);
|
||||||
ImGuiUtil.RightAlign($"({obj.ModelId.Id}-{obj.Variant.Id})");
|
ImGuiUtil.RightAlign($"({obj.PrimaryId.Id}-{obj.Variant.Id})");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool IsVisible(int globalIndex, LowerString filter)
|
protected override bool IsVisible(int globalIndex, LowerString filter)
|
||||||
=> base.IsVisible(globalIndex, filter) || filter.IsContained(Items[globalIndex].ModelId.Id.ToString());
|
=> base.IsVisible(globalIndex, filter) || filter.IsContained(Items[globalIndex].PrimaryId.Id.ToString());
|
||||||
|
|
||||||
protected override string ToString(BonusItem obj)
|
protected override string ToString(EquipItem obj)
|
||||||
=> obj.Name;
|
=> obj.Name;
|
||||||
|
|
||||||
private static string GetLabel(IDataManager gameData, BonusItemFlag slot)
|
private static string GetLabel(IDataManager gameData, BonusItemFlag slot)
|
||||||
|
|
@ -98,13 +98,10 @@ public sealed class BonusItemCombo : FilterComboCache<BonusItem>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<BonusItem> GetItems(FavoriteManager favorites, ItemManager items, BonusItemFlag slot)
|
private static List<EquipItem> GetItems(FavoriteManager favorites, ItemManager items, BonusItemFlag slot)
|
||||||
{
|
{
|
||||||
var nothing = BonusItem.Empty(slot);
|
var nothing = EquipItem.BonusItemNothing(slot);
|
||||||
if (slot is not BonusItemFlag.Glasses)
|
return items.ItemData.ByType[slot.ToEquipType()].OrderByDescending(favorites.Contains).ThenBy(i => i.Id.Id).Prepend(nothing).ToList();
|
||||||
return [nothing];
|
|
||||||
|
|
||||||
return items.DictBonusItems.Values.OrderByDescending(favorites.Contains).ThenBy(i => i.Id.Id).Prepend(nothing).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnClosePopup()
|
protected override void OnClosePopup()
|
||||||
|
|
|
||||||
|
|
@ -468,14 +468,14 @@ public class EquipmentDrawer
|
||||||
UiHelpers.OpenCombo($"##{combo.Label}");
|
UiHelpers.OpenCombo($"##{combo.Label}");
|
||||||
|
|
||||||
using var disabled = ImRaii.Disabled(data.Locked);
|
using var disabled = ImRaii.Disabled(data.Locked);
|
||||||
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
||||||
_requiredComboWidth);
|
_requiredComboWidth);
|
||||||
if (change)
|
if (change)
|
||||||
data.SetItem(combo.CurrentSelection);
|
data.SetItem(combo.CurrentSelection);
|
||||||
else if (combo.CustomVariant.Id > 0)
|
else if (combo.CustomVariant.Id > 0)
|
||||||
data.SetItem(_items.Identify(data.Slot, combo.CustomSetId, combo.CustomVariant));
|
data.SetItem(_items.Identify(data.Slot, combo.CustomSetId, combo.CustomVariant));
|
||||||
|
|
||||||
if (ResetOrClear(data.Locked, clear, data.AllowRevert, true, data.CurrentItem, data.GameItem, BonusItem.Empty(data.Slot), out var item))
|
if (ResetOrClear(data.Locked, clear, data.AllowRevert, true, data.CurrentItem, data.GameItem, EquipItem.BonusItemNothing(data.Slot), out var item))
|
||||||
data.SetItem(item);
|
data.SetItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ public sealed unsafe class AdvancedDyePopup(
|
||||||
{
|
{
|
||||||
EquipSlot.MainHand => _state.ModelData.Weapon(EquipSlot.MainHand),
|
EquipSlot.MainHand => _state.ModelData.Weapon(EquipSlot.MainHand),
|
||||||
EquipSlot.OffHand => _state.ModelData.Weapon(EquipSlot.OffHand),
|
EquipSlot.OffHand => _state.ModelData.Weapon(EquipSlot.OffHand),
|
||||||
EquipSlot.Unknown => _state.ModelData.BonusItem((index.SlotIndex - 16u).ToBonusSlot()).ToArmor().ToWeapon(0),
|
EquipSlot.Unknown => _state.ModelData.BonusItem((index.SlotIndex - 16u).ToBonusSlot()).Armor().ToWeapon(0), // TODO: Handle better
|
||||||
_ => _state.ModelData.Armor(slot).ToWeapon(0),
|
_ => _state.ModelData.Armor(slot).ToWeapon(0),
|
||||||
};
|
};
|
||||||
value = new MaterialValueState(internalRow, internalRow, weapon, StateSource.Manual);
|
value = new MaterialValueState(internalRow, internalRow, weapon, StateSource.Manual);
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ public unsafe class ModelEvaluationPanel(
|
||||||
{
|
{
|
||||||
var glassesId = actor.GetBonusItem(slot);
|
var glassesId = actor.GetBonusItem(slot);
|
||||||
if (bonusItems.TryGetValue(glassesId, out var glasses))
|
if (bonusItems.TryGetValue(glassesId, out var glasses))
|
||||||
ImGuiUtil.DrawTableColumn($"{glasses.ModelId.Id},{glasses.Variant.Id} ({glassesId})");
|
ImGuiUtil.DrawTableColumn($"{glasses.PrimaryId.Id},{glasses.Variant.Id} ({glassesId})");
|
||||||
else
|
else
|
||||||
ImGuiUtil.DrawTableColumn($"{glassesId}");
|
ImGuiUtil.DrawTableColumn($"{glassesId}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,11 +180,11 @@ public class UnlockOverview(
|
||||||
if (remainder > 0)
|
if (remainder > 0)
|
||||||
ImGuiClip.DrawEndDummy(remainder, iconSize.Y + spacing.Y);
|
ImGuiClip.DrawEndDummy(remainder, iconSize.Y + spacing.Y);
|
||||||
|
|
||||||
void DrawItem(BonusItem item)
|
void DrawItem(EquipItem item)
|
||||||
{
|
{
|
||||||
// TODO check unlocks
|
// TODO check unlocks
|
||||||
var unlocked = true;
|
var unlocked = true;
|
||||||
if (!textures.TryLoadIcon(item.Icon.Id, out var iconHandle))
|
if (!textures.TryLoadIcon(item.IconId.Id, out var iconHandle))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var (icon, size) = (iconHandle.ImGuiHandle, new Vector2(iconHandle.Width, iconHandle.Height));
|
var (icon, size) = (iconHandle.ImGuiHandle, new Vector2(iconHandle.Width, iconHandle.Height));
|
||||||
|
|
@ -202,9 +202,9 @@ public class UnlockOverview(
|
||||||
if (size.X >= iconSize.X && size.Y >= iconSize.Y)
|
if (size.X >= iconSize.X && size.Y >= iconSize.Y)
|
||||||
ImGui.Image(icon, size);
|
ImGui.Image(icon, size);
|
||||||
ImUtf8.Text(item.Name);
|
ImUtf8.Text(item.Name);
|
||||||
ImUtf8.Text($"{item.Slot.ToName()}");
|
ImUtf8.Text($"{item.Type.ToName()}");
|
||||||
ImUtf8.Text($"{item.Id.Id}");
|
ImUtf8.Text($"{item.Id.Id}");
|
||||||
ImUtf8.Text($"{item.ModelId.Id}-{item.Variant.Id}");
|
ImUtf8.Text($"{item.PrimaryId.Id}-{item.Variant.Id}");
|
||||||
// TODO
|
// TODO
|
||||||
ImUtf8.Text("Always Unlocked"); // : $"Unlocked on {time:g}" : "Not Unlocked.");
|
ImUtf8.Text("Always Unlocked"); // : $"Unlocked on {time:g}" : "Not Unlocked.");
|
||||||
// TODO
|
// TODO
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ public static class UiHelpers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawIcon(this BonusItem item, TextureService textures, Vector2 size, BonusItemFlag slot)
|
public static void DrawIcon(this EquipItem item, TextureService textures, Vector2 size, BonusItemFlag slot)
|
||||||
{
|
{
|
||||||
var isEmpty = item.ModelId.Id == 0;
|
var isEmpty = item.PrimaryId.Id == 0;
|
||||||
var (ptr, textureSize, empty) = textures.GetIcon(item, slot);
|
var (ptr, textureSize, empty) = textures.GetIcon(item, slot);
|
||||||
if (empty)
|
if (empty)
|
||||||
{
|
{
|
||||||
|
|
@ -149,27 +149,6 @@ public static class UiHelpers
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool DrawFavoriteStar(FavoriteManager favorites, BonusItem item)
|
|
||||||
{
|
|
||||||
var favorite = favorites.Contains(item);
|
|
||||||
var hovering = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(),
|
|
||||||
ImGui.GetCursorScreenPos() + new Vector2(ImGui.GetTextLineHeight()));
|
|
||||||
|
|
||||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
|
||||||
using var c = ImRaii.PushColor(ImGuiCol.Text,
|
|
||||||
hovering ? ColorId.FavoriteStarHovered.Value() : favorite ? ColorId.FavoriteStarOn.Value() : ColorId.FavoriteStarOff.Value());
|
|
||||||
ImGui.TextUnformatted(FontAwesomeIcon.Star.ToIconString());
|
|
||||||
if (!ImGui.IsItemClicked())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (favorite)
|
|
||||||
favorites.Remove(item);
|
|
||||||
else
|
|
||||||
favorites.TryAdd(item);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool DrawFavoriteStar(FavoriteManager favorites, StainId stain)
|
public static bool DrawFavoriteStar(FavoriteManager favorites, StainId stain)
|
||||||
{
|
{
|
||||||
var favorite = favorites.Contains(stain);
|
var favorite = favorites.Contains(stain);
|
||||||
|
|
|
||||||
|
|
@ -104,11 +104,11 @@ public sealed class CharaFile
|
||||||
|
|
||||||
if (id is 0)
|
if (id is 0)
|
||||||
{
|
{
|
||||||
data.SetBonusItem(slot, BonusItem.Empty(slot));
|
data.SetBonusItem(slot, EquipItem.BonusItemNothing(slot));
|
||||||
flags |= slot;
|
flags |= slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!items.DictBonusItems.TryGetValue((BonusItemId)id.Value, out var item) || item.Slot != slot)
|
if (!items.DictBonusItems.TryGetValue((BonusItemId)id.Value, out var item) || item.Type.ToBonus() != slot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
data.SetBonusItem(slot, item);
|
data.SetBonusItem(slot, item);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ public unsafe class UpdateSlotService : IDisposable
|
||||||
if (!_bonusItems.TryGetValue(id, out var glasses))
|
if (!_bonusItems.TryGetValue(id, out var glasses))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var armor = new CharacterArmor(glasses.ModelId, glasses.Variant, StainIds.None);
|
var armor = new CharacterArmor(glasses.PrimaryId, glasses.Variant, StainIds.None);
|
||||||
_flagBonusSlotForUpdateHook.Original(drawObject.Address, BonusItemFlag.Glasses.ToIndex(), &armor);
|
_flagBonusSlotForUpdateHook.Original(drawObject.Address, BonusItemFlag.Glasses.ToIndex(), &armor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Glamourer.Services;
|
||||||
|
|
||||||
public class ItemManager
|
public class ItemManager
|
||||||
{
|
{
|
||||||
public const string Nothing = "Nothing";
|
public const string Nothing = EquipItem.Nothing;
|
||||||
public const string SmallClothesNpc = "Smallclothes (NPC)";
|
public const string SmallClothesNpc = "Smallclothes (NPC)";
|
||||||
public const ushort SmallClothesNpcModel = 9903;
|
public const ushort SmallClothesNpcModel = 9903;
|
||||||
|
|
||||||
|
|
@ -126,31 +126,20 @@ public class ItemManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BonusItem Identify(BonusItemFlag slot, PrimaryId id, Variant variant)
|
public EquipItem Identify(BonusItemFlag slot, PrimaryId id, Variant variant)
|
||||||
{
|
{
|
||||||
var index = slot.ToIndex();
|
var index = slot.ToIndex();
|
||||||
if (index == uint.MaxValue)
|
if (index == uint.MaxValue)
|
||||||
return new BonusItem($"Invalid ({id.Id}-{variant})", 0, 0, id, variant, slot);
|
return new EquipItem($"Invalid ({id.Id}-{variant})", 0, 0, id, 0, variant, slot.ToEquipType(), 0, 0, 0);
|
||||||
|
|
||||||
var item = ObjectIdentification.Identify(id, variant, slot)
|
return ObjectIdentification.Identify(id, variant, slot)
|
||||||
.FirstOrDefault(BonusItem.FromIds(BonusItemId.Invalid, 0, id, variant, slot));
|
.FirstOrDefault(new EquipItem($"Invalid ({id.Id}-{variant})", 0, 0, id, 0, variant, slot.ToEquipType(), 0, 0, 0));
|
||||||
if (item.Id != BonusItemId.Invalid)
|
|
||||||
return item;
|
|
||||||
|
|
||||||
if (slot is BonusItemFlag.Glasses)
|
|
||||||
{
|
|
||||||
var headItem = ObjectIdentification.Identify(id, 0, variant, EquipSlot.Head).FirstOrDefault();
|
|
||||||
if (headItem.Valid)
|
|
||||||
return BonusItem.FromIds(BonusItemId.Invalid, headItem.IconId, id, variant, slot, $"{headItem.Name} ({EquipSlot.Head.ToName()}: {id}-{variant})");
|
|
||||||
}
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BonusItem Resolve(BonusItemFlag slot, BonusItemId id)
|
public EquipItem Resolve(BonusItemFlag slot, BonusItemId id)
|
||||||
=> IsBonusItemValid(slot, id, out var item) ? item : new BonusItem($"Invalid ({id.Id})", 0, id, 0, 0, slot);
|
=> IsBonusItemValid(slot, id, out var item) ? item : new EquipItem($"Invalid ({id.Id})", id, 0, 0, 0, 0, slot.ToEquipType(), 0, 0, 0);
|
||||||
|
|
||||||
public BonusItem Resolve(BonusItemFlag slot, CustomItemId id)
|
public EquipItem Resolve(BonusItemFlag slot, CustomItemId id)
|
||||||
{
|
{
|
||||||
// Only from early designs as migration.
|
// Only from early designs as migration.
|
||||||
if (!id.IsBonusItem)
|
if (!id.IsBonusItem)
|
||||||
|
|
@ -164,12 +153,12 @@ public class ItemManager
|
||||||
if (IsBonusItemValid(slot, id.BonusItem, out var item))
|
if (IsBonusItemValid(slot, id.BonusItem, out var item))
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
return BonusItem.Empty(slot);
|
return EquipItem.BonusItemNothing(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
var (model, variant, slot2) = id.SplitBonus;
|
var (model, variant, slot2) = id.SplitBonus;
|
||||||
if (slot != slot2)
|
if (slot != slot2)
|
||||||
return BonusItem.Empty(slot);
|
return EquipItem.BonusItemNothing(slot);
|
||||||
|
|
||||||
return Identify(slot, model, variant);
|
return Identify(slot, model, variant);
|
||||||
}
|
}
|
||||||
|
|
@ -213,12 +202,12 @@ public class ItemManager
|
||||||
|
|
||||||
/// <summary> Returns whether a bonus item id represents a valid item for a slot and gives the item. </summary>
|
/// <summary> Returns whether a bonus item id represents a valid item for a slot and gives the item. </summary>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public bool IsBonusItemValid(BonusItemFlag slot, BonusItemId itemId, out BonusItem item)
|
public bool IsBonusItemValid(BonusItemFlag slot, BonusItemId itemId, out EquipItem item)
|
||||||
{
|
{
|
||||||
if (itemId.Id != 0)
|
if (itemId.Id != 0)
|
||||||
return DictBonusItems.TryGetValue(itemId, out item) && slot == item.Slot;
|
return DictBonusItems.TryGetValue(itemId, out item) && slot == item.Type.ToBonus();
|
||||||
|
|
||||||
item = BonusItem.Empty(slot);
|
item = new EquipItem(Nothing, (BonusItemId)0, 0, 0, 0, 0, slot.ToEquipType(), 0, 0, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ public sealed class TextureService(IUiBuilder uiBuilder, IDataManager dataManage
|
||||||
: (nint.Zero, Vector2.Zero, true);
|
: (nint.Zero, Vector2.Zero, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public (nint, Vector2, bool) GetIcon(BonusItem item, BonusItemFlag slot)
|
public (nint, Vector2, bool) GetIcon(EquipItem item, BonusItemFlag slot)
|
||||||
{
|
{
|
||||||
if (item.Icon.Id != 0 && TryLoadIcon(item.Icon.Id, out var ret))
|
if (item.IconId.Id != 0 && TryLoadIcon(item.IconId.Id, out var ret))
|
||||||
return (ret.ImGuiHandle, new Vector2(ret.Width, ret.Height), false);
|
return (ret.ImGuiHandle, new Vector2(ret.Width, ret.Height), false);
|
||||||
|
|
||||||
var idx = slot.ToIndex();
|
var idx = slot.ToIndex();
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ public class InternalStateEditor(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Change a single bonus item. </summary>
|
/// <summary> Change a single bonus item. </summary>
|
||||||
public bool ChangeBonusItem(ActorState state, BonusItemFlag slot, BonusItem item, StateSource source, out BonusItem oldItem, uint key = 0)
|
public bool ChangeBonusItem(ActorState state, BonusItemFlag slot, EquipItem item, StateSource source, out EquipItem oldItem, uint key = 0)
|
||||||
{
|
{
|
||||||
oldItem = state.ModelData.BonusItem(slot);
|
oldItem = state.ModelData.BonusItem(slot);
|
||||||
if (!state.CanUnlock(key))
|
if (!state.CanUnlock(key))
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ public class StateApplier(
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
var item = state.ModelData.BonusItem(slot);
|
var item = state.ModelData.BonusItem(slot);
|
||||||
ChangeBonusItem(data, slot, item.ModelId, item.Variant);
|
ChangeBonusItem(data, slot, item.PrimaryId, item.Variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
@ -391,7 +391,7 @@ public class StateApplier(
|
||||||
foreach (var slot in BonusExtensions.AllFlags)
|
foreach (var slot in BonusExtensions.AllFlags)
|
||||||
{
|
{
|
||||||
var item = state.ModelData.BonusItem(slot);
|
var item = state.ModelData.BonusItem(slot);
|
||||||
ChangeBonusItem(actors, slot, item.ModelId, item.Variant);
|
ChangeBonusItem(actors, slot, item.PrimaryId, item.Variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
|
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ public class StateEditor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeBonusItem(object data, BonusItemFlag slot, BonusItem item, ApplySettings settings = default)
|
public void ChangeBonusItem(object data, BonusItemFlag slot, EquipItem item, ApplySettings settings = default)
|
||||||
{
|
{
|
||||||
var state = (ActorState)data;
|
var state = (ActorState)data;
|
||||||
if (!Editor.ChangeBonusItem(state, slot, item, settings.Source, out var old, settings.Key))
|
if (!Editor.ChangeBonusItem(state, slot, item, settings.Source, out var old, settings.Key))
|
||||||
|
|
|
||||||
|
|
@ -250,11 +250,11 @@ public class StateListener : IDisposable
|
||||||
else
|
else
|
||||||
apply = true;
|
apply = true;
|
||||||
if (apply)
|
if (apply)
|
||||||
item = state.ModelData.BonusItem(slot).ToArmor();
|
item = state.ModelData.BonusItem(slot).Armor();
|
||||||
break;
|
break;
|
||||||
// Use current model data.
|
// Use current model data.
|
||||||
case UpdateState.NoChange:
|
case UpdateState.NoChange:
|
||||||
item = state.ModelData.BonusItem(slot).ToArmor();
|
item = state.ModelData.BonusItem(slot).Armor();
|
||||||
break;
|
break;
|
||||||
case UpdateState.Transformed: break;
|
case UpdateState.Transformed: break;
|
||||||
}
|
}
|
||||||
|
|
@ -453,12 +453,12 @@ public class StateListener : IDisposable
|
||||||
return UpdateState.NoChange;
|
return UpdateState.NoChange;
|
||||||
|
|
||||||
// The actor item does not correspond to the model item, thus the actor is transformed.
|
// The actor item does not correspond to the model item, thus the actor is transformed.
|
||||||
if (actorItem.ModelId != item.Set || actorItem.Variant != item.Variant)
|
if (actorItem.PrimaryId != item.Set || actorItem.Variant != item.Variant)
|
||||||
return UpdateState.Transformed;
|
return UpdateState.Transformed;
|
||||||
|
|
||||||
var baseData = state.BaseData.BonusItem(slot);
|
var baseData = state.BaseData.BonusItem(slot);
|
||||||
var change = UpdateState.NoChange;
|
var change = UpdateState.NoChange;
|
||||||
if (baseData.Id != actorItem.Id || baseData.ModelId != item.Set || baseData.Variant != item.Variant)
|
if (baseData.Id != actorItem.Id || baseData.PrimaryId != item.Set || baseData.Variant != item.Variant)
|
||||||
{
|
{
|
||||||
var identified = _items.Identify(slot, item.Set, item.Variant);
|
var identified = _items.Identify(slot, item.Set, item.Variant);
|
||||||
state.BaseData.SetBonusItem(slot, identified);
|
state.BaseData.SetBonusItem(slot, identified);
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ public sealed class StateManager(
|
||||||
foreach (var slot in BonusExtensions.AllFlags)
|
foreach (var slot in BonusExtensions.AllFlags)
|
||||||
{
|
{
|
||||||
var item = state.ModelData.BonusItem(slot);
|
var item = state.ModelData.BonusItem(slot);
|
||||||
Applier.ChangeBonusItem(actors, slot, item.ModelId, item.Variant);
|
Applier.ChangeBonusItem(actors, slot, item.PrimaryId, item.Variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
|
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ public class FavoriteManager : ISavable
|
||||||
private readonly record struct FavoriteHairStyle(Gender Gender, SubRace Race, CustomizeIndex Type, CustomizeValue Id)
|
private readonly record struct FavoriteHairStyle(Gender Gender, SubRace Race, CustomizeIndex Type, CustomizeValue Id)
|
||||||
{
|
{
|
||||||
public uint ToValue()
|
public uint ToValue()
|
||||||
=> (uint)Id.Value | ((uint)Type << 8) | ((uint)Race << 16) | ((uint)Gender << 24);
|
=> Id.Value | ((uint)Type << 8) | ((uint)Race << 16) | ((uint)Gender << 24);
|
||||||
|
|
||||||
public FavoriteHairStyle(uint value)
|
public FavoriteHairStyle(uint value)
|
||||||
: this((Gender)((value >> 24) & 0xFF), (SubRace)((value >> 16) & 0xFF), (CustomizeIndex)((value >> 8) & 0xFF),
|
: this((Gender)((value >> 24) & 0xFF), (SubRace)((value >> 16) & 0xFF), (CustomizeIndex)((value >> 8) & 0xFF),
|
||||||
|
|
@ -61,9 +61,9 @@ public class FavoriteManager : ISavable
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
_favorites.UnionWith(load!.FavoriteItems.Select(i => (ItemId)i));
|
_favorites.UnionWith(load!.FavoriteItems.Select(i => (ItemId)i));
|
||||||
_favoriteColors.UnionWith(load!.FavoriteColors.Select(i => (StainId)i));
|
_favoriteColors.UnionWith(load.FavoriteColors.Select(i => (StainId)i));
|
||||||
_favoriteHairStyles.UnionWith(load!.FavoriteHairStyles.Select(t => new FavoriteHairStyle(t)));
|
_favoriteHairStyles.UnionWith(load.FavoriteHairStyles.Select(t => new FavoriteHairStyle(t)));
|
||||||
_favoriteBonusItems.UnionWith(load!.FavoriteBonusItems.Select(b => new BonusItemId(b)));
|
_favoriteBonusItems.UnionWith(load.FavoriteBonusItems.Select(b => new BonusItemId(b)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: throw new Exception($"Unknown Version {load?.Version ?? 0}");
|
default: throw new Exception($"Unknown Version {load?.Version ?? 0}");
|
||||||
|
|
@ -126,7 +126,12 @@ public class FavoriteManager : ISavable
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryAdd(EquipItem item)
|
public bool TryAdd(EquipItem item)
|
||||||
=> TryAdd(item.ItemId);
|
{
|
||||||
|
if (item.Id.IsBonusItem)
|
||||||
|
return TryAdd(item.Id.BonusItem);
|
||||||
|
|
||||||
|
return TryAdd(item.ItemId);
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryAdd(ItemId item)
|
public bool TryAdd(ItemId item)
|
||||||
{
|
{
|
||||||
|
|
@ -137,18 +142,18 @@ public class FavoriteManager : ISavable
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryAdd(StainId stain)
|
public bool TryAdd(BonusItemId item)
|
||||||
{
|
{
|
||||||
if (stain.Id == 0 || !_favoriteColors.Add(stain))
|
if (item.Id == 0 || !_favoriteBonusItems.Add(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryAdd(BonusItem bonusItem)
|
public bool TryAdd(StainId stain)
|
||||||
{
|
{
|
||||||
if (bonusItem.Id == 0 || !_favoriteBonusItems.Add(bonusItem.Id))
|
if (stain.Id == 0 || !_favoriteColors.Add(stain))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
|
|
@ -165,7 +170,11 @@ public class FavoriteManager : ISavable
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Remove(EquipItem item)
|
public bool Remove(EquipItem item)
|
||||||
=> Remove(item.ItemId);
|
{
|
||||||
|
if (item.Id.IsBonusItem)
|
||||||
|
Remove(item.Id.BonusItem);
|
||||||
|
return Remove(item.ItemId);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Remove(ItemId item)
|
public bool Remove(ItemId item)
|
||||||
{
|
{
|
||||||
|
|
@ -176,18 +185,18 @@ public class FavoriteManager : ISavable
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Remove(StainId stain)
|
public bool Remove(BonusItemId item)
|
||||||
{
|
{
|
||||||
if (!_favoriteColors.Remove(stain))
|
if (!_favoriteBonusItems.Remove(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Remove(BonusItem bonusItem)
|
public bool Remove(StainId stain)
|
||||||
{
|
{
|
||||||
if (!_favoriteBonusItems.Remove(bonusItem.Id))
|
if (!_favoriteColors.Remove(stain))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
|
|
@ -204,13 +213,21 @@ public class FavoriteManager : ISavable
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(EquipItem item)
|
public bool Contains(EquipItem item)
|
||||||
=> _favorites.Contains(item.ItemId);
|
{
|
||||||
|
if (item.Id.IsBonusItem)
|
||||||
|
return _favoriteBonusItems.Contains(item.Id.BonusItem);
|
||||||
|
|
||||||
|
return _favorites.Contains(item.ItemId);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Contains(StainId stain)
|
public bool Contains(StainId stain)
|
||||||
=> _favoriteColors.Contains(stain);
|
=> _favoriteColors.Contains(stain);
|
||||||
|
|
||||||
public bool Contains(BonusItem bonusItem)
|
public bool Contains(ItemId itemId)
|
||||||
=> _favoriteBonusItems.Contains(bonusItem.Id);
|
=> _favorites.Contains(itemId);
|
||||||
|
|
||||||
|
public bool Contains(BonusItemId bonusItemId)
|
||||||
|
=> _favoriteBonusItems.Contains(bonusItemId);
|
||||||
|
|
||||||
public bool Contains(Gender gender, SubRace race, CustomizeIndex type, CustomizeValue value)
|
public bool Contains(Gender gender, SubRace race, CustomizeIndex type, CustomizeValue value)
|
||||||
=> _favoriteHairStyles.Contains(new FavoriteHairStyle(gender, race, type, value));
|
=> _favoriteHairStyles.Contains(new FavoriteHairStyle(gender, race, type, value));
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit dd86dafb88ca4c7b662938bbc1310729ba7f788d
|
Subproject commit 2f6acca678b71203763ac4404c3f054747c14f75
|
||||||
Loading…
Add table
Add a link
Reference in a new issue