feat(ui): port retail item interaction policy

This commit is contained in:
Erik 2026-07-11 01:23:31 +02:00
parent 0cf780478a
commit a8da4fd05a
20 changed files with 1110 additions and 104 deletions

View file

@ -178,6 +178,14 @@ public sealed class ClientObject
public uint Priority { get; set; } // ClothingPriority / CoverageMask layer order
public uint? Useability { get; set; } // ITEM_USEABLE from PublicWeenieDesc
public uint? TargetType { get; set; } // ITEM_TYPE mask for targeted-use compatibility
/// <summary>Retail <c>PublicWeenieDesc._bitfield</c>; null until CreateObject supplies it.</summary>
public uint? PublicWeenieBitfield { get; set; }
/// <summary>Retail <c>PublicWeenieDesc._combatUse</c>; null when its header flag was absent.</summary>
public byte? CombatUse { get; set; }
/// <summary>Client-side trade state used by ItemHolder legality gates.</summary>
public int TradeState { get; set; }
/// <summary>Resolved membership in SpellComponentTable (retail IsComponentPack).</summary>
public bool IsComponentPack { get; set; }
/// <summary>Retail PublicWeenieDesc <c>_blipColor</c>; null until supplied by CreateObject.</summary>
public byte? RadarBlipColor { get; set; }
/// <summary>Retail PublicWeenieDesc <c>_radar_enum</c>; null until supplied by CreateObject.</summary>
@ -223,7 +231,9 @@ public readonly record struct WeenieData(
uint? Useability = null,
uint? TargetType = null,
byte? RadarBlipColor = null,
byte? RadarBehavior = null);
byte? RadarBehavior = null,
uint? PublicWeenieBitfield = null,
byte? CombatUse = null);
/// <summary>
/// Retail ITEM_USEABLE helpers (acclient.h:6478, ItemUses::* at 0x004fccd0).
@ -257,6 +267,18 @@ public static class ItemUseability
public static uint SourceFlags(uint useability)
=> useability & SourceMask;
/// <summary>Retail <c>ItemUses::GetLeastLimitedSourceUse</c>.</summary>
public static uint LeastLimitedSourceUse(uint useability)
{
uint s = SourceFlags(useability);
if ((s & Remote) != 0) return Remote;
if ((s & Viewed) != 0) return Viewed;
if ((s & Contained) != 0) return Contained;
if ((s & Wielded) != 0) return Wielded;
if ((s & Self) != 0) return Self;
return Undef;
}
public static uint TargetFlags(uint useability)
=> (useability & TargetMask) >> 16;