feat(net): wire IdentifyObjectResponse into ItemRepository + Spellbook

GameEventWiring now registers a handler for
GameEventType.IdentifyObjectResponse (0x00C9) that:

1. Runs AppraiseInfoParser.TryParse to extract the full property bundle.
2. If the item is in the repository, merges the bundle into its
   Properties via ItemRepository.UpdateProperties (fires
   ItemPropertiesUpdated).
3. Merges any SpellBook entries into Spellbook.OnSpellLearned (caster
   weapons list their cast-on-use spells; PlayerDescription reuses the
   same container for the player's learned set).

Effect: when the player clicks "Appraise" on an item, the tooltip
panel can read full property detail from ItemInstance.Properties
immediately after the server replies.

Build + 628 tests still green. No new test file needed — existing
AppraiseInfoParser tests cover the parse path; GameEventWiring round-
trip tests cover the dispatch path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-18 17:22:31 +02:00
parent e16f3315d2
commit 4d96156e05

View file

@ -151,5 +151,19 @@ public static class GameEventWiring
if (p is not null) items.MoveItem(p.Value.ItemGuid, p.Value.ContainerGuid,
newSlot: (int)p.Value.Placement);
});
dispatcher.Register(GameEventType.IdentifyObjectResponse, e =>
{
var p = AppraiseInfoParser.TryParse(e.Payload.Span);
if (p is null || !p.Value.Success) return;
// Merge parsed properties into the item if we know about it.
if (items.GetItem(p.Value.Guid) is not null)
items.UpdateProperties(p.Value.Guid, p.Value.Properties);
// Spell book from appraise: for ITEMS (caster / scrolls) this
// lists cast-on-use effects; for players (PlayerDescription)
// it's the whole learned spellbook. Both mutate the spellbook
// by adding any not-yet-known ids.
foreach (uint sid in p.Value.SpellBook)
spellbook.OnSpellLearned(sid);
});
}
}