Combat base added

This commit is contained in:
gamer147
2026-04-02 08:29:24 -04:00
parent 470e89b15b
commit ce92c6e435
14 changed files with 402 additions and 18 deletions

View File

@@ -0,0 +1,87 @@
# Combat System
## Overview
A stateless CombatSystem node that creates pre-combat proposals and applies combat resolution between two units. The system encapsulates all combat stat calculation so other systems don't need to know proposal logic.
## CombatProposal Resource
`resources/resource_definitions/combat_proposal.gd`
A Resource containing two sides — attacker and defender. Each side holds:
- A reference to the `Unit` node
- Pre-combat snapshot stats via an inner class `CombatantStats`:
- `hp: int` — from `current_stats.current_hp`
- `sp: int` — from `current_stats.current_sp`
- `hit: int` — calculated as `own hit - opponent's eva`
- `atk: int` — from `current_stats.phys_atk`
- `def: int` — from `current_stats.phys_def`
- `spd: int` — from `current_stats.spd`
### Stat Calculation
For the **attacker** side:
- `atk` = attacker's `phys_atk`
- `def` = attacker's `phys_def`
- `hit` = attacker's `hit` - defender's `eva`
- `hp`, `sp`, `spd` copied directly from attacker's `current_stats`
For the **defender** side:
- `atk` = defender's `phys_atk`
- `def` = defender's `phys_def`
- `hit` = defender's `hit` - attacker's `eva`
- `hp`, `sp`, `spd` copied directly from defender's `current_stats`
In the future, different attacks may swap between physical and magic stats, but for now only physical stats are used.
## CombatSystem Node
`nodes/combat_system.gd`
A `Node` added to the strategy phase scene tree. Stateless — operates purely on units passed in.
### `create_proposal(attacker: Unit, defender: Unit) -> CombatProposal`
- Reads both units' `current_stats`
- Builds a `CombatProposal` with snapshot stats for each side
- Applies cross-calculations (hit - eva)
- Returns the proposal without modifying any unit state
### `apply_proposal(proposal: CombatProposal) -> void`
1. **Attacker strikes:** Roll random int 1100. If roll <= attacker's calculated `hit`, apply `max(attacker.atk - defender.def, 0)` damage to the defender Unit's `current_stats.current_hp` (modifies the actual unit, not the snapshot).
2. **Counterattack:** If the defender Unit's `current_stats.current_hp > 0` after the attack, roll 1100 for defender. If roll <= defender's calculated `hit`, apply `max(defender.atk - attacker.def, 0)` damage to the attacker Unit's `current_stats.current_hp`.
- Damage has a floor of 0 (no negative damage / healing).
- Range is ignored for now. In the future, counterattack will depend on whether the defender has skills at appropriate range (defaulting to a "defend" action if not).
## Scene Integration
The CombatSystem node is added to `scenes/strategy_phase.tscn` as a sibling of PlayerController, CombatMap, etc. No exports needed.
```
CombatTest (Node2D)
├─ CombatUI
├─ CombatMap
├─ PlayerController
├─ CombatSystem <-- new
├─ Camera2D
└─ AudioStreamPlayer
```
## Files Changed
| File | Change |
|------|--------|
| `resources/resource_definitions/combat_proposal.gd` | New — CombatProposal resource with CombatantStats inner class |
| `nodes/combat_system.gd` | New — CombatSystem node with `create_proposal` and `apply_proposal` |
| `scenes/strategy_phase.tscn` | Add CombatSystem node to scene tree |
## Out of Scope
- Magic attack/defense selection (future: different attack types swap stats)
- Range-based counterattack eligibility (future: defend action when no skills in range)
- Critical hits
- UI for displaying the combat proposal
- Animations or visual feedback for combat resolution