Commit graph

7 commits

Author SHA1 Message Date
Erik
2c8620ea94 feat(L.1b): dual MotionCommand catalog — AceModern runtime + Retail2013 conformance
Splits MotionCommandResolver's single ACE-modern lookup into an
IMotionCommandCatalog seam with two implementations:

- AceModernCommandCatalog (runtime default): built cleanly from the
  DatReaderWriter MotionCommand enum (mirrors ACE + local DAT MotionTables)
  with a documented class-priority tiebreak. The old blind 0x016E-0x0197
  per-range override is DELETED — verified the ACE matrix (LifestoneRecall
  0x0153 to 0x10000153, MarketplaceRecall 0x0166, AllegianceHometownRecall
  0x0171, OffhandSlashHigh 0x0173) resolves correctly straight from the enum
  with no override. Stale shift-start comment corrected to SnowAngelState
  (0x43000115 to 0x43000118), not AllegianceHometownRecall.
- Retail2013CommandCatalog (conformance/reference): full verbatim extraction
  of command_ids[0x198] at 0x007c73e8 (acclient_2013_pseudo_c.txt:1017259-1017667),
  direct wire-low to full index lookup. 408 entries, anchors verified against
  source ([0x150]=0x10000150, [0x153]=0x09000153, [0x197]=0x10000197).

MotionCommandResolver.ReconstructFullCommand stays a static facade delegating
to an AceModern singleton — all ~10 runtime callers unchanged.

Removing the override exposed a pre-existing bug: CombatAnimationPlanner's
late-combat command block uses 2013 numbering, not ACE/DRW. Corrected the one
catalog test assertion pinned to the override's output (wire 0x0170 to
0x09000170 IssueSlashCommand, its true DRW identity) and filed the planner bug
as #159 rather than silently patching out-of-scope code.

Tests: +catalog matrices (ACE/2013), class-priority collisions, boundary
cases, real-DAT availability (gap-doc hit counts reproduced). Build + full
suite green (Core.Tests 1718, no regressions).

Spec: docs/superpowers/specs/2026-06-30-movement-wire-parity-design.md (1)
Research: docs/research/2026-06-26-ace-vs-2013-motion-command-gap.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:13:36 +02:00
Erik
4874d8595a feat(combat): Phase L.1c wire live attack input 2026-04-28 11:58:57 +02:00
Erik
646246ba84 feat(anim): Phase L.1c select combat maneuvers 2026-04-28 11:44:17 +02:00
Erik
831392a7b2 feat(anim): Phase L.1c classify combat animation commands 2026-04-28 11:37:49 +02:00
Erik
268af82e28 fix(combat): Phase L.1c align attack type flags 2026-04-28 10:59:29 +02:00
Erik
25b9616703 feat(combat): Phase L.1c add outbound combat actions 2026-04-28 10:57:12 +02:00
Erik
2e3f9d7a04 feat(combat): Phase E.4 AttackTargetRequest + combat notification pipeline
Completes the client-side combat loop: send attacks, receive server's
damage broadcasts, maintain per-entity health state for HP bars +
damage floaters. All atop Phase F.1's GameEvent dispatcher.

Wire layer:
- AttackTargetRequest (0x0008 C→S, inside 0xF7B1): targetGuid +
  powerLevel + accuracyLevel + attackHeight. 28-byte body.
- GameEvents parsers for all combat notifications from r08 §4:
  - VictimNotification (0x01AC) — you got hit, full details
  - KillerNotification (0x01AD) — you killed X
  - AttackerNotification (0x01B1) — you hit X for Y (damage%)
  - DefenderNotification (0x01B2) — X hit you
  - EvasionAttackerNotification (0x01B3) — X evaded
  - EvasionDefenderNotification (0x01B4) — you evaded X
  - AttackDone (0x01A7) — attack sequence completed

Core layer:
- CombatState: per-entity health-percent cache + typed events
  (HealthChanged, DamageTaken, DamageDealtAccepted, EvadedIncoming,
  MissedOutgoing, AttackDone). Each event carries enough detail for
  the UI to render damage floaters, HP bars, and a combat log panel.
  Server is authoritative; client only mirrors state.

The server computes damage (armor, resist, crit, hit-chance); the
client only displays results. Predictive UI like "estimated damage
at 0.75 power" still works via the existing CombatMath helper class
that was in the scaffold (r02 §5 formulas).

Tests (13 new):
- AttackTargetRequest byte-exact wire encoding
- VictimNotification / AttackerNotification / EvasionAttacker /
  AttackDone round-trip parse.
- CombatState: UpdateHealth caches + fires, Victim fires DamageTaken,
  Attacker fires DamageDealt, Evasion routes to right event, AttackDone
  carries sequence+error, Clear resets cache.

Build green, 544 tests pass (up from 532).

Ref: r02 §7 (wire formats), r08 §4 (event payloads), ACE
GameEvent*Notification.cs families.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 16:58:14 +02:00