feat(charakterbau): Rasse und Klasse werden gewaehlt
Der Held war seit M1 als Zwergenkrieger verdrahtet, waehrend zwei Rassen und zwei Klassen ungenutzt in der Registry lagen. Der Charakterbau ist eine Schleife ueber categories_ordered() und options_of() — ein Mod, der "Talent" mit pick = 2 ergaenzt, bekommt eine dritte Spalte ohne Code. - CharacterOption bekommt abilities und on_create (Ticket 02, TODO seit M3) - abilities_of liest jetzt Rasse und Klasse: Krieger traegt Wuchtschlag, Dieb Hinterhalt, Zwerg Steinsinn - on_create gibt die Startausruestung als gewoehnliche Aktionen — starting_hero() schrumpft auf Creature::new(name) - MainMenu trennt "neuer Held" von "Lauf fortsetzen" Befund: Das Feld abilities fehlte, obwohl Ticket 15 sein ganzes Argument darauf stuetzt — eine Klasse konnte nur flache Modifikatoren geben.
This commit is contained in:
@@ -97,10 +97,19 @@ pub struct CharacterOption {
|
||||
pub description: String,
|
||||
#[serde(default)]
|
||||
pub modifiers: Vec<Modifier>,
|
||||
/// **Was eine Charakteroption dauerhaft traegt** (Ticket 15): Modifikatoren
|
||||
/// veralten — „Zwerg: +2 Konstitution" ist auf Stufe 30 Rauschen —,
|
||||
/// Faehigkeiten nicht. Ein Magier bleibt ein Magier, weil er zaubern kann.
|
||||
#[serde(default)]
|
||||
pub abilities: Vec<String>,
|
||||
/// **Keine neue Mechanik**, sondern gewoehnliche Aktionen, einmal beim
|
||||
/// Charakterbau ausgefuehrt (Ticket 02). Startgold, Startausruestung und
|
||||
/// Startbuff sind damit moddbar, ohne dass die Engine den Begriff
|
||||
/// „Startausruestung" kennt.
|
||||
#[serde(default)]
|
||||
pub on_create: Vec<Action>,
|
||||
#[serde(default)]
|
||||
pub overrides: Option<String>,
|
||||
// TODO(M3): `abilities` und `on_create` (Ticket 02) — Faehigkeiten und
|
||||
// Startausruestung brauchen Kampf bzw. Inventar.
|
||||
}
|
||||
|
||||
/// Ein benannter, befristeter Modifikator — „Vergiftet", „Gesegnet".
|
||||
@@ -520,6 +529,30 @@ impl Registries {
|
||||
|
||||
/// Slots in Anzeigereihenfolge. Der Charakterbogen schleift darueber,
|
||||
/// statt ein Layout zu mauern (Ticket 02).
|
||||
/// Wahlkategorien in Anzeigereihenfolge. Der Charakterbau schleift
|
||||
/// darueber, statt ein Layout zu mauern — ein Mod darf „Talent" ergaenzen
|
||||
/// (Ticket 02/11).
|
||||
pub fn categories_ordered(&self) -> Vec<&Category> {
|
||||
let mut v: Vec<&Category> = self.categories.values().collect();
|
||||
v.sort_by(|a, b| (a.order, &a.id).cmp(&(b.order, &b.id)));
|
||||
v
|
||||
}
|
||||
|
||||
/// Wie viele der gewaehlten IDs in diese Kategorie fallen. Die Frage
|
||||
/// stellen `rejects`, der Screen und die Anzeige — also steht sie einmal
|
||||
/// hier und nicht dreimal als Filterkette.
|
||||
pub fn picked_in(&self, category: &str, gewaehlt: &[String]) -> usize {
|
||||
gewaehlt.iter().filter(|id| self.options.get(*id).is_some_and(|o| o.category == category)).count()
|
||||
}
|
||||
|
||||
/// Die Optionen einer Kategorie, in stabiler Reihenfolge.
|
||||
pub fn options_of(&self, category: &str) -> Vec<&CharacterOption> {
|
||||
let mut v: Vec<&CharacterOption> =
|
||||
self.options.values().filter(|o| o.category == category).collect();
|
||||
v.sort_by(|a, b| a.id.cmp(&b.id));
|
||||
v
|
||||
}
|
||||
|
||||
pub fn slots_ordered(&self) -> Vec<&Slot> {
|
||||
let mut v: Vec<&Slot> = self.slots.values().collect();
|
||||
v.sort_by_key(|s| (s.order, s.id.clone()));
|
||||
|
||||
Reference in New Issue
Block a user