mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-21 23:17:43 +01:00
Support human NPCs for identifiers.
This commit is contained in:
parent
a310e01296
commit
b00e6bd98b
17 changed files with 536 additions and 162 deletions
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Interface;
|
||||
using Glamourer.Designs;
|
||||
|
|
@ -24,16 +25,17 @@ public class EquipmentDrawer
|
|||
private readonly ItemCombo[] _itemCombo;
|
||||
private readonly Dictionary<FullEquipType, WeaponCombo> _weaponCombo;
|
||||
private readonly CodeService _codes;
|
||||
private readonly TextureService _textures;
|
||||
|
||||
|
||||
public EquipmentDrawer(DataManager gameData, ItemManager items, CodeService codes)
|
||||
public EquipmentDrawer(DataManager gameData, ItemManager items, CodeService codes, TextureService textures)
|
||||
{
|
||||
_items = items;
|
||||
_codes = codes;
|
||||
_textures = textures;
|
||||
_stainData = items.Stains;
|
||||
_stainCombo = new FilterComboColors(140,
|
||||
_stainData.Data.Prepend(new KeyValuePair<byte, (string Name, uint Dye, bool Gloss)>(0, ("None", 0, false))));
|
||||
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e)).ToArray();
|
||||
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, textures)).ToArray();
|
||||
_weaponCombo = new Dictionary<FullEquipType, WeaponCombo>(FullEquipTypeExtensions.WeaponTypes.Count * 2);
|
||||
foreach (var type in Enum.GetValues<FullEquipType>())
|
||||
{
|
||||
|
|
@ -46,6 +48,15 @@ public class EquipmentDrawer
|
|||
_weaponCombo.Add(FullEquipType.Unknown, new WeaponCombo(items, FullEquipType.Unknown));
|
||||
}
|
||||
|
||||
private Vector2 _iconSize;
|
||||
private float _comboLength;
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
_iconSize = new Vector2(2 * ImGui.GetFrameHeight() + ImGui.GetStyle().ItemSpacing.Y);
|
||||
_comboLength = 320 * ImGuiHelpers.GlobalScale;
|
||||
}
|
||||
|
||||
private string VerifyRestrictedGear(EquipItem gear, EquipSlot slot, Gender gender, Race race)
|
||||
{
|
||||
if (slot.IsAccessory())
|
||||
|
|
@ -61,12 +72,20 @@ 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);
|
||||
|
||||
current.DrawIcon(_textures, _iconSize);
|
||||
ImGui.SameLine();
|
||||
using var group = ImRaii.Group();
|
||||
|
||||
var combo = _itemCombo[slot.ToIndex()];
|
||||
armor = current;
|
||||
var change = combo.Draw(VerifyRestrictedGear(armor, slot, gender, race), armor.ItemId, 320 * ImGuiHelpers.GlobalScale);
|
||||
var change = combo.Draw(VerifyRestrictedGear(armor, slot, gender, race), armor.ItemId, _comboLength);
|
||||
if (change)
|
||||
armor = combo.CurrentSelection;
|
||||
|
||||
if (armor.ModelId.Value != 0)
|
||||
{
|
||||
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
||||
|
|
@ -75,95 +94,30 @@ public class EquipmentDrawer
|
|||
change = true;
|
||||
armor = ItemManager.NothingItem(slot);
|
||||
}
|
||||
else if (change)
|
||||
{
|
||||
armor = combo.CurrentSelection;
|
||||
}
|
||||
}
|
||||
else if (change)
|
||||
{
|
||||
armor = combo.CurrentSelection;
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
public bool DrawArmorArtisan(EquipItem current, EquipSlot slot, out EquipItem armor, Gender gender = Gender.Unknown,
|
||||
Race race = Race.Unknown)
|
||||
{
|
||||
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);
|
||||
var change = _stainCombo.Draw($"##stain{slot}", stain.RgbaColor, stain.Name, found, stain.Gloss, _comboLength);
|
||||
ret = current;
|
||||
if (change && _stainData.TryGetValue(_stainCombo.CurrentSelection.Key, out stain))
|
||||
ret = stain.RowIndex;
|
||||
|
||||
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
stain = Stain.None;
|
||||
ret = stain.RowIndex;
|
||||
return true;
|
||||
ret = Stain.None.RowIndex;
|
||||
change = true;
|
||||
}
|
||||
|
||||
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;
|
||||
return change;
|
||||
}
|
||||
|
||||
public bool DrawMainhand(EquipItem current, bool drawAll, out EquipItem weapon)
|
||||
|
|
@ -191,7 +145,9 @@ public class EquipmentDrawer
|
|||
|
||||
var change = combo.Draw(weapon.Name, weapon.ItemId, 320 * ImGuiHelpers.GlobalScale);
|
||||
if (change)
|
||||
{
|
||||
weapon = combo.CurrentSelection;
|
||||
}
|
||||
else if (!offType.IsOffhandType() && weapon.ModelId.Value != 0)
|
||||
{
|
||||
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
||||
|
|
@ -229,4 +185,59 @@ public class EquipmentDrawer
|
|||
|
||||
public bool DrawWetness(bool current, out bool on)
|
||||
=> DrawCheckbox("##wetness", current, out on);
|
||||
|
||||
/// <summary> Draw an input for armor that can set arbitrary values instead of choosing items. </summary>
|
||||
private bool DrawArmorArtisan(EquipItem current, EquipSlot slot, out EquipItem armor, Gender gender = Gender.Unknown,
|
||||
Race race = Race.Unknown)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary> Draw an input for stain that can set arbitrary values instead of choosing valid stains. </summary>
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,15 @@ namespace Glamourer.Gui.Equipment;
|
|||
|
||||
public sealed class ItemCombo : FilterComboCache<EquipItem>
|
||||
{
|
||||
private readonly TextureService _textures;
|
||||
|
||||
public readonly string Label;
|
||||
private uint _currentItem;
|
||||
|
||||
public ItemCombo(DataManager gameData, ItemManager items, EquipSlot slot)
|
||||
public ItemCombo(DataManager gameData, ItemManager items, EquipSlot slot, TextureService textures)
|
||||
: base(() => GetItems(items, slot))
|
||||
{
|
||||
_textures = textures;
|
||||
Label = GetLabel(gameData, slot);
|
||||
_currentItem = ItemManager.NothingId(slot);
|
||||
}
|
||||
|
|
@ -40,7 +43,6 @@ public sealed class ItemCombo : FilterComboCache<EquipItem>
|
|||
CurrentSelectionIdx = Items.IndexOf(i => i.ItemId == _currentItem);
|
||||
CurrentSelection = CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : default;
|
||||
return base.UpdateCurrentSelected(CurrentSelectionIdx);
|
||||
|
||||
}
|
||||
|
||||
public bool Draw(string previewName, uint previewIdx, float width)
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ public class ActorPanel
|
|||
if (_customizationDrawer.Draw(_state!.ModelData.Customize, false))
|
||||
_stateManager.ChangeCustomize(_state, _customizationDrawer.Customize, _customizationDrawer.Changed, StateChanged.Source.Manual);
|
||||
|
||||
_equipmentDrawer.Prepare();
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
var stain = _state.ModelData.Stain(slot);
|
||||
|
|
|
|||
95
Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs
Normal file
95
Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Game.ClientState.Objects.Enums;
|
||||
using Dalamud.Utility;
|
||||
using Glamourer.Services;
|
||||
using ImGuiNET;
|
||||
using OtterGui.Custom;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.GameData.Data;
|
||||
|
||||
namespace Glamourer.Gui.Tabs.AutomationTab;
|
||||
|
||||
public sealed class HumanNpcCombo : FilterComboCache<(string Name, ObjectKind Kind, uint[] Ids)>
|
||||
{
|
||||
private readonly string _label;
|
||||
|
||||
public HumanNpcCombo(string label, IdentifierService service, HumanModelList humans)
|
||||
: base(() => CreateList(service, humans))
|
||||
=> _label = label;
|
||||
|
||||
protected override string ToString((string Name, ObjectKind Kind, uint[] Ids) obj)
|
||||
=> obj.Name;
|
||||
|
||||
protected override bool DrawSelectable(int globalIdx, bool selected)
|
||||
{
|
||||
var (name, kind, ids) = Items[globalIdx];
|
||||
if (globalIdx > 0 && Items[globalIdx - 1].Name == name || globalIdx + 1 < Items.Count && Items[globalIdx + 1].Name == name)
|
||||
name = $"{name} ({kind.ToName()})";
|
||||
var ret = ImGui.Selectable(name, selected);
|
||||
if (ImGui.IsItemHovered())
|
||||
ImGui.SetTooltip(string.Join('\n', ids.Select(i => i.ToString())));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool Draw(float width)
|
||||
=> Draw(_label, CurrentSelection.Name, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
|
||||
|
||||
|
||||
/// <summary> Compare strings in a way that letters and numbers are sorted before any special symbols. </summary>
|
||||
private class NameComparer : IComparer<(string, ObjectKind)>
|
||||
{
|
||||
public int Compare((string, ObjectKind) x, (string, ObjectKind) y)
|
||||
{
|
||||
if (x.Item1.IsNullOrWhitespace() || y.Item1.IsNullOrWhitespace())
|
||||
return StringComparer.OrdinalIgnoreCase.Compare(x.Item1, y.Item1);
|
||||
|
||||
var comp = (char.IsAsciiLetterOrDigit(x.Item1[0]), char.IsAsciiLetterOrDigit(y.Item1[0])) switch
|
||||
{
|
||||
(true, false) => -1,
|
||||
(false, true) => 1,
|
||||
_ => StringComparer.OrdinalIgnoreCase.Compare(x.Item1, y.Item1),
|
||||
};
|
||||
|
||||
if (comp != 0)
|
||||
return comp;
|
||||
|
||||
return Comparer<ObjectKind>.Default.Compare(x.Item2, y.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyList<(string Name, ObjectKind Kind, uint[] Ids)> CreateList(IdentifierService service, HumanModelList humans)
|
||||
{
|
||||
var ret = new List<(string Name, ObjectKind Kind, uint Id)>(1024);
|
||||
for (var modelChara = 0u; modelChara < service.AwaitedService.NumModelChara; ++modelChara)
|
||||
{
|
||||
if (!humans.IsHuman(modelChara))
|
||||
continue;
|
||||
|
||||
var list = service.AwaitedService.ModelCharaNames(modelChara);
|
||||
if (list.Count == 0)
|
||||
continue;
|
||||
|
||||
foreach (var (name, kind, id) in list.Where(t => !t.Name.IsNullOrWhitespace()))
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case ObjectKind.BattleNpc:
|
||||
var nameIds = service.AwaitedService.GetBnpcNames(id);
|
||||
ret.AddRange(nameIds.Select(nameId => (name, kind, nameId)));
|
||||
break;
|
||||
case ObjectKind.EventNpc:
|
||||
ret.Add((name, kind, id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret.GroupBy(t => (t.Name, t.Kind)).OrderBy(g => g.Key, Comparer)
|
||||
.Select(g => (g.Key.Name, g.Key.Kind, g.Select(g => g.Id).ToArray())).ToList();
|
||||
}
|
||||
|
||||
private static readonly NameComparer Comparer = new();
|
||||
}
|
||||
70
Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs
Normal file
70
Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using Dalamud.Game.ClientState.Objects.Enums;
|
||||
using Glamourer.Services;
|
||||
using ImGuiNET;
|
||||
using OtterGui.Custom;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.String;
|
||||
|
||||
namespace Glamourer.Gui.Tabs.AutomationTab;
|
||||
|
||||
public class IdentifierDrawer
|
||||
{
|
||||
private readonly WorldCombo _worldCombo;
|
||||
private readonly HumanNpcCombo _humanNpcCombo;
|
||||
private readonly ActorService _actors;
|
||||
|
||||
private string _characterName = string.Empty;
|
||||
|
||||
public ActorIdentifier NpcIdentifier { get; private set; } = ActorIdentifier.Invalid;
|
||||
public ActorIdentifier PlayerIdentifier { get; private set; } = ActorIdentifier.Invalid;
|
||||
public ActorIdentifier RetainerIdentifier { get; private set; } = ActorIdentifier.Invalid;
|
||||
|
||||
public IdentifierDrawer(ActorService actors, IdentifierService identifier, HumanModelList humans)
|
||||
{
|
||||
_actors = actors;
|
||||
_worldCombo = new WorldCombo(actors.AwaitedService.Data.Worlds);
|
||||
_humanNpcCombo = new HumanNpcCombo("Human Event NPCs", identifier, humans);
|
||||
}
|
||||
|
||||
public void DrawName(float width)
|
||||
{
|
||||
ImGui.SetNextItemWidth(width);
|
||||
if (ImGui.InputTextWithHint("##Name", "Character Name...", ref _characterName, 32))
|
||||
UpdateIdentifiers();
|
||||
}
|
||||
|
||||
public void DrawWorld(float width)
|
||||
{
|
||||
if (_worldCombo.Draw(width))
|
||||
UpdateIdentifiers();
|
||||
}
|
||||
|
||||
public void DrawNpcs(float width)
|
||||
{
|
||||
if (_humanNpcCombo.Draw(width))
|
||||
UpdateIdentifiers();
|
||||
}
|
||||
|
||||
public bool CanSetPlayer
|
||||
=> PlayerIdentifier.IsValid;
|
||||
|
||||
public bool CanSetRetainer
|
||||
=> RetainerIdentifier.IsValid;
|
||||
|
||||
public bool CanSetNpc
|
||||
=> NpcIdentifier.IsValid;
|
||||
|
||||
private void UpdateIdentifiers()
|
||||
{
|
||||
if (ByteString.FromString(_characterName, out var byteName))
|
||||
{
|
||||
PlayerIdentifier = _actors.AwaitedService.CreatePlayer(byteName, _worldCombo.CurrentSelection.Key);
|
||||
RetainerIdentifier = _actors.AwaitedService.CreateRetainer(byteName, ActorIdentifier.RetainerType.Both);
|
||||
}
|
||||
|
||||
NpcIdentifier = _humanNpcCombo.CurrentSelection.Kind is ObjectKind.EventNpc or ObjectKind.BattleNpc
|
||||
? _actors.AwaitedService.CreateNpc(_humanNpcCombo.CurrentSelection.Kind, _humanNpcCombo.CurrentSelection.Ids[0])
|
||||
: ActorIdentifier.Invalid;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
|
|
@ -12,12 +11,12 @@ using Glamourer.Services;
|
|||
using Glamourer.Structs;
|
||||
using Glamourer.Unlocks;
|
||||
using ImGuiNET;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Action = System.Action;
|
||||
using CustomizeIndex = Glamourer.Customization.CustomizeIndex;
|
||||
|
||||
namespace Glamourer.Gui.Tabs.AutomationTab;
|
||||
|
||||
|
|
@ -29,8 +28,9 @@ public class SetPanel
|
|||
private readonly CustomizeUnlockManager _customizeUnlocks;
|
||||
private readonly CustomizationService _customizations;
|
||||
|
||||
private readonly DesignCombo _designCombo;
|
||||
private readonly JobGroupCombo _jobGroupCombo;
|
||||
private readonly DesignCombo _designCombo;
|
||||
private readonly JobGroupCombo _jobGroupCombo;
|
||||
private readonly IdentifierDrawer _identifierDrawer;
|
||||
|
||||
private string? _tempName;
|
||||
private int _dragIndex = -1;
|
||||
|
|
@ -38,13 +38,14 @@ public class SetPanel
|
|||
private Action? _endAction;
|
||||
|
||||
public SetPanel(SetSelector selector, AutoDesignManager manager, DesignManager designs, JobService jobs, ItemUnlockManager itemUnlocks,
|
||||
CustomizeUnlockManager customizeUnlocks, CustomizationService customizations)
|
||||
CustomizeUnlockManager customizeUnlocks, CustomizationService customizations, IdentifierDrawer identifierDrawer)
|
||||
{
|
||||
_selector = selector;
|
||||
_manager = manager;
|
||||
_itemUnlocks = itemUnlocks;
|
||||
_customizeUnlocks = customizeUnlocks;
|
||||
_customizations = customizations;
|
||||
_identifierDrawer = identifierDrawer;
|
||||
_designCombo = new DesignCombo(_manager, designs);
|
||||
_jobGroupCombo = new JobGroupCombo(manager, jobs);
|
||||
}
|
||||
|
|
@ -101,6 +102,9 @@ public class SetPanel
|
|||
if (ImGui.Checkbox("Enabled", ref enabled))
|
||||
_manager.SetState(_selector.SelectionIndex, enabled);
|
||||
|
||||
ImGui.Separator();
|
||||
DrawIdentifierSelection(_selector.SelectionIndex);
|
||||
|
||||
DrawDesignTable();
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +205,10 @@ public class SetPanel
|
|||
sb.Clear();
|
||||
var sb2 = new StringBuilder();
|
||||
var customize = design.Design.DesignData.Customize;
|
||||
var set = _customizations.AwaitedService.GetList(customize.Clan, customize.Gender);
|
||||
if (!design.Design.DesignData.IsHuman)
|
||||
sb.AppendLine("The base model id can not be changed automatically to something non-human.");
|
||||
|
||||
var set = _customizations.AwaitedService.GetList(customize.Clan, customize.Gender);
|
||||
foreach (var type in CustomizationExtensions.All)
|
||||
{
|
||||
var flag = type.ToFlag();
|
||||
|
|
@ -268,6 +275,21 @@ public class SetPanel
|
|||
_manager.ChangeApplicationType(set, autoDesignIndex, newType);
|
||||
}
|
||||
|
||||
private void DrawIdentifierSelection(int setIndex)
|
||||
{
|
||||
using var id = ImRaii.PushId("Identifiers");
|
||||
_identifierDrawer.DrawWorld(200);
|
||||
_identifierDrawer.DrawName(300);
|
||||
_identifierDrawer.DrawNpcs(300);
|
||||
if (ImGuiUtil.DrawDisabledButton("Set to Retainer", new Vector2(100, 0), string.Empty, !_identifierDrawer.CanSetRetainer))
|
||||
_manager.ChangeIdentifier(setIndex, _identifierDrawer.RetainerIdentifier);
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton("Set to Character", new Vector2(100, 0), string.Empty, !_identifierDrawer.CanSetPlayer))
|
||||
_manager.ChangeIdentifier(setIndex, _identifierDrawer.PlayerIdentifier);
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton("Set to Npc", new Vector2(100, 0), string.Empty, !_identifierDrawer.CanSetNpc))
|
||||
_manager.ChangeIdentifier(setIndex, _identifierDrawer.NpcIdentifier);
|
||||
}
|
||||
|
||||
|
||||
private static readonly IReadOnlyList<(AutoDesign.Type, string)> Types = new[]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Glamourer.Automation;
|
||||
|
|
@ -118,7 +119,7 @@ public class SetSelector : IDisposable
|
|||
_list.Clear();
|
||||
foreach (var set in _manager)
|
||||
{
|
||||
var id = set.Identifier.ToString();
|
||||
var id = set.Identifiers[0].ToString();
|
||||
if (CheckFilters(set, id))
|
||||
_list.Add(set);
|
||||
}
|
||||
|
|
@ -195,11 +196,11 @@ public class SetSelector : IDisposable
|
|||
|
||||
DrawDragDrop(set, index);
|
||||
|
||||
var text = set.Identifier.ToString();
|
||||
var text = set.Identifiers[0].ToString();
|
||||
if (IncognitoMode)
|
||||
text = set.Identifier.Incognito(text);
|
||||
text = set.Identifiers[0].Incognito(text);
|
||||
var textSize = ImGui.CalcTextSize(text);
|
||||
var textColor = _objects.ContainsKey(set.Identifier) ? ColorId.AutomationActorAvailable : ColorId.AutomationActorUnavailable;
|
||||
var textColor = set.Identifiers.Any(_objects.ContainsKey) ? ColorId.AutomationActorAvailable : ColorId.AutomationActorUnavailable;
|
||||
ImGui.SetCursorPos(new Vector2(ImGui.GetContentRegionAvail().X - textSize.X,
|
||||
ImGui.GetCursorPosY() - ImGui.GetTextLineHeightWithSpacing()));
|
||||
ImGuiUtil.TextColored(textColor.Value(), text);
|
||||
|
|
|
|||
|
|
@ -1304,7 +1304,7 @@ public unsafe class DebugTab : ITab
|
|||
ImGuiUtil.DrawTableColumn(set.Enabled.ToString());
|
||||
|
||||
ImGuiUtil.DrawTableColumn("Actor");
|
||||
ImGuiUtil.DrawTableColumn(set.Identifier.ToString());
|
||||
ImGuiUtil.DrawTableColumn(set.Identifiers[0].ToString());
|
||||
|
||||
foreach (var (design, designIdx) in set.Designs.WithIndex())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ public class DesignPanel
|
|||
if (!ImGui.CollapsingHeader("Equipment"))
|
||||
return;
|
||||
|
||||
_equipmentDrawer.Prepare();
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
var stain = _selector.Selected!.DesignData.Stain(slot);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public class UnlockOverview
|
|||
private readonly CustomizationService _customizations;
|
||||
private readonly CustomizeUnlockManager _customizeUnlocks;
|
||||
private readonly PenumbraChangedItemTooltip _tooltip;
|
||||
private readonly TextureCache _textureCache;
|
||||
private readonly TextureService _textures;
|
||||
|
||||
private static readonly Vector4 UnavailableTint = new(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
|
|
@ -67,14 +67,14 @@ public class UnlockOverview
|
|||
}
|
||||
|
||||
public UnlockOverview(ItemManager items, CustomizationService customizations, ItemUnlockManager itemUnlocks,
|
||||
CustomizeUnlockManager customizeUnlocks, PenumbraChangedItemTooltip tooltip, TextureCache textureCache)
|
||||
CustomizeUnlockManager customizeUnlocks, PenumbraChangedItemTooltip tooltip, TextureService textures)
|
||||
{
|
||||
_items = items;
|
||||
_customizations = customizations;
|
||||
_itemUnlocks = itemUnlocks;
|
||||
_customizeUnlocks = customizeUnlocks;
|
||||
_tooltip = tooltip;
|
||||
_textureCache = textureCache;
|
||||
_textures = textures;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
|
|
@ -154,7 +154,7 @@ public class UnlockOverview
|
|||
void DrawItem(EquipItem item)
|
||||
{
|
||||
var unlocked = _itemUnlocks.IsUnlocked(item.ItemId, out var time);
|
||||
var iconHandle = _textureCache.LoadIcon(item.IconId);
|
||||
var iconHandle = _textures.LoadIcon(item.IconId);
|
||||
if (!iconHandle.HasValue)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ using Glamourer.Structs;
|
|||
using Glamourer.Unlocks;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Table;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
|
@ -22,10 +21,10 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
{
|
||||
private readonly ObjectUnlocked _event;
|
||||
|
||||
public UnlockTable(ItemManager items, TextureCache cache, ItemUnlockManager itemUnlocks,
|
||||
public UnlockTable(ItemManager items, TextureService textures, ItemUnlockManager itemUnlocks,
|
||||
PenumbraChangedItemTooltip tooltip, ObjectUnlocked @event)
|
||||
: base("ItemUnlockTable", new ItemList(items),
|
||||
new NameColumn(cache, tooltip) { Label = "Item Name..." },
|
||||
new NameColumn(textures, tooltip) { Label = "Item Name..." },
|
||||
new SlotColumn() { Label = "Equip Slot" },
|
||||
new TypeColumn() { Label = "Item Type..." },
|
||||
new UnlockDateColumn(itemUnlocks) { Label = "Unlocked" },
|
||||
|
|
@ -36,7 +35,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
Sortable = true;
|
||||
Flags |= ImGuiTableFlags.Hideable;
|
||||
_event.Subscribe(OnObjectUnlock, ObjectUnlocked.Priority.UnlockTable);
|
||||
cache.Logger = Glamourer.Log;
|
||||
textures.Logger = Glamourer.Log;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -44,13 +43,13 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
|
||||
private sealed class NameColumn : ColumnString<EquipItem>
|
||||
{
|
||||
private readonly TextureCache _textures;
|
||||
private readonly TextureService _textures;
|
||||
private readonly PenumbraChangedItemTooltip _tooltip;
|
||||
|
||||
public override float Width
|
||||
=> 400 * ImGuiHelpers.GlobalScale;
|
||||
|
||||
public NameColumn(TextureCache textures, PenumbraChangedItemTooltip tooltip)
|
||||
public NameColumn(TextureService textures, PenumbraChangedItemTooltip tooltip)
|
||||
{
|
||||
_textures = textures;
|
||||
_tooltip = tooltip;
|
||||
|
|
|
|||
34
Glamourer/Gui/UiHelpers.cs
Normal file
34
Glamourer/Gui/UiHelpers.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Glamourer.Services;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
||||
namespace Glamourer.Gui;
|
||||
|
||||
public static class UiHelpers
|
||||
{
|
||||
|
||||
public static void DrawIcon(this EquipItem item, TextureService textures, Vector2 size)
|
||||
{
|
||||
var isEmpty = item.ModelId.Value == 0;
|
||||
var (ptr, textureSize, empty) = textures.GetIcon(item);
|
||||
if (empty)
|
||||
{
|
||||
var pos = ImGui.GetCursorScreenPos();
|
||||
ImGui.GetWindowDrawList().AddRectFilled(pos, pos + size,
|
||||
ImGui.GetColorU32(isEmpty ? ImGuiCol.FrameBg : ImGuiCol.FrameBgActive), 5 * ImGuiHelpers.GlobalScale);
|
||||
if (ptr != nint.Zero)
|
||||
ImGui.Image(ptr, size, Vector2.Zero, Vector2.One,
|
||||
isEmpty ? new Vector4(0.1f, 0.1f, 0.1f, 0.5f) : new Vector4(0.3f, 0.3f, 0.3f, 0.8f));
|
||||
else
|
||||
ImGui.Dummy(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiUtil.HoverIcon(ptr, textureSize, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue