fix(ui): match retail item appraisal semantics
Preserve PublicWeenieDesc hook identity from CreateObject through the item model so hook appraisals suppress sentinel capacities exactly. Use appraisal-only Value and Burden presence, retain AddItemInfo paragraph and authored font-color selection, and port retail lock, page, enchantment, and spell-block formatting. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
bc47bc4917
commit
d3c5e06fdd
21 changed files with 982 additions and 145 deletions
|
|
@ -184,6 +184,11 @@ public static class CreateObject
|
|||
int? Burden = null,
|
||||
int? ItemsCapacity = null,
|
||||
int? ContainersCapacity = null,
|
||||
// PublicWeenieDesc hook identity. ACCWeenieObject::IsHook
|
||||
// @ 0x0058C660 requires both values to be non-zero.
|
||||
// The wire stores HookItemTypes as u32 and HookType as u16.
|
||||
uint? HookItemTypes = null,
|
||||
uint? HookType = null,
|
||||
uint? ContainerId = null,
|
||||
uint? WielderId = null,
|
||||
uint? ValidLocations = null,
|
||||
|
|
@ -778,6 +783,8 @@ public static class CreateObject
|
|||
int? wBurden = null;
|
||||
int? wItemsCapacity = null;
|
||||
int? wContainersCapacity = null;
|
||||
uint? wHookItemTypes = null;
|
||||
uint? wHookType = null;
|
||||
uint? wContainerId = null;
|
||||
uint? wWielderId = null;
|
||||
uint? wValidLocations = null;
|
||||
|
|
@ -852,9 +859,9 @@ public static class CreateObject
|
|||
// 0x00400000 Spell u16 (skip)
|
||||
// 0x02000000 HouseOwner u32 (skip)
|
||||
// 0x04000000 HouseRestrictions RestrictionDB (skip, variable-length)
|
||||
// 0x20000000 HookItemTypes u32 (skip)
|
||||
// 0x20000000 HookItemTypes u32 CAPTURE
|
||||
// 0x00000040 Monarch u32 (skip)
|
||||
// 0x10000000 HookType u16 (skip)
|
||||
// 0x10000000 HookType u16 CAPTURE
|
||||
// 0x40000000 IconOverlay PackedDwordKnownType(0x06000000) CAPTURE
|
||||
// weenieFlags2 bit 0x01:
|
||||
// IconUnderlay PackedDwordKnownType(0x06000000) CAPTURE
|
||||
|
|
@ -1050,7 +1057,7 @@ public static class CreateObject
|
|||
if ((weenieFlags & 0x20000000u) != 0) // HookItemTypes u32
|
||||
{
|
||||
if (body.Length - pos < 4) throw new FormatException("trunc HookItemTypes");
|
||||
pos += 4;
|
||||
wHookItemTypes = ReadU32(body, ref pos);
|
||||
}
|
||||
if ((weenieFlags & 0x00000040u) != 0) // Monarch u32
|
||||
{
|
||||
|
|
@ -1060,6 +1067,7 @@ public static class CreateObject
|
|||
if ((weenieFlags & 0x10000000u) != 0) // HookType u16
|
||||
{
|
||||
if (body.Length - pos < 2) throw new FormatException("trunc HookType");
|
||||
wHookType = BinaryPrimitives.ReadUInt16LittleEndian(body.Slice(pos));
|
||||
pos += 2;
|
||||
}
|
||||
if ((weenieFlags & 0x40000000u) != 0) // IconOverlay PackedDwordOfKnownType(0x06000000) ← CAPTURE
|
||||
|
|
@ -1117,6 +1125,7 @@ public static class CreateObject
|
|||
WeenieClassId: weenieClassId,
|
||||
Value: wValue, StackSize: wStackSize, StackSizeMax: wMaxStackSize,
|
||||
Burden: wBurden, ItemsCapacity: wItemsCapacity, ContainersCapacity: wContainersCapacity,
|
||||
HookItemTypes: wHookItemTypes, HookType: wHookType,
|
||||
ContainerId: wContainerId, WielderId: wWielderId,
|
||||
ValidLocations: wValidLocations, CurrentWieldedLocation: wCurrentWieldedLocation,
|
||||
Priority: wPriority, Structure: wStructure, MaxStructure: wMaxStructure,
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ public static class ObjectTableWiring
|
|||
Priority: s.Priority,
|
||||
ItemsCapacity: s.ItemsCapacity,
|
||||
ContainersCapacity: s.ContainersCapacity,
|
||||
HookItemTypes: s.HookItemTypes,
|
||||
HookType: s.HookType,
|
||||
Structure: s.Structure,
|
||||
MaxStructure: s.MaxStructure,
|
||||
Workmanship: s.Workmanship,
|
||||
|
|
|
|||
|
|
@ -156,7 +156,9 @@ public sealed class WorldSession : IDisposable
|
|||
uint? SpellId = null,
|
||||
uint? CooldownId = null,
|
||||
double? CooldownDuration = null,
|
||||
PhysicsSpawnData? Physics = null);
|
||||
PhysicsSpawnData? Physics = null,
|
||||
uint? HookItemTypes = null,
|
||||
uint? HookType = null);
|
||||
|
||||
/// <summary>
|
||||
/// Projects the wire-level CreateObject result into the stable session
|
||||
|
|
@ -219,7 +221,9 @@ public sealed class WorldSession : IDisposable
|
|||
SpellId: parsed.SpellId,
|
||||
CooldownId: parsed.CooldownId,
|
||||
CooldownDuration: parsed.CooldownDuration,
|
||||
Physics: parsed.Physics);
|
||||
Physics: parsed.Physics,
|
||||
HookItemTypes: parsed.HookItemTypes,
|
||||
HookType: parsed.HookType);
|
||||
|
||||
/// <summary>Fires when the session finishes parsing a CreateObject.</summary>
|
||||
public event Action<EntitySpawn>? EntitySpawned;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue