diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs b/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
index 0ea2a5c56..029e9716c 100644
--- a/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
@@ -94,6 +94,38 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
this.addonLifecycle.UnregisterListener(this.preRequestedUpdateListener);
}
+ ///
+ /// 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[..3].SequenceEqual(" «"u8) && text[^2..].SequenceEqual("»"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[..3].SequenceEqual("《"u8) && text[^3..].SequenceEqual("》"u8))
+ {
+ return text[3..^3];
+ }
+
+ return text;
+ }
+
private static nint CreateEmptyStringPointer()
{
var pointer = Marshal.AllocHGlobal(1);
diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateInfoView.cs b/Dalamud/Game/Gui/NamePlate/NamePlateInfoView.cs
index a51ed20c3..020905422 100644
--- a/Dalamud/Game/Gui/NamePlate/NamePlateInfoView.cs
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateInfoView.cs
@@ -16,21 +16,28 @@ public interface INamePlateInfoView
SeString Name { get; }
///
- /// Gets the displayed free company tag for this nameplate according to the nameplate info object.
+ /// 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 title for this nameplate according to the nameplate info object. In this field, the quote
+ /// 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. In this field, the quote
+ /// 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 DisplayTitle { get; }
+ SeString QuotedTitle { get; }
///
/// Gets the displayed level text for this nameplate according to the nameplate info object.
@@ -63,21 +70,26 @@ internal unsafe class NamePlateInfoView(RaptureAtkModule.NamePlateInfo* info) :
{
private SeString? name;
private SeString? freeCompanyTag;
+ private SeString? quotedFreeCompanyTag;
private SeString? title;
- private SeString? displayTitle;
+ private SeString? quotedTitle;
private SeString? levelText;
///
public SeString Name => this.name ??= SeString.Parse(info->Name);
///
- public SeString FreeCompanyTag => this.freeCompanyTag ??= SeString.Parse(info->FcName);
+ 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 DisplayTitle => this.displayTitle ??= SeString.Parse(info->DisplayTitle);
+ public SeString QuotedTitle => this.quotedTitle ??= SeString.Parse(info->DisplayTitle);
///
public SeString LevelText => this.levelText ??= SeString.Parse(info->LevelText);
diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateQuotedParts.cs b/Dalamud/Game/Gui/NamePlate/NamePlateQuotedParts.cs
index 684578fcd..fed0dd144 100644
--- a/Dalamud/Game/Gui/NamePlate/NamePlateQuotedParts.cs
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateQuotedParts.cs
@@ -51,12 +51,12 @@ public class NamePlateQuotedParts(NamePlateStringField field, bool isFreeCompany
if (this.TextWrap is { Item1: var left, Item2: var right })
{
sb.Append(left);
- sb.Append(this.Text ?? handler.GetFieldAsSeString(field));
+ sb.Append(this.Text ?? this.GetStrippedField(handler));
sb.Append(right);
}
else
{
- sb.Append(this.Text ?? handler.GetFieldAsSeString(field));
+ sb.Append(this.Text ?? this.GetStrippedField(handler));
}
if (this.RightQuote is not null)
@@ -70,4 +70,12 @@ public class NamePlateQuotedParts(NamePlateStringField field, bool isFreeCompany
handler.SetField(field, sb.Build());
}
+
+ private SeString GetStrippedField(NamePlateUpdateHandler handler)
+ {
+ return SeString.Parse(
+ isFreeCompany
+ ? NamePlateGui.StripFreeCompanyTagQuotes(handler.GetFieldAsSpan(field))
+ : NamePlateGui.StripTitleQuotes(handler.GetFieldAsSpan(field)));
+ }
}