Reorganized input
This commit is contained in:
@@ -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)
|
||||
Reference in New Issue
Block a user