Skip to content

Commit

Permalink
Add Emotes to Changed Items.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ottermandias committed Sep 6, 2023
1 parent a890258 commit 6cc89f3
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 37 deletions.
2 changes: 1 addition & 1 deletion Penumbra.GameData
78 changes: 54 additions & 24 deletions Penumbra/UI/ChangedItemDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,23 @@ public class ChangedItemDrawer : IDisposable
[Flags]
public enum ChangedItemIcon : uint
{
Head = 0x0001,
Body = 0x0002,
Hands = 0x0004,
Legs = 0x0008,
Feet = 0x0010,
Ears = 0x0020,
Neck = 0x0040,
Wrists = 0x0080,
Finger = 0x0100,
Monster = 0x0200,
Demihuman = 0x0400,
Customization = 0x0800,
Action = 0x1000,
Mainhand = 0x2000,
Offhand = 0x4000,
Unknown = 0x8000,
Head = 0x00_00_01,
Body = 0x00_00_02,
Hands = 0x00_00_04,
Legs = 0x00_00_08,
Feet = 0x00_00_10,
Ears = 0x00_00_20,
Neck = 0x00_00_40,
Wrists = 0x00_00_80,
Finger = 0x00_01_00,
Monster = 0x00_02_00,
Demihuman = 0x00_04_00,
Customization = 0x00_08_00,
Action = 0x00_10_00,
Mainhand = 0x00_20_00,
Offhand = 0x00_40_00,
Unknown = 0x00_80_00,
Emote = 0x01_00_00,
}

public const ChangedItemIcon AllFlags = (ChangedItemIcon)0xFFFF;
Expand All @@ -51,10 +52,11 @@ public enum ChangedItemIcon : uint
private readonly Configuration _config;
private readonly ExcelSheet<Item> _items;
private readonly CommunicatorService _communicator;
private readonly Dictionary<ChangedItemIcon, TextureWrap> _icons = new(16);
private readonly Dictionary<ChangedItemIcon, TextureWrap> _icons = new(16);
private float _smallestIconWidth;

public ChangedItemDrawer(UiBuilder uiBuilder, IDataManager gameData, ITextureProvider textureProvider, CommunicatorService communicator, Configuration config)
public ChangedItemDrawer(UiBuilder uiBuilder, IDataManager gameData, ITextureProvider textureProvider, CommunicatorService communicator,
Configuration config)
{
_items = gameData.GetExcelSheet<Item>()!;
uiBuilder.RunWhenUiPrepared(() => CreateEquipSlotIcons(uiBuilder, gameData, textureProvider), true);
Expand Down Expand Up @@ -164,6 +166,7 @@ public void DrawTypeFilter()
ChangedItemIcon.Offhand,
ChangedItemIcon.Customization,
ChangedItemIcon.Action,
ChangedItemIcon.Emote,
ChangedItemIcon.Monster,
ChangedItemIcon.Demihuman,
ChangedItemIcon.Unknown,
Expand All @@ -182,14 +185,12 @@ void DrawIcon(ChangedItemIcon type)

using var popup = ImRaii.ContextPopupItem(type.ToString());
if (popup)
{
if (ImGui.MenuItem("Enable Only This"))
{
_config.ChangedItemFilter = type;
_config.Save();
ImGui.CloseCurrentPopup();
}
}

if (ImGui.IsItemHovered())
{
Expand Down Expand Up @@ -238,6 +239,8 @@ internal static ChangedItemIcon GetCategoryIcon(string name, object? obj)
{
if (name.StartsWith("Action: "))
iconType = ChangedItemIcon.Action;
else if (name.StartsWith("Emote: "))
iconType = ChangedItemIcon.Emote;
else if (name.StartsWith("Customization: "))
iconType = ChangedItemIcon.Customization;
break;
Expand Down Expand Up @@ -306,6 +309,7 @@ private static string ToDescription(ChangedItemIcon icon)
ChangedItemIcon.Demihuman => "Demi-Human",
ChangedItemIcon.Customization => "Customization",
ChangedItemIcon.Action => "Action",
ChangedItemIcon.Emote => "Emote",
ChangedItemIcon.Mainhand => "Weapon (Mainhand)",
ChangedItemIcon.Offhand => "Weapon (Offhand)",
_ => "Other",
Expand Down Expand Up @@ -354,21 +358,47 @@ void Add(ChangedItemIcon icon, TextureWrap? tex)
Add(ChangedItemIcon.Demihuman, textureProvider.GetTextureFromGame("ui/icon/062000/062041_hr1.tex", true));
Add(ChangedItemIcon.Customization, textureProvider.GetTextureFromGame("ui/icon/062000/062043_hr1.tex", true));
Add(ChangedItemIcon.Action, textureProvider.GetTextureFromGame("ui/icon/062000/062001_hr1.tex", true));
Add(ChangedItemIcon.Emote, LoadEmoteTexture(gameData, uiBuilder));
Add(ChangedItemIcon.Unknown, LoadUnknownTexture(gameData, uiBuilder));
Add(AllFlags, textureProvider.GetTextureFromGame("ui/icon/114000/114052_hr1.tex", true));

_smallestIconWidth = _icons.Values.Min(i => i.Width);

return true;
}

private static unsafe TextureWrap? LoadUnknownTexture(IDataManager gameData, UiBuilder uiBuilder)
{
var unk = gameData.GetFile<TexFile>("ui/uld/levelup2_hr1.tex");
if (unk == null)
return true;
return null;

var image = unk.GetRgbaImageData();
var bytes = new byte[unk.Header.Height * unk.Header.Height * 4];
var diff = 2 * (unk.Header.Height - unk.Header.Width);
for (var y = 0; y < unk.Header.Height; ++y)
image.AsSpan(4 * y * unk.Header.Width, 4 * unk.Header.Width).CopyTo(bytes.AsSpan(4 * y * unk.Header.Height + diff));
Add(ChangedItemIcon.Unknown, uiBuilder.LoadImageRaw(bytes, unk.Header.Height, unk.Header.Height, 4));

_smallestIconWidth = _icons.Values.Min(i => i.Width);
return uiBuilder.LoadImageRaw(bytes, unk.Header.Height, unk.Header.Height, 4);
}

return true;
private static unsafe TextureWrap? LoadEmoteTexture(IDataManager gameData, UiBuilder uiBuilder)
{
var emote = gameData.GetFile<TexFile>("ui/icon/000000/000019_hr1.tex");
if (emote == null)
return null;

var image2 = emote.GetRgbaImageData();
fixed (byte* ptr = image2)
{
var color = (uint*)ptr;
for (var i = 0; i < image2.Length / 4; ++i)
{
if (color[i] == 0xFF000000)
image2[i * 4 + 3] = 0;
}
}

return uiBuilder.LoadImageRaw(image2, emote.Header.Width, emote.Header.Height, 4);
}
}
72 changes: 60 additions & 12 deletions Penumbra/UI/Tabs/DebugTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Interface.Windowing;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Group;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
Expand Down Expand Up @@ -66,14 +67,15 @@ public class DebugTab : Window, ITab
private readonly FrameworkManager _framework;
private readonly TextureManager _textureManager;
private readonly SkinFixer _skinFixer;
private readonly IdentifierService _identifier;

public DebugTab(StartTracker timer, PerformanceTracker performance, Configuration config, CollectionManager collectionManager,
ValidityChecker validityChecker, ModManager modManager, HttpApi httpApi, ActorService actorService,
DalamudServices dalamud, StainService stains, CharacterUtility characterUtility, ResidentResourceManager residentResources,
ResourceManagerService resourceManager, PenumbraIpcProviders ipc, CollectionResolver collectionResolver,
DrawObjectState drawObjectState, PathState pathState, SubfileHelper subfileHelper, IdentifiedCollectionCache identifiedCollectionCache,
CutsceneService cutsceneService, ModImportManager modImporter, ImportPopup importPopup, FrameworkManager framework,
TextureManager textureManager, SkinFixer skinFixer)
TextureManager textureManager, SkinFixer skinFixer, IdentifierService identifier)
: base("Penumbra Debug Window", ImGuiWindowFlags.NoCollapse, false)
{
IsOpen = true;
Expand Down Expand Up @@ -107,6 +109,7 @@ public DebugTab(StartTracker timer, PerformanceTracker performance, Configuratio
_framework = framework;
_textureManager = textureManager;
_skinFixer = skinFixer;
_identifier = identifier;
}

public ReadOnlySpan<byte> Label
Expand Down Expand Up @@ -138,12 +141,10 @@ public void DrawContent()
ImGui.NewLine();
DrawDebugCharacterUtility();
ImGui.NewLine();
DrawStainTemplates();
DrawData();
ImGui.NewLine();
DrawDebugTabMetaLists();
ImGui.NewLine();
DrawDebugResidentResources();
ImGui.NewLine();
DrawResourceProblems();
ImGui.NewLine();
DrawPlayerModelInfo();
Expand Down Expand Up @@ -370,7 +371,9 @@ void DrawSpecial(string name, ActorIdentifier id)
{
ImGuiUtil.DrawTableColumn($"{((GameObject*)obj.Address)->ObjectIndex}");
ImGuiUtil.DrawTableColumn($"0x{obj.Address:X}");
ImGuiUtil.DrawTableColumn((obj.Address == nint.Zero) ? string.Empty : $"0x{(nint)((Character*)obj.Address)->GameObject.GetDrawObject():X}");
ImGuiUtil.DrawTableColumn(obj.Address == nint.Zero
? string.Empty
: $"0x{(nint)((Character*)obj.Address)->GameObject.GetDrawObject():X}");
var identifier = _actorService.AwaitedService.FromObject(obj, false, true, false);
ImGuiUtil.DrawTableColumn(_actorService.AwaitedService.ToString(identifier));
var id = obj.ObjectKind == ObjectKind.BattleNpc ? $"{identifier.DataId} | {obj.DataId}" : identifier.DataId.ToString();
Expand Down Expand Up @@ -546,9 +549,49 @@ private unsafe void DrawPathResolverDebug()
}
}

private void DrawData()
{
if (!ImGui.CollapsingHeader("Game Data"))
return;

DrawEmotes();
DrawStainTemplates();
}

private string _emoteSearchFile = string.Empty;
private string _emoteSearchName = string.Empty;

private void DrawEmotes()
{
using var mainTree = TreeNode("Emotes");
if (!mainTree)
return;

ImGui.InputText("File Name", ref _emoteSearchFile, 256);
ImGui.InputText("Emote Name", ref _emoteSearchName, 256);
using var table = Table("##table", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit, new Vector2(-1, 12 * ImGui.GetTextLineHeightWithSpacing()));
if (!table)
return;

var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeightWithSpacing());
var dummy = ImGuiClip.FilteredClippedDraw(_identifier.AwaitedService.Emotes, skips,
p => p.Key.Contains(_emoteSearchFile, StringComparison.OrdinalIgnoreCase)
&& (_emoteSearchName.Length == 0
|| p.Value.Any(s => s.Name.ToDalamudString().TextValue.Contains(_emoteSearchName, StringComparison.OrdinalIgnoreCase))),
p =>
{
ImGui.TableNextColumn();
ImGui.TextUnformatted(p.Key);
ImGui.TableNextColumn();
ImGui.TextUnformatted(string.Join(", ", p.Value.Select(v => v.Name.ToDalamudString().TextValue)));
});
ImGuiClip.DrawEndDummy(dummy, ImGui.GetTextLineHeightWithSpacing());
}

private void DrawStainTemplates()
{
if (!ImGui.CollapsingHeader("Staining Templates"))
using var mainTree = TreeNode("Staining Templates");
if (!mainTree)
return;

foreach (var (key, data) in _stains.StmFile.Entries)
Expand Down Expand Up @@ -625,16 +668,15 @@ private unsafe void DrawDebugCharacterUtility()
ImGui.TableNextRow();
continue;
}

UiHelpers.Text(resource);
ImGui.TableNextColumn();
var data = (nint)ResourceHandle.GetData(resource);
var data = (nint)ResourceHandle.GetData(resource);
var length = ResourceHandle.GetLength(resource);
if (ImGui.Selectable($"0x{data:X}"))
{
if (data != nint.Zero && length > 0)
ImGui.SetClipboardText(string.Join("\n",
new ReadOnlySpan<byte>((byte*)data, (int)length).ToArray().Select(b => b.ToString("X2"))));
}

ImGuiUtil.HoverTooltip("Click to copy bytes to clipboard.");
ImGui.TableNextColumn();
Expand All @@ -655,7 +697,9 @@ private unsafe void DrawDebugCharacterUtility()
ImGui.TextUnformatted($"{_characterUtility.DefaultResource(intern).Size}");
}
else
{
ImGui.TableNextColumn();
}
}
}

Expand All @@ -679,7 +723,8 @@ private void DrawDebugTabMetaLists()
/// <summary> Draw information about the resident resource files. </summary>
private unsafe void DrawDebugResidentResources()
{
if (!ImGui.CollapsingHeader("Resident Resources"))
using var tree = TreeNode("Resident Resources");
if (!tree)
return;

if (_residentResources.Address == null || _residentResources.Address->NumResources == 0)
Expand All @@ -703,8 +748,10 @@ private unsafe void DrawDebugResidentResources()
private static void DrawCopyableAddress(string label, nint address)
{
using (var _ = PushFont(UiBuilder.MonoFont))
{
if (ImGui.Selectable($"0x{address:X16} {label}"))
ImGui.SetClipboardText($"{address:X16}");
}

ImGuiUtil.HoverTooltip("Click to copy address to clipboard.");
}
Expand Down Expand Up @@ -789,9 +836,10 @@ private unsafe void DrawGlobalVariableInfo()
if (!header)
return;

DrawCopyableAddress("CharacterUtility", _characterUtility.Address);
DrawCopyableAddress("CharacterUtility", _characterUtility.Address);
DrawCopyableAddress("ResidentResourceManager", _residentResources.Address);
DrawCopyableAddress("Device", Device.Instance());
DrawCopyableAddress("Device", Device.Instance());
DrawDebugResidentResources();
}

/// <summary> Draw resources with unusual reference count. </summary>
Expand Down

0 comments on commit 6cc89f3

Please sign in to comment.