aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Pasquet <dev@etenil.net>2019-11-21 19:54:38 +0000
committerGuillaume Pasquet <dev@etenil.net>2019-11-21 19:54:38 +0000
commit538008cbdc8ec8a873e62a8b991201fda5762d63 (patch)
treed9dab5a34ac13d4393ca4531807e455cf5af828a
parentb53947f191ad6ffc9b72890abb916a44f581c0c3 (diff)
Fog of war! Inneficient and buggy but works
-rw-r--r--src/entities.rs27
-rw-r--r--src/main.rs6
-rw-r--r--src/state.rs13
-rw-r--r--src/tiling.rs24
4 files changed, 55 insertions, 15 deletions
diff --git a/src/entities.rs b/src/entities.rs
index b3cdf34..430e37a 100644
--- a/src/entities.rs
+++ b/src/entities.rs
@@ -22,6 +22,8 @@ pub trait Entity {
fn is_dirty(&self) -> bool;
/// Declare the entity clean
fn clean(&mut self);
+ fn visibility(&mut self, visible: bool);
+ fn is_visible(&self) -> bool;
}
#[derive(Clone)]
@@ -39,12 +41,19 @@ pub struct Character {
luck: i32,
xp: i32,
tile: Tile,
+ visible: bool,
}
pub trait Enemy {
- fn new(class: String, health: i32, attack: i32, dodge: i32, luck: i32,
- location: Point, tile_str: &'static str)
- -> Self;
+ fn new(
+ class: String,
+ health: i32,
+ attack: i32,
+ dodge: i32,
+ luck: i32,
+ location: Point,
+ tile_str: &'static str,
+ ) -> Self;
fn set_tile(&mut self, tile: Tile);
}
@@ -103,6 +112,14 @@ impl Entity for Character {
fn clean(&mut self) {
self.dirty = false;
}
+
+ fn visibility(&mut self, visible: bool) {
+ self.visible = visible;
+ }
+
+ fn is_visible(&self) -> bool {
+ self.visible
+ }
}
impl Enemy for Character {
@@ -129,6 +146,7 @@ impl Enemy for Character {
previous_location: location,
tile: Tile::from(TileType::Character(tile_str)),
dirty: false,
+ visible: false,
}
}
@@ -160,9 +178,10 @@ impl Player for Character {
previous_location: (0, 0),
tile: Tile::new(
TileType::Player,
- true, // player is visible by default
+ true, // player is visible by default
),
dirty: false,
+ visible: true,
}
}
diff --git a/src/main.rs b/src/main.rs
index 5acbbef..e45701a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -42,15 +42,13 @@ fn main() {
let _raw = RawScreen::into_raw_mode();
- state.render_level();
-
let input = input();
let mut reader = input.read_sync();
loop {
- // update
+ state.render_player();
+ state.render_level();
state.render_entities();
-
state.render_player();
state.render_ui();
diff --git a/src/state.rs b/src/state.rs
index 9939226..805e9e9 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -6,6 +6,8 @@ use crate::entities::{Character, Entity, Player};
use crate::tiling::{tile_to_str, Tile, TileGrid, TileType};
use crate::world::{apply_movement, Dungeon, Generatable, Level, Movement};
+const PLAYER_SIGHT: usize = 5;
+
pub struct State {
pub player: Character,
dungeon: Dungeon,
@@ -48,7 +50,7 @@ impl State {
}
fn render_entity(&self, entity: &dyn Entity) {
- if !entity.is_dirty() {
+ if !entity.is_visible() || !entity.is_dirty() {
return;
}
let dirt = entity.previous_location();
@@ -71,8 +73,13 @@ impl State {
}
}
- pub fn render_player(&self) {
- self.render_entity(&self.player)
+ 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 {
diff --git a/src/tiling.rs b/src/tiling.rs
index c79d6ef..b7c2bc6 100644
--- a/src/tiling.rs
+++ b/src/tiling.rs
@@ -25,15 +25,23 @@ impl Tile {
pub fn get_type(&self) -> &TileType {
&self.tile_type
}
+
+ pub fn is_visible(&self) -> bool {
+ self.visible
+ }
+
+ pub fn visibility(&mut self, visible: bool) {
+ self.visible = visible;
+ }
}
impl From<TileType> for Tile {
fn from(tile_type: TileType) -> Self {
Tile {
tile_type,
- visible: true, // <--- TODO: this set the default beaviour
- // - true: all tiles of world and entities will be drawn
- // - false: only draw tiles visible for the player
+ visible: false, // <--- TODO: this set the default beaviour
+ // - true: all tiles of world and entities will be drawn
+ // - false: only draw tiles visible for the player
}
}
}
@@ -94,10 +102,18 @@ impl TileGrid {
pub fn ysize(&self) -> usize {
self.ysize
}
+
+ pub fn clear_fog_of_war(&mut self, center: &(usize, usize), radius: usize) {
+ for x in 0.max(center.0 - radius)..center.0 + radius {
+ for y in 0.max(center.1 - radius)..center.1 + radius {
+ self.grid[y][x].visibility(true)
+ }
+ }
+ }
}
pub fn tile_to_str(tile: &Tile) -> &str {
- if tile.visible {
+ if tile.is_visible() {
match tile.tile_type {
TileType::Floor => ".",
TileType::Wall => "#",