From 518ad5caf2cbf313cb784d9fd1a51632fe600fae Mon Sep 17 00:00:00 2001 From: Guillaume Pasquet Date: Thu, 2 Jan 2020 17:28:15 +0000 Subject: Fix for invisible enemies - Don't double-count visibility - Set enemies visibility with LOS - Set dirty flag when enemies are revealed --- .gitignore | 2 ++ src/entities.rs | 10 +++++----- src/main.rs | 1 - src/state.rs | 37 +++++++++++++++++++++++++++++++------ src/world.rs | 33 ++++++++++++++++++--------------- 5 files changed, 56 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 53eaa21..5542972 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target **/*.rs.bk +/log +*.log diff --git a/src/entities.rs b/src/entities.rs index 430e37a..4a8cd7f 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -41,7 +41,6 @@ pub struct Character { luck: i32, xp: i32, tile: Tile, - visible: bool, } pub trait Enemy { @@ -114,11 +113,14 @@ impl Entity for Character { } fn visibility(&mut self, visible: bool) { - self.visible = visible; + if visible != self.is_visible() { + self.dirty = true; + } + self.tile.visibility(visible) } fn is_visible(&self) -> bool { - self.visible + self.tile.is_visible() } } @@ -146,7 +148,6 @@ impl Enemy for Character { previous_location: location, tile: Tile::from(TileType::Character(tile_str)), dirty: false, - visible: false, } } @@ -181,7 +182,6 @@ impl Player for Character { true, // player is visible by default ), dirty: false, - visible: true, } } diff --git a/src/main.rs b/src/main.rs index e45701a..f17b9cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,7 +46,6 @@ fn main() { let mut reader = input.read_sync(); loop { - state.render_player(); state.render_level(); state.render_entities(); state.render_player(); diff --git a/src/state.rs b/src/state.rs index be32228..6f91d27 100644 --- a/src/state.rs +++ b/src/state.rs @@ -29,6 +29,7 @@ impl State { self.dungeon.generate(); self.switch_level(0); self.player.place(self.current_level().start_point()); + self.clear_los() } pub fn switch_level(&mut self, num_level: usize) { @@ -76,11 +77,6 @@ impl State { pub fn render_player(&mut self) { self.render_entity(&self.player); - - self.grid - .as_mut() - .unwrap() - .clear_fog_of_war(self.player.location(), PLAYER_SIGHT); } fn ui_state_position(&self) -> MoveTo { @@ -120,6 +116,10 @@ impl State { &self.dungeon.levels[self.level] } + pub fn current_level_mut(&mut self) -> &mut Level { + &mut self.dungeon.levels[self.level] + } + fn can_step_on(tile: &Tile) -> bool { match tile.get_type() { TileType::Floor => true, @@ -129,6 +129,27 @@ impl State { } } + fn clear_los(&mut self) { + { + let grid = self.grid.as_mut().unwrap(); + grid.clear_fog_of_war(self.player.location(), PLAYER_SIGHT); + } + + for i in 0..self.current_level().entities.len() { + let loc = *self.current_level().entities[i].location(); + if self + .grid + .as_ref() + .unwrap() + .block_at(loc.0, loc.1) + .is_visible() + && !self.current_level().entities[i].is_visible() + { + self.current_level_mut().entities[i].visibility(true); + } + } + } + pub fn move_player(&mut self, dir: Movement) -> Result<(), String> { let grid = match &self.grid { Some(g) => g, @@ -140,7 +161,11 @@ impl State { if !State::can_step_on(grid.block_at(loc.0, loc.1)) { return Err(String::from("Can't move entity!")); } - self.player.move_by(dir) + self.player.move_by(dir)?; + + self.clear_los(); + + Ok(()) } pub fn down_stairs(&mut self) -> Result<(), String> { diff --git a/src/world.rs b/src/world.rs index 507e6b8..9eeaaed 100644 --- a/src/world.rs +++ b/src/world.rs @@ -310,7 +310,11 @@ impl Level { corridor.tile(&mut grid)?; } - grid.set_tile(self.entrance.0, self.entrance.1, Tile::from(TileType::StairsUp)); + grid.set_tile( + self.entrance.0, + self.entrance.1, + Tile::from(TileType::StairsUp), + ); grid.set_tile(self.exit.0, self.exit.1, Tile::from(TileType::StairsDown)); Ok(grid) @@ -426,20 +430,19 @@ impl Generatable for Level { let room = &self.rooms[rng.gen_range(0, self.rooms.len() - 1)]; // Create the enemy - self.entities.push(Box::::new( - Enemy::new( - String::from("snake"), - 2 * self.depth as i32, - (2.0 * self.depth as f32 * 0.6).round() as i32, - (20.0 * self.depth as f32 * 0.2).max(80.0).round() as i32, - 0, - ( - room.start.0 + rng.gen_range(0, room.width), - room.start.1 + rng.gen_range(0, room.height), - ), - "s", - ) - )); + let enemy_coords = ( + room.start.0 + rng.gen_range(0, room.width - 1) + 1, + room.start.1 + rng.gen_range(0, room.height - 1) + 1, + ); + self.entities.push(Box::::new(Enemy::new( + String::from("snake"), + 2 * self.depth as i32, + (2.0 * self.depth as f32 * 0.6).round() as i32, + (20.0 * self.depth as f32 * 0.2).max(80.0).round() as i32, + 0, + enemy_coords, + "s", + ))); } } } -- cgit v1.2.3