feat: m4 teil 1 — beute, inventar und affixe
- data/: [[loot_tables]] und [[affixes]] als Registries; LootEntry mit guaranteed, nothing, table-in-table, count und affixes - game/loot.rs: EINE Ziehmaschinerie fuer Gegenstaende und Affixe, Tiefendeckel gegen wechselseitigen Bezug - PickUp zieht erst beim Aufheben (Ticket 16) — moeglich nur, weil alle Haufen dasselbe Symbol zeigen - UseItem/Equip/Unequip/Drop, Inventar-Screen als Registry-Schleife - Affixe im Attributpfad, in der Resistenz und in der Trigger-Suche; item_label stellt Affixnamen voran, item_price multipliziert Faktoren - Room haelt eine loot_table (nicht je Haufen eine), Prefab-loot ueberschreibt die Etagentabelle 53 Tests. Offen aus M4: Handel.
This commit is contained in:
@@ -16,6 +16,10 @@ pub enum Screen {
|
||||
/// Cursor in der Faehigkeitsliste.
|
||||
pick: usize,
|
||||
},
|
||||
/// Zwei Bereiche: Inventar mit Cursor, Ausrüstung als Registry-Schleife.
|
||||
Inventory {
|
||||
pick: usize,
|
||||
},
|
||||
CharacterSheet,
|
||||
/// Vollbild, kein Overlay. Bewusst nicht die lazy Variante mit einer
|
||||
/// Meldungszeile im Hauptmenue: Ein Abstiegs-Roguelike lebt davon, dass der
|
||||
@@ -73,8 +77,10 @@ impl Screen {
|
||||
}
|
||||
KeyCode::Char('.') => Response::Command(Command::Wait),
|
||||
KeyCode::Char('>') => Response::Command(Command::Descend),
|
||||
KeyCode::Char('g') => Response::Command(Command::PickUp),
|
||||
// Screen-Navigation ist reine UI und fasst `Game` nie an.
|
||||
KeyCode::Char('c') => Response::Push(Screen::CharacterSheet),
|
||||
KeyCode::Char('i') => Response::Push(Screen::Inventory { pick: 0 }),
|
||||
KeyCode::Esc => Response::Pop,
|
||||
_ => Response::None,
|
||||
},
|
||||
@@ -118,6 +124,42 @@ impl Screen {
|
||||
}
|
||||
}
|
||||
|
||||
Screen::Inventory { pick } => {
|
||||
let n = game.player.inventory.len();
|
||||
if n > 0 {
|
||||
*pick = (*pick).min(n - 1);
|
||||
}
|
||||
|
||||
match key {
|
||||
KeyCode::Up | KeyCode::Char('k') => {
|
||||
*pick = pick.saturating_sub(1);
|
||||
Response::None
|
||||
}
|
||||
KeyCode::Down | KeyCode::Char('j') => {
|
||||
*pick = (*pick + 1).min(n.saturating_sub(1));
|
||||
Response::None
|
||||
}
|
||||
KeyCode::Enter | KeyCode::Char('u') if n > 0 => {
|
||||
Response::Command(Command::UseItem(*pick))
|
||||
}
|
||||
KeyCode::Char('e') if n > 0 => Response::Command(Command::Equip(*pick)),
|
||||
KeyCode::Char('d') if n > 0 => Response::Command(Command::Drop(*pick)),
|
||||
// Ablegen ueber die Slot-Reihenfolge aus der Registry —
|
||||
// der Charakterbogen mauert kein Layout (Ticket 02).
|
||||
KeyCode::Char(c @ '1'..='9') => {
|
||||
let index = (c as u8 - b'1') as usize;
|
||||
match reg.slots_ordered().get(index) {
|
||||
Some(slot) => {
|
||||
Response::Command(Command::Unequip(slot.id.clone()))
|
||||
}
|
||||
None => Response::None,
|
||||
}
|
||||
}
|
||||
KeyCode::Esc | KeyCode::Char('i') | KeyCode::Char('q') => 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