Make doors opaque, and block the way

This commit is contained in:
Timothy Warren 2021-12-17 14:07:14 -05:00
parent d028065a4a
commit ae3f83b544
6 changed files with 42 additions and 6 deletions

View File

@ -229,6 +229,14 @@ pub struct EntityMoved {}
#[derive(Component, Debug, Serialize, Deserialize, Clone)] #[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct SingleActivation {} pub struct SingleActivation {}
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct BlocksVisibility {}
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Door {
pub open: bool,
}
// Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an // Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an
// Entity. // Entity.

View File

@ -544,6 +544,8 @@ fn main() -> rltk::BError {
EntryTrigger, EntryTrigger,
EntityMoved, EntityMoved,
SingleActivation, SingleActivation,
BlocksVisibility,
Door,
); );
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new()); gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());

View File

@ -25,6 +25,7 @@ pub struct Map {
pub blocked: Vec<bool>, pub blocked: Vec<bool>,
pub depth: i32, pub depth: i32,
pub bloodstains: HashSet<usize>, pub bloodstains: HashSet<usize>,
pub view_blocked: HashSet<usize>,
#[serde(skip_serializing)] #[serde(skip_serializing)]
#[serde(skip_deserializing)] #[serde(skip_deserializing)]
@ -70,13 +71,14 @@ impl Map {
tile_content: vec![Vec::new(); MAP_COUNT], tile_content: vec![Vec::new(); MAP_COUNT],
depth: new_depth, depth: new_depth,
bloodstains: HashSet::new(), bloodstains: HashSet::new(),
view_blocked: HashSet::new(),
} }
} }
} }
impl BaseMap for Map { impl BaseMap for Map {
fn is_opaque(&self, idx: usize) -> bool { fn is_opaque(&self, idx: usize) -> bool {
self.tiles[idx as usize] == TileType::Wall self.tiles[idx] == TileType::Wall || self.view_blocked.contains(&idx)
} }
fn get_available_exits(&self, idx: usize) -> SmallVec<[(usize, f32); 10]> { fn get_available_exits(&self, idx: usize) -> SmallVec<[(usize, f32); 10]> {

View File

@ -85,6 +85,8 @@ pub fn save_game(ecs: &mut World) {
EntryTrigger, EntryTrigger,
EntityMoved, EntityMoved,
SingleActivation, SingleActivation,
BlocksVisibility,
Door,
); );
} }
@ -174,6 +176,8 @@ pub fn load_game(ecs: &mut World) {
EntryTrigger, EntryTrigger,
EntityMoved, EntityMoved,
SingleActivation, SingleActivation,
BlocksVisibility,
Door,
); );
} }

View File

@ -388,6 +388,9 @@ fn door(ecs: &mut World, x: i32, y: i32) {
render_order: 2, render_order: 2,
}) })
.with(Name::from("Door")) .with(Name::from("Door"))
.with(BlocksTile {})
.with(BlocksVisibility {})
.with(Door { open: false })
.marked::<SimpleMarker<SerializeMe>>() .marked::<SimpleMarker<SerializeMe>>()
.build(); .build();
} }

View File

@ -1,7 +1,7 @@
use rltk::{field_of_view, Point}; use rltk::{field_of_view, Point, RandomNumberGenerator};
use specs::prelude::*; use specs::prelude::*;
use crate::components::{Hidden, Name}; use crate::components::{BlocksVisibility, Hidden, Name};
use crate::game_log::GameLog; use crate::game_log::GameLog;
use crate::{Map, Player, Position, Viewshed}; use crate::{Map, Player, Position, Viewshed};
@ -16,14 +16,31 @@ impl<'a> System<'a> for VisibilitySystem {
ReadStorage<'a, Position>, ReadStorage<'a, Position>,
ReadStorage<'a, Player>, ReadStorage<'a, Player>,
WriteStorage<'a, Hidden>, WriteStorage<'a, Hidden>,
WriteExpect<'a, rltk::RandomNumberGenerator>, WriteExpect<'a, RandomNumberGenerator>,
WriteExpect<'a, GameLog>, WriteExpect<'a, GameLog>,
ReadStorage<'a, Name>, ReadStorage<'a, Name>,
ReadStorage<'a, BlocksVisibility>,
); );
fn run(&mut self, data: Self::SystemData) { fn run(&mut self, data: Self::SystemData) {
let (mut map, entities, mut viewshed, pos, player, mut hidden, mut rng, mut log, names) = let (
data; mut map,
entities,
mut viewshed,
pos,
player,
mut hidden,
mut rng,
mut log,
names,
blocks_visibility,
) = data;
map.view_blocked.clear();
for (block_pos, _block) in (&pos, &blocks_visibility).join() {
let idx = map.xy_idx(block_pos.x, block_pos.y);
map.view_blocked.insert(idx);
}
for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() { for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() {
if viewshed.dirty { if viewshed.dirty {