mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-23 07:57:46 +01:00
Current state.
This commit is contained in:
parent
2850067f43
commit
e8c6204c25
15 changed files with 294 additions and 219 deletions
|
|
@ -100,7 +100,7 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
|
||||||
|
|
||||||
// Event NPCs have a reference to NpcEquip but also contain the appearance in their own row.
|
// Event NPCs have a reference to NpcEquip but also contain the appearance in their own row.
|
||||||
// Prefer the NpcEquip reference if it is set and the own does not appear to be set, otherwise use the own.
|
// Prefer the NpcEquip reference if it is set and the own does not appear to be set, otherwise use the own.
|
||||||
if (row.NpcEquip.RowId != 0 && row.NpcEquip.Value is { } equip && row is { ModelBody: 0, ModelLegs: 0 })
|
if (row.NpcEquip.RowId is not 0 && row.NpcEquip.Value is { } equip && row is { ModelBody: 0, ModelLegs: 0 })
|
||||||
ApplyNpcEquip(ref ret, equip);
|
ApplyNpcEquip(ref ret, equip);
|
||||||
else
|
else
|
||||||
ApplyNpcEquip(ref ret, row);
|
ApplyNpcEquip(ref ret, row);
|
||||||
|
|
@ -121,12 +121,12 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
|
||||||
foreach (var baseRow in bnpcSheet)
|
foreach (var baseRow in bnpcSheet)
|
||||||
{
|
{
|
||||||
// Only accept humans.
|
// Only accept humans.
|
||||||
if (baseRow.ModelChara.Value.Type != 1)
|
if (baseRow.ModelChara.Value.Type is not 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var bnpcNameIds = bNpcNames[baseRow.RowId];
|
var bnpcNameIds = bNpcNames[baseRow.RowId];
|
||||||
// Only accept battle NPCs with known associated names.
|
// Only accept battle NPCs with known associated names.
|
||||||
if (bnpcNameIds.Count == 0)
|
if (bnpcNameIds.Count is 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check if the customization is a valid human.
|
// Check if the customization is a valid human.
|
||||||
|
|
@ -186,7 +186,7 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is only a single entry, add that.
|
// If there is only a single entry, add that.
|
||||||
if (duplicates.Count == 1)
|
if (duplicates.Count is 1)
|
||||||
{
|
{
|
||||||
_data.Add(duplicates[0]);
|
_data.Add(duplicates[0]);
|
||||||
Memory += 96;
|
Memory += 96;
|
||||||
|
|
@ -200,7 +200,7 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
|
||||||
|
|
||||||
// Sort non-alphanumeric entries at the end instead of the beginning.
|
// Sort non-alphanumeric entries at the end instead of the beginning.
|
||||||
var lastWeird = _data.FindIndex(d => char.IsAsciiLetterOrDigit(d.Name[0]));
|
var lastWeird = _data.FindIndex(d => char.IsAsciiLetterOrDigit(d.Name[0]));
|
||||||
if (lastWeird != -1)
|
if (lastWeird is not -1)
|
||||||
{
|
{
|
||||||
_data.AddRange(_data.Take(lastWeird));
|
_data.AddRange(_data.Take(lastWeird));
|
||||||
_data.RemoveRange(0, lastWeird);
|
_data.RemoveRange(0, lastWeird);
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,13 @@ using Penumbra.GameData.Structs;
|
||||||
namespace Glamourer.GameData;
|
namespace Glamourer.GameData;
|
||||||
|
|
||||||
/// <summary> A struct containing everything to replicate the appearance of a human NPC. </summary>
|
/// <summary> A struct containing everything to replicate the appearance of a human NPC. </summary>
|
||||||
public unsafe struct NpcData
|
public struct NpcData
|
||||||
{
|
{
|
||||||
/// <summary> The name of the NPC. </summary>
|
/// <summary> The name of the NPC. </summary>
|
||||||
public string Name;
|
public string Name;
|
||||||
|
|
||||||
/// <summary> The customizations of the NPC. </summary>
|
|
||||||
public CustomizeArray Customize;
|
|
||||||
|
|
||||||
/// <summary> The equipment appearance of the NPC, 10 * CharacterArmor. </summary>
|
/// <summary> The equipment appearance of the NPC, 10 * CharacterArmor. </summary>
|
||||||
private fixed byte _equip[CharacterArmor.Size * 10];
|
private EquipArray _equip;
|
||||||
|
|
||||||
/// <summary> The mainhand weapon appearance of the NPC. </summary>
|
/// <summary> The mainhand weapon appearance of the NPC. </summary>
|
||||||
public CharacterWeapon Mainhand;
|
public CharacterWeapon Mainhand;
|
||||||
|
|
@ -21,6 +18,9 @@ public unsafe struct NpcData
|
||||||
/// <summary> The offhand weapon appearance of the NPC. </summary>
|
/// <summary> The offhand weapon appearance of the NPC. </summary>
|
||||||
public CharacterWeapon Offhand;
|
public CharacterWeapon Offhand;
|
||||||
|
|
||||||
|
/// <summary> The customizations of the NPC. </summary>
|
||||||
|
public CustomizeArray Customize;
|
||||||
|
|
||||||
/// <summary> The data ID of the NPC, either event NPC or battle NPC name. </summary>
|
/// <summary> The data ID of the NPC, either event NPC or battle NPC name. </summary>
|
||||||
public NpcId Id;
|
public NpcId Id;
|
||||||
|
|
||||||
|
|
@ -33,57 +33,50 @@ public unsafe struct NpcData
|
||||||
/// <summary> Whether the NPC is an event NPC or a battle NPC. </summary>
|
/// <summary> Whether the NPC is an event NPC or a battle NPC. </summary>
|
||||||
public ObjectKind Kind;
|
public ObjectKind Kind;
|
||||||
|
|
||||||
|
/// <summary> Obtain an equipment piece. </summary>
|
||||||
|
public readonly CharacterArmor Item(int i)
|
||||||
|
=> _equip[i];
|
||||||
|
|
||||||
/// <summary> Obtain the equipment as CharacterArmors. </summary>
|
/// <summary> Obtain the equipment as CharacterArmors. </summary>
|
||||||
public ReadOnlySpan<CharacterArmor> Equip
|
public readonly CharacterArmor[] Equip()
|
||||||
{
|
=> ((ReadOnlySpan<CharacterArmor>)_equip).ToArray();
|
||||||
get
|
|
||||||
{
|
|
||||||
fixed (byte* ptr = _equip)
|
|
||||||
{
|
|
||||||
return new ReadOnlySpan<CharacterArmor>((CharacterArmor*)ptr, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Write all the gear appearance to a single string. </summary>
|
/// <summary> Write all the gear appearance to a single string. </summary>
|
||||||
public string WriteGear()
|
public string WriteGear()
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder(128);
|
var sb = new StringBuilder(256);
|
||||||
var span = Equip;
|
|
||||||
for (var i = 0; i < 10; ++i)
|
for (var i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
sb.Append(span[i].Set.Id.ToString("D4"))
|
sb.Append($"{_equip[i].Set.Id:D4}")
|
||||||
.Append('-')
|
.Append('-')
|
||||||
.Append(span[i].Variant.Id.ToString("D3"));
|
.Append($"{_equip[i].Variant.Id:D3}");
|
||||||
foreach (var stain in span[i].Stains)
|
foreach (var stain in _equip[i].Stains)
|
||||||
sb.Append('-').Append(stain.Id.ToString("D3"));
|
sb.Append('-').Append($"{stain.Id:D3}");
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.Append(Mainhand.Skeleton.Id.ToString("D4"))
|
sb.Append($"{Mainhand.Skeleton.Id:D4}")
|
||||||
.Append('-')
|
.Append('-')
|
||||||
.Append(Mainhand.Weapon.Id.ToString("D4"))
|
.Append($"{Mainhand.Weapon.Id:D4}")
|
||||||
.Append('-')
|
.Append('-')
|
||||||
.Append(Mainhand.Variant.Id.ToString("D3"));
|
.Append($"{Mainhand.Variant.Id:D3}");
|
||||||
foreach (var stain in Mainhand.Stains)
|
foreach (var stain in Mainhand.Stains)
|
||||||
sb.Append('-').Append(stain.Id.ToString("D3"));
|
sb.Append('-').Append($"{stain.Id:D3}");
|
||||||
sb.Append(", ")
|
sb.Append(", ")
|
||||||
.Append(Offhand.Skeleton.Id.ToString("D4"))
|
.Append($"{Offhand.Skeleton.Id:D4}")
|
||||||
.Append('-')
|
.Append('-')
|
||||||
.Append(Offhand.Weapon.Id.ToString("D4"))
|
.Append($"{Offhand.Weapon.Id:D4}")
|
||||||
.Append('-')
|
.Append('-')
|
||||||
.Append(Offhand.Variant.Id.ToString("D3"));
|
.Append($"{Offhand.Variant.Id:D3}");
|
||||||
foreach (var stain in Mainhand.Stains)
|
foreach (var stain in Mainhand.Stains)
|
||||||
sb.Append('-').Append(stain.Id.ToString("D3"));
|
sb.Append('-').Append($"{stain.Id:D3}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Set an equipment piece to a given value. </summary>
|
/// <summary> Set an equipment piece to a given value. </summary>
|
||||||
internal void Set(int idx, ulong value)
|
internal void Set(int idx, ulong value)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = _equip)
|
_equip[idx] = Unsafe.As<ulong, CharacterArmor>(ref value);
|
||||||
{
|
|
||||||
((ulong*)ptr)[idx] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Check if the appearance data, excluding ID and Name, of two NpcData is equal. </summary>
|
/// <summary> Check if the appearance data, excluding ID and Name, of two NpcData is equal. </summary>
|
||||||
|
|
@ -104,9 +97,12 @@ public unsafe struct NpcData
|
||||||
if (!Offhand.Equals(other.Offhand))
|
if (!Offhand.Equals(other.Offhand))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fixed (byte* ptr1 = _equip, ptr2 = other._equip)
|
return ((ReadOnlySpan<CharacterArmor>)_equip).SequenceEqual(other._equip);
|
||||||
{
|
}
|
||||||
return new ReadOnlySpan<byte>(ptr1, 40).SequenceEqual(new ReadOnlySpan<byte>(ptr2, 40));
|
|
||||||
}
|
[InlineArray(10)]
|
||||||
|
private struct EquipArray
|
||||||
|
{
|
||||||
|
private CharacterArmor _element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,80 @@
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Bindings.ImGui;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using Dalamud.Bindings.ImGui;
|
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using Lumina.Excel.Sheets;
|
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Extensions;
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Raii;
|
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
using Addon = Lumina.Excel.Sheets.Addon;
|
||||||
using MouseWheelType = OtterGui.Widgets.MouseWheelType;
|
using MouseWheelType = OtterGui.Widgets.MouseWheelType;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Equipment;
|
namespace Glamourer.Gui.Equipment;
|
||||||
|
|
||||||
|
public sealed class BonusItemCombo2(IDataManager gameData, ItemManager items, FavoriteManager favorites, BonusItemFlag slot)
|
||||||
|
: ImSharp.FilterComboBase<BonusItemCombo2.CacheItem>(new ItemFilter())
|
||||||
|
{
|
||||||
|
public readonly StringU8 Label = GetLabel(gameData, slot);
|
||||||
|
public readonly BonusItemFlag Slot = slot;
|
||||||
|
|
||||||
|
public readonly struct CacheItem(EquipItem item) : IDisposable
|
||||||
|
{
|
||||||
|
public readonly EquipItem Item = item;
|
||||||
|
public readonly StringPair Name = new(item.Name);
|
||||||
|
public readonly SizedString Model = new($"({item.PrimaryId.Id}-{item.Variant.Id})");
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
=> Model.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class ItemFilter : PartwiseFilterBase<CacheItem>
|
||||||
|
{
|
||||||
|
protected override string ToFilterString(in CacheItem item, int globalIndex)
|
||||||
|
=> item.Name.Utf16;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<CacheItem> GetItems()
|
||||||
|
{
|
||||||
|
var nothing = EquipItem.BonusItemNothing(Slot);
|
||||||
|
return items.ItemData.ByType[Slot.ToEquipType()].OrderByDescending(favorites.Contains).ThenBy(i => i.Id.Id).Prepend(nothing)
|
||||||
|
.Select(i => new CacheItem(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float ItemHeight
|
||||||
|
=> Im.Style.TextHeightWithSpacing;
|
||||||
|
|
||||||
|
protected override bool DrawItem(in CacheItem item, int globalIndex, bool selected)
|
||||||
|
{
|
||||||
|
UiHelpers.DrawFavoriteStar(favorites, item.Item);
|
||||||
|
Im.Line.Same();
|
||||||
|
var ret = Im.Selectable(item.Name.Utf8, selected);
|
||||||
|
Im.Line.Same();
|
||||||
|
using var color = ImGuiColor.Text.Push(Rgba32.Gray);
|
||||||
|
ImEx.TextRightAligned(item.Model);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool IsSelected(CacheItem item, int globalIndex)
|
||||||
|
=> throw new NotImplementedException();
|
||||||
|
|
||||||
|
private static StringU8 GetLabel(IDataManager gameData, BonusItemFlag slot)
|
||||||
|
{
|
||||||
|
var sheet = gameData.GetExcelSheet<Addon>()!;
|
||||||
|
|
||||||
|
return slot switch
|
||||||
|
{
|
||||||
|
BonusItemFlag.Glasses => sheet.TryGetRow(16050, out var text) ? new StringU8(text.Text.Data, false) : new StringU8("Facewear"u8),
|
||||||
|
BonusItemFlag.UnkSlot => sheet.TryGetRow(16051, out var text) ? new StringU8(text.Text.Data, false) : new StringU8("Facewear"u8),
|
||||||
|
|
||||||
|
_ => StringU8.Empty,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class BonusItemCombo : FilterComboCache<EquipItem>
|
public sealed class BonusItemCombo : FilterComboCache<EquipItem>
|
||||||
{
|
{
|
||||||
private readonly FavoriteManager _favorites;
|
private readonly FavoriteManager _favorites;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ using Lumina.Excel.Sheets;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Extensions;
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Raii;
|
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public sealed class MainWindow : Window, IDisposable
|
||||||
SizeConstraints = new WindowSizeConstraints
|
SizeConstraints = new WindowSizeConstraints
|
||||||
{
|
{
|
||||||
MinimumSize = new Vector2(700, 675),
|
MinimumSize = new Vector2(700, 675),
|
||||||
MaximumSize = Im.Io.DisplaySize,
|
MaximumSize = new Vector2(3840, 2160),
|
||||||
};
|
};
|
||||||
_mainTabBar = mainTabBar;
|
_mainTabBar = mainTabBar;
|
||||||
_quickBar = quickBar;
|
_quickBar = quickBar;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using Dalamud.Bindings.ImGui;
|
using ImSharp;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
@ -14,20 +14,20 @@ public sealed class FunPanel(FunModule funModule, Configuration config) : IGameD
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted($"Current Festival: {funModule.CurrentFestival}");
|
Im.Text($"Current Festival: {funModule.CurrentFestival}");
|
||||||
ImGui.TextUnformatted($"Festivals Enabled: {config.DisableFestivals switch { 1 => "Undecided", 0 => "Enabled", _ => "Disabled" }}");
|
Im.Text($"Festivals Enabled: {config.DisableFestivals switch { 1 => "Undecided"u8, 0 => "Enabled"u8, _ => "Disabled"u8 }}");
|
||||||
ImGui.TextUnformatted($"Popup Open: {ImGui.IsPopupOpen("FestivalPopup", ImGuiPopupFlags.AnyPopup)}");
|
Im.Text($"Popup Open: {Im.Popup.IsOpen("FestivalPopup"u8, PopupQueryFlags.AnyPopup)}");
|
||||||
if (ImGui.Button("Force Christmas"))
|
if (Im.Button("Force Christmas"u8))
|
||||||
funModule.ForceFestival(FunModule.FestivalType.Christmas);
|
funModule.ForceFestival(FunModule.FestivalType.Christmas);
|
||||||
if (ImGui.Button("Force Halloween"))
|
if (Im.Button("Force Halloween"u8))
|
||||||
funModule.ForceFestival(FunModule.FestivalType.Halloween);
|
funModule.ForceFestival(FunModule.FestivalType.Halloween);
|
||||||
if (ImGui.Button("Force April First"))
|
if (Im.Button("Force April First"u8))
|
||||||
funModule.ForceFestival(FunModule.FestivalType.AprilFirst);
|
funModule.ForceFestival(FunModule.FestivalType.AprilFirst);
|
||||||
if (ImGui.Button("Force None"))
|
if (Im.Button("Force None"u8))
|
||||||
funModule.ForceFestival(FunModule.FestivalType.None);
|
funModule.ForceFestival(FunModule.FestivalType.None);
|
||||||
if (ImGui.Button("Revert"))
|
if (Im.Button("Revert"u8))
|
||||||
funModule.ResetFestival();
|
funModule.ResetFestival();
|
||||||
if (ImGui.Button("Reset Popup"))
|
if (Im.Button("Reset Popup"u8))
|
||||||
{
|
{
|
||||||
config.DisableFestivals = 1;
|
config.DisableFestivals = 1;
|
||||||
config.Save();
|
config.Save();
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Plugin.Services;
|
||||||
using Dalamud.Plugin.Services;
|
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using Dalamud.Bindings.ImGui;
|
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using OtterGui.Extensions;
|
|
||||||
using OtterGui.Text;
|
|
||||||
using Penumbra.GameData;
|
using Penumbra.GameData;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
@ -43,29 +39,29 @@ public sealed unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
var manager = MirageManager.Instance();
|
var manager = MirageManager.Instance();
|
||||||
using (ImRaii.Group())
|
using (Im.Group())
|
||||||
{
|
{
|
||||||
ImUtf8.Text("Address:"u8);
|
Im.Text("Address:"u8);
|
||||||
ImUtf8.Text("Number of Glamour Plates:"u8);
|
Im.Text("Number of Glamour Plates:"u8);
|
||||||
ImUtf8.Text("Glamour Plates Requested:"u8);
|
Im.Text("Glamour Plates Requested:"u8);
|
||||||
ImUtf8.Text("Glamour Plates Loaded:"u8);
|
Im.Text("Glamour Plates Loaded:"u8);
|
||||||
ImUtf8.Text("Is Applying Glamour Plates:"u8);
|
Im.Text("Is Applying Glamour Plates:"u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
using (ImRaii.Group())
|
using (Im.Group())
|
||||||
{
|
{
|
||||||
ImUtf8.CopyOnClickSelectable($"0x{(ulong)manager:X}");
|
Glamourer.Dynamis.DrawPointer(manager);
|
||||||
ImUtf8.Text(manager == null ? "-" : manager->GlamourPlates.Length.ToString());
|
Im.Text(manager is null ? "-"u8 : $"{manager->GlamourPlates.Length}");
|
||||||
ImUtf8.Text(manager == null ? "-" : manager->GlamourPlatesRequested.ToString());
|
Im.Text(manager is null ? "-"u8 : $"{manager->GlamourPlatesRequested}");
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
if (Im.SmallButton("Request Update"u8))
|
if (Im.SmallButton("Request Update"u8))
|
||||||
RequestGlamour();
|
RequestGlamour();
|
||||||
ImUtf8.Text(manager == null ? "-" : manager->GlamourPlatesLoaded.ToString());
|
Im.Text(manager is null ? "-"u8 : $"{manager->GlamourPlatesLoaded}");
|
||||||
ImUtf8.Text(manager == null ? "-" : manager->IsApplyingGlamourPlate.ToString());
|
Im.Text(manager is null ? "-"u8 : $"{manager->IsApplyingGlamourPlate}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manager == null)
|
if (manager is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ActorState? state = null;
|
ActorState? state = null;
|
||||||
|
|
@ -74,28 +70,28 @@ public sealed unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
|
|
||||||
for (var i = 0; i < manager->GlamourPlates.Length; ++i)
|
for (var i = 0; i < manager->GlamourPlates.Length; ++i)
|
||||||
{
|
{
|
||||||
using var tree = ImUtf8.TreeNode($"Plate #{i + 1:D2}");
|
using var tree = Im.Tree.Node($"Plate #{i + 1:D2}");
|
||||||
if (!tree)
|
if (!tree)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ref var plate = ref manager->GlamourPlates[i];
|
ref var plate = ref manager->GlamourPlates[i];
|
||||||
if (ImUtf8.ButtonEx("Apply to Player"u8, ""u8, Vector2.Zero, !enabled))
|
if (ImEx.Button("Apply to Player"u8, Vector2.Zero, StringU8.Empty, !enabled))
|
||||||
{
|
{
|
||||||
var design = CreateDesign(plate);
|
var design = CreateDesign(plate);
|
||||||
_state.ApplyDesign(state!, design, ApplySettings.Manual with { IsFinal = true });
|
_state.ApplyDesign(state!, design, ApplySettings.Manual with { IsFinal = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
using (ImRaii.Group())
|
using (Im.Group())
|
||||||
{
|
{
|
||||||
foreach (var slot in EquipSlotExtensions.FullSlots)
|
foreach (var slot in EquipSlotExtensions.FullSlots)
|
||||||
ImUtf8.Text(slot.ToName());
|
Im.Text(slot.ToNameU8());
|
||||||
}
|
}
|
||||||
|
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
using (ImRaii.Group())
|
using (Im.Group())
|
||||||
{
|
{
|
||||||
foreach (var (_, index) in EquipSlotExtensions.FullSlots.WithIndex())
|
foreach (var (index, _) in EquipSlotExtensions.FullSlots.Index())
|
||||||
ImUtf8.Text($"{plate.ItemIds[index]:D6}, {StainIds.FromGlamourPlate(plate, index)}");
|
Im.Text($"{plate.ItemIds[index]:D6}, {StainIds.FromGlamourPlate(plate, index)}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +102,7 @@ public sealed unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
public void RequestGlamour()
|
public void RequestGlamour()
|
||||||
{
|
{
|
||||||
var manager = MirageManager.Instance();
|
var manager = MirageManager.Instance();
|
||||||
if (manager == null)
|
if (manager is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_requestUpdate(manager);
|
_requestUpdate(manager);
|
||||||
|
|
@ -116,10 +112,10 @@ public sealed unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
{
|
{
|
||||||
var design = _design.CreateTemporary();
|
var design = _design.CreateTemporary();
|
||||||
design.Application = ApplicationCollection.None;
|
design.Application = ApplicationCollection.None;
|
||||||
foreach (var (slot, index) in EquipSlotExtensions.FullSlots.WithIndex())
|
foreach (var (index, slot) in EquipSlotExtensions.FullSlots.Index())
|
||||||
{
|
{
|
||||||
var itemId = plate.ItemIds[index];
|
var itemId = plate.ItemIds[index];
|
||||||
if (itemId == 0)
|
if (itemId is 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var item = _items.Resolve(slot, itemId);
|
var item = _items.Resolve(slot, itemId);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using Dalamud.Bindings.ImGui;
|
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Raii;
|
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
@ -18,16 +15,16 @@ public sealed unsafe class InventoryPanel : IGameDataDrawer
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
var inventory = InventoryManager.Instance();
|
var inventory = InventoryManager.Instance();
|
||||||
if (inventory == null)
|
if (inventory is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiUtil.CopyOnClickSelectable($"0x{(ulong)inventory:X}");
|
Glamourer.Dynamis.DrawPointer(inventory);
|
||||||
|
|
||||||
var equip = inventory->GetInventoryContainer(InventoryType.EquippedItems);
|
var equip = inventory->GetInventoryContainer(InventoryType.EquippedItems);
|
||||||
if (equip == null || equip->IsLoaded)
|
if (equip is null || equip->IsLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiUtil.CopyOnClickSelectable($"0x{(ulong)equip:X}");
|
Glamourer.Dynamis.DrawPointer(equip);
|
||||||
|
|
||||||
using var table = Im.Table.Begin("items"u8, 4, TableFlags.RowBackground | TableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("items"u8, 4, TableFlags.RowBackground | TableFlags.SizingFixedFit);
|
||||||
if (!table)
|
if (!table)
|
||||||
|
|
@ -35,19 +32,19 @@ public sealed unsafe class InventoryPanel : IGameDataDrawer
|
||||||
|
|
||||||
for (var i = 0; i < equip->Size; ++i)
|
for (var i = 0; i < equip->Size; ++i)
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn(i.ToString());
|
table.DrawColumn($"{i}");
|
||||||
var item = equip->GetInventorySlot(i);
|
var item = equip->GetInventorySlot(i);
|
||||||
if (item == null)
|
if (item is null)
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn("NULL");
|
table.DrawColumn("NULL"u8);
|
||||||
ImGui.TableNextRow();
|
table.NextRow();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn(item->ItemId.ToString());
|
table.DrawColumn($"{item->ItemId}");
|
||||||
ImGuiUtil.DrawTableColumn(item->GlamourId.ToString());
|
table.DrawColumn($"{item->GlamourId}");
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
ImGuiUtil.CopyOnClickSelectable($"0x{(ulong)item:X}");
|
Glamourer.Dynamis.DrawPointer(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Glamourer.Services;
|
||||||
using Glamourer.Services;
|
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using Dalamud.Bindings.ImGui;
|
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using OtterGui;
|
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
using ImGuiClip = OtterGui.ImGuiClip;
|
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
|
|
@ -32,31 +28,28 @@ public sealed class ItemUnlockPanel(ItemUnlockManager itemUnlocks, ItemManager i
|
||||||
table.SetupColumn("Model"u8, TableColumnFlags.WidthFixed, 80 * Im.Style.GlobalScale);
|
table.SetupColumn("Model"u8, TableColumnFlags.WidthFixed, 80 * Im.Style.GlobalScale);
|
||||||
table.SetupColumn("Unlock"u8, TableColumnFlags.WidthFixed, 120 * Im.Style.GlobalScale);
|
table.SetupColumn("Unlock"u8, TableColumnFlags.WidthFixed, 120 * Im.Style.GlobalScale);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
using var clipper = new Im.ListClipper(itemUnlocks.Count, Im.Style.TextHeightWithSpacing);
|
||||||
var skips = ImGuiClip.GetNecessarySkips(Im.Style.TextHeightWithSpacing);
|
foreach (var (id, _) in clipper.Iterate(itemUnlocks))
|
||||||
ImGui.TableNextRow();
|
|
||||||
var remainder = ImGuiClip.ClippedDraw(itemUnlocks, skips, t =>
|
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn(t.Key.ToString());
|
table.DrawColumn($"{id}");
|
||||||
if (items.ItemData.TryGetValue(t.Key, EquipSlot.MainHand, out var equip))
|
if (items.ItemData.TryGetValue(id, EquipSlot.MainHand, out var equip))
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn(equip.Name);
|
table.DrawColumn(equip.Name);
|
||||||
ImGuiUtil.DrawTableColumn(equip.Type.ToName());
|
table.DrawColumn(equip.Type.ToName());
|
||||||
ImGuiUtil.DrawTableColumn(equip.Weapon().ToString());
|
table.DrawColumn($"{equip.Weapon()}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn(itemUnlocks.IsUnlocked(t.Key, out var time)
|
table.DrawColumn(itemUnlocks.IsUnlocked(id, out var time)
|
||||||
? time == DateTimeOffset.MinValue
|
? time == DateTimeOffset.MinValue
|
||||||
? "Always"
|
? "Always"u8
|
||||||
: time.LocalDateTime.ToString("g")
|
: $"{time.LocalDateTime:g}"
|
||||||
: "Never");
|
: "Never"u8);
|
||||||
}, itemUnlocks.Count);
|
}
|
||||||
ImGuiClip.DrawEndDummy(remainder, Im.Style.TextHeight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Utility;
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using Dalamud.Bindings.ImGui;
|
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using OtterGui.Raii;
|
using Luna;
|
||||||
using OtterGui.Text;
|
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
using Penumbra.GameData.Interop;
|
using Penumbra.GameData.Interop;
|
||||||
using ImGuiClip = OtterGui.ImGuiClip;
|
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public sealed class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateManager, ActorObjectManager objectManager, DesignConverter designConverter)
|
public sealed class NpcAppearancePanel(
|
||||||
|
NpcCustomizeSet npcData,
|
||||||
|
StateManager stateManager,
|
||||||
|
ActorObjectManager objectManager,
|
||||||
|
DesignConverter designConverter)
|
||||||
: IGameDataDrawer
|
: IGameDataDrawer
|
||||||
{
|
{
|
||||||
public ReadOnlySpan<byte> Label
|
public ReadOnlySpan<byte> Label
|
||||||
|
|
@ -24,22 +24,44 @@ public sealed class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateMana
|
||||||
public bool Disabled
|
public bool Disabled
|
||||||
=> false;
|
=> false;
|
||||||
|
|
||||||
private string _npcFilter = string.Empty;
|
private readonly NpcDataFilter _filter = new();
|
||||||
private bool _customizeOrGear;
|
private bool _customizeOrGear;
|
||||||
|
|
||||||
|
private sealed class NpcDataFilter : TextFilterBase<CacheItem>
|
||||||
|
{
|
||||||
|
protected override string ToFilterString(in CacheItem item, int globalIndex)
|
||||||
|
=> item.Name.Utf16;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly struct CacheItem(NpcData data)
|
||||||
|
{
|
||||||
|
public readonly NpcData Data = data;
|
||||||
|
public readonly StringPair Name = new(data.Name);
|
||||||
|
public readonly StringU8 DataId = new($"{data.Id.Id}");
|
||||||
|
public readonly StringU8 ModelId = new($"{data.ModelId}");
|
||||||
|
public readonly AwesomeIcon Visor = data.VisorToggled ? LunaStyle.TrueIcon : LunaStyle.FalseIcon;
|
||||||
|
public readonly StringU8 CustomizeData = new($"{data.Customize}");
|
||||||
|
public readonly StringU8 GearData = StringU8.Empty; //new(data.WriteGear());
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class Cache(NpcCustomizeSet npcData, NpcDataFilter filter) : BasicFilterCache<CacheItem>(filter)
|
||||||
|
{
|
||||||
|
protected override IEnumerable<CacheItem> GetItems()
|
||||||
|
=> npcData.Select(i => new CacheItem(i));
|
||||||
|
}
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
ImUtf8.Checkbox("Compare Customize (or Gear)"u8, ref _customizeOrGear);
|
Im.Checkbox("Compare Customize (or Gear)"u8, ref _customizeOrGear);
|
||||||
ImGui.SetNextItemWidth(Im.ContentRegion.Available.X);
|
var resetScroll = _filter.DrawFilter("Filter..."u8, Im.ContentRegion.Available);
|
||||||
var resetScroll = ImUtf8.InputText("##npcFilter"u8, ref _npcFilter, "Filter..."u8);
|
|
||||||
|
|
||||||
using var table = Im.Table.Begin("npcs"u8, 7, TableFlags.RowBackground | TableFlags.ScrollY | TableFlags.SizingFixedFit,
|
using var table = Im.Table.Begin("npcs"u8, 7, TableFlags.RowBackground | TableFlags.ScrollY | TableFlags.SizingFixedFit,
|
||||||
new Vector2(-1, 400 * Im.Style.GlobalScale));
|
Im.ContentRegion.Available with { Y = 400 * Im.Style.GlobalScale });
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (resetScroll)
|
if (resetScroll)
|
||||||
ImGui.SetScrollY(0);
|
Im.Scroll.Y = 0;
|
||||||
|
|
||||||
table.SetupColumn("Button"u8, TableColumnFlags.WidthFixed);
|
table.SetupColumn("Button"u8, TableColumnFlags.WidthFixed);
|
||||||
table.SetupColumn("Name"u8, TableColumnFlags.WidthFixed, Im.Style.GlobalScale * 300);
|
table.SetupColumn("Name"u8, TableColumnFlags.WidthFixed, Im.Style.GlobalScale * 300);
|
||||||
|
|
@ -49,44 +71,29 @@ public sealed class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateMana
|
||||||
table.SetupColumn("Visor"u8, TableColumnFlags.WidthFixed);
|
table.SetupColumn("Visor"u8, TableColumnFlags.WidthFixed);
|
||||||
table.SetupColumn("Compare"u8, TableColumnFlags.WidthStretch);
|
table.SetupColumn("Compare"u8, TableColumnFlags.WidthStretch);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
var cache = CacheManager.Instance.GetOrCreateCache(Im.Id.Current, () => new Cache(npcData, _filter));
|
||||||
var skips = ImGuiClip.GetNecessarySkips(Im.Style.FrameHeightWithSpacing);
|
using var clipper = new Im.ListClipper(cache.Count, Im.Style.FrameHeightWithSpacing);
|
||||||
ImGui.TableNextRow();
|
foreach (var (idx, data) in clipper.Iterate(cache).Index())
|
||||||
var idx = 0;
|
|
||||||
var remainder = ImGuiClip.FilteredClippedDraw(npcCombo.Items, skips,
|
|
||||||
d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), DrawData);
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGuiClip.DrawEndDummy(remainder, Im.Style.FrameHeightWithSpacing);
|
|
||||||
return;
|
|
||||||
|
|
||||||
void DrawData(NpcData data)
|
|
||||||
{
|
{
|
||||||
using var id = Im.Id.Push(idx++);
|
using var id = Im.Id.Push(idx);
|
||||||
var disabled = !stateManager.GetOrCreate(objectManager.Player, out var state);
|
var disabled = !stateManager.GetOrCreate(objectManager.Player, out var state);
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
if (ImUtf8.ButtonEx("Apply"u8, ""u8, Vector2.Zero, disabled))
|
if (ImEx.Button("Apply"u8, Vector2.Zero, StringU8.Empty, disabled))
|
||||||
{
|
{
|
||||||
foreach (var (slot, item, stain) in designConverter.FromDrawData(data.Equip.ToArray(), data.Mainhand, data.Offhand, true))
|
foreach (var (slot, item, stain) in designConverter.FromDrawData(data.Data.Equip(), data.Data.Mainhand, data.Data.Offhand, true))
|
||||||
stateManager.ChangeEquip(state!, slot, item, stain, ApplySettings.Manual);
|
stateManager.ChangeEquip(state!, slot, item, stain, ApplySettings.Manual);
|
||||||
stateManager.ChangeMetaState(state!, MetaIndex.VisorState, data.VisorToggled, ApplySettings.Manual);
|
stateManager.ChangeMetaState(state!, MetaIndex.VisorState, data.Data.VisorToggled, ApplySettings.Manual);
|
||||||
stateManager.ChangeEntireCustomize(state!, data.Customize, CustomizeFlagExtensions.All, ApplySettings.Manual);
|
stateManager.ChangeEntireCustomize(state!, data.Data.Customize, CustomizeFlagExtensions.All, ApplySettings.Manual);
|
||||||
}
|
|
||||||
|
|
||||||
ImUtf8.DrawFrameColumn(data.Name);
|
|
||||||
|
|
||||||
ImUtf8.DrawFrameColumn(data.Kind is ObjectKind.BattleNpc ? "B" : "E");
|
|
||||||
|
|
||||||
ImUtf8.DrawFrameColumn(data.Id.Id.ToString());
|
|
||||||
|
|
||||||
ImUtf8.DrawFrameColumn(data.ModelId.ToString());
|
|
||||||
|
|
||||||
using (_ = ImRaii.PushFont(UiBuilder.IconFont))
|
|
||||||
{
|
|
||||||
ImUtf8.DrawFrameColumn(data.VisorToggled ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.DrawFrameColumn(data.Name.Utf8);
|
||||||
|
table.DrawFrameColumn(data.Data.Kind is ObjectKind.BattleNpc ? "B"u8 : "E"u8);
|
||||||
|
table.DrawFrameColumn(data.DataId);
|
||||||
|
table.DrawFrameColumn(data.ModelId);
|
||||||
|
table.NextColumn();
|
||||||
|
ImEx.Icon.DrawAligned(data.Visor);
|
||||||
using var mono = Im.Font.PushMono();
|
using var mono = Im.Font.PushMono();
|
||||||
ImUtf8.DrawFrameColumn(_customizeOrGear ? data.Customize.ToString() : data.WriteGear());
|
table.DrawFrameColumn(_customizeOrGear ? data.CustomizeData : data.GearData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using ImSharp;
|
||||||
using ImSharp;
|
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Text;
|
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
using Penumbra.GameData.Interop;
|
using Penumbra.GameData.Interop;
|
||||||
|
|
@ -16,7 +13,44 @@ public sealed class ObjectManagerPanel(ActorObjectManager objectManager, ActorMa
|
||||||
public bool Disabled
|
public bool Disabled
|
||||||
=> false;
|
=> false;
|
||||||
|
|
||||||
private string _objectFilter = string.Empty;
|
private sealed class Filter : TextFilterBase<CacheItem>
|
||||||
|
{
|
||||||
|
protected override string ToFilterString(in CacheItem item, int globalIndex)
|
||||||
|
=> item.Label.Utf16;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly struct CacheItem(ActorIdentifier identifier, ActorData data)
|
||||||
|
{
|
||||||
|
public readonly StringPair Label = new(data.Label);
|
||||||
|
public readonly StringU8 Name = new($"{identifier}");
|
||||||
|
public readonly StringU8 Objects = StringU8.Join(", "u8, data.Objects.OrderBy(a => a.Index).Select(a => a.Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class Cache : BasicFilterCache<CacheItem>
|
||||||
|
{
|
||||||
|
private readonly ActorObjectManager _objectManager;
|
||||||
|
|
||||||
|
public Cache(ActorObjectManager objectManager, Filter filter)
|
||||||
|
: base(filter)
|
||||||
|
{
|
||||||
|
_objectManager = objectManager;
|
||||||
|
_objectManager.Objects.OnUpdate += OnUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUpdate()
|
||||||
|
=> Dirty |= IManagedCache.DirtyFlags.Custom;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
_objectManager.Objects.OnUpdate -= OnUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<CacheItem> GetItems()
|
||||||
|
=> _objectManager.Select(o => new CacheItem(o.Key, o.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Filter _filter = new();
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
|
|
@ -27,58 +61,52 @@ public sealed class ObjectManagerPanel(ActorObjectManager objectManager, ActorMa
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImUtf8.DrawTableColumn("World"u8);
|
table.DrawColumn("World"u8);
|
||||||
ImUtf8.DrawTableColumn(actors.Finished ? actors.Data.ToWorldName(objectManager.World) : "Service Missing");
|
table.DrawColumn(actors.Finished ? actors.Data.ToWorldName(objectManager.World) : "Service Missing"u8);
|
||||||
ImUtf8.DrawTableColumn(objectManager.World.ToString());
|
table.DrawColumn($"{objectManager.World}");
|
||||||
|
|
||||||
ImUtf8.DrawTableColumn("Player Character"u8);
|
table.DrawColumn("Player Character"u8);
|
||||||
ImUtf8.DrawTableColumn($"{objectManager.Player.Utf8Name} ({objectManager.Player.Index})");
|
table.DrawColumn($"{objectManager.Player.Utf8Name} ({objectManager.Player.Index})");
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
ImUtf8.CopyOnClickSelectable(objectManager.Player.ToString());
|
Glamourer.Dynamis.DrawPointer(objectManager.Player.Address);
|
||||||
|
|
||||||
ImUtf8.DrawTableColumn("In GPose"u8);
|
table.DrawColumn("In GPose"u8);
|
||||||
ImUtf8.DrawTableColumn(objectManager.IsInGPose.ToString());
|
table.DrawColumn($"{objectManager.IsInGPose}");
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
|
|
||||||
ImUtf8.DrawTableColumn("In Lobby"u8);
|
table.DrawColumn("In Lobby"u8);
|
||||||
ImUtf8.DrawTableColumn(objectManager.IsInLobby.ToString());
|
table.DrawColumn($"{objectManager.IsInLobby}");
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
|
|
||||||
if (objectManager.IsInGPose)
|
if (objectManager.IsInGPose)
|
||||||
{
|
{
|
||||||
ImUtf8.DrawTableColumn("GPose Player"u8);
|
table.DrawColumn("GPose Player"u8);
|
||||||
ImUtf8.DrawTableColumn($"{objectManager.GPosePlayer.Utf8Name} ({objectManager.GPosePlayer.Index})");
|
table.DrawColumn($"{objectManager.GPosePlayer.Utf8Name} ({objectManager.GPosePlayer.Index})");
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
ImUtf8.CopyOnClickSelectable(objectManager.GPosePlayer.ToString());
|
Glamourer.Dynamis.DrawPointer(objectManager.GPosePlayer.Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImUtf8.DrawTableColumn("Number of Players"u8);
|
table.DrawColumn("Number of Players"u8);
|
||||||
ImUtf8.DrawTableColumn(objectManager.Count.ToString());
|
table.DrawColumn($"{objectManager.Count}");
|
||||||
ImGui.TableNextColumn();
|
table.NextColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
var filterChanged = ImUtf8.InputText("##Filter"u8, ref _objectFilter, "Filter..."u8);
|
var filterChanged = _filter.DrawFilter("Filter..."u8, Im.ContentRegion.Available);
|
||||||
using var table2 = Im.Table.Begin("##data2"u8, 3,
|
using var table2 = Im.Table.Begin("##data2"u8, 3, TableFlags.RowBackground | TableFlags.BordersOuter | TableFlags.ScrollY,
|
||||||
TableFlags.RowBackground | TableFlags.BordersOuter | TableFlags.ScrollY,
|
Im.ContentRegion.Available with { Y = 20 * Im.Style.TextHeightWithSpacing });
|
||||||
new Vector2(-1, 20 * Im.Style.TextHeightWithSpacing));
|
|
||||||
if (!table2)
|
if (!table2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (filterChanged)
|
if (filterChanged)
|
||||||
ImGui.SetScrollY(0);
|
Im.Scroll.Y = 0;
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
var cache = CacheManager.Instance.GetOrCreateCache(Im.Id.Current, () => new Cache(objectManager, _filter));
|
||||||
var skips = ImGuiClip.GetNecessarySkips(Im.Style.TextHeightWithSpacing);
|
using var clip = new Im.ListClipper(cache.Count, Im.Style.TextHeightWithSpacing);
|
||||||
ImGui.TableNextRow();
|
foreach (var item in clip.Iterate(cache))
|
||||||
|
{
|
||||||
var remainder = ImGuiClip.FilteredClippedDraw(objectManager, skips,
|
table2.DrawColumn(item.Name);
|
||||||
p => p.Value.Label.Contains(_objectFilter, StringComparison.OrdinalIgnoreCase), p
|
table2.DrawColumn(item.Label.Utf8);
|
||||||
=>
|
table2.DrawColumn(item.Objects);
|
||||||
{
|
}
|
||||||
ImUtf8.DrawTableColumn(p.Key.ToString());
|
|
||||||
ImUtf8.DrawTableColumn(p.Value.Label);
|
|
||||||
ImUtf8.DrawTableColumn(string.Join(", ", p.Value.Objects.OrderBy(a => a.Index).Select(a => a.Index.ToString())));
|
|
||||||
});
|
|
||||||
ImGuiClip.DrawEndDummy(remainder, Im.Style.TextHeightWithSpacing);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ public class NpcPanel
|
||||||
private DesignData ToDesignData()
|
private DesignData ToDesignData()
|
||||||
{
|
{
|
||||||
var selection = _selector.Selection;
|
var selection = _selector.Selection;
|
||||||
var items = _converter.FromDrawData(selection.Equip.ToArray(), selection.Mainhand, selection.Offhand, true).ToArray();
|
var items = _converter.FromDrawData(selection.Equip(), selection.Mainhand, selection.Offhand, true).ToArray();
|
||||||
var designData = new DesignData { Customize = selection.Customize };
|
var designData = new DesignData { Customize = selection.Customize };
|
||||||
foreach (var (slot, item, stain) in items)
|
foreach (var (slot, item, stain) in items)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ public sealed class UnlocksTab : Window, ITab<MainTabType>
|
||||||
IsOpen = false;
|
IsOpen = false;
|
||||||
SizeConstraints = new WindowSizeConstraints
|
SizeConstraints = new WindowSizeConstraints
|
||||||
{
|
{
|
||||||
MinimumSize = new Vector2(700, 675),
|
MinimumSize = new Vector2(700, 675),
|
||||||
MaximumSize = Im.Io.DisplaySize,
|
MaximumSize = new Vector2(3840, 2160),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ public unsafe class FunModule : IDisposable
|
||||||
customize = npc.Customize;
|
customize = npc.Customize;
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
foreach (ref var a in armor)
|
foreach (ref var a in armor)
|
||||||
a = npc.Equip[idx++];
|
a = npc.Item(idx++);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit b5213e2dee715bb6c53dc15dee61392b183a34a1
|
Subproject commit 478febd4ed9af42055ce7396f69cec0334bc4140
|
||||||
Loading…
Add table
Add a link
Reference in a new issue