acdream/src/AcDream.Core.Net/Messages
Erik 58e155615d feat(B.8): retail useability gate + tall-scenery indicator scaling
Two retail divergences fixed end-to-end:

1. R-key Use on non-useable entities (signs, banners, decorative
   scenery) was silently sending Use/PickUp to ACE, triggering
   auto-walk + NPC-style chat fallback. Retail's client checks
   ITEM_USEABLE (acclient.h:6478) and silently ignores Use when
   the USEABLE_REMOTE (0x20) bit isn't set. Now ports that gate.

2. Holtburg town sign indicator + click sphere only covered the
   base of the pole because the "everything else" default in
   EntityHeightFor was 1.5 m and the picker's vertical offset
   for default class was 0.2 m. A 3 m sign on a pole was almost
   entirely outside both shapes.

Wire change:
- CreateObject parser now walks the WeenieHeader optional tail
  (per ACE WorldObject_Networking.cs:87-114) up through Useability
  + UseRadius. Captures weenieFlags upfront, then conditionally
  skips PluralName, ItemCapacity, ContainerCapacity, AmmoType,
  Value before reading Useability (u32) and UseRadius (f32).
- CreateObject.Parsed + WorldSession.EntitySpawn record append two
  new optional fields (Useability uint?, UseRadius float?), both
  defaulting to null. Existing call sites unchanged.
- 3 new tests cover: no weenieFlags → null, weenieFlags=0x10 alone
  → useability read, weenieFlags=0x8|0x10|0x20 → walker skips Value
  then reads Useability + UseRadius in correct order.

Behaviour change:
- GameWindow.IsUseableTarget(guid) — authoritative path uses spawn
  .Useability when present (REMOTE bit gate); fallback when null
  permits Use on creatures + BF_DOOR/LIFESTONE/PORTAL/CORPSE for
  M1 flow continuity.
- UseCurrentSelection (R-key dispatcher) and SendUse + SendPickUp
  (double-click + F-key direct paths) gate on IsUseableTarget,
  silent early-return matching retail. isRetryAfterArrival skips
  the gate (re-fires only previously-gated actions).
- TargetIndicatorPanel.EntityHeightFor default branch 1.5 m → 3 m
  for non-creature non-flat non-small-item entities (sign-class).
  Scale > 1 still grows proportionally.
- WorldPicker callbacks: new IsTallSceneryGuid branch lifts sphere
  centre to 1.5 m with 1.6 m radius for sign-class entities,
  mirroring the indicator's 3 m default so click sphere matches
  the visible box.

Tests: 293/293 pass in AcDream.Core.Net.Tests (+3 new walker
tests). dotnet build clean.

Retail anchors:
- acclient.h:6478 — ITEM_USEABLE enum (USEABLE_REMOTE = 0x20)
- acclient.h:6431-6463 — PWD bitfield (BF_DOOR etc.)
- ACE WorldObject_Networking.cs:87-114 — wire field order
- ACE WeenieHeaderFlag — Usable = 0x10, UseRadius = 0x20

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 20:07:32 +02:00
..
AllegianceRequests.cs feat(allegiance): Phase H.2 AllegianceRequests + AllegianceTree model 2026-04-18 17:17:45 +02:00
AppraiseInfoParser.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
AppraiseRequest.cs feat(items): Phase F.2 ItemRepository + AppraiseRequest round-trip 2026-04-18 16:55:36 +02:00
AttackTargetRequest.cs fix(net): Phase L.1c conform combat wire events 2026-04-28 10:54:50 +02:00
AutonomousPosition.cs feat(net): Phase B.2 — MoveToState + AutonomousPosition message builders 2026-04-12 14:28:35 +02:00
CastSpellRequest.cs feat(spells): Phase E.5 CastSpellRequest + Spellbook/enchantment state 2026-04-18 17:00:32 +02:00
CharacterActions.cs fix(net): Phase L.1c conform combat wire events 2026-04-28 10:54:50 +02:00
CharacterEnterWorld.cs feat(net): acdream enters the world — CharacterList parsed + CharacterEnterWorld sent + 68 CreateObject received (Phase 4.7) 2026-04-11 15:14:31 +02:00
CharacterList.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
ChatRequests.cs fix(chat): BuildTell wire field order + retail-style FormatEntry + suppress duplicate Channel echo 2026-04-25 20:49:02 +02:00
CreateObject.cs feat(B.8): retail useability gate + tall-scenery indicator scaling 2026-05-15 20:07:32 +02:00
DddInterrogationResponse.cs feat(net): Phase 4.10 — DddInterrogationResponse + correct LoginComplete trigger 2026-04-11 23:48:37 +02:00
DeleteObject.cs fix(anim): Phase L.1c route creature actions and despawns 2026-04-28 19:21:02 +02:00
EmoteText.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
Encodings.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
GameActionLoginComplete.cs feat(net): Phase 4.8 — send GameAction.LoginComplete after EnterWorld 2026-04-11 23:36:19 +02:00
GameEventDispatcher.cs feat(net): Phase F.1 GameEvent (0xF7B0) envelope dispatcher 2026-04-18 16:52:46 +02:00
GameEventEnvelope.cs feat(net): Phase F.1 GameEvent (0xF7B0) envelope dispatcher 2026-04-18 16:52:46 +02:00
GameEvents.cs fix(net): Phase L.1c conform combat wire events 2026-04-28 10:54:50 +02:00
GameEventType.cs feat(net): Phase F.1 GameEvent (0xF7B0) envelope dispatcher 2026-04-18 16:52:46 +02:00
GameMessageFragment.cs feat(net): acdream enters the world — CharacterList parsed + CharacterEnterWorld sent + 68 CreateObject received (Phase 4.7) 2026-04-11 15:14:31 +02:00
HearSpeech.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
InteractRequests.cs feat(B.5): InteractRequests.BuildPickUp — PutItemInContainer 0x0019 2026-05-14 15:01:24 +02:00
InventoryActions.cs feat(net): InventoryActions — stack merge/split + give + shortcut + poi recall 2026-04-19 10:28:35 +02:00
JumpAction.cs feat(movement): send jump packet to server (opcode 0xF61B) 2026-04-14 10:23:52 +02:00
MoveToState.cs fix(movement+anim+session): clothing dedup, motion wire format, jump-skill default 2026-04-18 15:01:32 +02:00
ObjDescEvent.cs feat(net): wire 0xF625 ObjDescEvent for live appearance updates 2026-05-06 10:46:14 +02:00
PickupEvent.cs fix(B.5): handle PickupEvent 0xF74A so picked-up items despawn locally 2026-05-14 16:13:16 +02:00
PlayerDescriptionParser.cs feat(net): #13 heuristic inventory locator after gameplay_options blob 2026-05-10 09:37:46 +02:00
PlayerKilled.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
PrivateUpdateVital.cs feat(player): #5 PlayerDescription parser — Stam/Mana via attribute block 2026-04-25 16:42:24 +02:00
ServerMessage.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
SetState.cs feat(phys L.2g slice 1): WorldSession dispatches SetState (0xF74B) + hex probe 2026-05-12 22:28:04 +02:00
SetTurbineChatChannels.cs feat(net+chat): #19 TurbineChat (0xF7DE) codec + ChatChannelInfo + SetTurbineChatChannels parser 2026-04-25 19:44:56 +02:00
SocialActions.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
SoulEmote.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
StringReader.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
TurbineChat.cs feat(net+chat): #19 TurbineChat (0xF7DE) codec + ChatChannelInfo + SetTurbineChatChannels parser 2026-04-25 19:44:56 +02:00
UpdateMotion.cs feat(anim): Phase L.1c port MoveTo path data + per-tick steer 2026-04-28 21:49:22 +02:00
UpdatePosition.cs feat(net): plumb IsGrounded through EntityPositionUpdate (L.3.2 Task 2) 2026-05-03 10:15:02 +02:00
VectorUpdate.cs fix(net): VectorUpdate parser was reading guid from opcode bytes — remote jumps invisible 2026-04-26 21:51:36 +02:00