88 lines
2.4 KiB
Markdown
88 lines
2.4 KiB
Markdown
# Data Model: Quick HP Input
|
|
|
|
## Existing Entities (unchanged)
|
|
|
|
### Combatant
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| id | CombatantId (branded string) | Unique identifier |
|
|
| name | string | Display name |
|
|
| initiative | number or undefined | Turn order value |
|
|
| maxHp | number or undefined | Positive integer >= 1, optional |
|
|
| currentHp | number or undefined | Integer in [0, maxHp], optional |
|
|
|
|
No changes to the domain `Combatant` type. HP fields already support the full range of operations needed.
|
|
|
|
### Encounter
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| combatants | readonly Combatant[] | Ordered list |
|
|
| currentTurnIndex | number | Active combatant index |
|
|
| roundNumber | number | Current round |
|
|
|
|
No changes to the domain `Encounter` type.
|
|
|
|
## Existing Domain Events (unchanged)
|
|
|
|
### CurrentHpAdjusted
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| type | "CurrentHpAdjusted" | Discriminant |
|
|
| combatantId | CombatantId | Target combatant |
|
|
| previousHp | number | HP before adjustment |
|
|
| newHp | number | HP after adjustment (clamped) |
|
|
| delta | number | Signed delta applied |
|
|
|
|
This event is already emitted by `adjustHp()` and fully supports the quick input feature. A negative delta represents damage, a positive delta represents healing.
|
|
|
|
## New UI-Only State (component-local, not persisted)
|
|
|
|
### QuickHpInput component state
|
|
|
|
| State | Type | Default | Notes |
|
|
|-------|------|---------|-------|
|
|
| mode | "damage" or "heal" | "damage" | Toggle between subtract and add |
|
|
| inputValue | string | "" | Raw text in the input field |
|
|
|
|
This state is local to the React component and does not persist across page reloads. The mode resets to "damage" on component mount. The input value clears after each successful application.
|
|
|
|
## State Transitions
|
|
|
|
### Apply damage
|
|
|
|
```
|
|
User enters number N in damage mode -> Enter
|
|
-> adjustHp(encounter, combatantId, -N)
|
|
-> currentHp = max(0, currentHp - N)
|
|
-> input clears
|
|
```
|
|
|
|
### Apply healing
|
|
|
|
```
|
|
User enters number N in heal mode -> Enter
|
|
-> adjustHp(encounter, combatantId, +N)
|
|
-> currentHp = min(maxHp, currentHp + N)
|
|
-> input clears
|
|
```
|
|
|
|
### Toggle mode
|
|
|
|
```
|
|
User clicks toggle or presses Tab while focused
|
|
-> mode flips: "damage" <-> "heal"
|
|
-> input value preserved (not cleared)
|
|
-> visual treatment updates immediately
|
|
```
|
|
|
|
### Dismiss
|
|
|
|
```
|
|
User presses Escape
|
|
-> input clears
|
|
-> no HP change applied
|
|
```
|