feat(D.5.1): capture IconId in CreateObject.Parsed (was discarded at cs:516)
ReadPackedDwordOfKnownType at the old line 516 was throwing the icon dat id away. Declare iconId before the try-block, assign it there, and pass IconId: iconId in the Parsed initializer so downstream UI (action bar / equipment panels) can read the 0x06xxxxxx dat id without a separate lookup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
30b28c248a
commit
da171cb4e3
2 changed files with 36 additions and 4 deletions
|
|
@ -127,6 +127,12 @@ public static class CreateObject
|
|||
// defaults (0.05f elasticity, 0.5f friction).
|
||||
float? Friction = null,
|
||||
float? Elasticity = null,
|
||||
// D.5.1 (2026-06-16): icon dat id (0x06xxxxxx) from the WeenieHeader
|
||||
// fixed prefix. Previously discarded at cs:516; surfaced so the action
|
||||
// bar / equipment UI can display the correct icon sprite without a
|
||||
// separate dat lookup. Zero means "not sent" (packed zero sentinel in
|
||||
// ReadPackedDwordOfKnownType preserves 0 as-is).
|
||||
uint IconId = 0,
|
||||
// 2026-05-15: optional WeenieHeader tail. The retail
|
||||
// `ITEM_USEABLE _useability` (acclient.h:6478) — gates whether the
|
||||
// R-key Use action does anything. <c>(Useability & USEABLE_REMOTE
|
||||
|
|
@ -506,6 +512,7 @@ public static class CreateObject
|
|||
string? name = null;
|
||||
uint? itemType = null;
|
||||
uint weenieFlags = 0;
|
||||
uint iconId = 0;
|
||||
if (body.Length - pos >= 4)
|
||||
{
|
||||
weenieFlags = ReadU32(body, ref pos);
|
||||
|
|
@ -513,7 +520,7 @@ public static class CreateObject
|
|||
{
|
||||
name = ReadString16L(body, ref pos);
|
||||
_ = ReadPackedDword(body, ref pos); // WeenieClassId
|
||||
_ = ReadPackedDwordOfKnownType(body, ref pos, IconTypePrefix);
|
||||
iconId = ReadPackedDwordOfKnownType(body, ref pos, IconTypePrefix);
|
||||
if (body.Length - pos >= 4)
|
||||
itemType = ReadU32(body, ref pos);
|
||||
if (body.Length - pos >= 4)
|
||||
|
|
@ -611,7 +618,8 @@ public static class CreateObject
|
|||
instanceSeq, teleportSeq, serverControlSeq, forcePositionSeq,
|
||||
physicsState, objectDescriptionFlags,
|
||||
friction, elasticity,
|
||||
useability, useRadius);
|
||||
IconId: iconId,
|
||||
Useability: useability, UseRadius: useRadius);
|
||||
|
||||
// Local helper: if we ran out of fields past PhysicsData, still
|
||||
// return the useful prefix (guid/position/setup/animParts/textures/palettes/scale/motion).
|
||||
|
|
|
|||
|
|
@ -156,6 +156,29 @@ public sealed class CreateObjectTests
|
|||
Assert.Equal(2.5f, parsed.Value.UseRadius!.Value, precision: 3);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// D.5.1 (2026-06-16): IconId was discarded at cs:516 — surface it so the
|
||||
// action bar / equipment UI can read icon dat ids from spawn messages.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void TryParse_IconId_Surfaced()
|
||||
{
|
||||
// Icon dat id 0x06001234: the wire writer strips the 0x06000000 prefix
|
||||
// before packing (WritePackedDwordOfKnownType strips it), so we write
|
||||
// 0x1234 as the packed value and expect 0x06001234 back.
|
||||
byte[] body = BuildMinimalCreateObjectWithWeenieHeader(
|
||||
guid: 0x50000009u,
|
||||
name: "SwordIcon",
|
||||
itemType: (uint)ItemType.MeleeWeapon,
|
||||
iconId: 0x1234u);
|
||||
|
||||
var parsed = CreateObject.TryParse(body);
|
||||
|
||||
Assert.NotNull(parsed);
|
||||
Assert.Equal(0x06001234u, parsed!.Value.IconId);
|
||||
}
|
||||
|
||||
private static byte[] BuildMinimalCreateObjectWithWeenieHeader(
|
||||
uint guid,
|
||||
string name,
|
||||
|
|
@ -163,6 +186,7 @@ public sealed class CreateObjectTests
|
|||
uint physicsState = 0,
|
||||
uint objectDescriptionFlags = 0,
|
||||
uint weenieFlags = 0,
|
||||
uint iconId = 0,
|
||||
uint? value = null,
|
||||
uint? useability = null,
|
||||
float? useRadius = null)
|
||||
|
|
@ -187,8 +211,8 @@ public sealed class CreateObjectTests
|
|||
// Fixed WeenieHeader prefix per ACE SerializeCreateObject.
|
||||
WriteU32(bytes, weenieFlags); // weenieFlags
|
||||
WriteString16L(bytes, name);
|
||||
WritePackedDword(bytes, 0x1234); // WeenieClassId
|
||||
WritePackedDword(bytes, 0); // IconId via known-type writer
|
||||
WritePackedDword(bytes, 0x1234); // WeenieClassId
|
||||
WritePackedDword(bytes, iconId); // IconId via known-type writer (prefix stripped by ACE writer)
|
||||
WriteU32(bytes, itemType);
|
||||
WriteU32(bytes, objectDescriptionFlags);
|
||||
Align4(bytes);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue