Disallow player phasing through walls

This commit is contained in:
Alex Bethel 2022-01-06 14:04:55 -06:00
parent 96525e24bf
commit 72ed107d17
2 changed files with 27 additions and 2 deletions

View file

@ -98,6 +98,12 @@ impl DungeonLevel {
DungeonTile::Hallway => '#',
}
}
/// Gets a reference to the tile at the given coordinates. Panics
/// of the coordinates are out of bounds.
pub fn tile(&self, x: i32, y: i32) -> &DungeonTile {
&self.tiles[y as usize][x as usize]
}
}
impl Display for DungeonLevel {

View file

@ -5,7 +5,7 @@ use specs::prelude::*;
use crate::{
components::{CharRender, MobAction, Mobile, Player, Position},
game::DungeonLevel,
game::{DungeonLevel, DungeonTile},
quit,
};
@ -53,7 +53,9 @@ pub fn player_turn(ecs: &mut World, screen: &mut Window) {
};
if let Some(action) = action {
break action;
if possible(ecs, &action) {
break action;
}
}
};
@ -64,6 +66,23 @@ pub fn player_turn(ecs: &mut World, screen: &mut Window) {
}
}
/// Checks whether an action is possible for the player to execute in
/// the given world.
fn possible(ecs: &World, action: &MobAction) -> bool {
match action {
MobAction::Nop => true,
MobAction::Move(dx, dy) => {
let players = ecs.read_storage::<Player>();
let positions = ecs.read_storage::<Position>();
let map = ecs.fetch::<DungeonLevel>();
(&players, &positions)
.join()
.all(|(_plr, pos)| map.tile(pos.x + dx, pos.y + dy) != &DungeonTile::Wall)
}
}
}
/// Renders the state of the world onto the screen.
fn render_screen(ecs: &mut World, screen: &mut Window) {
// screen.clear();