diff options
author | Griffin Smith <root@gws.fyi> | 2019-07-29T15·22-0400 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2019-07-29T15·22-0400 |
commit | 9db5fad2f900732d59f9714ac4517952d26506d7 (patch) | |
tree | 1f8de240a1f7ccecd37282b0f984e1d0a7d38000 /src/game.rs | |
parent | 34b20b7786a8f6753bb449425772958e0285c385 (diff) |
Describe what you see when you walk over it
If the character walks over any number of entities, describe those entities to the character.
Diffstat (limited to 'src/game.rs')
-rw-r--r-- | src/game.rs | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/src/game.rs b/src/game.rs index dd45b3009a37..a42edb553711 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,14 +1,14 @@ +use crate::description::list_to_sentence; use crate::display::{self, Viewport}; use crate::entities::{ - Character, Creature, Entity, EntityID, Identified, Item, + AnEntity, Character, Creature, EntityID, Identified, Item, }; use crate::messages::message; use crate::settings::Settings; use crate::types::command::Command; use crate::types::entity_map::EntityMap; use crate::types::{ - pos, BoundingBox, Collision, Dimensions, Position, Positioned, - PositionedMut, Ticks, + pos, BoundingBox, Collision, Dimensions, Position, Positioned, Ticks, }; use crate::util::promise::Cancelled; use crate::util::promise::{promise, Complete, Promise, Promises}; @@ -24,25 +24,30 @@ type Stdout<'a> = RawTerminal<StdoutLock<'a>>; type Rng = SmallRng; -type AnEntity = Box<dyn Entity>; - -impl Positioned for AnEntity { - fn position(&self) -> Position { - (**self).position() - } -} - -impl PositionedMut for AnEntity { - fn set_position(&mut self, pos: Position) { - (**self).set_position(pos) - } -} - enum PromptResolution { Uncancellable(Complete<String>), Cancellable(Complete<Result<String, Cancelled>>), } +/// The mode to use when describing entities on a tile to the user +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum EntityDescriptionMode { + /// Describe the entities that the user is walking over. + /// + /// This means: + /// - Skip the character themselves + /// - Describe nothing if there are no items other than the character + Walk, + + /// Describe entities that the user is actively asking about. + /// + /// This means: + /// - Describe the character themselves if they've asked to look at the tile + /// they're standing on + /// - Explicitly say there's nothing there if there's nothing there. + Look, +} + impl PromptResolution { fn is_cancellable(&self) -> bool { use PromptResolution::*; @@ -251,6 +256,43 @@ impl<'a> Game<'a> { } } + /// Describe all the entities at a given position to the user. + /// + /// If `force` is not set to `true`, will not do anything if there are no + /// entities + fn describe_entities_at( + &mut self, + pos: Position, + mode: EntityDescriptionMode, + ) -> io::Result<()> { + use EntityDescriptionMode::*; + let mut entities = self.entities.at(pos); + if mode == Walk { + entities.retain(|e| e.id() != self.character_entity_id); + } + + if entities.len() == 0 { + match mode { + Walk => return Ok(()), + Look => { + return self.say( + "global.describe_no_entities", + &template_params!(), + ) + } + } + } + + let descriptions = list_to_sentence( + &entities.iter().map(|e| e.description()).collect(), + ); + + self.say( + "global.describe_entities", + &template_params!({ "descriptions" => &descriptions, }), + ) + } + /// Remove the given entity from the game, drawing over it if it's visible fn remove_entity(&mut self, entity_id: EntityID) -> io::Result<()> { if let Some(entity) = self.entities.remove(entity_id) { @@ -446,17 +488,18 @@ impl<'a> Game<'a> { match old_position { Some(old_pos) => { let character = self.character(); - self.viewport.game_cursor_position = - character.position; + let char_pos = character.position.clone(); + self.viewport.game_cursor_position = char_pos; self.viewport.clear(old_pos)?; self.draw_entities_at(old_pos)?; self.draw_entity(self.character_entity_id)?; - self.tick( - self.character().speed().tiles_to_ticks( - (old_pos - self.character().position) - .as_tiles(), - ), - ); + self.describe_entities_at( + char_pos, + EntityDescriptionMode::Walk, + )?; + self.tick(self.character().speed().tiles_to_ticks( + (old_pos - char_pos).as_tiles(), + )); } None => (), } |