Reorganized input

This commit is contained in:
gamer147
2026-04-02 23:02:18 -04:00
parent b9030b7899
commit 2ad8686ad5
7 changed files with 533 additions and 75 deletions

View File

@@ -0,0 +1,94 @@
# Input Centralization Design
## Problem
Input handling is scattered across `PlayerController`, `CameraController`, and `TileHighlight`, each independently reading mouse state. There's no way to globally disable gameplay input during overlays or animations.
## Design
### PlayerController — single input authority
`PlayerController` becomes the only script that reads raw input. All other gameplay scripts react to its signals.
**Signals:**
| Signal | Emitted when |
|--------|-------------|
| `mouse_grid_changed(coords: Vector2i)` | Hovered grid cell changes (every frame check in `_process()`) |
| `camera_drag(delta: Vector2)` | Mouse is dragged (left-drag past 8px threshold, or any middle-drag) |
| `combat_requested(attacker, defender)` | Existing — click on enemy unit while friendly selected |
**Properties:**
| Property | Purpose |
|----------|---------|
| `input_disabled: bool` | When true, all input processing stops — no signals emitted, no click handling, no movement |
**Input handling (`_unhandled_input`):**
- Left click release (no drag): unit selection or movement target (existing logic)
- Left click release on enemy unit while friendly selected: emit `combat_requested` (existing logic)
- Left mouse drag: track press position, once delta exceeds 8px threshold, enter drag mode and emit `camera_drag(delta)` on each `InputEventMouseMotion`
- Middle mouse drag: immediately enter drag mode, emit `camera_drag(delta)` on each motion
- All of the above gated by `if input_disabled: return` at the top
**Mouse grid tracking (`_process`):**
- Read `get_global_mouse_position()`, snap to grid, convert to `Vector2i`
- If coords changed from previous frame, emit `mouse_grid_changed(coords)`
- Gated by `input_disabled`
**Left-drag vs left-click disambiguation:**
- On left button press: record press position, set `_drag_candidate = true`
- On mouse motion while `_drag_candidate`: if distance from press > 8px, enter drag mode (`_dragging = true`), stop treating this as a click
- On left button release: if `_dragging`, end drag and reset state; if not, treat as click (existing selection/movement logic)
- This matches the existing `CameraController` behavior
### CameraController — reactive
- Remove `_unhandled_input()` entirely
- Remove all drag detection state (`_dragging`, `_drag_start`, etc.)
- Expose a method (e.g., `apply_drag(delta: Vector2)`) or connect directly to `camera_drag` signal
- Apply delta to camera position, respecting any existing bounds/smoothing
### TileHighlight — reactive
- Remove `_process()` mouse tracking and `get_global_mouse_position()` calls
- Keep the pulse animation (can run in its own `_process` gated on visibility)
- Expose a method like `set_grid_coords(coords: Vector2i)` that positions the highlight
- Hide when input is disabled (connected to a signal or called directly)
- Keep `_notification` for `WM_MOUSE_EXIT` / `WM_MOUSE_ENTER` if still relevant, or remove if PlayerController handles this
### strategy_phase.gd — wiring
Connects signals in `_ready()`:
```
player_controller.mouse_grid_changed → tile_highlight.set_grid_coords (or similar)
player_controller.camera_drag → camera_controller.apply_drag
```
Overlays toggle input:
```
# When showing overlay:
player_controller.input_disabled = true
# When hiding overlay:
player_controller.input_disabled = false
```
## What doesn't change
- `CombatUI._unhandled_input()` for right-click dismiss — this is UI-layer input, not gameplay input
- Unit signals (`unit_died`, `unit_selected_changed`)
- CombatSystem logic
- All existing click behavior (selection, movement, combat requests) — just consolidated under the `input_disabled` gate
## Migration notes
- `CameraController` drag state variables and `_unhandled_input` are deleted, not left as dead code
- `TileHighlight._process` mouse reading is deleted
- `TileHighlight` keeps its `tile_size` export and grid-snapping math (used by `set_grid_coords`)
- PlayerController needs `dl_map` reference for grid coordinate conversion (already has it)