feat(progression): Erfahrung, Aufstieg und Punkteverteilung
Toeten gibt Erfahrung (exp_reward stand seit M3 ungelesen an jedem Gegner), give_exp als zwoelfte Aktion fuer spaetere Quests. Aufstieg in einer Schleife am Zugende, ein Punkt je Stufe, keine Obergrenze. Verteilt wird im Charakterbogen — kein zwoelfter Screen. AssignPoints nimmt alle Punkte auf einmal und kostet damit einen Zug. luck wirkt jetzt: eine Chance auf einen Zusatzzug auf jeder Beutetabelle. Drei Befunde: - strength und constitution las niemand, zwei der fuenf verteilbaren Grundwerte waren Fallen. Zwei balance-Knoepfe rechnen sie beim Verteilen um. - Rng::chance(0.0) verbrauchte eine Zahl und verschob den Zufallsstrom. - Cheat::ClearRoom ging am Todesweg vorbei.
This commit is contained in:
@@ -136,7 +136,9 @@ fn draw(frame: &mut Frame, app: &App) {
|
||||
draw_combat(frame, area, app, *pick, *target, *targeting)
|
||||
}
|
||||
Screen::Inventory { pick } => draw_inventory(frame, area, app, *pick),
|
||||
Screen::CharacterSheet => draw_sheet(frame, area, app),
|
||||
Screen::CharacterSheet { pick, pending } => {
|
||||
draw_sheet(frame, area, app, *pick, pending)
|
||||
}
|
||||
Screen::Dialog { pick } => draw_dialog(frame, area, app, *pick),
|
||||
Screen::Shop { pick, selling } => draw_shop(frame, area, app, *pick, *selling),
|
||||
Screen::Debug { pick } => draw_debug(frame, area, app, *pick),
|
||||
@@ -530,7 +532,7 @@ fn draw_game_over(frame: &mut Frame, area: Rect, app: &App) {
|
||||
|
||||
/// Der Charakterbogen ist eine **Schleife ueber Registries**, kein gemauertes
|
||||
/// Layout — Modder koennen Slots und Wahlkategorien ergaenzen (Ticket 02).
|
||||
fn draw_sheet(frame: &mut Frame, area: Rect, app: &App) {
|
||||
fn draw_sheet(frame: &mut Frame, area: Rect, app: &App, pick: usize, pending: &[u32; 5]) {
|
||||
let block = Block::bordered().title(" Charakterbogen ");
|
||||
let inner = block.inner(area);
|
||||
frame.render_widget(block, area);
|
||||
@@ -554,7 +556,16 @@ fn draw_sheet(frame: &mut Frame, area: Rect, app: &App) {
|
||||
} else {
|
||||
format!("{total:.0} ({base:.0} Basis)")
|
||||
};
|
||||
Row::new(vec![a.name().to_string(), cell])
|
||||
|
||||
// Verteilbare Grundwerte tragen Cursor und Vormerkung — der Bogen
|
||||
// ist zugleich der Verteil-Screen (Ticket 15).
|
||||
let Some(i) = Attribute::ASSIGNABLE.iter().position(|x| x == a) else {
|
||||
return Row::new(vec![format!(" {}", a.name()), cell]);
|
||||
};
|
||||
let zeiger = if i == pick { "›" } else { " " };
|
||||
let vorgemerkt = if pending[i] > 0 { format!(" +{}", pending[i]) } else { String::new() };
|
||||
Row::new(vec![format!("{zeiger} {} {vorgemerkt}", a.name()), cell])
|
||||
.style(Style::new().fg(if i == pick { Color::Yellow } else { Color::Reset }))
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -566,6 +577,21 @@ fn draw_sheet(frame: &mut Frame, area: Rect, app: &App) {
|
||||
|
||||
let mut lines = Vec::new();
|
||||
|
||||
// Erfahrung und Punkte stehen an `Game`, nicht am `Creature` (Ticket 15).
|
||||
let offen = app.game.unspent_points - pending.iter().sum::<u32>();
|
||||
lines.push(Line::from(format!(
|
||||
"Erfahrung {}/{}",
|
||||
app.game.current_exp,
|
||||
app.game.exp_needed(&app.registries)
|
||||
)));
|
||||
if app.game.unspent_points > 0 {
|
||||
lines.push(
|
||||
Line::from(format!("{offen} Punkte offen · ←→ verteilen · Enter bestätigen"))
|
||||
.style(Style::new().fg(Color::Yellow)),
|
||||
);
|
||||
}
|
||||
lines.push(Line::from(""));
|
||||
|
||||
lines.push(Line::from("Herkunft".bold()));
|
||||
for id in &app.game.player.options {
|
||||
let name = app.registries.options.get(id).map(|o| o.name.as_str()).unwrap_or(id);
|
||||
|
||||
Reference in New Issue
Block a user