151 lines
4.8 KiB
Markdown
151 lines
4.8 KiB
Markdown
|
|
# **Barracks Specification: The Squad Quarters**
|
||
|
|
|
||
|
|
This document defines the UI and Logic for the **Barracks Screen**. This is the persistent management interface where the player oversees their entire roster of Explorers.
|
||
|
|
|
||
|
|
## **1. System Overview**
|
||
|
|
|
||
|
|
**Role:** The Barracks serves as the "List View" for the RosterManager. It allows the player to browse, sort, heal, and dismiss units.
|
||
|
|
|
||
|
|
### **Integration Context**
|
||
|
|
|
||
|
|
- **Parent:** Rendered inside the HubScreen overlay container.
|
||
|
|
- **Data Source:** GameStateManager.rosterManager (The source of truth for units).
|
||
|
|
- **Dependencies:** \* CharacterSheet (For detailed editing).
|
||
|
|
- Persistence (Saving changes).
|
||
|
|
- Wallet (Paying for healing).
|
||
|
|
|
||
|
|
## **2. Visual Design & Layout**
|
||
|
|
|
||
|
|
**Setting:** Inside the large **Troop Tent**. Rows of cots and weapon racks.
|
||
|
|
|
||
|
|
- **Vibe:** Organized, slightly military, warm lantern light.
|
||
|
|
|
||
|
|
### **Layout (Split View)**
|
||
|
|
|
||
|
|
#### **A. Roster List (Left - 60%)**
|
||
|
|
|
||
|
|
- **Header:** \* **Count:** "Roster: 6/12".
|
||
|
|
- **Filters:** [ALL] [READY] [INJURED] [CLASS].
|
||
|
|
- **Sort:** [Level] [Name] [Status].
|
||
|
|
- **Scroll Area:** A vertical grid of **Unit Cards**.
|
||
|
|
- _Card Visual:_ Portrait, Name, Class Icon, Level, HP Bar.
|
||
|
|
- _Status Indicators:_ "Injured" (Red overlay), "Ready" (Green dot).
|
||
|
|
|
||
|
|
#### **B. Command Sidebar (Right - 40%)**
|
||
|
|
|
||
|
|
- **Selection Preview:** Shows the 3D model of the currently selected unit.
|
||
|
|
- **Quick Stats:** HP, Stress/Fatigue (if implemented), XP bar.
|
||
|
|
- **Actions:**
|
||
|
|
- **"Inspect / Equip":** Opens the full CharacterSheet modal.
|
||
|
|
- **"Heal":** (If injured) Shows cost in Aether Shards. Button: "Treat Wounds (50 💎)".
|
||
|
|
- **"Dismiss":** Permanently removes unit from roster (Confirmation required).
|
||
|
|
|
||
|
|
## **3. TypeScript Interfaces (Data Model)**
|
||
|
|
|
||
|
|
```ts
|
||
|
|
// src/types/Barracks.ts
|
||
|
|
|
||
|
|
import { UnitStatus } from "./Inventory"; // Assuming shared status types
|
||
|
|
|
||
|
|
export type RosterFilter = "ALL" | "READY" | "INJURED" | "CLASS";
|
||
|
|
export type SortMethod = "LEVEL_DESC" | "NAME_ASC" | "HP_ASC";
|
||
|
|
|
||
|
|
export interface BarracksState {
|
||
|
|
/** Full list of units from RosterManager */
|
||
|
|
units: RosterUnitData[];
|
||
|
|
/** ID of the currently selected unit */
|
||
|
|
selectedUnitId: string | null;
|
||
|
|
/** Current filter applied */
|
||
|
|
filter: RosterFilter;
|
||
|
|
/** Current sort method */
|
||
|
|
sort: SortMethod;
|
||
|
|
/** Cost multiplier for healing (e.g. 1 HP = 0.5 Shards) */
|
||
|
|
healingCostPerHp: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Lightweight data for the list view
|
||
|
|
*/
|
||
|
|
export interface RosterUnitData {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
classId: string;
|
||
|
|
level: number;
|
||
|
|
currentHp: number;
|
||
|
|
maxHp: number;
|
||
|
|
status: "READY" | "INJURED" | "DEAD" | "MISSION";
|
||
|
|
portrait: string; // Asset path
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface BarracksEvents {
|
||
|
|
"open-character-sheet": { unitId: string };
|
||
|
|
"request-heal": { unitId: string; cost: number };
|
||
|
|
"request-dismiss": { unitId: string };
|
||
|
|
"close-barracks": void;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## **4. Logic & Algorithms**
|
||
|
|
|
||
|
|
### **A. Healing Logic**
|
||
|
|
|
||
|
|
Healing is not free in the Hub; it acts as a resource sink.
|
||
|
|
|
||
|
|
1. **Calculate Cost:** `(MaxHP - CurrentHP) * CostPerHP`.
|
||
|
|
2. **Validate:** Check `Wallet >= Cost`.
|
||
|
|
3. **Execute:**
|
||
|
|
- Deduct Currency.
|
||
|
|
- Set `unit.currentHp = unit.maxHp`.
|
||
|
|
- Set `unit.status = 'READY'`.
|
||
|
|
- Save Roster & Wallet via `Persistence`.
|
||
|
|
|
||
|
|
### **B. Filtering**
|
||
|
|
|
||
|
|
The UI must filter the raw roster list locally.
|
||
|
|
|
||
|
|
- **READY:** `unit.status === 'READY'`
|
||
|
|
- **INJURED:** `unit.currentHp < unit.maxHp`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## **5. Conditions of Acceptance (CoA)**
|
||
|
|
|
||
|
|
**CoA 1: Roster Synchronization**
|
||
|
|
|
||
|
|
- The list must match the contents of `RosterManager`.
|
||
|
|
- If a unit is dismissed, it must immediately disappear from the list.
|
||
|
|
|
||
|
|
**CoA 2: Healing Transaction**
|
||
|
|
|
||
|
|
- Clicking "Heal" on an injured unit must update their HP to max immediately.
|
||
|
|
- The Global Wallet in the Hub Top Bar must update to reflect the spent shards.
|
||
|
|
- A unit with full HP cannot be healed (Button Disabled).
|
||
|
|
|
||
|
|
**CoA 3: Navigation**
|
||
|
|
|
||
|
|
- Clicking "Inspect" opens the `CharacterSheet`.
|
||
|
|
- Closing the `CharacterSheet` returns the user to the Barracks (not the Main Hub), maintaining their selection state.
|
||
|
|
|
||
|
|
**CoA 4: Selection Persistence**
|
||
|
|
|
||
|
|
- If the roster is re-sorted, the currently selected unit remains selected.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## **6. Prompt for Coding Agent**
|
||
|
|
|
||
|
|
"Create `src/ui/screens/barracks-screen.js` as a LitElement.
|
||
|
|
|
||
|
|
**Imports:**
|
||
|
|
|
||
|
|
- `gameStateManager`, `rosterManager`.
|
||
|
|
- `CharacterSheet` (for dynamic import).
|
||
|
|
|
||
|
|
**Functionality:**
|
||
|
|
|
||
|
|
1. **Load:** On `connectedCallback`, fetch `rosterManager.roster`.
|
||
|
|
2. **Render:** > \* Left Column: `map` over filtered units to create `unit-card` buttons.
|
||
|
|
- Right Column: Detail view. If `selectedUnit` is injured, show `Heal Button` with calculated cost.
|
||
|
|
3. **Healing:** Implement `_handleHeal()`. access `gameStateManager.activeRunData` (or wallet state). Deduct funds, update unit HP, trigger save. Dispatch event to update Hub header.
|
||
|
|
4. **Inspect:** Dispatch `open-character-sheet` event (handled by `index.html`) OR instantiate the modal internally if preferred for layout stacking."
|