# **Combat State & Movement Specification**

This document defines the logic for managing the Turn-Based Combat Loop and the execution of Movement Actions.

## **1. TypeScript Interfaces (Data Models)**

```typescript
export type CombatPhase =
  | "INIT"
  | "TURN_START"
  | "WAITING_FOR_INPUT"
  | "EXECUTING_ACTION"
  | "TURN_END"
  | "COMBAT_END";

export interface CombatState {
  /** Whether combat is currently active */
  isActive: boolean;
  /** Current Round number */
  round: number;
  /** Ordered list of Unit IDs for the current round */
  turnQueue: string[];
  /** The ID of the unit currently taking their turn */
  activeUnitId: string | null;
  /** Current phase of the turn loop */
  phase: CombatPhase;
}

// src/types/Actions.ts

export interface ActionRequest {
  type: "MOVE" | "SKILL" | "ITEM" | "WAIT";
  sourceId: string;
  targetId?: string; // For targeted skills
  targetPosition?: { x: number; y: number; z: number }; // For movement/AoE
  skillId?: string;
  itemId?: string;
}

export interface MovementResult {
  success: boolean;
  path: { x: number; y: number; z: number }[];
  costAP: number;
  finalPosition: { x: number; y: number; z: number };
}
```

## **2. Conditions of Acceptance (CoA)**

These checks ensure the combat loop feels fair and responsive.

### **System: TurnSystem (src/systems/TurnSystem.js)**

- **CoA 1: Initiative Roll:** Upon starting combat, all active units must be sorted into the turnQueue based on their Speed stat (Highest First).
- **CoA 2: Turn Start Hygiene:** When a unit's turn begins:
  - Their currentAP must reset to baseAP.
  - Status effects (DoTs) must tick.
  - Cooldowns must decrement.
- **CoA 3: Cycling:** Calling endTurn() must move the activeUnitId to the next in the queue. If the queue is empty, increment round and re-roll/reset the queue.

### **System: MovementSystem (src/systems/MovementSystem.js)**

- **CoA 1: Validation:** Moving to a tile must fail if:
  - The tile is blocked/occupied.
  - No path exists.
  - The unit has insufficient AP for the _entire_ path.
- **CoA 2: Execution:** A successful move must:
  - Update the Unit's position in the UnitManager.
  - Update the VoxelGrid occupancy map.
  - Deduct the correct AP cost (including terrain modifiers).
- **CoA 3: Path Snapping:** If the user clicks a tile, but the unit only has AP to reach halfway, the system should allow moving to the _furthest reachable tile_ on that path (optional QoL).

## **3. Implementation Prompts**

Use these prompts to generate the specific logic files.

### **Prompt 1: The Turn System**

"Create src/systems/TurnSystem.js. It should manage the CombatState.

1. Implement startCombat(units): Sorts units by speed into turnQueue and sets phase to TURN_START.
2. Implement startTurn(): Refills the active unit's AP, processes cooldowns/statuses, and sets phase to WAITING_FOR_INPUT.
3. Implement endTurn(): Rotates the queue. If queue is empty, start new Round.
4. It should accept the UnitManager in the constructor to access unit stats.
5. Dispatch events: combat-start, turn-start, turn-end."

### **Prompt 2: The Movement System**

"Create src/systems/MovementSystem.js. It coordinates Pathfinding, VoxelGrid, and UnitManager.

1. Implement validateMove(unit, targetPos): Returns { valid: boolean, cost: number, path: [] }. It checks `A*` pathfinding and compares cost vs unit.currentAP.
2. Implement executeMove(unit, targetPos):
   - Validates the move first.
   - Updates grid.moveUnit(unit, targetPos).
   - Deducts AP.
   - Returns a Promise that resolves when the visual movement (optional animation hook) would handle it, or immediately for logic."
