feat(save): Speicherstand als Game-Baum
Autosave beim Betreten einer Etage und beim Beenden, ein Slot, bei Tod geloescht. Der Save ist der Baum selbst — keine eigenen Save-Structs, die man zweimal pflegt. - Kacheln als ASCII-Zeilen wie ein Prefab, nicht 3200 Enum-Eintraege - atomar geschrieben: tmp plus rename, der einzige Stand ueberlebt einen Abbruch - fremdes Schema wird abgelehnt, die Datei bleibt liegen - fehlende Mods verwerfen Eintraege, nie den Lauf - Confirm-Screen vor dem Spiel, wenn der Save Eintraege verloren hat Fuenf Befunde: die Ereigniswarteschlange gehoert nicht in den Save, die Feldreihenfolge ist Teil des TOML-Formats, Serialize fuer Floor muss von Hand, Confirm braucht on_no, und die Rueckfrage galt zuerst auch fuer Mod-Ladewarnungen.
This commit is contained in:
@@ -8,6 +8,7 @@ use crate::game::{Attribute, Cheat, Command, CreatureRef, Direction, Game};
|
||||
/// 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.
|
||||
#[derive(Clone)]
|
||||
pub enum Screen {
|
||||
MainMenu,
|
||||
Explore,
|
||||
@@ -38,6 +39,16 @@ pub enum Screen {
|
||||
/// Meldungszeile im Hauptmenue: Ein Abstiegs-Roguelike lebt davon, dass der
|
||||
/// Lauf am Ende *erzaehlt* wird (Ticket 14).
|
||||
GameOver,
|
||||
/// Rueckfrage. Ticket 09 wollte `on_yes: Box<Response>` und ein implizites
|
||||
/// „Nein = wegklicken" — das reicht nicht: Beim Ladefall heisst Nein
|
||||
/// *beenden und den Mod nachinstallieren*, denn diese Wahl hat der Spieler
|
||||
/// nur **vor** dem Laden. Das symmetrische Paar ist ein Feld mehr und
|
||||
/// spart die ungeschriebene Regel.
|
||||
Confirm {
|
||||
text: String,
|
||||
on_yes: Box<Response>,
|
||||
on_no: Box<Response>,
|
||||
},
|
||||
/// Werkbank. Immer mit gebaut statt hinter `cfg(debug_assertions)`: Das
|
||||
/// waere ein `#[cfg]` an der Variante *und* an jedem `match` darueber, fuer
|
||||
/// ein Spiel, das niemand ausliefert. Ein `#[cfg]` reicht spaeter nach.
|
||||
@@ -63,6 +74,7 @@ pub enum Screen {
|
||||
/// 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/`.
|
||||
#[derive(Clone)]
|
||||
pub enum Response {
|
||||
None,
|
||||
Pop,
|
||||
@@ -344,6 +356,12 @@ impl Screen {
|
||||
}
|
||||
}
|
||||
|
||||
Screen::Confirm { on_yes, on_no, .. } => match key {
|
||||
KeyCode::Char('j' | 'y') | KeyCode::Enter => (**on_yes).clone(),
|
||||
KeyCode::Char('n' | 'q') | KeyCode::Esc => (**on_no).clone(),
|
||||
_ => Response::None,
|
||||
},
|
||||
|
||||
Screen::GameOver => Response::Quit,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user