using System;
using System.Buffers.Binary;
namespace AcDream.Core.Net.Messages;
///
/// Inbound PublicUpdatePropertyInt (0x02CE) — the server updates one
/// PropertyInt on a visible object (carries the object guid). Standalone
/// GameMessage, dispatched like / CreateObject.
///
///
/// The companion PrivateUpdatePropertyInt (0x02CD) targets the player's OWN
/// object (no guid) and is not parsed here — it has no item-icon impact.
///
///
/// Wire layout (ACE GameMessagePublicUpdatePropertyInt, size hint 17):
///
/// u32 opcode = 0x02CE
/// u8 sequence // single byte (ByteSequence.NextBytes) — see PrivateUpdateVital
/// u32 guid
/// u32 property // PropertyInt enum; UiEffects = 18
/// i32 value
///
/// The sequence is parsed-past but not honored (latest-wins; divergence DR-4).
///
public static class PublicUpdatePropertyInt
{
public const uint Opcode = 0x02CEu;
public readonly record struct Parsed(uint Guid, uint Property, int Value);
/// Parse a raw 0x02CE body. Returns null on opcode mismatch / truncation.
public static Parsed? TryParse(ReadOnlySpan body)
{
if (body.Length < 17) return null; // 4 + 1 + 4 + 4 + 4
if (BinaryPrimitives.ReadUInt32LittleEndian(body) != Opcode) return null;
int pos = 4;
pos += 1; // sequence byte (not honored)
uint guid = BinaryPrimitives.ReadUInt32LittleEndian(body[pos..]); pos += 4;
uint prop = BinaryPrimitives.ReadUInt32LittleEndian(body[pos..]); pos += 4;
int value = BinaryPrimitives.ReadInt32LittleEndian(body[pos..]);
return new Parsed(guid, prop, value);
}
}