feat(ui): port retail appraisal panel

Preserve retail's one-pending-appraisal busy lifetime, parse the complete gated response, and mount the authored examination layout in the shared main-panel host. Keep known 3D preview and inscription-write gaps explicit in AP-110.
This commit is contained in:
Erik 2026-07-23 11:34:08 +02:00
parent 6b1ae4fb76
commit 643cdfe66e
24 changed files with 17132 additions and 40 deletions

View file

@ -49,6 +49,50 @@ public sealed class GameEventWiringTests
return (dispatcher, items, combat, spellbook, chat);
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void WireAll_IdentifyObjectResponse_ForwardsCompleteResultAndMergesOnlySuccess(
bool success)
{
const uint guid = 0x50000001u;
var dispatcher = new GameEventDispatcher();
var items = new ClientObjectTable();
items.UpsertProperties(guid, new PropertyBundle());
AppraiseInfoParser.Parsed? received = null;
GameEventWiring.WireAll(
dispatcher,
items,
new CombatState(),
new Spellbook(),
new ChatLog(),
onAppraisal: appraisal => received = appraisal);
byte[] payload = new byte[24];
BinaryPrimitives.WriteUInt32LittleEndian(payload, guid);
BinaryPrimitives.WriteUInt32LittleEndian(
payload.AsSpan(4),
(uint)AppraiseInfoParser.IdentifyResponseFlags.IntStatsTable);
BinaryPrimitives.WriteUInt32LittleEndian(payload.AsSpan(8), success ? 1u : 0u);
BinaryPrimitives.WriteUInt16LittleEndian(payload.AsSpan(12), 1);
BinaryPrimitives.WriteUInt16LittleEndian(payload.AsSpan(14), 16);
BinaryPrimitives.WriteUInt32LittleEndian(payload.AsSpan(16), 25u);
BinaryPrimitives.WriteInt32LittleEndian(payload.AsSpan(20), 42);
GameEventEnvelope? envelope = GameEventEnvelope.TryParse(
WrapEnvelope(GameEventType.IdentifyObjectResponse, payload));
Assert.NotNull(envelope);
dispatcher.Dispatch(envelope.Value);
Assert.NotNull(received);
Assert.Equal(success, received.Value.Success);
Assert.Equal(42, received.Value.Properties.Ints[25u]);
if (success)
Assert.Equal(42, items.Get(guid)!.Properties.Ints[25u]);
else
Assert.False(items.Get(guid)!.Properties.Ints.ContainsKey(25u));
}
[Fact]
public void WireAll_ChannelBroadcast_RoutesToChatLog()