diff --git a/Pilz.Dalamud/NamePlate/INamePlateGui.cs b/Pilz.Dalamud/NamePlate/INamePlateGui.cs
deleted file mode 100644
index 0d34c8a..0000000
--- a/Pilz.Dalamud/NamePlate/INamePlateGui.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System.Collections.Generic;
-
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// Class used to modify the data used when rendering nameplates.
-///
-public interface INamePlateGui
-{
- ///
- /// The delegate used for receiving nameplate update events.
- ///
- /// An object containing information about the pending data update.
- /// A list of handlers used for updating nameplate data.
- public delegate void OnPlateUpdateDelegate(INamePlateUpdateContext context, IReadOnlyList handlers);
-
- ///
- /// An event which fires when nameplate data is updated and at least one nameplate has important updates. The
- /// subscriber is provided with a list of handlers for nameplates with important updates.
- ///
- ///
- /// Fires after .
- ///
- event OnPlateUpdateDelegate? OnNamePlateUpdate;
-
- ///
- /// An event which fires when nameplate data is updated. The subscriber is provided with a list of handlers for all
- /// nameplates.
- ///
- ///
- /// This event is likely to fire every frame even when no nameplates are actually updated, so in most cases
- /// is preferred. Fires before .
- ///
- event OnPlateUpdateDelegate? OnDataUpdate;
-
- ///
- /// Requests that all nameplates should be redrawn on the following frame.
- ///
- void RequestRedraw();
-
- private static NamePlateGui instance;
- public static INamePlateGui Instance => instance ??= new ();
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlateGui.cs b/Pilz.Dalamud/NamePlate/NamePlateGui.cs
deleted file mode 100644
index b44c2d2..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateGui.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-using Dalamud.Game.Addon.Lifecycle;
-using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
-using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Client.UI;
-using System.Runtime.InteropServices;
-
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// Class used to modify the data used when rendering nameplates.
-///
-public sealed class NamePlateGui : IDisposable, INamePlateGui
-{
- ///
- /// The index for the number array used by the NamePlate addon.
- ///
- public const int NumberArrayIndex = 5;
-
- ///
- /// The index for the string array used by the NamePlate addon.
- ///
- public const int StringArrayIndex = 4;
-
- ///
- /// The index for of the FullUpdate entry in the NamePlate number array.
- ///
- internal const int NumberArrayFullUpdateIndex = 4;
-
- ///
- /// An empty null-terminated string pointer allocated in unmanaged memory, used to tag removed fields.
- ///
- internal static readonly nint EmptyStringPointer = CreateEmptyStringPointer();
-
- private readonly IAddonLifecycle addonLifecycle = PluginServices.AddonLifecycle;
-
- private readonly IGameGui gameGui = PluginServices.GameGui;
-
- private readonly IObjectTable objectTable = PluginServices.ObjectTable;
-
- private NamePlateUpdateContext? context;
-
- private NamePlateUpdateHandler[] updateHandlers = [];
-
- internal NamePlateGui()
- {
- this.addonLifecycle.RegisterListener(AddonEvent.PreRequestedUpdate, "NamePlate", this.OnPreRequestedUpdate);
- }
-
- ///
- public event INamePlateGui.OnPlateUpdateDelegate? OnNamePlateUpdate;
-
- ///
- public event INamePlateGui.OnPlateUpdateDelegate? OnDataUpdate;
-
- ///
- public unsafe void RequestRedraw()
- {
- var addon = this.gameGui.GetAddonByName("NamePlate");
- if (addon != 0)
- {
- var raptureAtkModule = RaptureAtkModule.Instance();
- if (raptureAtkModule == null)
- {
- return;
- }
-
- ((AddonNamePlate*)addon)->DoFullUpdate = 1;
- var namePlateNumberArrayData = raptureAtkModule->AtkArrayDataHolder.NumberArrays[NumberArrayIndex];
- namePlateNumberArrayData->SetValue(NumberArrayFullUpdateIndex, 1);
- }
- }
-
- ///
- public void Dispose()
- {
- this.addonLifecycle.UnregisterListener(AddonEvent.PreRequestedUpdate, "NamePlate", this.OnPreRequestedUpdate);
- }
-
- ///
- /// Strips the surrounding quotes from a free company tag. If the quotes are not present in the expected location,
- /// no modifications will be made.
- ///
- /// A quoted free company tag.
- /// A span containing the free company tag without its surrounding quote characters.
- internal static ReadOnlySpan StripFreeCompanyTagQuotes(ReadOnlySpan text)
- {
- if (text.Length > 4 && text.StartsWith(" «"u8) && text.EndsWith("»"u8))
- {
- return text[3..^2];
- }
-
- return text;
- }
-
- ///
- /// Strips the surrounding quotes from a title. If the quotes are not present in the expected location, no
- /// modifications will be made.
- ///
- /// A quoted title.
- /// A span containing the title without its surrounding quote characters.
- internal static ReadOnlySpan StripTitleQuotes(ReadOnlySpan text)
- {
- if (text.Length > 5 && text.StartsWith("《"u8) && text.EndsWith("》"u8))
- {
- return text[3..^3];
- }
-
- return text;
- }
-
- private static nint CreateEmptyStringPointer()
- {
- var pointer = Marshal.AllocHGlobal(1);
- Marshal.WriteByte(pointer, 0, 0);
- return pointer;
- }
-
- private void CreateHandlers(NamePlateUpdateContext createdContext)
- {
- var handlers = new List();
- for (var i = 0; i < AddonNamePlate.NumNamePlateObjects; i++)
- {
- handlers.Add(new NamePlateUpdateHandler(createdContext, i));
- }
-
- this.updateHandlers = handlers.ToArray();
- }
-
- private void OnPreRequestedUpdate(AddonEvent type, AddonArgs args)
- {
- if (this.OnDataUpdate == null && this.OnNamePlateUpdate == null)
- {
- return;
- }
-
- var reqArgs = (AddonRequestedUpdateArgs)args;
- if (this.context == null)
- {
- this.context = new NamePlateUpdateContext(this.objectTable, reqArgs);
- this.CreateHandlers(this.context);
- }
- else
- {
- this.context.ResetState(reqArgs);
- }
-
- var activeNamePlateCount = this.context.ActiveNamePlateCount;
- if (activeNamePlateCount == 0)
- return;
-
- var activeHandlers = this.updateHandlers[..activeNamePlateCount];
-
- if (this.context.IsFullUpdate)
- {
- foreach (var handler in activeHandlers)
- {
- handler.ResetState();
- }
-
- this.OnDataUpdate?.Invoke(this.context, activeHandlers);
- this.OnNamePlateUpdate?.Invoke(this.context, activeHandlers);
- if (this.context.HasParts)
- this.ApplyBuilders(activeHandlers);
- }
- else
- {
- var udpatedHandlers = new List(activeNamePlateCount);
- foreach (var handler in activeHandlers)
- {
- handler.ResetState();
- if (handler.IsUpdating)
- udpatedHandlers.Add(handler);
- }
-
- if (this.OnDataUpdate is not null)
- {
- this.OnDataUpdate?.Invoke(this.context, activeHandlers);
- this.OnNamePlateUpdate?.Invoke(this.context, udpatedHandlers);
- if (this.context.HasParts)
- this.ApplyBuilders(activeHandlers);
- }
- else if (udpatedHandlers.Count != 0)
- {
- var changedHandlersSpan = udpatedHandlers.ToArray().AsSpan();
- this.OnNamePlateUpdate?.Invoke(this.context, udpatedHandlers);
- if (this.context.HasParts)
- this.ApplyBuilders(changedHandlersSpan);
- }
- }
- }
-
- private void ApplyBuilders(Span handlers)
- {
- foreach (var handler in handlers)
- {
- if (handler.PartsContainer is { } container)
- {
- container.ApplyBuilders(handler);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Pilz.Dalamud/NamePlate/NamePlateInfoView.cs b/Pilz.Dalamud/NamePlate/NamePlateInfoView.cs
deleted file mode 100644
index e64f3b4..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateInfoView.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-using Dalamud.Game.Text.SeStringHandling;
-
-using FFXIVClientStructs.FFXIV.Client.UI;
-
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// Provides a read-only view of the nameplate info object data for a nameplate. Modifications to
-/// fields do not affect this data.
-///
-public interface INamePlateInfoView
-{
- ///
- /// Gets the displayed name for this nameplate according to the nameplate info object.
- ///
- SeString Name { get; }
-
- ///
- /// Gets the displayed free company tag for this nameplate according to the nameplate info object. For this field,
- /// the quote characters which appear on either side of the title are NOT included.
- ///
- SeString FreeCompanyTag { get; }
-
- ///
- /// Gets the displayed free company tag for this nameplate according to the nameplate info object. For this field,
- /// the quote characters which appear on either side of the title ARE included.
- ///
- SeString QuotedFreeCompanyTag { get; }
-
- ///
- /// Gets the displayed title for this nameplate according to the nameplate info object. For this field, the quote
- /// characters which appear on either side of the title are NOT included.
- ///
- SeString Title { get; }
-
- ///
- /// Gets the displayed title for this nameplate according to the nameplate info object. For this field, the quote
- /// characters which appear on either side of the title ARE included.
- ///
- SeString QuotedTitle { get; }
-
- ///
- /// Gets the displayed level text for this nameplate according to the nameplate info object.
- ///
- SeString LevelText { get; }
-
- ///
- /// Gets the flags for this nameplate according to the nameplate info object.
- ///
- int Flags { get; }
-
- ///
- /// Gets a value indicating whether this nameplate is considered 'dirty' or not according to the nameplate
- /// info object.
- ///
- bool IsDirty { get; }
-
- ///
- /// Gets a value indicating whether the title for this nameplate is a prefix title or not according to the nameplate
- /// info object. This value is derived from the field.
- ///
- bool IsPrefixTitle { get; }
-}
-
-///
-/// Provides a read-only view of the nameplate info object data for a nameplate. Modifications to
-/// fields do not affect this data.
-///
-internal unsafe class NamePlateInfoView(RaptureAtkModule.NamePlateInfo* info) : INamePlateInfoView
-{
- private SeString? name;
- private SeString? freeCompanyTag;
- private SeString? quotedFreeCompanyTag;
- private SeString? title;
- private SeString? quotedTitle;
- private SeString? levelText;
-
- ///
- public SeString Name => this.name ??= SeString.Parse(info->Name);
-
- ///
- public SeString FreeCompanyTag => this.freeCompanyTag ??=
- SeString.Parse(NamePlateGui.StripFreeCompanyTagQuotes(info->FcName));
-
- ///
- public SeString QuotedFreeCompanyTag => this.quotedFreeCompanyTag ??= SeString.Parse(info->FcName);
-
- ///
- public SeString Title => this.title ??= SeString.Parse(info->Title);
-
- ///
- public SeString QuotedTitle => this.quotedTitle ??= SeString.Parse(info->DisplayTitle);
-
- ///
- public SeString LevelText => this.levelText ??= SeString.Parse(info->LevelText);
-
- ///
- public int Flags => info->Flags;
-
- ///
- public bool IsDirty => info->IsDirty;
-
- ///
- public bool IsPrefixTitle => ((info->Flags >> (8 * 3)) & 0xFF) == 1;
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlateKind.cs b/Pilz.Dalamud/NamePlate/NamePlateKind.cs
deleted file mode 100644
index 09b4159..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateKind.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// An enum describing what kind of game object this nameplate represents.
-///
-public enum NamePlateKind : byte
-{
- ///
- /// A player character.
- ///
- PlayerCharacter = 0,
-
- ///
- /// An event NPC or companion.
- ///
- EventNpcCompanion = 1,
-
- ///
- /// A retainer.
- ///
- Retainer = 2,
-
- ///
- /// An enemy battle NPC.
- ///
- BattleNpcEnemy = 3,
-
- ///
- /// A friendly battle NPC.
- ///
- BattleNpcFriendly = 4,
-
- ///
- /// An event object.
- ///
- EventObject = 5,
-
- ///
- /// Treasure.
- ///
- Treasure = 6,
-
- ///
- /// A gathering point.
- ///
- GatheringPoint = 7,
-
- ///
- /// A battle NPC with subkind 6.
- ///
- BattleNpcSubkind6 = 8,
-
- ///
- /// Something else.
- ///
- Other = 9,
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlatePartsContainer.cs b/Pilz.Dalamud/NamePlate/NamePlatePartsContainer.cs
deleted file mode 100644
index bc3be1b..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlatePartsContainer.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// A container for parts.
-///
-internal class NamePlatePartsContainer
-{
- private NamePlateSimpleParts? nameParts;
- private NamePlateQuotedParts? titleParts;
- private NamePlateQuotedParts? freeCompanyTagParts;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The currently executing update context.
- public NamePlatePartsContainer(NamePlateUpdateContext context)
- {
- context.HasParts = true;
- }
-
- ///
- /// Gets a parts object for constructing a nameplate name.
- ///
- internal NamePlateSimpleParts Name => this.nameParts ??= new NamePlateSimpleParts(NamePlateStringField.Name);
-
- ///
- /// Gets a parts object for constructing a nameplate title.
- ///
- internal NamePlateQuotedParts Title => this.titleParts ??= new NamePlateQuotedParts(NamePlateStringField.Title, false);
-
- ///
- /// Gets a parts object for constructing a nameplate free company tag.
- ///
- internal NamePlateQuotedParts FreeCompanyTag => this.freeCompanyTagParts ??= new NamePlateQuotedParts(NamePlateStringField.FreeCompanyTag, true);
-
- ///
- /// Applies all container parts.
- ///
- /// The handler to apply the builders to.
- internal void ApplyBuilders(NamePlateUpdateHandler handler)
- {
- this.nameParts?.Apply(handler);
- this.freeCompanyTagParts?.Apply(handler);
- this.titleParts?.Apply(handler);
- }
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlateQuotedParts.cs b/Pilz.Dalamud/NamePlate/NamePlateQuotedParts.cs
deleted file mode 100644
index c82c046..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateQuotedParts.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-using Dalamud.Game.Text.SeStringHandling;
-
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// A part builder for constructing and setting quoted nameplate fields (i.e. free company tag and title).
-///
-/// The field type which should be set.
-///
-/// This class works as a lazy writer initialized with empty parts, where an empty part signifies no change should be
-/// performed. Only after all handler processing is complete does it write out any parts which were set to the
-/// associated field. Reading fields from this class is usually not what you want to do, as you'll only be reading the
-/// contents of parts which other plugins have written to. Prefer reading from the base handler's properties or using
-/// .
-///
-public class NamePlateQuotedParts(NamePlateStringField field, bool isFreeCompany)
-{
- ///
- /// Gets or sets the opening and closing SeStrings which will wrap the entire contents, which can be used to apply
- /// colors or styling to the entire field.
- ///
- public (SeString, SeString)? OuterWrap { get; set; }
-
- ///
- /// Gets or sets the opening quote string which appears before the text and opening text-wrap.
- ///
- public SeString? LeftQuote { get; set; }
-
- ///
- /// Gets or sets the closing quote string which appears after the text and closing text-wrap.
- ///
- public SeString? RightQuote { get; set; }
-
- ///
- /// Gets or sets the opening and closing SeStrings which will wrap the text, which can be used to apply colors or
- /// styling to the field's text.
- ///
- public (SeString, SeString)? TextWrap { get; set; }
-
- ///
- /// Gets or sets this field's text.
- ///
- public SeString? Text { get; set; }
-
- ///
- /// Applies the changes from this builder to the actual field.
- ///
- /// The handler to perform the changes on.
- internal unsafe void Apply(NamePlateUpdateHandler handler)
- {
- if ((nint)handler.GetFieldAsPointer(field) == NamePlateGui.EmptyStringPointer)
- return;
-
- var sb = new SeStringBuilder();
- if (this.OuterWrap is { Item1: var outerLeft })
- {
- sb.Append(outerLeft);
- }
-
- if (this.LeftQuote is not null)
- {
- sb.Append(this.LeftQuote);
- }
- else
- {
- sb.Append(isFreeCompany ? " «" : "《");
- }
-
- if (this.TextWrap is { Item1: var left, Item2: var right })
- {
- sb.Append(left);
- sb.Append(this.Text ?? this.GetStrippedField(handler));
- sb.Append(right);
- }
- else
- {
- sb.Append(this.Text ?? this.GetStrippedField(handler));
- }
-
- if (this.RightQuote is not null)
- {
- sb.Append(this.RightQuote);
- }
- else
- {
- sb.Append(isFreeCompany ? "»" : "》");
- }
-
- if (this.OuterWrap is { Item2: var outerRight })
- {
- sb.Append(outerRight);
- }
-
- handler.SetField(field, sb.Build());
- }
-
- private SeString GetStrippedField(NamePlateUpdateHandler handler)
- {
- return SeString.Parse(
- isFreeCompany
- ? NamePlateGui.StripFreeCompanyTagQuotes(handler.GetFieldAsSpan(field))
- : NamePlateGui.StripTitleQuotes(handler.GetFieldAsSpan(field)));
- }
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlateSimpleParts.cs b/Pilz.Dalamud/NamePlate/NamePlateSimpleParts.cs
deleted file mode 100644
index 4c58881..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateSimpleParts.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Dalamud.Game.Text.SeStringHandling;
-
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// A part builder for constructing and setting a simple (unquoted) nameplate field.
-///
-/// The field type which should be set.
-///
-/// This class works as a lazy writer initialized with empty parts, where an empty part signifies no change should be
-/// performed. Only after all handler processing is complete does it write out any parts which were set to the
-/// associated field. Reading fields from this class is usually not what you want to do, as you'll only be reading the
-/// contents of parts which other plugins have written to. Prefer reading from the base handler's properties or using
-/// .
-///
-public class NamePlateSimpleParts(NamePlateStringField field)
-{
- ///
- /// Gets or sets the opening and closing SeStrings which will wrap the text, which can be used to apply colors or
- /// styling to the field's text.
- ///
- public (SeString, SeString)? TextWrap { get; set; }
-
- ///
- /// Gets or sets this field's text.
- ///
- public SeString? Text { get; set; }
-
- ///
- /// Applies the changes from this builder to the actual field.
- ///
- /// The handler to perform the changes on.
- internal unsafe void Apply(NamePlateUpdateHandler handler)
- {
- if ((nint)handler.GetFieldAsPointer(field) == NamePlateGui.EmptyStringPointer)
- return;
-
- if (this.TextWrap is { Item1: var left, Item2: var right })
- {
- var sb = new SeStringBuilder();
- sb.Append(left);
- sb.Append(this.Text ?? handler.GetFieldAsSeString(field));
- sb.Append(right);
- handler.SetField(field, sb.Build());
- }
- else if (this.Text is not null)
- {
- handler.SetField(field, this.Text);
- }
- }
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlateStringField.cs b/Pilz.Dalamud/NamePlate/NamePlateStringField.cs
deleted file mode 100644
index a64e552..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateStringField.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// An enum describing the string fields available in nameplate data. The and various flags
-/// determine which fields will actually be rendered.
-///
-public enum NamePlateStringField
-{
- ///
- /// The object's name.
- ///
- Name = 0,
-
- ///
- /// The object's title.
- ///
- Title = 50,
-
- ///
- /// The object's free company tag.
- ///
- FreeCompanyTag = 100,
-
- ///
- /// The object's status prefix.
- ///
- StatusPrefix = 150,
-
- ///
- /// The object's target suffix.
- ///
- TargetSuffix = 200,
-
- ///
- /// The object's level prefix.
- ///
- LevelPrefix = 250,
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlateUpdateContext.cs b/Pilz.Dalamud/NamePlate/NamePlateUpdateContext.cs
deleted file mode 100644
index c30cb18..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateUpdateContext.cs
+++ /dev/null
@@ -1,152 +0,0 @@
-using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
-using Dalamud.Game.ClientState.Objects;
-using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Client.UI;
-using FFXIVClientStructs.FFXIV.Component.GUI;
-
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// Contains information related to the pending nameplate data update. This is only valid for a single frame and should
-/// not be kept across frames.
-///
-public interface INamePlateUpdateContext
-{
- ///
- /// Gets the number of active nameplates. The actual number visible may be lower than this in cases where some
- /// nameplates are hidden by default (based on in-game "Display Name Settings" and so on).
- ///
- int ActiveNamePlateCount { get; }
-
- ///
- /// Gets a value indicating whether the game is currently performing a full update of all active nameplates.
- ///
- bool IsFullUpdate { get; }
-
- ///
- /// Gets the address of the NamePlate addon.
- ///
- nint AddonAddress { get; }
-
- ///
- /// Gets the address of the NamePlate addon's number array data container.
- ///
- nint NumberArrayDataAddress { get; }
-
- ///
- /// Gets the address of the NamePlate addon's string array data container.
- ///
- nint StringArrayDataAddress { get; }
-
- ///
- /// Gets the address of the first entry in the NamePlate addon's int array.
- ///
- nint NumberArrayDataEntryAddress { get; }
-}
-
-///
-/// Contains information related to the pending nameplate data update. This is only valid for a single frame and should
-/// not be kept across frames.
-///
-internal unsafe class NamePlateUpdateContext : INamePlateUpdateContext
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// An object table.
- /// The addon lifecycle arguments for the update request.
- internal NamePlateUpdateContext(IObjectTable objectTable, AddonRequestedUpdateArgs args)
- {
- this.ObjectTable = objectTable;
- this.RaptureAtkModule = FFXIVClientStructs.FFXIV.Client.UI.RaptureAtkModule.Instance();
- this.Ui3DModule = UIModule.Instance()->GetUI3DModule();
- this.ResetState(args);
- }
-
- ///
- /// Gets the number of active nameplates. The actual number visible may be lower than this in cases where some
- /// nameplates are hidden by default (based on in-game "Display Name Settings" and so on).
- ///
- public int ActiveNamePlateCount { get; private set; }
-
- ///
- /// Gets a value indicating whether the game is currently performing a full update of all active nameplates.
- ///
- public bool IsFullUpdate { get; private set; }
-
- ///
- /// Gets the address of the NamePlate addon.
- ///
- public nint AddonAddress => (nint)this.Addon;
-
- ///
- /// Gets the address of the NamePlate addon's number array data container.
- ///
- public nint NumberArrayDataAddress => (nint)this.NumberData;
-
- ///
- /// Gets the address of the NamePlate addon's string array data container.
- ///
- public nint StringArrayDataAddress => (nint)this.StringData;
-
- ///
- /// Gets the address of the first entry in the NamePlate addon's int array.
- ///
- public nint NumberArrayDataEntryAddress => (nint)this.NumberStruct;
-
- ///
- /// Gets the RaptureAtkModule.
- ///
- internal RaptureAtkModule* RaptureAtkModule { get; }
-
- ///
- /// Gets the Ui3DModule.
- ///
- internal UI3DModule* Ui3DModule { get; }
-
- ///
- /// Gets the ObjectTable.
- ///
- internal IObjectTable ObjectTable { get; }
-
- ///
- /// Gets a pointer to the NamePlate addon.
- ///
- internal AddonNamePlate* Addon { get; private set; }
-
- ///
- /// Gets a pointer to the NamePlate addon's number array data container.
- ///
- internal NumberArrayData* NumberData { get; private set; }
-
- ///
- /// Gets a pointer to the NamePlate addon's string array data container.
- ///
- internal StringArrayData* StringData { get; private set; }
-
- ///
- /// Gets a pointer to the NamePlate addon's number array entries as a struct.
- ///
- internal AddonNamePlate.NamePlateIntArrayData* NumberStruct { get; private set; }
-
- ///
- /// Gets or sets a value indicating whether any handler in the current context has instantiated a part builder.
- ///
- internal bool HasParts { get; set; }
-
- ///
- /// Resets the state of the context based on the provided addon lifecycle arguments.
- ///
- /// The addon lifecycle arguments for the update request.
- internal void ResetState(AddonRequestedUpdateArgs args)
- {
- this.Addon = (AddonNamePlate*)args.Addon;
- this.NumberData = ((NumberArrayData**)args.NumberArrayData)![NamePlateGui.NumberArrayIndex];
- this.NumberStruct = (AddonNamePlate.NamePlateIntArrayData*)this.NumberData->IntArray;
- this.StringData = ((StringArrayData**)args.StringArrayData)![NamePlateGui.StringArrayIndex];
- this.HasParts = false;
-
- this.ActiveNamePlateCount = this.NumberStruct->ActiveNamePlateCount;
- this.IsFullUpdate = this.Addon->DoFullUpdate != 0;
- }
-}
diff --git a/Pilz.Dalamud/NamePlate/NamePlateUpdateHandler.cs b/Pilz.Dalamud/NamePlate/NamePlateUpdateHandler.cs
deleted file mode 100644
index cd300f9..0000000
--- a/Pilz.Dalamud/NamePlate/NamePlateUpdateHandler.cs
+++ /dev/null
@@ -1,606 +0,0 @@
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-
-using Dalamud.Game.ClientState.Objects.SubKinds;
-using Dalamud.Game.ClientState.Objects.Types;
-using Dalamud.Game.Text.SeStringHandling;
-
-using FFXIVClientStructs.FFXIV.Client.UI;
-using FFXIVClientStructs.Interop;
-
-namespace Pilz.Dalamud.NamePlate;
-
-///
-/// A class representing a single nameplate. Provides mechanisms to look up the game object associated with the
-/// nameplate and allows for modification of various backing fields in number and string array data, which in turn
-/// affect aspects of the nameplate's appearance when drawn. Instances of this class are only valid for a single frame
-/// and should not be kept across frames.
-///
-public interface INamePlateUpdateHandler
-{
- ///
- /// Gets the GameObjectId of the game object associated with this nameplate.
- ///
- ulong GameObjectId { get; }
-
- ///
- /// Gets the associated with this nameplate, if possible. Performs an object table scan
- /// and caches the result if successful.
- ///
- IGameObject? GameObject { get; }
-
- ///
- /// Gets a read-only view of the nameplate info object data for a nameplate. Modifications to
- /// fields do not affect fields in the returned view.
- ///
- INamePlateInfoView InfoView { get; }
-
- ///
- /// Gets the index for this nameplate data in the backing number and string array data. This is not the same as the
- /// rendered or object index, which can be retrieved from .
- ///
- int ArrayIndex { get; }
-
- ///
- /// Gets the associated with this nameplate, if possible. Returns null if the nameplate
- /// has an associated , but that object cannot be assigned to .
- ///
- IBattleChara? BattleChara { get; }
-
- ///
- /// Gets the associated with this nameplate, if possible. Returns null if the
- /// nameplate has an associated , but that object cannot be assigned to
- /// .
- ///
- IPlayerCharacter? PlayerCharacter { get; }
-
- ///
- /// Gets the address of the nameplate info struct.
- ///
- nint NamePlateInfoAddress { get; }
-
- ///
- /// Gets the address of the first entry associated with this nameplate in the NamePlate addon's int array.
- ///
- nint NamePlateObjectAddress { get; }
-
- ///
- /// Gets a value indicating what kind of nameplate this is, based on the kind of object it is associated with.
- ///
- NamePlateKind NamePlateKind { get; }
-
- ///
- /// Gets the update flags for this nameplate.
- ///
- int UpdateFlags { get; }
-
- ///
- /// Gets or sets the overall text color for this nameplate. If this value is changed, the appropriate update flag
- /// will be set so that the game will reflect this change immediately.
- ///
- uint TextColor { get; set; }
-
- ///
- /// Gets or sets the overall text edge color for this nameplate. If this value is changed, the appropriate update
- /// flag will be set so that the game will reflect this change immediately.
- ///
- uint EdgeColor { get; set; }
-
- ///
- /// Gets or sets the icon ID for the nameplate's marker icon, which is the large icon used to indicate quest
- /// availability and so on. This value is read from and reset by the game every frame, not just when a nameplate
- /// changes. Setting this to 0 disables the icon.
- ///
- int MarkerIconId { get; set; }
-
- ///
- /// Gets or sets the icon ID for the nameplate's name icon, which is the small icon shown to the left of the name.
- /// Setting this to -1 disables the icon.
- ///
- int NameIconId { get; set; }
-
- ///
- /// Gets the nameplate index, which is the index used for rendering and looking up entries in the object array. For
- /// number and string array data, is used.
- ///
- int NamePlateIndex { get; }
-
- ///
- /// Gets the draw flags for this nameplate.
- ///
- int DrawFlags { get; }
-
- ///
- /// Gets or sets the visibility flags for this nameplate.
- ///
- int VisibilityFlags { get; set; }
-
- ///
- /// Gets a value indicating whether this nameplate is undergoing a major update or not. This is usually true when a
- /// nameplate has just appeared or something meaningful about the entity has changed (e.g. its job or status). This
- /// flag is reset by the game during the update process (during requested update and before draw).
- ///
- bool IsUpdating { get; }
-
- ///
- /// Gets or sets a value indicating whether the title (when visible) will be displayed above the object's name (a
- /// prefix title) instead of below the object's name (a suffix title).
- ///
- bool IsPrefixTitle { get; set; }
-
- ///
- /// Gets or sets a value indicating whether the title should be displayed at all.
- ///
- bool DisplayTitle { get; set; }
-
- ///
- /// Gets or sets the name for this nameplate.
- ///
- SeString Name { get; set; }
-
- ///
- /// Gets a builder which can be used to help cooperatively build a new name for this nameplate even when other
- /// plugins modifying the name are present. Specifically, this builder allows setting text and text-wrapping
- /// payloads (e.g. for setting text color) separately.
- ///
- NamePlateSimpleParts NameParts { get; }
-
- ///
- /// Gets or sets the title for this nameplate.
- ///
- SeString Title { get; set; }
-
- ///
- /// Gets a builder which can be used to help cooperatively build a new title for this nameplate even when other
- /// plugins modifying the title are present. Specifically, this builder allows setting text, text-wrapping
- /// payloads (e.g. for setting text color), and opening and closing quote sequences separately.
- ///
- NamePlateQuotedParts TitleParts { get; }
-
- ///
- /// Gets or sets the free company tag for this nameplate.
- ///
- SeString FreeCompanyTag { get; set; }
-
- ///
- /// Gets a builder which can be used to help cooperatively build a new FC tag for this nameplate even when other
- /// plugins modifying the FC tag are present. Specifically, this builder allows setting text, text-wrapping
- /// payloads (e.g. for setting text color), and opening and closing quote sequences separately.
- ///
- NamePlateQuotedParts FreeCompanyTagParts { get; }
-
- ///
- /// Gets or sets the status prefix for this nameplate. This prefix is used by the game to add BitmapFontIcon-based
- /// online status icons to player nameplates.
- ///
- SeString StatusPrefix { get; set; }
-
- ///
- /// Gets or sets the target suffix for this nameplate. This suffix is used by the game to add the squared-letter
- /// target tags to the end of combat target nameplates.
- ///
- SeString TargetSuffix { get; set; }
-
- ///
- /// Gets or sets the level prefix for this nameplate. This "Lv60" style prefix is added to enemy and friendly battle
- /// NPC nameplates to indicate the NPC level.
- ///
- SeString LevelPrefix { get; set; }
-
- ///
- /// Removes the contents of the name field for this nameplate. This differs from simply setting the field
- /// to an empty string because it writes a special value to memory, and other setters (except SetField variants)
- /// will refuse to overwrite this value. Therefore, fields removed this way are more likely to stay removed.
- ///
- void RemoveName();
-
- ///
- /// Removes the contents of the title field for this nameplate. This differs from simply setting the field
- /// to an empty string because it writes a special value to memory, and other setters (except SetField variants)
- /// will refuse to overwrite this value. Therefore, fields removed this way are more likely to stay removed.
- ///
- void RemoveTitle();
-
- ///
- /// Removes the contents of the FC tag field for this nameplate. This differs from simply setting the field
- /// to an empty string because it writes a special value to memory, and other setters (except SetField variants)
- /// will refuse to overwrite this value. Therefore, fields removed this way are more likely to stay removed.
- ///
- void RemoveFreeCompanyTag();
-
- ///
- /// Removes the contents of the status prefix field for this nameplate. This differs from simply setting the field
- /// to an empty string because it writes a special value to memory, and other setters (except SetField variants)
- /// will refuse to overwrite this value. Therefore, fields removed this way are more likely to stay removed.
- ///
- void RemoveStatusPrefix();
-
- ///
- /// Removes the contents of the target suffix field for this nameplate. This differs from simply setting the field
- /// to an empty string because it writes a special value to memory, and other setters (except SetField variants)
- /// will refuse to overwrite this value. Therefore, fields removed this way are more likely to stay removed.
- ///
- void RemoveTargetSuffix();
-
- ///
- /// Removes the contents of the level prefix field for this nameplate. This differs from simply setting the field
- /// to an empty string because it writes a special value to memory, and other setters (except SetField variants)
- /// will refuse to overwrite this value. Therefore, fields removed this way are more likely to stay removed.
- ///
- void RemoveLevelPrefix();
-
- ///
- /// Gets a pointer to the string array value in the provided field.
- ///
- /// The field to read from.
- /// A pointer to a sequence of non-null bytes.
- unsafe byte* GetFieldAsPointer(NamePlateStringField field);
-
- ///
- /// Gets a byte span containing the string array value in the provided field.
- ///
- /// The field to read from.
- /// A ReadOnlySpan containing a sequence of non-null bytes.
- ReadOnlySpan GetFieldAsSpan(NamePlateStringField field);
-
- ///
- /// Gets a UTF8 string copy of the string array value in the provided field.
- ///
- /// The field to read from.
- /// A copy of the string array value as a string.
- string GetFieldAsString(NamePlateStringField field);
-
- ///
- /// Gets a parsed SeString copy of the string array value in the provided field.
- ///
- /// The field to read from.
- /// A copy of the string array value as a parsed SeString.
- SeString GetFieldAsSeString(NamePlateStringField field);
-
- ///
- /// Sets the string array value for the provided field.
- ///
- /// The field to write to.
- /// The string to write.
- void SetField(NamePlateStringField field, string value);
-
- ///
- /// Sets the string array value for the provided field.
- ///
- /// The field to write to.
- /// The SeString to write.
- void SetField(NamePlateStringField field, SeString value);
-
- ///
- /// Sets the string array value for the provided field.
- ///
- /// The field to write to.
- /// The ReadOnlySpan of bytes to write.
- void SetField(NamePlateStringField field, ReadOnlySpan value);
-
- ///
- /// Sets the string array value for the provided field.
- ///
- /// The field to write to.
- /// The pointer to a null-terminated sequence of bytes to write.
- unsafe void SetField(NamePlateStringField field, byte* value);
-
- ///
- /// Sets the string array value for the provided field to a fixed pointer to an empty string in unmanaged memory.
- /// Other methods may notice this fixed pointer and refuse to overwrite it, preserving the emptiness of the field.
- ///
- /// The field to write to.
- void RemoveField(NamePlateStringField field);
-}
-
-///
-/// A class representing a single nameplate. Provides mechanisms to look up the game object associated with the
-/// nameplate and allows for modification of various backing fields in number and string array data, which in turn
-/// affect aspects of the nameplate's appearance when drawn. Instances of this class are only valid for a single frame
-/// and should not be kept across frames.
-///
-internal unsafe class NamePlateUpdateHandler : INamePlateUpdateHandler
-{
- private readonly NamePlateUpdateContext context;
-
- private ulong? gameObjectId;
- private IGameObject? gameObject;
- private NamePlateInfoView? infoView;
- private NamePlatePartsContainer? partsContainer;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The current update context.
- /// The index for this nameplate data in the backing number and string array data. This is
- /// not the same as the rendered index, which can be retrieved from .
- internal NamePlateUpdateHandler(NamePlateUpdateContext context, int arrayIndex)
- {
- this.context = context;
- this.ArrayIndex = arrayIndex;
- }
-
- ///
- public int ArrayIndex { get; }
-
- ///
- public ulong GameObjectId => this.gameObjectId ??= this.NamePlateInfo->ObjectId;
-
- ///
- public IGameObject? GameObject => this.gameObject ??= this.context.ObjectTable.CreateObjectReference(
- (nint)this.context.Ui3DModule->NamePlateObjectInfoPointers[
- this.ArrayIndex].Value->GameObject);
-
- ///
- public IBattleChara? BattleChara => this.GameObject as IBattleChara;
-
- ///
- public IPlayerCharacter? PlayerCharacter => this.GameObject as IPlayerCharacter;
-
- ///
- public INamePlateInfoView InfoView => this.infoView ??= new NamePlateInfoView(this.NamePlateInfo);
-
- ///
- public nint NamePlateInfoAddress => (nint)this.NamePlateInfo;
-
- ///
- public nint NamePlateObjectAddress => (nint)this.NamePlateObject;
-
- ///
- public NamePlateKind NamePlateKind => (NamePlateKind)this.ObjectData->NamePlateKind;
-
- ///
- public int UpdateFlags
- {
- get => this.ObjectData->UpdateFlags;
- private set => this.ObjectData->UpdateFlags = value;
- }
-
- ///
- public uint TextColor
- {
- get => this.ObjectData->NameTextColor;
- set
- {
- if (value != this.TextColor) this.UpdateFlags |= 2;
- this.ObjectData->NameTextColor = value;
- }
- }
-
- ///
- public uint EdgeColor
- {
- get => this.ObjectData->NameEdgeColor;
- set
- {
- if (value != this.EdgeColor) this.UpdateFlags |= 2;
- this.ObjectData->NameEdgeColor = value;
- }
- }
-
- ///
- public int MarkerIconId
- {
- get => this.ObjectData->MarkerIconId;
- set => this.ObjectData->MarkerIconId = value;
- }
-
- ///
- public int NameIconId
- {
- get => this.ObjectData->NameIconId;
- set => this.ObjectData->NameIconId = value;
- }
-
- ///
- public int NamePlateIndex => this.ObjectData->NamePlateObjectIndex;
-
- ///
- public int DrawFlags
- {
- get => this.ObjectData->DrawFlags;
- private set => this.ObjectData->DrawFlags = value;
- }
-
- ///
- public int VisibilityFlags
- {
- get => ObjectData->VisibilityFlags;
- set => ObjectData->VisibilityFlags = value;
- }
-
- ///
- public bool IsUpdating => (this.UpdateFlags & 1) != 0;
-
- ///
- public bool IsPrefixTitle
- {
- get => (this.DrawFlags & 1) != 0;
- set => this.DrawFlags = value ? this.DrawFlags | 1 : this.DrawFlags & ~1;
- }
-
- ///
- public bool DisplayTitle
- {
- get => (this.DrawFlags & 0x80) == 0;
- set => this.DrawFlags = value ? this.DrawFlags & ~0x80 : this.DrawFlags | 0x80;
- }
-
- ///
- public SeString Name
- {
- get => this.GetFieldAsSeString(NamePlateStringField.Name);
- set => this.WeakSetField(NamePlateStringField.Name, value);
- }
-
- ///
- public NamePlateSimpleParts NameParts => this.PartsContainer.Name;
-
- ///
- public SeString Title
- {
- get => this.GetFieldAsSeString(NamePlateStringField.Title);
- set => this.WeakSetField(NamePlateStringField.Title, value);
- }
-
- ///
- public NamePlateQuotedParts TitleParts => this.PartsContainer.Title;
-
- ///
- public SeString FreeCompanyTag
- {
- get => this.GetFieldAsSeString(NamePlateStringField.FreeCompanyTag);
- set => this.WeakSetField(NamePlateStringField.FreeCompanyTag, value);
- }
-
- ///
- public NamePlateQuotedParts FreeCompanyTagParts => this.PartsContainer.FreeCompanyTag;
-
- ///
- public SeString StatusPrefix
- {
- get => this.GetFieldAsSeString(NamePlateStringField.StatusPrefix);
- set => this.WeakSetField(NamePlateStringField.StatusPrefix, value);
- }
-
- ///
- public SeString TargetSuffix
- {
- get => this.GetFieldAsSeString(NamePlateStringField.TargetSuffix);
- set => this.WeakSetField(NamePlateStringField.TargetSuffix, value);
- }
-
- ///
- public SeString LevelPrefix
- {
- get => this.GetFieldAsSeString(NamePlateStringField.LevelPrefix);
- set => this.WeakSetField(NamePlateStringField.LevelPrefix, value);
- }
-
- ///
- /// Gets or (lazily) creates a part builder container for this nameplate.
- ///
- internal NamePlatePartsContainer PartsContainer =>
- this.partsContainer ??= new NamePlatePartsContainer(this.context);
-
- private RaptureAtkModule.NamePlateInfo* NamePlateInfo =>
- this.context.RaptureAtkModule->NamePlateInfoEntries.GetPointer(this.NamePlateIndex);
-
- private AddonNamePlate.NamePlateObject* NamePlateObject =>
- &this.context.Addon->NamePlateObjectArray[this.NamePlateIndex];
-
- private AddonNamePlate.NamePlateIntArrayData.NamePlateObjectIntArrayData* ObjectData =>
- this.context.NumberStruct->ObjectData.GetPointer(this.ArrayIndex);
-
- ///
- public void RemoveName() => this.RemoveField(NamePlateStringField.Name);
-
- ///
- public void RemoveTitle() => this.RemoveField(NamePlateStringField.Title);
-
- ///
- public void RemoveFreeCompanyTag() => this.RemoveField(NamePlateStringField.FreeCompanyTag);
-
- ///
- public void RemoveStatusPrefix() => this.RemoveField(NamePlateStringField.StatusPrefix);
-
- ///
- public void RemoveTargetSuffix() => this.RemoveField(NamePlateStringField.TargetSuffix);
-
- ///
- public void RemoveLevelPrefix() => this.RemoveField(NamePlateStringField.LevelPrefix);
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public byte* GetFieldAsPointer(NamePlateStringField field)
- {
- return this.context.StringData->StringArray[this.ArrayIndex + (int)field];
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ReadOnlySpan GetFieldAsSpan(NamePlateStringField field)
- {
- return MemoryMarshal.CreateReadOnlySpanFromNullTerminated(this.GetFieldAsPointer(field));
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public string GetFieldAsString(NamePlateStringField field)
- {
- return Encoding.UTF8.GetString(this.GetFieldAsSpan(field));
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public SeString GetFieldAsSeString(NamePlateStringField field)
- {
- return SeString.Parse(this.GetFieldAsSpan(field));
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void SetField(NamePlateStringField field, string value)
- {
- this.context.StringData->SetValue(this.ArrayIndex + (int)field, value, true, true, true);
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void SetField(NamePlateStringField field, SeString value)
- {
- this.context.StringData->SetValue(this.ArrayIndex + (int)field, value.Encode(), true, true, true);
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void SetField(NamePlateStringField field, ReadOnlySpan value)
- {
- this.context.StringData->SetValue(this.ArrayIndex + (int)field, value, true, true, true);
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void SetField(NamePlateStringField field, byte* value)
- {
- this.context.StringData->SetValue(this.ArrayIndex + (int)field, value, true, true, true);
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void RemoveField(NamePlateStringField field)
- {
- this.context.StringData->SetValue(
- this.ArrayIndex + (int)field,
- (byte*)NamePlateGui.EmptyStringPointer,
- true,
- false,
- true);
- }
-
- ///
- /// Resets the state of this handler for re-use in a new update.
- ///
- internal void ResetState()
- {
- this.gameObjectId = null;
- this.gameObject = null;
- this.infoView = null;
- this.partsContainer = null;
- }
-
- ///
- /// Sets the string array value for the provided field, unless it was already set to the special empty string
- /// pointer used by the Remove methods.
- ///
- /// The field to write to.
- /// The SeString to write.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void WeakSetField(NamePlateStringField field, SeString value)
- {
- if ((nint)this.GetFieldAsPointer(field) == NamePlateGui.EmptyStringPointer)
- return;
- this.context.StringData->SetValue(this.ArrayIndex + (int)field, value.Encode(), true, true, true);
- }
-}
diff --git a/Pilz.Dalamud/Tools/NamePlates/NameplateChanges.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateChanges.cs
index 2a8cc7b..2a56815 100644
--- a/Pilz.Dalamud/Tools/NamePlates/NameplateChanges.cs
+++ b/Pilz.Dalamud/Tools/NamePlates/NameplateChanges.cs
@@ -1,4 +1,4 @@
-using Pilz.Dalamud.NamePlate;
+using Dalamud.Game.Gui.NamePlate;
namespace Pilz.Dalamud.Tools.NamePlates;
diff --git a/Pilz.Dalamud/Tools/NamePlates/NameplateElementChange.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateElementChange.cs
index 53a7c3a..5cf4a4f 100644
--- a/Pilz.Dalamud/Tools/NamePlates/NameplateElementChange.cs
+++ b/Pilz.Dalamud/Tools/NamePlates/NameplateElementChange.cs
@@ -1,5 +1,5 @@
-using Dalamud.Game.Text.SeStringHandling;
-using Pilz.Dalamud.NamePlate;
+using Dalamud.Game.Gui.NamePlate;
+using Dalamud.Game.Text.SeStringHandling;
using Pilz.Dalamud.Tools.Strings;
namespace Pilz.Dalamud.Tools.NamePlates;
diff --git a/Pilz.Dalamud/Tools/NamePlates/NameplateUpdateFactory.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateUpdateFactory.cs
index fd6d1e3..3b07913 100644
--- a/Pilz.Dalamud/Tools/NamePlates/NameplateUpdateFactory.cs
+++ b/Pilz.Dalamud/Tools/NamePlates/NameplateUpdateFactory.cs
@@ -1,8 +1,8 @@
-using Dalamud.Game.Text.SeStringHandling;
+using Dalamud.Game.Gui.NamePlate;
+using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Pilz.Dalamud.ActivityContexts;
using Pilz.Dalamud.Icons;
-using Pilz.Dalamud.NamePlate;
namespace Pilz.Dalamud.Tools.NamePlates;
@@ -31,7 +31,7 @@ public static class NameplateUpdateFactory
if (handler.StatusPrefix is SeString str)
str.Payloads.Insert(0, icon);
else
- handler.StatusPrefix = SeString.Empty.Append(icon);
+ handler.StatusPrefix = SeString.Empty.Append(icon);
// If we moved it, we don't need it as icon anymore, yay :D
isPrio = false;