mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-14 20:54:16 +01:00
fix(ItemPayload): thorough clean up, collectibles, eventitems, aging
This commit is contained in:
parent
bb7128e6fe
commit
c232befd83
9 changed files with 244 additions and 27 deletions
|
|
@ -11,6 +11,7 @@ using Dalamud.Interface;
|
||||||
using Dalamud.IoC;
|
using Dalamud.IoC;
|
||||||
using Dalamud.IoC.Internal;
|
using Dalamud.IoC.Internal;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ namespace Dalamud.Game.Gui
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PluginInterface]
|
[PluginInterface]
|
||||||
[InterfaceVersion("1.0")]
|
[InterfaceVersion("1.0")]
|
||||||
public sealed class GameGui : IDisposable
|
public sealed unsafe class GameGui : IDisposable
|
||||||
{
|
{
|
||||||
private readonly GameGuiAddressResolver address;
|
private readonly GameGuiAddressResolver address;
|
||||||
|
|
||||||
|
|
@ -36,6 +37,7 @@ namespace Dalamud.Game.Gui
|
||||||
private readonly Hook<HandleActionOutDelegate> handleActionOutHook;
|
private readonly Hook<HandleActionOutDelegate> handleActionOutHook;
|
||||||
private readonly Hook<HandleImmDelegate> handleImmHook;
|
private readonly Hook<HandleImmDelegate> handleImmHook;
|
||||||
private readonly Hook<ToggleUiHideDelegate> toggleUiHideHook;
|
private readonly Hook<ToggleUiHideDelegate> toggleUiHideHook;
|
||||||
|
private readonly Hook<Utf8StringFromSequenceDelegate> utf8StringFromSequenceHook;
|
||||||
|
|
||||||
private GetUIMapObjectDelegate getUIMapObject;
|
private GetUIMapObjectDelegate getUIMapObject;
|
||||||
private OpenMapWithFlagDelegate openMapWithFlag;
|
private OpenMapWithFlagDelegate openMapWithFlag;
|
||||||
|
|
@ -79,6 +81,8 @@ namespace Dalamud.Game.Gui
|
||||||
this.toggleUiHideHook = new Hook<ToggleUiHideDelegate>(this.address.ToggleUiHide, this.ToggleUiHideDetour);
|
this.toggleUiHideHook = new Hook<ToggleUiHideDelegate>(this.address.ToggleUiHide, this.ToggleUiHideDetour);
|
||||||
|
|
||||||
this.getAgentModule = Marshal.GetDelegateForFunctionPointer<GetAgentModuleDelegate>(this.address.GetAgentModule);
|
this.getAgentModule = Marshal.GetDelegateForFunctionPointer<GetAgentModuleDelegate>(this.address.GetAgentModule);
|
||||||
|
|
||||||
|
this.utf8StringFromSequenceHook = new Hook<Utf8StringFromSequenceDelegate>(this.address.Utf8StringFromSequence, this.Utf8StringFromSequenceDetour);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshaled delegates
|
// Marshaled delegates
|
||||||
|
|
@ -93,6 +97,9 @@ namespace Dalamud.Game.Gui
|
||||||
|
|
||||||
// Hooked delegates
|
// Hooked delegates
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
|
private delegate Utf8String* Utf8StringFromSequenceDelegate(Utf8String* thisPtr, byte* sourcePtr, nuint sourceLen);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
private delegate IntPtr GetUIMapObjectDelegate(IntPtr uiObject);
|
private delegate IntPtr GetUIMapObjectDelegate(IntPtr uiObject);
|
||||||
|
|
||||||
|
|
@ -439,6 +446,7 @@ namespace Dalamud.Game.Gui
|
||||||
this.toggleUiHideHook.Enable();
|
this.toggleUiHideHook.Enable();
|
||||||
this.handleActionHoverHook.Enable();
|
this.handleActionHoverHook.Enable();
|
||||||
this.handleActionOutHook.Enable();
|
this.handleActionOutHook.Enable();
|
||||||
|
this.utf8StringFromSequenceHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -457,6 +465,7 @@ namespace Dalamud.Game.Gui
|
||||||
this.toggleUiHideHook.Dispose();
|
this.toggleUiHideHook.Dispose();
|
||||||
this.handleActionHoverHook.Dispose();
|
this.handleActionHoverHook.Dispose();
|
||||||
this.handleActionOutHook.Dispose();
|
this.handleActionOutHook.Dispose();
|
||||||
|
this.utf8StringFromSequenceHook.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -602,5 +611,15 @@ namespace Dalamud.Game.Gui
|
||||||
? (char)0
|
? (char)0
|
||||||
: result;
|
: result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Utf8String* Utf8StringFromSequenceDetour(Utf8String* thisPtr, byte* sourcePtr, nuint sourceLen)
|
||||||
|
{
|
||||||
|
if (sourcePtr != null)
|
||||||
|
this.utf8StringFromSequenceHook.Original(thisPtr, sourcePtr, sourceLen);
|
||||||
|
else
|
||||||
|
thisPtr->Ctor(); // this is in clientstructs but you could do it manually too
|
||||||
|
|
||||||
|
return thisPtr; // this function shouldn't need to return but the original asm moves this into rax before returning so be safe?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,11 @@ namespace Dalamud.Game.Gui
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr GetAgentModule { get; private set; }
|
public IntPtr GetAgentModule { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the native Utf8StringFromSequence method.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Utf8StringFromSequence { get; private set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override void Setup64Bit(SigScanner sig)
|
protected override void Setup64Bit(SigScanner sig)
|
||||||
{
|
{
|
||||||
|
|
@ -88,6 +93,7 @@ namespace Dalamud.Game.Gui
|
||||||
this.GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
|
this.GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
|
||||||
this.ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
|
this.ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
|
||||||
this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??");
|
this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??");
|
||||||
|
this.Utf8StringFromSequence = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8D 41 22 66 C7 41 ?? ?? ?? 48 89 01 49 8B D8");
|
||||||
|
|
||||||
var uiModuleVtableSig = sig.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 4C 89 61 28");
|
var uiModuleVtableSig = sig.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 4C 89 61 28");
|
||||||
this.GetAgentModule = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size);
|
this.GetAgentModule = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ namespace Dalamud.Game.Text
|
||||||
/// </summary>
|
/// </summary>
|
||||||
HighQuality = 0xE03C,
|
HighQuality = 0xE03C,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The collectible icon unicode character.
|
||||||
|
/// </summary>
|
||||||
|
Collectible = 0xE03D,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The clock icon unicode character.
|
/// The clock icon unicode character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -5,6 +6,7 @@ using System.Text;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
|
|
@ -22,7 +24,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
||||||
private string? displayName;
|
private string? displayName;
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private uint itemId;
|
private uint rawItemId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ItemPayload"/> class.
|
/// 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>
|
/// TextPayload that is a part of a full item link in chat.</param>
|
||||||
public ItemPayload(uint itemId, bool isHq, string? displayNameOverride = null)
|
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.Kind = isHq ? ItemKind.Hq : ItemKind.Normal;
|
||||||
this.displayName = displayNameOverride;
|
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>
|
/// TextPayload that is a part of a full item link in chat.</param>
|
||||||
public ItemPayload(uint itemId, ItemKind kind = ItemKind.Normal, string? displayNameOverride = null)
|
public ItemPayload(uint itemId, ItemKind kind = ItemKind.Normal, string? displayNameOverride = null)
|
||||||
{
|
{
|
||||||
this.itemId = itemId;
|
|
||||||
this.Kind = kind;
|
this.Kind = kind;
|
||||||
|
this.rawItemId = itemId;
|
||||||
|
if (kind != ItemKind.EventItem)
|
||||||
|
this.rawItemId += (uint)kind;
|
||||||
|
|
||||||
this.displayName = displayNameOverride;
|
this.displayName = displayNameOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,10 +120,16 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the raw item ID of this payload.
|
/// Gets the actual item ID of this payload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[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>
|
/// <summary>
|
||||||
/// Gets the underlying Lumina Item represented by this payload.
|
/// 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.
|
/// The value is evaluated lazily and cached.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[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>
|
/// <summary>
|
||||||
/// Gets a value indicating whether or not this item link is for a high-quality version of the item.
|
/// 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/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
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/>
|
/// <inheritdoc/>
|
||||||
protected override byte[] EncodeImpl()
|
protected override byte[] EncodeImpl()
|
||||||
{
|
{
|
||||||
var actualItemId = this.itemId - (uint)this.Kind;
|
var idBytes = MakeInteger(this.rawItemId);
|
||||||
|
|
||||||
var idBytes = MakeInteger(actualItemId);
|
|
||||||
var hasName = !string.IsNullOrEmpty(this.displayName);
|
var hasName = !string.IsNullOrEmpty(this.displayName);
|
||||||
|
|
||||||
var chunkLen = idBytes.Length + 4;
|
var chunkLen = idBytes.Length + 4;
|
||||||
|
|
@ -218,10 +244,8 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override void DecodeImpl(BinaryReader reader, long endOfStream)
|
protected override void DecodeImpl(BinaryReader reader, long endOfStream)
|
||||||
{
|
{
|
||||||
var (id, kind) = GetAdjustedId(GetInteger(reader));
|
this.rawItemId = GetInteger(reader);
|
||||||
|
this.Kind = GetAdjustedId(this.rawItemId).Kind;
|
||||||
this.itemId = id;
|
|
||||||
this.Kind = kind;
|
|
||||||
|
|
||||||
if (reader.BaseStream.Position + 3 < endOfStream)
|
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),
|
> 500_000 and < 1_000_000 => (rawItemId - 500_000, ItemKind.Collectible),
|
||||||
> 1_000_000 and < 2_000_000 => (rawItemId - 1_000_000, ItemKind.Hq),
|
> 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),
|
_ => (rawItemId, ItemKind.Normal),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
||||||
public class TextPayload : Payload, ITextProvider
|
public class TextPayload : Payload, ITextProvider
|
||||||
{
|
{
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private string text;
|
private string? text;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TextPayload"/> class.
|
/// Initializes a new instance of the <see cref="TextPayload"/> class.
|
||||||
/// Creates a new TextPayload for the given text.
|
/// Creates a new TextPayload for the given text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The text to include for this payload.</param>
|
/// <param name="text">The text to include for this payload.</param>
|
||||||
public TextPayload(string text)
|
public TextPayload(string? text)
|
||||||
{
|
{
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
@ -41,12 +41,9 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
||||||
/// This may contain SE's special unicode characters.
|
/// This may contain SE's special unicode characters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string Text
|
public string? Text
|
||||||
{
|
{
|
||||||
get
|
get => this.text;
|
||||||
{
|
|
||||||
return this.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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="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>
|
/// <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>
|
/// <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 data = Service<DataManager>.Get();
|
||||||
|
|
||||||
var displayName = displayNameOverride ?? data.GetExcelSheet<Item>()?.GetRow(itemId)?.Name;
|
var displayName = displayNameOverride;
|
||||||
if (isHq)
|
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}";
|
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
|
// TODO: probably a cleaner way to build these than doing the bulk+insert
|
||||||
var payloads = new List<Payload>(new Payload[]
|
var payloads = new List<Payload>(new Payload[]
|
||||||
{
|
{
|
||||||
new UIForegroundPayload(0x0225),
|
new UIForegroundPayload(0x0225),
|
||||||
new UIGlowPayload(0x0226),
|
new UIGlowPayload(0x0226),
|
||||||
new ItemPayload(itemId, isHq),
|
new ItemPayload(itemId, kind),
|
||||||
// arrow goes here
|
// arrow goes here
|
||||||
new TextPayload(displayName),
|
new TextPayload(displayName),
|
||||||
RawPayload.LinkTerminator,
|
RawPayload.LinkTerminator,
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,14 @@ namespace Dalamud.Game.Text.SeStringHandling
|
||||||
public SeStringBuilder AddItemLink(uint itemId, ItemPayload.ItemKind kind, string? itemNameOverride = null) =>
|
public SeStringBuilder AddItemLink(uint itemId, ItemPayload.ItemKind kind, string? itemNameOverride = null) =>
|
||||||
this.Add(new ItemPayload(itemId, kind, itemNameOverride));
|
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>
|
/// <summary>
|
||||||
/// Add italicized raw text to the builder.
|
/// Add italicized raw text to the builder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.Gui;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
using ImGuiNET;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Test setup for item payloads.
|
||||||
|
/// </summary>
|
||||||
|
internal class ItemPayloadAgingStep : IAgingStep
|
||||||
|
{
|
||||||
|
private SubStep currentSubStep;
|
||||||
|
|
||||||
|
private enum SubStep
|
||||||
|
{
|
||||||
|
PrintNormalItem,
|
||||||
|
HoverNormalItem,
|
||||||
|
PrintHqItem,
|
||||||
|
HoverHqItem,
|
||||||
|
PrintCollectable,
|
||||||
|
HoverCollectable,
|
||||||
|
PrintEventItem,
|
||||||
|
HoverEventItem,
|
||||||
|
PrintNormalWithText,
|
||||||
|
HoverNormalWithText,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string Name => "Item Payloads";
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public SelfTestStepResult RunStep()
|
||||||
|
{
|
||||||
|
var gameGui = Service<GameGui>.Get();
|
||||||
|
var chatGui = Service<ChatGui>.Get();
|
||||||
|
|
||||||
|
const uint normalItemId = 24002; // Capybara pup
|
||||||
|
const uint hqItemId = 31861; // Exarchic circlets of healing
|
||||||
|
const uint collectableItemId = 36299; // Rarefied Annite
|
||||||
|
const uint eventItemId = 2003363; // Speude bradeos figurine
|
||||||
|
|
||||||
|
SeString? toPrint = null;
|
||||||
|
|
||||||
|
ImGui.Text(this.currentSubStep.ToString());
|
||||||
|
|
||||||
|
switch (this.currentSubStep)
|
||||||
|
{
|
||||||
|
case SubStep.PrintNormalItem:
|
||||||
|
toPrint = SeString.CreateItemLink(normalItemId);
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.HoverNormalItem:
|
||||||
|
ImGui.Text("Hover the item.");
|
||||||
|
if (gameGui.HoveredItem != normalItemId)
|
||||||
|
return SelfTestStepResult.Waiting;
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.PrintHqItem:
|
||||||
|
toPrint = SeString.CreateItemLink(hqItemId, ItemPayload.ItemKind.Hq);
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.HoverHqItem:
|
||||||
|
ImGui.Text("Hover the item.");
|
||||||
|
if (gameGui.HoveredItem != 1_000_000 + hqItemId)
|
||||||
|
return SelfTestStepResult.Waiting;
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.PrintCollectable:
|
||||||
|
toPrint = SeString.CreateItemLink(collectableItemId, ItemPayload.ItemKind.Collectible);
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.HoverCollectable:
|
||||||
|
ImGui.Text("Hover the item.");
|
||||||
|
if (gameGui.HoveredItem != 500_000 + collectableItemId)
|
||||||
|
return SelfTestStepResult.Waiting;
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.PrintEventItem:
|
||||||
|
toPrint = SeString.CreateItemLink(eventItemId, ItemPayload.ItemKind.EventItem);
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.HoverEventItem:
|
||||||
|
ImGui.Text("Hover the item.");
|
||||||
|
if (gameGui.HoveredItem != eventItemId)
|
||||||
|
return SelfTestStepResult.Waiting;
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.PrintNormalWithText:
|
||||||
|
toPrint = SeString.CreateItemLink(normalItemId, displayNameOverride: "Gort");
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.HoverNormalWithText:
|
||||||
|
ImGui.Text("Hover the item.");
|
||||||
|
if (gameGui.HoveredItem != normalItemId)
|
||||||
|
return SelfTestStepResult.Waiting;
|
||||||
|
this.currentSubStep++;
|
||||||
|
break;
|
||||||
|
case SubStep.Done:
|
||||||
|
return SelfTestStepResult.Pass;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toPrint != null)
|
||||||
|
chatGui.Print(toPrint);
|
||||||
|
|
||||||
|
return SelfTestStepResult.Waiting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void CleanUp()
|
||||||
|
{
|
||||||
|
this.currentSubStep = SubStep.PrintNormalItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
|
|
@ -26,6 +27,7 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest
|
||||||
new LoginEventAgingStep(),
|
new LoginEventAgingStep(),
|
||||||
new WaitFramesAgingStep(1000),
|
new WaitFramesAgingStep(1000),
|
||||||
new EnterTerritoryAgingStep(148, "Central Shroud"),
|
new EnterTerritoryAgingStep(148, "Central Shroud"),
|
||||||
|
new ItemPayloadAgingStep(),
|
||||||
new ActorTableAgingStep(),
|
new ActorTableAgingStep(),
|
||||||
new FateTableAgingStep(),
|
new FateTableAgingStep(),
|
||||||
new AetheryteListAgingStep(),
|
new AetheryteListAgingStep(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue