mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 10:17:23 +01:00
Allow drag & drop of equipment pieces.
This commit is contained in:
parent
d7b189b714
commit
282935c6d6
6 changed files with 169 additions and 4 deletions
83
Glamourer/Gui/Equipment/EquipItemSlotCache.cs
Normal file
83
Glamourer/Gui/Equipment/EquipItemSlotCache.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
using Glamourer.Services;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Glamourer.Gui.Equipment;
|
||||||
|
|
||||||
|
[InlineArray(13)]
|
||||||
|
public struct EquipItemSlotCache
|
||||||
|
{
|
||||||
|
private EquipItem _element;
|
||||||
|
|
||||||
|
public EquipItem Dragged
|
||||||
|
{
|
||||||
|
get => this[^1];
|
||||||
|
set => this[^1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
=> ((Span<EquipItem>)this).Clear();
|
||||||
|
|
||||||
|
public EquipItem this[EquipSlot slot]
|
||||||
|
{
|
||||||
|
get => this[(int)slot.ToIndex()];
|
||||||
|
set => this[(int)slot.ToIndex()] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(ItemManager items, in EquipItem item, EquipSlot startSlot)
|
||||||
|
{
|
||||||
|
if (item.Id == Dragged.Id && item.Type == Dragged.Type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (startSlot)
|
||||||
|
{
|
||||||
|
case EquipSlot.MainHand:
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
this[EquipSlot.MainHand] = item;
|
||||||
|
if (item.Type is FullEquipType.Sword)
|
||||||
|
this[EquipSlot.OffHand] = items.FindClosestShield(item.ItemId, out var shield) ? shield : default;
|
||||||
|
else
|
||||||
|
this[EquipSlot.OffHand] = items.ItemData.Secondary.GetValueOrDefault(item.ItemId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EquipSlot.OffHand:
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
if (item.Type is FullEquipType.Shield)
|
||||||
|
this[EquipSlot.MainHand] = items.FindClosestSword(item.ItemId, out var sword) ? sword : default;
|
||||||
|
else
|
||||||
|
this[EquipSlot.MainHand] = items.ItemData.Primary.GetValueOrDefault(item.ItemId);
|
||||||
|
this[EquipSlot.OffHand] = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
this[EquipSlot.MainHand] = default;
|
||||||
|
this[EquipSlot.OffHand] = default;
|
||||||
|
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||||
|
{
|
||||||
|
if (startSlot == slot)
|
||||||
|
{
|
||||||
|
this[slot] = item;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slotItem = items.Identify(slot, item.PrimaryId, item.Variant);
|
||||||
|
if (!slotItem.Valid || slotItem.ItemId.Id is not 0 != item.ItemId.Id is not 0)
|
||||||
|
{
|
||||||
|
slotItem = items.Identify(EquipSlot.OffHand, item.PrimaryId, item.SecondaryId, 1, item.Type);
|
||||||
|
if (slotItem.ItemId.Id is not 0 != item.ItemId.Id is not 0)
|
||||||
|
slotItem = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
this[slot] = slotItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dragged = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,8 @@ public class EquipmentDrawer
|
||||||
private float _requiredComboWidth;
|
private float _requiredComboWidth;
|
||||||
|
|
||||||
private Stain? _draggedStain;
|
private Stain? _draggedStain;
|
||||||
|
private EquipItemSlotCache _draggedItem;
|
||||||
|
private EquipSlot _dragTarget;
|
||||||
|
|
||||||
public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, TextureService textures,
|
public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, TextureService textures,
|
||||||
Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes, ItemCopyService itemCopy)
|
Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes, ItemCopyService itemCopy)
|
||||||
|
|
@ -80,6 +82,7 @@ public class EquipmentDrawer
|
||||||
|
|
||||||
_requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale;
|
_requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale;
|
||||||
_advancedMaterialColor = ColorId.AdvancedDyeActive.Value();
|
_advancedMaterialColor = ColorId.AdvancedDyeActive.Value();
|
||||||
|
_dragTarget = EquipSlot.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool VerifyRestrictedGear(EquipDrawData data)
|
private bool VerifyRestrictedGear(EquipDrawData data)
|
||||||
|
|
@ -429,7 +432,7 @@ public class EquipmentDrawer
|
||||||
using var dragSource = ImUtf8.DragDropSource();
|
using var dragSource = ImUtf8.DragDropSource();
|
||||||
if (dragSource.Success)
|
if (dragSource.Success)
|
||||||
{
|
{
|
||||||
if (DragDropSource.SetPayload("stainDragDrop"u8))
|
DragDropSource.SetPayload("stainDragDrop"u8);
|
||||||
_draggedStain = stain;
|
_draggedStain = stain;
|
||||||
ImUtf8.Text($"Dragging {stain.Name}...");
|
ImUtf8.Text($"Dragging {stain.Name}...");
|
||||||
}
|
}
|
||||||
|
|
@ -455,6 +458,7 @@ public class EquipmentDrawer
|
||||||
using var disabled = ImRaii.Disabled(data.Locked);
|
using var disabled = ImRaii.Disabled(data.Locked);
|
||||||
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
||||||
_requiredComboWidth);
|
_requiredComboWidth);
|
||||||
|
DrawGearDragDrop(data);
|
||||||
if (change)
|
if (change)
|
||||||
data.SetItem(combo.CurrentSelection);
|
data.SetItem(combo.CurrentSelection);
|
||||||
else if (combo.CustomVariant.Id > 0)
|
else if (combo.CustomVariant.Id > 0)
|
||||||
|
|
@ -495,6 +499,50 @@ public class EquipmentDrawer
|
||||||
data.SetItem(item);
|
data.SetItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawGearDragDrop(in EquipDrawData data)
|
||||||
|
{
|
||||||
|
if (data.CurrentItem.Valid)
|
||||||
|
{
|
||||||
|
using var dragSource = ImUtf8.DragDropSource();
|
||||||
|
if (dragSource.Success)
|
||||||
|
{
|
||||||
|
DragDropSource.SetPayload("equipDragDrop"u8);
|
||||||
|
_draggedItem.Update(_items, data.CurrentItem, data.Slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using var dragTarget = ImUtf8.DragDropTarget();
|
||||||
|
if (!dragTarget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var item = _draggedItem[data.Slot];
|
||||||
|
if (!item.Valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dragTarget = data.Slot;
|
||||||
|
if (!dragTarget.IsDropping("equipDragDrop"u8))
|
||||||
|
return;
|
||||||
|
|
||||||
|
data.SetItem(item);
|
||||||
|
_draggedItem.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void DrawDragDropTooltip()
|
||||||
|
{
|
||||||
|
var payload = ImGui.GetDragDropPayload().NativePtr;
|
||||||
|
if (payload is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!MemoryMarshal.CreateReadOnlySpanFromNullTerminated(payload->DataType).SequenceEqual("equipDragDrop"u8))
|
||||||
|
return;
|
||||||
|
|
||||||
|
using var tt = ImUtf8.Tooltip();
|
||||||
|
if (_dragTarget is EquipSlot.Unknown)
|
||||||
|
ImUtf8.Text($"Dragging {_draggedItem.Dragged.Name}...");
|
||||||
|
else
|
||||||
|
ImUtf8.Text($"Converting to {_draggedItem[_dragTarget].Name}...");
|
||||||
|
}
|
||||||
|
|
||||||
private static bool ResetOrClear<T>(bool locked, bool clicked, bool allowRevert, bool allowClear,
|
private static bool ResetOrClear<T>(bool locked, bool clicked, bool allowRevert, bool allowClear,
|
||||||
in T currentItem, in T revertItem, in T clearItem, out T? item) where T : IEquatable<T>
|
in T currentItem, in T revertItem, in T clearItem, out T? item) where T : IEquatable<T>
|
||||||
{
|
{
|
||||||
|
|
@ -546,6 +594,7 @@ public class EquipmentDrawer
|
||||||
else if (combo.CustomVariant.Id > 0 && (drawAll || ItemData.ConvertWeaponId(combo.CustomSetId) == mainhand.CurrentItem.Type))
|
else if (combo.CustomVariant.Id > 0 && (drawAll || ItemData.ConvertWeaponId(combo.CustomSetId) == mainhand.CurrentItem.Type))
|
||||||
changedItem = _items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant);
|
changedItem = _items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant);
|
||||||
_itemCopy.HandleCopyPaste(mainhand);
|
_itemCopy.HandleCopyPaste(mainhand);
|
||||||
|
DrawGearDragDrop(mainhand);
|
||||||
|
|
||||||
if (ResetOrClear(mainhand.Locked || unknown, open, mainhand.AllowRevert, false, mainhand.CurrentItem, mainhand.GameItem,
|
if (ResetOrClear(mainhand.Locked || unknown, open, mainhand.AllowRevert, false, mainhand.CurrentItem, mainhand.GameItem,
|
||||||
default, out var c))
|
default, out var c))
|
||||||
|
|
@ -589,6 +638,7 @@ public class EquipmentDrawer
|
||||||
else if (combo.CustomVariant.Id > 0 && ItemData.ConvertWeaponId(combo.CustomSetId) == offhand.CurrentItem.Type)
|
else if (combo.CustomVariant.Id > 0 && ItemData.ConvertWeaponId(combo.CustomSetId) == offhand.CurrentItem.Type)
|
||||||
offhand.SetItem(_items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant));
|
offhand.SetItem(_items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant));
|
||||||
_itemCopy.HandleCopyPaste(offhand);
|
_itemCopy.HandleCopyPaste(offhand);
|
||||||
|
DrawGearDragDrop(offhand);
|
||||||
|
|
||||||
var defaultOffhand = _items.GetDefaultOffhand(mainhand.CurrentItem);
|
var defaultOffhand = _items.GetDefaultOffhand(mainhand.CurrentItem);
|
||||||
if (ResetOrClear(locked, clear, offhand.AllowRevert, true, offhand.CurrentItem, offhand.GameItem, defaultOffhand, out var item))
|
if (ResetOrClear(locked, clear, offhand.AllowRevert, true, offhand.CurrentItem, offhand.GameItem, defaultOffhand, out var item))
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,7 @@ public class ActorPanel
|
||||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||||
DrawEquipmentMetaToggles();
|
DrawEquipmentMetaToggles();
|
||||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||||
|
_equipmentDrawer.DrawDragDropTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawParameterHeader()
|
private void DrawParameterHeader()
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ public class DesignPanel
|
||||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||||
DrawEquipmentMetaToggles();
|
DrawEquipmentMetaToggles();
|
||||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||||
|
_equipmentDrawer.DrawDragDropTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawEquipmentMetaToggles()
|
private void DrawEquipmentMetaToggles()
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,36 @@ public class ItemManager
|
||||||
return NothingItem(offhandType);
|
return NothingItem(offhandType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool FindClosestShield(ItemId id, out EquipItem item)
|
||||||
|
{
|
||||||
|
var list = ItemData.ByType[FullEquipType.Shield];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
item = list.Where(i => i.ItemId.Id > id.Id && i.ItemId.Id - id.Id < 50).MinBy(i => i.ItemId.Id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
item = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FindClosestSword(ItemId id, out EquipItem item)
|
||||||
|
{
|
||||||
|
var list = ItemData.ByType[FullEquipType.Sword];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
item = list.Where(i => i.ItemId.Id < id.Id && id.Id - i.ItemId.Id < 50).MaxBy(i => i.ItemId.Id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
item = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public EquipItem Identify(EquipSlot slot, PrimaryId id, SecondaryId type, Variant variant,
|
public EquipItem Identify(EquipSlot slot, PrimaryId id, SecondaryId type, Variant variant,
|
||||||
FullEquipType mainhandType = FullEquipType.Unknown)
|
FullEquipType mainhandType = FullEquipType.Unknown)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 574ef3a8afd42b949e713e247a0b812886f088bb
|
Subproject commit ff7b3b4014a97455f823380c78b8a7c5107f8e2f
|
||||||
Loading…
Add table
Add a link
Reference in a new issue