aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Pasquet <dev@etenil.net>2020-01-02 15:19:35 +0000
committerGuillaume Pasquet <dev@etenil.net>2020-01-02 15:19:35 +0000
commit61efc432f5b6cbd3b580bdb330507661a3213222 (patch)
tree055c0cbf4957a21a803fc6611813792c4dc01837 /src
parent4032fc8200980025b015c5f798de87a5918b798b (diff)
Add line of sight
Diffstat (limited to 'src')
-rw-r--r--src/main.rs39
-rw-r--r--src/tiling.rs27
2 files changed, 46 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs
index e45701a..d00db53 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,23 +1,22 @@
-extern crate crossterm;
-extern crate ignore_result;
-extern crate rand;
-extern crate text_io;
-
mod entities;
mod state;
mod tiling;
mod world;
+use std::env;
+use std::fs::File;
+use std::io::{stdout, Write};
+
use crossterm::cursor;
use crossterm::execute;
use crossterm::input::{input, InputEvent, KeyEvent};
use crossterm::screen::{EnterAlternateScreen, LeaveAlternateScreen, RawScreen};
use crossterm::terminal;
-use entities::Player;
use ignore_result::Ignore;
+use simplelog::*;
+
+use entities::Player;
use state::State;
-use std::env;
-use std::io::{stdout, Write};
use world::{Dungeon, DOWN, LEFT, RIGHT, UP};
fn player_name() -> String {
@@ -28,23 +27,35 @@ fn player_name() -> String {
}
fn main() {
+ // Set up the debug logger only if required.
+ if let Ok(_val) = env::var("DEBUG") {
+ WriteLogger::init(
+ LevelFilter::Debug,
+ Config::default(),
+ File::create("roguerust.log").unwrap(),
+ )
+ .unwrap();
+ }
+
+ // Initialise the terminal, the raw alternate mode allows direct character
+ // seeking and hides the prompt.
let term_size = terminal::size().unwrap();
+ execute!(stdout(), EnterAlternateScreen).unwrap();
+ execute!(stdout(), cursor::Hide).unwrap();
+ let _raw = RawScreen::into_raw_mode();
+ // Initialise state, create the player and dungeon
let mut state = State::new(
Player::new(player_name(), String::from("Warrior"), 30, 10, 10, 20),
Dungeon::new(term_size.0 as usize, (term_size.1 - 2) as usize, 5),
);
-
state.init();
- execute!(stdout(), EnterAlternateScreen).unwrap();
- execute!(stdout(), cursor::Hide).unwrap();
-
- let _raw = RawScreen::into_raw_mode();
-
let input = input();
let mut reader = input.read_sync();
+ // Main loop, dispatches events and calls rendering routines. Don't
+ // add any game logic here.
loop {
state.render_player();
state.render_level();
diff --git a/src/tiling.rs b/src/tiling.rs
index f2a9b02..17e8f32 100644
--- a/src/tiling.rs
+++ b/src/tiling.rs
@@ -1,3 +1,4 @@
+use log::debug;
use std::convert::From;
#[derive(Clone)]
@@ -103,6 +104,10 @@ impl TileGrid {
self.ysize
}
+ fn reveal(&mut self, x: usize, y: usize) {
+ self.grid[y][x].visibility(true);
+ }
+
/// Clears all blocks in a single line of sight ray; stop when encountering a wall
/// This uses the bresenham algorithm, see:
/// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
@@ -116,11 +121,15 @@ impl TileGrid {
let mut x = start.0;
let mut y = start.1;
+ // the tile we're standing on needs to be visible.
+ self.reveal(start.0, start.1);
+
loop {
if x == end.0 && y == end.1 {
+ self.reveal(x, y);
break;
}
- if let TileType::Wall = self.grid[y][x].get_type() {
+ if let TileType::Empty = self.grid[y][x].get_type() {
break;
}
@@ -133,7 +142,7 @@ impl TileGrid {
err += dx;
y = (y as isize + sy).max(0) as usize;
}
- self.grid[y][x].visibility(true);
+ self.reveal(x, y);
}
}
@@ -148,20 +157,26 @@ impl TileGrid {
let c = (center.0 + radius, center.1 + radius);
let d = (center.0.saturating_sub(radius), center.1 + radius);
+ debug!("LOS: {:?} - {:?} {:?} {:?} {:?}", center, a, b, c, d);
+
// From a to b
- for x in a.0..b.0 {
+ for x in a.0..=b.0 {
+ // debug!("Clear LOS from {:?} to {:?}", center, (x, a.1));
self.clear_los(center, &(x, a.1));
}
// From b to c
- for y in b.1..c.1 {
+ for y in b.1..=c.1 {
+ // debug!("Clear LOS from {:?} to {:?}", center, (b.0, y));
self.clear_los(center, &(b.0, y));
}
// From c to d
- for x in d.0..c.0 {
+ for x in d.0..=c.0 {
+ // debug!("Clear LOS from {:?} to {:?}", center, (x, c.1));
self.clear_los(center, &(x, c.1));
}
// From d to a
- for y in a.1..d.1 {
+ for y in a.1..=d.1 {
+ // debug!("Clear LOS from {:?} to {:?}", center, (d.0, y));
self.clear_los(center, &(d.0, y));
}
}