fix(net): sign-extend retail capacity bytes
Mirror PublicWeenieDesc::UnPack MOVSX behavior so ACE's FF capacity sentinels remain -1 instead of becoming 255. This suppresses non-container capacity prose through the normal retail appraisal checks, with raw-wire and formatter regression coverage. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
d3c5e06fdd
commit
2c00d53db2
7 changed files with 101 additions and 41 deletions
|
|
@ -808,9 +808,11 @@ public static class ItemAppraisalTextFormatter
|
|||
AppraiseInfoParser.Parsed appraisal)
|
||||
{
|
||||
PropertyBundle properties = appraisal.Properties;
|
||||
// Appraisal_ShowCapacity @ 0x004B2680 suppresses the hook object's
|
||||
// own container capacity while a HookProfile describes the item
|
||||
// mounted on it. This is the Black Phyntos Hive 255/255 case.
|
||||
// Appraisal_ShowCapacity @ 0x004B2680 suppresses a hook object's own
|
||||
// capacity while a HookProfile describes the item mounted on it.
|
||||
// Non-container sentinels are independently preserved as -1 by
|
||||
// PublicWeenieDesc::UnPack's signed-byte loads, so they fail the
|
||||
// positive-capacity tests below exactly as they do in retail.
|
||||
if (!obj.IsHook || appraisal.HookProfile is null)
|
||||
{
|
||||
if (obj.ItemsCapacity > 0 && obj.ContainersCapacity > 0)
|
||||
|
|
|
|||
|
|
@ -833,8 +833,8 @@ public static class CreateObject
|
|||
// --------- ------------------ -----
|
||||
// 0x04000000 (objDescFlags) weenieFlags2 u32 (skip)
|
||||
// 0x00000001 PluralName String16L CAPTURE
|
||||
// 0x00000002 ItemsCapacity u8 (skip)
|
||||
// 0x00000004 ContainersCapacity u8 (skip)
|
||||
// 0x00000002 ItemsCapacity s8 -> int CAPTURE
|
||||
// 0x00000004 ContainersCapacity s8 -> int CAPTURE
|
||||
// 0x00000100 AmmoType u16 (skip)
|
||||
// 0x00000008 Value u32 (skip)
|
||||
// 0x00000010 Usable u32 KEPT
|
||||
|
|
@ -905,15 +905,22 @@ public static class CreateObject
|
|||
if ((weenieFlags & 0x00000001u) != 0) // PluralName
|
||||
pluralName = ReadString16L(body, ref pos);
|
||||
|
||||
if ((weenieFlags & 0x00000002u) != 0) // ItemsCapacity u8
|
||||
if ((weenieFlags & 0x00000002u) != 0) // ItemsCapacity s8 -> int
|
||||
{
|
||||
if (body.Length - pos < 1) throw new FormatException("trunc ItemCap");
|
||||
wItemsCapacity = body[pos]; pos += 1;
|
||||
// PublicWeenieDesc::UnPack @ 0x005AD52C uses MOVSX.
|
||||
// ACE stores the creature/non-container sentinel -1 as
|
||||
// 0xFF; retail retains -1 rather than turning it into 255.
|
||||
wItemsCapacity = unchecked((sbyte)body[pos]);
|
||||
pos += 1;
|
||||
}
|
||||
if ((weenieFlags & 0x00000004u) != 0) // ContainersCapacity u8
|
||||
if ((weenieFlags & 0x00000004u) != 0) // ContainersCapacity s8 -> int
|
||||
{
|
||||
if (body.Length - pos < 1) throw new FormatException("trunc ContCap");
|
||||
wContainersCapacity = body[pos]; pos += 1;
|
||||
// PublicWeenieDesc::UnPack @ 0x005AD53E likewise uses
|
||||
// MOVSX before assigning the 32-bit public field.
|
||||
wContainersCapacity = unchecked((sbyte)body[pos]);
|
||||
pos += 1;
|
||||
}
|
||||
if ((weenieFlags & 0x00000100u) != 0) // AmmoType u16
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue