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)]
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
// Entity.

View File

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

View File

@ -25,6 +25,7 @@ pub struct Map {
pub blocked: Vec<bool>,
pub depth: i32,
pub bloodstains: HashSet<usize>,
pub view_blocked: HashSet<usize>,
#[serde(skip_serializing)]
#[serde(skip_deserializing)]
@ -70,13 +71,14 @@ impl Map {
tile_content: vec![Vec::new(); MAP_COUNT],
depth: new_depth,
bloodstains: HashSet::new(),
view_blocked: HashSet::new(),
}
}
}
impl BaseMap for Map {
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]> {

View File

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

View File

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

View File

@ -1,7 +1,7 @@
use rltk::{field_of_view, Point};
use rltk::{field_of_view, Point, RandomNumberGenerator};
use specs::prelude::*;
use crate::components::{Hidden, Name};
use crate::components::{BlocksVisibility, Hidden, Name};
use crate::game_log::GameLog;
use crate::{Map, Player, Position, Viewshed};
@ -16,14 +16,31 @@ impl<'a> System<'a> for VisibilitySystem {
ReadStorage<'a, Position>,
ReadStorage<'a, Player>,
WriteStorage<'a, Hidden>,
WriteExpect<'a, rltk::RandomNumberGenerator>,
WriteExpect<'a, RandomNumberGenerator>,
WriteExpect<'a, GameLog>,
ReadStorage<'a, Name>,
ReadStorage<'a, BlocksVisibility>,
);
fn run(&mut self, data: Self::SystemData) {
let (mut map, entities, mut viewshed, pos, player, mut hidden, mut rng, mut log, names) =
data;
let (
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() {
if viewshed.dirty {