diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/ItemPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/ItemPayload.cs
index fff92cadd..d7404506b 100644
--- a/Dalamud/Game/Text/SeStringHandling/Payloads/ItemPayload.cs
+++ b/Dalamud/Game/Text/SeStringHandling/Payloads/ItemPayload.cs
@@ -13,13 +13,13 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
///
public class ItemPayload : Payload
{
- private Item item;
+ private Item? item;
// mainly to allow overriding the name (for things like owo)
// TODO: even though this is present in some item links, it may not really have a use at all
// For things like owo, changing the text payload is probably correct, whereas changing the
// actual embedded name might not work properly.
- private string? displayName = null;
+ private string? displayName;
[JsonProperty]
private uint itemId;
@@ -36,7 +36,23 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
public ItemPayload(uint itemId, bool isHq, string? displayNameOverride = null)
{
this.itemId = itemId;
- this.IsHQ = isHq;
+ this.Kind = isHq ? ItemKind.Hq : ItemKind.Normal;
+ this.displayName = displayNameOverride;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// Creates a payload representing an interactable item link for the specified item.
+ ///
+ /// The id of the item.
+ /// Kind of item to encode.
+ /// An optional name to include in the item link. Typically this should
+ /// be left as null, or set to the normal item name. Actual overrides are better done with the subsequent
+ /// TextPayload that is a part of a full item link in chat.
+ public ItemPayload(uint itemId, ItemKind kind = ItemKind.Normal, string? displayNameOverride = null)
+ {
+ this.itemId = itemId;
+ this.Kind = kind;
this.displayName = displayNameOverride;
}
@@ -48,6 +64,32 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
{
}
+ ///
+ /// Kinds of items that can be fetched from this payload.
+ ///
+ public enum ItemKind : uint
+ {
+ ///
+ /// Normal items.
+ ///
+ Normal,
+
+ ///
+ /// Collectible Items.
+ ///
+ Collectible = 500_000,
+
+ ///
+ /// High-Quality items.
+ ///
+ Hq = 1_000_000,
+
+ ///
+ /// Event/Key items.
+ ///
+ EventItem = 2_000_000,
+ }
+
///
public override PayloadType Type => PayloadType.Item;
@@ -55,7 +97,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// Gets or sets the displayed name for this item link. Note that incoming links only sometimes have names embedded,
/// often the name is only present in a following text payload.
///
- public string DisplayName
+ public string? DisplayName
{
get
{
@@ -82,24 +124,45 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// The value is evaluated lazily and cached.
///
[JsonIgnore]
- public Item Item => this.item ??= this.DataResolver.GetExcelSheet- ().GetRow(this.itemId);
+ public Item? Item => this.item ??= this.DataResolver.GetExcelSheet
- ()!.GetRow(this.itemId);
///
/// Gets a value indicating whether or not this item link is for a high-quality version of the item.
///
[JsonProperty]
- public bool IsHQ { get; private set; } = false;
+ public bool IsHQ => this.Kind == ItemKind.Hq;
+
+ ///
+ /// Gets or sets the kind of item represented by this payload.
+ ///
+ public ItemKind Kind { get; set; } = ItemKind.Normal;
+
+ ///
+ /// Initializes a new instance of the class.
+ /// Creates a payload representing an interactable item link for the specified item.
+ ///
+ /// The raw, unadjusted id of the item.
+ /// An optional name to include in the item link. Typically this should
+ /// be left as null, or set to the normal item name. Actual overrides are better done with the subsequent
+ /// TextPayload that is a part of a full item link in chat.
+ /// The created item payload.
+ public static ItemPayload FromRaw(uint rawItemId, string? displayNameOverride = null)
+ {
+ var (id, kind) = GetAdjustedId(rawItemId);
+ return new ItemPayload(id, kind, displayNameOverride);
+ }
///
public override string ToString()
{
- return $"{this.Type} - ItemId: {this.itemId}, IsHQ: {this.IsHQ}, Name: {this.displayName ?? this.Item.Name}";
+ return $"{this.Type} - ItemId: {this.itemId}, Kind: {this.Kind}, Name: {this.displayName ?? this.Item?.Name}";
}
///
protected override byte[] EncodeImpl()
{
- var actualItemId = this.IsHQ ? this.itemId + 1000000 : this.itemId;
+ var actualItemId = this.itemId - (uint)this.Kind;
+
var idBytes = MakeInteger(actualItemId);
var hasName = !string.IsNullOrEmpty(this.displayName);
@@ -154,13 +217,10 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
///
protected override void DecodeImpl(BinaryReader reader, long endOfStream)
{
- this.itemId = GetInteger(reader);
+ var (id, kind) = GetAdjustedId(GetInteger(reader));
- if (this.itemId > 1000000)
- {
- this.itemId -= 1000000;
- this.IsHQ = true;
- }
+ this.itemId = id;
+ this.Kind = kind;
if (reader.BaseStream.Position + 3 < endOfStream)
{
@@ -185,5 +245,16 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
this.displayName = Encoding.UTF8.GetString(itemNameBytes);
}
}
+
+ private static (uint ItemId, ItemKind Kind) GetAdjustedId(uint rawItemId)
+ {
+ return rawItemId switch
+ {
+ > 500_000 and < 1_000_000 => (rawItemId - 500_000, ItemKind.Collectible),
+ > 1_000_000 and < 2_000_000 => (rawItemId - 1_000_000, ItemKind.Hq),
+ > 2_000_000 => (rawItemId - 2_000_000, ItemKind.EventItem),
+ _ => (rawItemId, ItemKind.Normal),
+ };
+ }
}
}