feat(ui): port retail radar and compass

This commit is contained in:
Erik 2026-07-10 16:14:37 +02:00
parent c4af181b92
commit 3cbe4b00a1
43 changed files with 2882 additions and 262 deletions

View file

@ -172,6 +172,70 @@ public sealed class CreateObjectTests
Assert.Equal((uint)ItemType.Creature, parsed!.Value.TargetType);
}
// -----------------------------------------------------------------------
// Retail radar: PublicWeenieDesc carries two independently gated bytes.
// Absence is distinct from an explicitly transmitted zero because zero is
// the enum's undefined/default value, not proof the field was omitted.
// -----------------------------------------------------------------------
[Fact]
public void TryParse_NoRadarFlags_LeavesRadarFieldsNull()
{
byte[] body = BuildMinimalCreateObjectWithWeenieHeader(
guid: 0x5000000Au,
name: "Unspecified Radar Object",
itemType: (uint)ItemType.Misc);
var parsed = CreateObject.TryParse(body);
Assert.NotNull(parsed);
Assert.Null(parsed.Value.RadarBlipColor);
Assert.Null(parsed.Value.RadarBehavior);
}
[Fact]
public void TryParse_RadarFlags_CapturesBothBytesAndContinuesTailWalk()
{
const uint radarBlipColorFlag = 0x00100000u;
const uint radarBehaviorFlag = 0x00800000u;
const uint workmanshipFlag = 0x01000000u;
byte[] body = BuildMinimalCreateObjectWithWeenieHeader(
guid: 0x5000000Bu,
name: "Radar Portal",
itemType: (uint)ItemType.Portal,
weenieFlags: radarBlipColorFlag | radarBehaviorFlag | workmanshipFlag,
radarBlipColor: 4,
radarBehavior: 4,
workmanship: 6.25f);
var parsed = CreateObject.TryParse(body);
Assert.NotNull(parsed);
Assert.Equal((byte)4, parsed.Value.RadarBlipColor);
Assert.Equal((byte)4, parsed.Value.RadarBehavior);
Assert.Equal(6.25f, parsed.Value.Workmanship);
}
[Fact]
public void TryParse_RadarFlagsWithZero_PreservesExplicitDefaultValues()
{
byte[] body = BuildMinimalCreateObjectWithWeenieHeader(
guid: 0x5000000Cu,
name: "Explicit Radar Defaults",
itemType: (uint)ItemType.Misc,
weenieFlags: 0x00100000u | 0x00800000u,
radarBlipColor: 0,
radarBehavior: 0);
var parsed = CreateObject.TryParse(body);
Assert.NotNull(parsed);
Assert.True(parsed.Value.RadarBlipColor.HasValue);
Assert.Equal((byte)0, parsed.Value.RadarBlipColor.Value);
Assert.True(parsed.Value.RadarBehavior.HasValue);
Assert.Equal((byte)0, parsed.Value.RadarBehavior.Value);
}
// -----------------------------------------------------------------------
// 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.
@ -500,6 +564,8 @@ public sealed class CreateObjectTests
uint? currentWieldedLocation = null,
uint? priority = null,
float? workmanship = null,
byte? radarBlipColor = null,
byte? radarBehavior = null,
ushort movementSeq = 0)
{
var bytes = new List<byte>();
@ -562,8 +628,8 @@ public sealed class CreateObjectTests
if ((weenieFlags & 0x00010000u) != 0) WriteU32(bytes, validLocations ?? 0); // ValidLocations u32
if ((weenieFlags & 0x00020000u) != 0) WriteU32(bytes, currentWieldedLocation ?? 0); // CurrentlyWieldedLocation u32
if ((weenieFlags & 0x00040000u) != 0) WriteU32(bytes, priority ?? 0); // Priority u32
if ((weenieFlags & 0x00100000u) != 0) bytes.Add(0); // RadarBlipColor u8
if ((weenieFlags & 0x00800000u) != 0) bytes.Add(0); // RadarBehavior u8
if ((weenieFlags & 0x00100000u) != 0) bytes.Add(radarBlipColor ?? 0); // RadarBlipColor u8
if ((weenieFlags & 0x00800000u) != 0) bytes.Add(radarBehavior ?? 0); // RadarBehavior u8
if ((weenieFlags & 0x08000000u) != 0) WriteU16(bytes, 0); // PScript u16
if ((weenieFlags & 0x01000000u) != 0) // Workmanship f32
{