add "Previous message" command

ctrl+p, like nethack. Cycles through messages, also like nethack.

May want to add some sort of indicator of how many messages there have
been.
This commit is contained in:
Griffin Smith 2019-07-07 13:02:50 -04:00
parent c643ee1dfc
commit 20f1ccb460
3 changed files with 31 additions and 5 deletions

View file

@ -31,6 +31,10 @@ pub struct Game<'a> {
/// The messages that have been said to the user, in forward time order /// The messages that have been said to the user, in forward time order
messages: Vec<String>, messages: Vec<String>,
/// The index of the currently-displayed message. Used to track the index of
/// the currently displayed message when handling PreviousMessage commands
message_idx: usize,
/// A global random number generator for the game /// A global random number generator for the game
rng: Rng, rng: Rng,
} }
@ -50,6 +54,7 @@ impl<'a> Game<'a> {
Game { Game {
settings, settings,
rng, rng,
message_idx: 0,
viewport: Viewport::new( viewport: Viewport::new(
BoundingBox::at_origin(Dimensions { w, h }), BoundingBox::at_origin(Dimensions { w, h }),
BoundingBox::at_origin(Dimensions { w: w - 2, h: h - 2 }), BoundingBox::at_origin(Dimensions { w: w - 2, h: h - 2 }),
@ -80,6 +85,16 @@ impl<'a> Game<'a> {
fn say(&mut self, message_name: &str) -> io::Result<()> { fn say(&mut self, message_name: &str) -> io::Result<()> {
let message = self.message(message_name); let message = self.message(message_name);
self.messages.push(message.to_string()); self.messages.push(message.to_string());
self.message_idx = self.messages.len() - 1;
self.viewport.write_message(message)
}
fn previous_message(&mut self) -> io::Result<()> {
if self.message_idx == 0 {
return Ok(());
}
self.message_idx -= 1;
let message = &self.messages[self.message_idx];
self.viewport.write_message(message) self.viewport.write_message(message)
} }
@ -89,23 +104,28 @@ impl<'a> Game<'a> {
self.viewport.init()?; self.viewport.init()?;
self.draw_entities()?; self.draw_entities()?;
self.say("global.welcome")?; self.say("global.welcome")?;
self.say("somethign else")?;
self.flush()?; self.flush()?;
loop { loop {
let mut old_position = None; let mut old_position = None;
use Command::*;
match Command::from_key(self.keys.next().unwrap().unwrap()) { match Command::from_key(self.keys.next().unwrap().unwrap()) {
Some(Command::Quit) => { Some(Quit) => {
info!("Quitting game due to user request"); info!("Quitting game due to user request");
break; break;
} }
Some(Command::Move(direction)) => { Some(Move(direction)) => {
let new_pos = self.character.position + direction; let new_pos = self.character.position + direction;
if !self.collision_at(new_pos) { if !self.collision_at(new_pos) {
old_position = Some(self.character.position); old_position = Some(self.character.position);
self.character.position = new_pos; self.character.position = new_pos;
} }
} }
_ => (),
Some(PreviousMessage) => self.previous_message()?,
None => (),
} }
match old_position { match old_position {

View file

@ -175,7 +175,6 @@ lazy_static! {
/// Look up a game message based on the given (dot-separated) name, with the /// Look up a game message based on the given (dot-separated) name, with the
/// given random generator used to select from choice-based messages /// given random generator used to select from choice-based messages
pub fn message<R: Rng + ?Sized>(name: &str, rng: &mut R) -> &'static str { pub fn message<R: Rng + ?Sized>(name: &str, rng: &mut R) -> &'static str {
use Message::*;
MESSAGES MESSAGES
.lookup(name) .lookup(name)
.and_then(|msg| msg.resolve(rng)) .and_then(|msg| msg.resolve(rng))

View file

@ -1,11 +1,17 @@
use super::Direction; use super::Direction;
use super::Direction::*; use super::Direction::*;
use termion::event::Key; use termion::event::Key;
use termion::event::Key::Char; use termion::event::Key::{Char, Ctrl};
pub enum Command { pub enum Command {
/// Quit the game
Quit, Quit,
/// Move the character in a direction
Move(Direction), Move(Direction),
/// Display the previous message
PreviousMessage,
} }
impl Command { impl Command {
@ -17,6 +23,7 @@ impl Command {
Char('k') | Char('w') | Key::Up => Some(Move(Up)), Char('k') | Char('w') | Key::Up => Some(Move(Up)),
Char('j') | Char('s') | Key::Down => Some(Move(Down)), Char('j') | Char('s') | Key::Down => Some(Move(Down)),
Char('l') | Char('d') | Key::Right => Some(Move(Right)), Char('l') | Char('d') | Key::Right => Some(Move(Right)),
Ctrl('p') => Some(PreviousMessage),
_ => None, _ => None,
} }
} }