fix(ItemPayload): thorough clean up, collectibles, eventitems, aging

This commit is contained in:
goaaats 2022-01-27 01:04:46 +01:00
parent bb7128e6fe
commit c232befd83
No known key found for this signature in database
GPG key ID: F18F057873895461
9 changed files with 244 additions and 27 deletions

View file

@ -30,6 +30,11 @@ namespace Dalamud.Game.Text
/// </summary>
HighQuality = 0xE03C,
/// <summary>
/// The collectible icon unicode character.
/// </summary>
Collectible = 0xE03D,
/// <summary>
/// The clock icon unicode character.
/// </summary>

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -5,6 +6,7 @@ using System.Text;
using Lumina.Excel.GeneratedSheets;
using Newtonsoft.Json;
using Serilog;
namespace Dalamud.Game.Text.SeStringHandling.Payloads
{
@ -22,7 +24,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
private string? displayName;
[JsonProperty]
private uint itemId;
private uint rawItemId;
/// <summary>
/// Initializes a new instance of the <see cref="ItemPayload"/> class.
@ -35,7 +37,10 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// TextPayload that is a part of a full item link in chat.</param>
public ItemPayload(uint itemId, bool isHq, string? displayNameOverride = null)
{
this.itemId = itemId;
this.rawItemId = itemId;
if (isHq)
this.rawItemId += (uint)ItemKind.Hq;
this.Kind = isHq ? ItemKind.Hq : ItemKind.Normal;
this.displayName = displayNameOverride;
}
@ -51,8 +56,11 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// TextPayload that is a part of a full item link in chat.</param>
public ItemPayload(uint itemId, ItemKind kind = ItemKind.Normal, string? displayNameOverride = null)
{
this.itemId = itemId;
this.Kind = kind;
this.rawItemId = itemId;
if (kind != ItemKind.EventItem)
this.rawItemId += (uint)kind;
this.displayName = displayNameOverride;
}
@ -112,10 +120,16 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
}
/// <summary>
/// Gets the raw item ID of this payload.
/// Gets the actual item ID of this payload.
/// </summary>
[JsonIgnore]
public uint ItemId => this.itemId;
public uint ItemId => GetAdjustedId(this.rawItemId).ItemId;
/// <summary>
/// Gets the raw, unadjusted item ID of this payload.
/// </summary>
[JsonIgnore]
public uint RawItemId => this.rawItemId;
/// <summary>
/// Gets the underlying Lumina Item represented by this payload.
@ -124,7 +138,21 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// The value is evaluated lazily and cached.
/// </remarks>
[JsonIgnore]
public Item? Item => this.item ??= this.DataResolver.GetExcelSheet<Item>()!.GetRow(this.itemId);
public Item? Item
{
get
{
// TODO(goat): This should be revamped/removed on an API level change.
if (this.Kind == ItemKind.EventItem)
{
Log.Warning("Event items cannot be fetched from the ItemPayload");
return null;
}
this.item ??= this.DataResolver.GetExcelSheet<Item>()!.GetRow(this.ItemId);
return this.item;
}
}
/// <summary>
/// Gets a value indicating whether or not this item link is for a high-quality version of the item.
@ -156,15 +184,13 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// <inheritdoc/>
public override string ToString()
{
return $"{this.Type} - ItemId: {this.itemId}, Kind: {this.Kind}, Name: {this.displayName ?? this.Item?.Name}";
return $"{this.Type} - ItemId: {this.ItemId}, Kind: {this.Kind}, Name: {this.displayName ?? this.Item?.Name}";
}
/// <inheritdoc/>
protected override byte[] EncodeImpl()
{
var actualItemId = this.itemId - (uint)this.Kind;
var idBytes = MakeInteger(actualItemId);
var idBytes = MakeInteger(this.rawItemId);
var hasName = !string.IsNullOrEmpty(this.displayName);
var chunkLen = idBytes.Length + 4;
@ -218,10 +244,8 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// <inheritdoc/>
protected override void DecodeImpl(BinaryReader reader, long endOfStream)
{
var (id, kind) = GetAdjustedId(GetInteger(reader));
this.itemId = id;
this.Kind = kind;
this.rawItemId = GetInteger(reader);
this.Kind = GetAdjustedId(this.rawItemId).Kind;
if (reader.BaseStream.Position + 3 < endOfStream)
{
@ -253,7 +277,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
{
> 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),
> 2_000_000 => (rawItemId, ItemKind.EventItem), // EventItem IDs are NOT adjusted
_ => (rawItemId, ItemKind.Normal),
};
}

View file

@ -13,14 +13,14 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
public class TextPayload : Payload, ITextProvider
{
[JsonProperty]
private string text;
private string? text;
/// <summary>
/// Initializes a new instance of the <see cref="TextPayload"/> class.
/// Creates a new TextPayload for the given text.
/// </summary>
/// <param name="text">The text to include for this payload.</param>
public TextPayload(string text)
public TextPayload(string? text)
{
this.text = text;
}
@ -41,12 +41,9 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
/// This may contain SE's special unicode characters.
/// </summary>
[JsonIgnore]
public string Text
public string? Text
{
get
{
return this.text;
}
get => this.text;
set
{

View file

@ -156,22 +156,58 @@ namespace Dalamud.Game.Text.SeStringHandling
/// <param name="isHq">Whether to link the high-quality variant of the item.</param>
/// <param name="displayNameOverride">An optional name override to display, instead of the actual item name.</param>
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
public static SeString CreateItemLink(uint itemId, bool isHq, string? displayNameOverride = null)
public static SeString CreateItemLink(uint itemId, bool isHq, string? displayNameOverride = null) =>
CreateItemLink(itemId, isHq ? ItemPayload.ItemKind.Hq : ItemPayload.ItemKind.Normal, displayNameOverride);
/// <summary>
/// Creates an SeString representing an entire Payload chain that can be used to link an item in the chat log.
/// </summary>
/// <param name="itemId">The id of the item to link.</param>
/// <param name="kind">The kind of item to link.</param>
/// <param name="displayNameOverride">An optional name override to display, instead of the actual item name.</param>
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
public static SeString CreateItemLink(uint itemId, ItemPayload.ItemKind kind = ItemPayload.ItemKind.Normal, string? displayNameOverride = null)
{
var data = Service<DataManager>.Get();
var displayName = displayNameOverride ?? data.GetExcelSheet<Item>()?.GetRow(itemId)?.Name;
if (isHq)
var displayName = displayNameOverride;
if (displayName == null)
{
switch (kind)
{
case ItemPayload.ItemKind.Normal:
case ItemPayload.ItemKind.Collectible:
case ItemPayload.ItemKind.Hq:
displayName = data.GetExcelSheet<Item>()?.GetRow(itemId)?.Name;
break;
case ItemPayload.ItemKind.EventItem:
displayName = data.GetExcelSheet<EventItem>()?.GetRow(itemId)?.Name;
break;
default:
throw new ArgumentOutOfRangeException(nameof(kind), kind, null);
}
}
if (displayName == null)
{
throw new Exception("Invalid item ID specified, could not determine item name.");
}
if (kind == ItemPayload.ItemKind.Hq)
{
displayName += $" {(char)SeIconChar.HighQuality}";
}
else if (kind == ItemPayload.ItemKind.Collectible)
{
displayName += $" {(char)SeIconChar.Collectible}";
}
// TODO: probably a cleaner way to build these than doing the bulk+insert
var payloads = new List<Payload>(new Payload[]
{
new UIForegroundPayload(0x0225),
new UIGlowPayload(0x0226),
new ItemPayload(itemId, isHq),
new ItemPayload(itemId, kind),
// arrow goes here
new TextPayload(displayName),
RawPayload.LinkTerminator,

View file

@ -116,6 +116,14 @@ namespace Dalamud.Game.Text.SeStringHandling
public SeStringBuilder AddItemLink(uint itemId, ItemPayload.ItemKind kind, string? itemNameOverride = null) =>
this.Add(new ItemPayload(itemId, kind, itemNameOverride));
/// <summary>
/// Add an item link to the builder.
/// </summary>
/// <param name="rawItemId">The raw item ID.</param>
/// <returns>The current builder.</returns>
public SeStringBuilder AddItemLinkRaw(uint rawItemId) =>
this.Add(ItemPayload.FromRaw(rawItemId));
/// <summary>
/// Add italicized raw text to the builder.
/// </summary>