This commit is contained in:
Ottermandias 2023-07-10 16:33:42 +02:00
parent ee98d6b600
commit 20cc67275a
25 changed files with 324 additions and 173 deletions

View file

@ -1,5 +1,6 @@
using System;
using System.Numerics;
using Dalamud.Interface;
using Glamourer.Customization;
using ImGuiNET;
using OtterGui.Raii;
@ -14,19 +15,33 @@ public partial class CustomizationDrawer
{
using var _ = SetId(index);
var (current, custom) = GetCurrentCustomization(index);
var color = ImGui.ColorConvertU32ToFloat4(custom.Color);
// Print 1-based index instead of 0.
if (ImGui.ColorButton($"{current + 1}##color", color, ImGuiColorEditFlags.None, _framedIconSize))
ImGui.OpenPopup(ColorPickerPopupName);
var color = ImGui.ColorConvertU32ToFloat4(current < 0 ? ImGui.GetColorU32(ImGuiCol.FrameBg) : custom.Color);
using (var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, current < 0))
{
// Print 1-based index instead of 0.
if (ImGui.ColorButton($"{current + 1}##color", color, ImGuiColorEditFlags.None, _framedIconSize))
ImGui.OpenPopup(ColorPickerPopupName);
}
if (current < 0)
{
using var font = ImRaii.PushFont(UiBuilder.IconFont);
var size = ImGui.CalcTextSize(FontAwesomeIcon.Question.ToIconString());
var pos = ImGui.GetItemRectMin() + (ImGui.GetItemRectSize() - size) / 2;
ImGui.GetWindowDrawList().AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), FontAwesomeIcon.Question.ToIconString());
current = 0;
}
ImGui.SameLine();
using (var group = ImRaii.Group())
{
DataInputInt(current);
ImGui.TextUnformatted(_currentOption);
ImGui.TextUnformatted(custom.Color == 0 ? $"{_currentOption} (Custom #{custom.Value})" : _currentOption);
}
DrawColorPickerPopup();
}
@ -57,8 +72,8 @@ public partial class CustomizationDrawer
{
var current = _set.DataByValue(index, _customize[index], out var custom, _customize.Face);
if (_set.IsAvailable(index) && current < 0)
throw new Exception($"Read invalid customization value {_customize[index]} for {index}.");
return (current, new CustomizeData(index, _customize[index], 0, 0));
return (current, custom!.Value);
}
}
}

View file

@ -1,17 +1,21 @@
using System;
using System.Numerics;
using System.Reflection;
using Dalamud.Interface;
using Dalamud.Plugin;
using Glamourer.Customization;
using Glamourer.Services;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using CustomizeData = Penumbra.GameData.Structs.CustomizeData;
namespace Glamourer.Gui.Customization;
public partial class CustomizationDrawer : IDisposable
{
private readonly CodeService _codes;
private readonly Vector4 _redTint = new(0.6f, 0.3f, 0.3f, 1f);
private readonly ImGuiScene.TextureWrap? _legacyTattoo;
@ -38,9 +42,10 @@ public partial class CustomizationDrawer : IDisposable
private readonly CustomizationService _service;
public CustomizationDrawer(DalamudPluginInterface pi, CustomizationService service)
public CustomizationDrawer(DalamudPluginInterface pi, CustomizationService service, CodeService codes)
{
_service = service;
_codes = codes;
_legacyTattoo = GetLegacyTattooIcon(pi);
_customize = Customize.Default;
}
@ -100,6 +105,9 @@ public partial class CustomizationDrawer : IDisposable
try
{
if (_codes.EnabledArtisan)
return DrawArtisan();
DrawRaceGenderSelector();
_set = _service.AwaitedService.GetList(_customize.Clan, _customize.Gender);
@ -129,6 +137,31 @@ public partial class CustomizationDrawer : IDisposable
}
}
private unsafe bool DrawArtisan()
{
for (var i = 0; i < CustomizeData.Size; ++i)
{
using var id = ImRaii.PushId(i);
int value = _customize.Data.Data[i];
ImGui.SetNextItemWidth(40 * ImGuiHelpers.GlobalScale);
if (!ImGui.InputInt(string.Empty, ref value, 0, 0))
continue;
var newValue = (byte)Math.Clamp(value, 0, byte.MaxValue);
if (newValue != _customize.Data.Data[i])
foreach (var flag in Enum.GetValues<CustomizeIndex>())
{
var (j, mask) = flag.ToByteAndMask();
if (j == i)
Changed |= flag.ToFlag();
}
_customize.Data.Data[i] = newValue;
}
return Changed != 0;
}
private void UpdateSizes()
{
_iconSize = new Vector2(ImGui.GetTextLineHeightWithSpacing() * 2);

View file

@ -8,6 +8,7 @@ using Glamourer.Designs;
using Glamourer.Services;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.GameData.Data;
using Penumbra.GameData.Enums;
@ -22,10 +23,13 @@ public class EquipmentDrawer
private readonly StainData _stainData;
private readonly ItemCombo[] _itemCombo;
private readonly Dictionary<FullEquipType, WeaponCombo> _weaponCombo;
private readonly CodeService _codes;
public EquipmentDrawer(DataManager gameData, ItemManager items)
public EquipmentDrawer(DataManager gameData, ItemManager items, CodeService codes)
{
_items = items;
_codes = codes;
_stainData = items.Stains;
_stainCombo = new FilterComboColors(140,
_stainData.Data.Prepend(new KeyValuePair<byte, (string Name, uint Dye, bool Gloss)>(0, ("None", 0, false))));
@ -57,9 +61,12 @@ public class EquipmentDrawer
public bool DrawArmor(EquipItem current, EquipSlot slot, out EquipItem armor, Gender gender = Gender.Unknown, Race race = Race.Unknown)
{
Debug.Assert(slot.IsEquipment() || slot.IsAccessory(), $"Called {nameof(DrawArmor)} on {slot}.");
if (_codes.EnabledArtisan)
return DrawArmorArtisan(current, slot, out armor, gender, race);
var combo = _itemCombo[slot.ToIndex()];
armor = current;
var change = combo.Draw(VerifyRestrictedGear(armor, slot, gender, race), armor.Id, 320 * ImGuiHelpers.GlobalScale);
var change = combo.Draw(VerifyRestrictedGear(armor, slot, gender, race), armor.ItemId, 320 * ImGuiHelpers.GlobalScale);
if (armor.ModelId.Value != 0)
{
ImGuiUtil.HoverTooltip("Right-click to clear.");
@ -81,18 +88,82 @@ public class EquipmentDrawer
return change;
}
public bool DrawStain(StainId current, EquipSlot slot, out Stain stain)
public bool DrawArmorArtisan(EquipItem current, EquipSlot slot, out EquipItem armor, Gender gender = Gender.Unknown,
Race race = Race.Unknown)
{
var found = _stainData.TryGetValue(current, out stain);
using var id = ImRaii.PushId((int)slot);
int setId = current.ModelId.Value;
int variant = current.Variant;
var ret = false;
armor = current;
ImGui.SetNextItemWidth(80 * ImGuiHelpers.GlobalScale);
if (ImGui.InputInt("##setId", ref setId, 0, 0))
{
var newSetId = (SetId)Math.Clamp(setId, 0, ushort.MaxValue);
if (newSetId.Value != current.ModelId.Value)
{
armor = _items.Identify(slot, newSetId, current.Variant);
ret = true;
}
}
ImGui.SameLine();
ImGui.SetNextItemWidth(40 * ImGuiHelpers.GlobalScale);
if (ImGui.InputInt("##variant", ref variant, 0, 0))
{
var newVariant = (byte)Math.Clamp(variant, 0, byte.MaxValue);
if (newVariant != current.Variant)
{
armor = _items.Identify(slot, current.ModelId, newVariant);
ret = true;
}
}
return ret;
}
public bool DrawStain(StainId current, EquipSlot slot, out StainId ret)
{
if (_codes.EnabledArtisan)
return DrawStainArtisan(current, slot, out ret);
var found = _stainData.TryGetValue(current, out var stain);
var change = _stainCombo.Draw($"##stain{slot}", stain.RgbaColor, stain.Name, found);
ImGuiUtil.HoverTooltip("Right-click to clear.");
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
stain = Stain.None;
ret = stain.RowIndex;
return true;
}
return change && _stainData.TryGetValue(_stainCombo.CurrentSelection.Key, out stain);
if (change && _stainData.TryGetValue(_stainCombo.CurrentSelection.Key, out stain))
{
ret = stain.RowIndex;
return true;
}
ret = current;
return false;
}
public bool DrawStainArtisan(StainId current, EquipSlot slot, out StainId stain)
{
using var id = ImRaii.PushId((int)slot);
int stainId = current.Value;
ImGui.SetNextItemWidth(40 * ImGuiHelpers.GlobalScale);
if (ImGui.InputInt("##stain", ref stainId, 0, 0))
{
var newStainId = (StainId)Math.Clamp(stainId, 0, byte.MaxValue);
if (newStainId != current)
{
stain = newStainId;
return true;
}
}
stain = current;
return false;
}
public bool DrawMainhand(EquipItem current, bool drawAll, out EquipItem weapon)
@ -101,7 +172,7 @@ public class EquipmentDrawer
if (!_weaponCombo.TryGetValue(drawAll ? FullEquipType.Unknown : current.Type, out var combo))
return false;
if (!combo.Draw(weapon.Name, weapon.Id, 320 * ImGuiHelpers.GlobalScale))
if (!combo.Draw(weapon.Name, weapon.ItemId, 320 * ImGuiHelpers.GlobalScale))
return false;
weapon = combo.CurrentSelection;
@ -118,7 +189,7 @@ public class EquipmentDrawer
if (!_weaponCombo.TryGetValue(offType, out var combo))
return false;
var change = combo.Draw(weapon.Name, weapon.Id, 320 * ImGuiHelpers.GlobalScale);
var change = combo.Draw(weapon.Name, weapon.ItemId, 320 * ImGuiHelpers.GlobalScale);
if (!offType.IsOffhandType() && weapon.ModelId.Value != 0)
{
ImGuiUtil.HoverTooltip("Right-click to clear.");

View file

@ -34,10 +34,10 @@ public sealed class ItemCombo : FilterComboCache<EquipItem>
protected override int UpdateCurrentSelected(int currentSelected)
{
if (CurrentSelection.Id == _currentItem)
if (CurrentSelection.ItemId == _currentItem)
return currentSelected;
CurrentSelectionIdx = Items.IndexOf(i => i.Id == _currentItem);
CurrentSelectionIdx = Items.IndexOf(i => i.ItemId == _currentItem);
CurrentSelection = CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : default;
return base.UpdateCurrentSelected(CurrentSelectionIdx);

View file

@ -30,10 +30,10 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
protected override int UpdateCurrentSelected(int currentSelected)
{
if (CurrentSelection.Id == _currentItemId)
if (CurrentSelection.ItemId == _currentItemId)
return currentSelected;
CurrentSelectionIdx = Items.IndexOf(i => i.Id == _currentItemId);
CurrentSelectionIdx = Items.IndexOf(i => i.ItemId == _currentItemId);
CurrentSelection = CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : default;
return base.UpdateCurrentSelected(CurrentSelectionIdx);
}

View file

@ -210,7 +210,7 @@ public class PenumbraChangedItemTooltip : IDisposable
else
{
var oldItem = state.ModelData.Item(slot);
if (oldItem.Id != item.Id)
if (oldItem.ItemId != item.ItemId)
_lastItems[slot.ToIndex()] = oldItem;
}
}

View file

@ -131,33 +131,33 @@ public class ActorPanel
{
var stain = _state.ModelData.Stain(slot);
if (_equipmentDrawer.DrawStain(stain, slot, out var newStain))
_stateManager.ChangeStain(_state, slot, newStain.RowIndex, StateChanged.Source.Manual);
_stateManager.ChangeStain(_state, slot, newStain, StateChanged.Source.Manual);
ImGui.SameLine();
var armor = _state.ModelData.Item(slot);
if (_equipmentDrawer.DrawArmor(armor, slot, out var newArmor, _state.ModelData.Customize.Gender, _state.ModelData.Customize.Race))
_stateManager.ChangeEquip(_state, slot, newArmor, newStain.RowIndex, StateChanged.Source.Manual);
_stateManager.ChangeEquip(_state, slot, newArmor, newStain, StateChanged.Source.Manual);
}
var mhStain = _state.ModelData.Stain(EquipSlot.MainHand);
if (_equipmentDrawer.DrawStain(mhStain, EquipSlot.MainHand, out var newMhStain))
_stateManager.ChangeStain(_state, EquipSlot.MainHand, newMhStain.RowIndex, StateChanged.Source.Manual);
_stateManager.ChangeStain(_state, EquipSlot.MainHand, newMhStain, StateChanged.Source.Manual);
ImGui.SameLine();
var mh = _state.ModelData.Item(EquipSlot.MainHand);
if (_equipmentDrawer.DrawMainhand(mh, false, out var newMh))
_stateManager.ChangeEquip(_state, EquipSlot.MainHand, newMh, newMhStain.RowIndex, StateChanged.Source.Manual);
_stateManager.ChangeEquip(_state, EquipSlot.MainHand, newMh, newMhStain, StateChanged.Source.Manual);
if (newMh.Type.Offhand() is not FullEquipType.Unknown)
{
var ohStain = _state.ModelData.Stain(EquipSlot.OffHand);
if (_equipmentDrawer.DrawStain(ohStain, EquipSlot.OffHand, out var newOhStain))
_stateManager.ChangeStain(_state, EquipSlot.OffHand, newOhStain.RowIndex, StateChanged.Source.Manual);
_stateManager.ChangeStain(_state, EquipSlot.OffHand, newOhStain, StateChanged.Source.Manual);
ImGui.SameLine();
var oh = _state.ModelData.Item(EquipSlot.OffHand);
if (_equipmentDrawer.DrawMainhand(oh, false, out var newOh))
_stateManager.ChangeEquip(_state, EquipSlot.OffHand, newOh, newOhStain.RowIndex, StateChanged.Source.Manual);
_stateManager.ChangeEquip(_state, EquipSlot.OffHand, newOh, newOhStain, StateChanged.Source.Manual);
}
}

View file

@ -168,7 +168,7 @@ public class SetPanel
continue;
var item = design.Design.DesignData.Item(slot);
if (!_itemUnlocks.IsUnlocked(item.Id, out _))
if (!_itemUnlocks.IsUnlocked(item.ItemId, out _))
sb.AppendLine($"{item.Name} in {slot.ToName()} slot is not unlocked but should be applied.");
}

View file

@ -155,6 +155,15 @@ public unsafe class DebugTab : ITab
ImGui.TableNextColumn();
ImGuiUtil.CopyOnClickSelectable(model.ToString());
ImGui.TableNextColumn();
if (actor.IsCharacter)
{
if (actor.AsCharacter->CharacterData.TransformationId != 0)
ImGui.TextUnformatted($"Transformation Id: {actor.AsCharacter->CharacterData.TransformationId}");
if (actor.AsCharacter->CharacterData.ModelCharaId_2 != -1)
ImGui.TextUnformatted($"ModelChara2 {actor.AsCharacter->CharacterData.ModelCharaId_2}");
if (actor.AsCharacter->CharacterData.StatusEffectVFXId != 0)
ImGui.TextUnformatted($"Status Id: {actor.AsCharacter->CharacterData.StatusEffectVFXId}");
}
ImGuiUtil.DrawTableColumn("Mainhand");
ImGuiUtil.DrawTableColumn(actor.IsCharacter ? actor.GetMainhand().ToString() : "No Character");
@ -712,7 +721,7 @@ public unsafe class DebugTab : ITab
return;
disabled.Dispose();
ImRaii.TreeNode($"Default Sword: {_items.DefaultSword.Name} ({_items.DefaultSword.Id}) ({_items.DefaultSword.Weapon()})",
ImRaii.TreeNode($"Default Sword: {_items.DefaultSword.Name} ({_items.DefaultSword.ItemId}) ({_items.DefaultSword.Weapon()})",
ImGuiTreeNodeFlags.Leaf).Dispose();
DrawNameTable("All Items (Main)", ref _itemFilter,
_items.ItemService.AwaitedService.AllItems(true).Select(p => (p.Item1,
@ -726,7 +735,7 @@ public unsafe class DebugTab : ITab
{
DrawNameTable(type.ToName(), ref _itemFilter,
_items.ItemService.AwaitedService[type]
.Select(p => (p.Id, $"{p.Name} ({(p.WeaponType == 0 ? p.Armor().ToString() : p.Weapon().ToString())})")));
.Select(p => (Id: p.ItemId, $"{p.Name} ({(p.WeaponType == 0 ? p.Armor().ToString() : p.Weapon().ToString())})")));
}
}
@ -1091,7 +1100,7 @@ public unsafe class DebugTab : ITab
var stain = data.Stain(slot);
ImGuiUtil.DrawTableColumn(slot.ToName());
ImGuiUtil.DrawTableColumn(item.Name);
ImGuiUtil.DrawTableColumn(item.Id.ToString());
ImGuiUtil.DrawTableColumn(item.ItemId.ToString());
ImGuiUtil.DrawTableColumn(stain.ToString());
}
@ -1175,7 +1184,7 @@ public unsafe class DebugTab : ITab
var applyStain = design.DoApplyStain(slot);
ImGuiUtil.DrawTableColumn(slot.ToName());
ImGuiUtil.DrawTableColumn(item.Name);
ImGuiUtil.DrawTableColumn(item.Id.ToString());
ImGuiUtil.DrawTableColumn(item.ItemId.ToString());
ImGuiUtil.DrawTableColumn(apply ? "Apply" : "Keep");
ImGuiUtil.DrawTableColumn(stain.ToString());
ImGuiUtil.DrawTableColumn(applyStain ? "Apply" : "Keep");

View file

@ -131,7 +131,7 @@ public class DesignPanel
{
var stain = _selector.Selected!.DesignData.Stain(slot);
if (_equipmentDrawer.DrawStain(stain, slot, out var newStain))
_manager.ChangeStain(_selector.Selected!, slot, newStain.RowIndex);
_manager.ChangeStain(_selector.Selected!, slot, newStain);
ImGui.SameLine();
var armor = _selector.Selected!.DesignData.Item(slot);
@ -142,7 +142,7 @@ public class DesignPanel
var mhStain = _selector.Selected!.DesignData.Stain(EquipSlot.MainHand);
if (_equipmentDrawer.DrawStain(mhStain, EquipSlot.MainHand, out var newMhStain))
_manager.ChangeStain(_selector.Selected!, EquipSlot.MainHand, newMhStain.RowIndex);
_manager.ChangeStain(_selector.Selected!, EquipSlot.MainHand, newMhStain);
ImGui.SameLine();
var mh = _selector.Selected!.DesignData.Item(EquipSlot.MainHand);
@ -153,7 +153,7 @@ public class DesignPanel
{
var ohStain = _selector.Selected!.DesignData.Stain(EquipSlot.OffHand);
if (_equipmentDrawer.DrawStain(ohStain, EquipSlot.OffHand, out var newOhStain))
_manager.ChangeStain(_selector.Selected!, EquipSlot.OffHand, newOhStain.RowIndex);
_manager.ChangeStain(_selector.Selected!, EquipSlot.OffHand, newOhStain);
ImGui.SameLine();
var oh = _selector.Selected!.DesignData.Item(EquipSlot.OffHand);

View file

@ -153,7 +153,7 @@ public class UnlockOverview
void DrawItem(EquipItem item)
{
var unlocked = _itemUnlocks.IsUnlocked(item.Id, out var time);
var unlocked = _itemUnlocks.IsUnlocked(item.ItemId, out var time);
var iconHandle = _textureCache.LoadIcon(item.IconId);
if (!iconHandle.HasValue)
return;
@ -179,7 +179,7 @@ public class UnlockOverview
ImGui.TextUnformatted($"{item.Type.ToName()} ({slot.ToName()})");
if (item.Type.Offhand().IsOffhandType())
ImGui.TextUnformatted(
$"{item.Weapon()}{(_items.ItemService.AwaitedService.TryGetValue(item.Id, false, out var offhand) ? $" | {offhand.Weapon()}" : string.Empty)}");
$"{item.Weapon()}{(_items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand) ? $" | {offhand.Weapon()}" : string.Empty)}");
else
ImGui.TextUnformatted(slot is EquipSlot.MainHand ? $"{item.Weapon()}" : $"{item.Armor()}");
ImGui.TextUnformatted(

View file

@ -193,7 +193,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
public override void DrawColumn(EquipItem item, int idx)
{
if (!_unlocks.IsUnlocked(item.Id, out var time))
if (!_unlocks.IsUnlocked(item.ItemId, out var time))
return;
ImGui.AlignTextToFramePadding();
@ -202,8 +202,8 @@ public class UnlockTable : Table<EquipItem>, IDisposable
public override int Compare(EquipItem lhs, EquipItem rhs)
{
var unlockedLhs = _unlocks.IsUnlocked(lhs.Id, out var timeLhs);
var unlockedRhs = _unlocks.IsUnlocked(rhs.Id, out var timeRhs);
var unlockedLhs = _unlocks.IsUnlocked(lhs.ItemId, out var timeLhs);
var unlockedRhs = _unlocks.IsUnlocked(rhs.ItemId, out var timeRhs);
var c1 = unlockedLhs.CompareTo(unlockedRhs);
return c1 != 0 ? c1 : timeLhs.CompareTo(timeRhs);
}
@ -215,15 +215,15 @@ public class UnlockTable : Table<EquipItem>, IDisposable
=> 70 * ImGuiHelpers.GlobalScale;
public override int Compare(EquipItem lhs, EquipItem rhs)
=> lhs.Id.CompareTo(rhs.Id);
=> lhs.ItemId.CompareTo(rhs.ItemId);
public override string ToName(EquipItem item)
=> item.Id.ToString();
=> item.ItemId.ToString();
public override void DrawColumn(EquipItem item, int _)
{
ImGui.AlignTextToFramePadding();
ImGuiUtil.RightAlign(item.Id.ToString());
ImGuiUtil.RightAlign(item.ItemId.ToString());
}
}
@ -243,7 +243,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
ImGuiUtil.RightAlign(item.ModelString);
if (ImGui.IsItemHovered()
&& item.Type.Offhand().IsOffhandType()
&& _items.ItemService.AwaitedService.TryGetValue(item.Id, false, out var offhand))
&& _items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand))
{
using var tt = ImRaii.Tooltip();
ImGui.TextUnformatted("Offhand: " + offhand.ModelString);
@ -261,7 +261,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
if (FilterRegex?.IsMatch(item.ModelString) ?? item.ModelString.Contains(FilterValue, StringComparison.OrdinalIgnoreCase))
return true;
if (item.Type.Offhand().IsOffhandType() && _items.ItemService.AwaitedService.TryGetValue(item.Id, false, out var offhand))
if (item.Type.Offhand().IsOffhandType() && _items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand))
return FilterRegex?.IsMatch(offhand.ModelString)
?? offhand.ModelString.Contains(FilterValue, StringComparison.OrdinalIgnoreCase);