feat: m1 vertikaler durchstich — mod-lader, registries, attributberechnung, screen-stack
Ersetzt src/ vollstaendig: print_box, include_str! und enum ItemType fallen, wie Ticket 01-03 es vorgezeichnet haben. - data/: Mod-Lader mit zwei Suchpfaden, selbstheilender load_order.toml, drei Phasen und zweistufiger Deserialisierung (03/04) - game/: Attributkatalog, Creature, Game::attribute ueber mehrere Quellen, Command mit Outcome (01/07/11/12) - ui/: Screen-Stack mit Response, Grid-Widget, Press-Filter (06/11/12) - mods/core/: echte TOML-Dateien auf der Platte statt include_str! 10 Tests, darunter der Borrow-Beweis fuer Registries-neben-Game, den Ticket 12 nicht fuehren konnte.
This commit is contained in:
73
src/ui/screen.rs
Normal file
73
src/ui/screen.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
//! Screen-Stack und Antwort — Ticket 11, im Durchstich (12) bestaetigt.
|
||||
|
||||
use ratatui::crossterm::event::KeyCode;
|
||||
|
||||
use crate::game::{Command, Direction};
|
||||
|
||||
/// Popups sind gewoehnliche Screens, die sich beim Rendern als Overlay
|
||||
/// ausweisen — ein gemeinsamer `Vec<Screen>` statt `current` plus
|
||||
/// `Option<Popup>`, weil Popup ueber Popup real ist.
|
||||
pub enum Screen {
|
||||
MainMenu,
|
||||
Explore,
|
||||
CharacterSheet,
|
||||
// TODO(M2+): `CharacterCreation`, `Combat`, `Inventory`, `QuestLog`,
|
||||
// `Shop`, `Dialog`, `Confirm`, `GameOver` — elf sind es am Ende
|
||||
// (Ticket 11/14).
|
||||
}
|
||||
|
||||
/// Der Screen **gibt zurueck, statt selbst zu schieben**: sonst haelt er ein
|
||||
/// `&mut` auf genau die `Vec`, in der er liegt. Nebeneffekt — `Response::Command`
|
||||
/// ist der einzige Weg nach `game/`.
|
||||
pub enum Response {
|
||||
None,
|
||||
Pop,
|
||||
Push(Screen),
|
||||
Command(Command),
|
||||
Quit,
|
||||
}
|
||||
|
||||
impl Screen {
|
||||
pub fn is_overlay(&self) -> bool {
|
||||
// TODO(M2): `Confirm` ist das erste echte Overlay. Bis dahin haelt die
|
||||
// Regel „ein Command schliesst alle Overlays" nur die Luft.
|
||||
false
|
||||
}
|
||||
|
||||
pub fn handle_key(&mut self, key: KeyCode) -> Response {
|
||||
match self {
|
||||
Screen::MainMenu => match key {
|
||||
KeyCode::Enter => Response::Push(Screen::Explore),
|
||||
KeyCode::Char('q') | KeyCode::Esc => Response::Quit,
|
||||
_ => Response::None,
|
||||
},
|
||||
|
||||
Screen::Explore => match key {
|
||||
// Pfeiltasten *und* hjkl — drei zusaetzliche Arme sind die
|
||||
// billige Hoeflichkeit gegenueber Vim-Fingern (Ticket 11).
|
||||
KeyCode::Up | KeyCode::Char('k') => {
|
||||
Response::Command(Command::Move(Direction::North))
|
||||
}
|
||||
KeyCode::Down | KeyCode::Char('j') => {
|
||||
Response::Command(Command::Move(Direction::South))
|
||||
}
|
||||
KeyCode::Left | KeyCode::Char('h') => {
|
||||
Response::Command(Command::Move(Direction::West))
|
||||
}
|
||||
KeyCode::Right | KeyCode::Char('l') => {
|
||||
Response::Command(Command::Move(Direction::East))
|
||||
}
|
||||
KeyCode::Char('.') => Response::Command(Command::Wait),
|
||||
// Screen-Navigation ist reine UI und fasst `Game` nie an.
|
||||
KeyCode::Char('c') => Response::Push(Screen::CharacterSheet),
|
||||
KeyCode::Esc => Response::Pop,
|
||||
_ => Response::None,
|
||||
},
|
||||
|
||||
Screen::CharacterSheet => match key {
|
||||
KeyCode::Esc | KeyCode::Char('c') | KeyCode::Char('q') => Response::Pop,
|
||||
_ => Response::None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user