When a belt drag ends with the cursor over a non-belt building or construction
site, the end tile now snaps to the input-capable adjacent tile closest to the
cursor and points into the target, instead of showing an invalid ghost on the
occupied tile.
Adds BuildingSystem::getInputPorts(id) (reusing computeInputPorts, refactored
into a bodyCells+outputPorts core) as the single source of truth for a target's
input-capable adjacent tiles; works for both operational buildings (stored
inputPorts) and construction sites (mask-derived). GameWorldView tracks the
cursor world position and, in recomputeBeltDragPath, picks the nearest input
port and overrides the end tile's rotation. Ghost preview, resolve, and apply
consume the snapped path unchanged.
Implements REQ-BLD-BELT-DRAG snapping-to-a-building.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y7N59FsLA5e2kuVdqe4Uhc
Add deterministic record/playback for a run.
Recording captures `(seed, config hash, ordered tick-tagged commands)` and re-simulates on playback — no state snapshots. `DotaFactory.exe --replay <file>` re-plays a recorded run view-only with manual speed/pause.
Reviewed-on: #4
Co-authored-by: Malte Langkabel <malte.langkabel@gmail.com>
Co-committed-by: Malte Langkabel <malte.langkabel@gmail.com>