Skip to content

Commit 2d035c8

Browse files
committed
Missing file again.
1 parent 0d4fd84 commit 2d035c8

2 files changed

Lines changed: 118 additions & 32 deletions

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use std::sync::Mutex;
2+
use specs::prelude::*;
3+
use crate::{ Map, tile_walkable };
4+
5+
struct SpatialMap {
6+
blocked : Vec<(bool, bool)>,
7+
tile_content : Vec<Vec<(Entity, bool)>>
8+
}
9+
10+
impl SpatialMap {
11+
fn new() -> Self {
12+
Self {
13+
blocked: Vec::new(),
14+
tile_content: Vec::new()
15+
}
16+
}
17+
}
18+
19+
lazy_static! {
20+
static ref SPATIAL_MAP : Mutex<SpatialMap> = Mutex::new(SpatialMap::new());
21+
}
22+
23+
pub fn set_size(map_tile_count: usize) {
24+
let mut lock = SPATIAL_MAP.lock().unwrap();
25+
lock.blocked = vec![(false, false); map_tile_count];
26+
lock.tile_content = vec![Vec::new(); map_tile_count];
27+
}
28+
29+
pub fn clear() {
30+
let mut lock = SPATIAL_MAP.lock().unwrap();
31+
lock.blocked.iter_mut().for_each(|b| { b.0 = false; b.1 = false; });
32+
for content in lock.tile_content.iter_mut() {
33+
content.clear();
34+
}
35+
}
36+
37+
pub fn populate_blocked_from_map(map: &Map) {
38+
let mut lock = SPATIAL_MAP.lock().unwrap();
39+
for (i,tile) in map.tiles.iter().enumerate() {
40+
lock.blocked[i].0 = !tile_walkable(*tile);
41+
}
42+
}
43+
44+
pub fn index_entity(entity: Entity, idx: usize, blocks_tile: bool) {
45+
let mut lock = SPATIAL_MAP.lock().unwrap();
46+
lock.tile_content[idx].push((entity, blocks_tile));
47+
if blocks_tile {
48+
lock.blocked[idx].1 = true;
49+
}
50+
}
51+
52+
pub fn is_blocked(idx: usize) -> bool {
53+
let lock = SPATIAL_MAP.lock().unwrap();
54+
lock.blocked[idx].0 || lock.blocked[idx].1
55+
}
56+
57+
pub fn set_blocked(idx: usize, blocked: bool) {
58+
let mut lock = SPATIAL_MAP.lock().unwrap();
59+
lock.blocked[idx] = (lock.blocked[idx].0, blocked);
60+
}
61+
62+
pub fn for_each_tile_content<F>(idx: usize, mut f: F)
63+
where F : FnMut(Entity)
64+
{
65+
let lock = SPATIAL_MAP.lock().unwrap();
66+
for entity in lock.tile_content[idx].iter() {
67+
f(entity.0);
68+
}
69+
}
70+
71+
pub fn get_tile_content_clone(idx:usize) -> Vec<Entity> {
72+
let lock = SPATIAL_MAP.lock().unwrap();
73+
lock.tile_content[idx].iter().map(|(e,_)| *e).collect()
74+
}
75+
76+
pub fn move_entity(entity: Entity, moving_from: usize, moving_to: usize) {
77+
let mut lock = SPATIAL_MAP.lock().unwrap();
78+
let mut entity_blocks = false;
79+
lock.tile_content[moving_from].retain(|(e, blocks) | {
80+
if *e == entity {
81+
entity_blocks = *blocks;
82+
false
83+
} else {
84+
true
85+
}
86+
});
87+
lock.tile_content[moving_to].push((entity, entity_blocks));
88+
89+
// Recalculate blocks for both tiles
90+
let mut from_blocked = false;
91+
let mut to_blocked = false;
92+
lock.tile_content[moving_from].iter().for_each(|(_,blocks)| if *blocks { from_blocked = true; } );
93+
lock.tile_content[moving_to].iter().for_each(|(_,blocks)| if *blocks { to_blocked = true; } );
94+
lock.blocked[moving_from].1 = from_blocked;
95+
lock.blocked[moving_to].1 = to_blocked;
96+
}
97+
98+
pub fn remove_entity(entity: Entity, idx: usize) {
99+
let mut lock = SPATIAL_MAP.lock().unwrap();
100+
lock.tile_content[idx].retain(|(e, _)| *e != entity );
101+
let mut from_blocked = false;
102+
lock.tile_content[idx].iter().for_each(|(_,blocks)| if *blocks { from_blocked = true; } );
103+
lock.blocked[idx].1 = from_blocked;
104+
}

chapter-73-systems/src/systems/map_indexing_system.rs

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,30 @@
11
use specs::prelude::*;
2-
use crate::{Map, Position, BlocksTile, TileSize};
2+
use crate::{Map, Position, BlocksTile, Pools, spatial};
33

44
pub struct MapIndexingSystem {}
55

66
impl<'a> System<'a> for MapIndexingSystem {
7-
type SystemData = ( WriteExpect<'a, Map>,
7+
type SystemData = ( ReadExpect<'a, Map>,
88
ReadStorage<'a, Position>,
99
ReadStorage<'a, BlocksTile>,
10-
ReadStorage<'a, TileSize>,
10+
ReadStorage<'a, Pools>,
1111
Entities<'a>,);
1212

1313
fn run(&mut self, data : Self::SystemData) {
14-
let (mut map, position, blockers, sizes, entities) = data;
14+
let (map, position, blockers, pools, entities) = data;
1515

16-
map.populate_blocked();
17-
map.clear_content_index();
16+
spatial::clear();
17+
spatial::populate_blocked_from_map(&*map);
1818
for (entity, position) in (&entities, &position).join() {
19-
let idx = map.xy_idx(position.x, position.y);
20-
21-
if let Some(size) = sizes.get(entity) {
22-
// Multi-tile
23-
for y in position.y .. position.y + size.y {
24-
for x in position.x .. position.x + size.x {
25-
if x > 0 && x < map.width-1 && y > 0 && y < map.height-1 {
26-
let idx = map.xy_idx(x, y);
27-
if blockers.get(entity).is_some() {
28-
crate::spatial::set_blocked(idx, true);
29-
}
30-
31-
// Push the entity to the appropriate index slot. It's a Copy
32-
// type, so we don't need to clone it (we want to avoid moving it out of the ECS!)
33-
crate::spatial::index_entity(entity, idx, true);
34-
}
35-
}
36-
}
37-
} else {
38-
// Single Tile
39-
if blockers.get(entity).is_some() {
40-
crate::spatial::set_blocked(idx, true);
19+
let mut alive = true;
20+
if let Some(pools) = pools.get(entity) {
21+
if pools.hit_points.current < 1 {
22+
alive = false;
4123
}
42-
43-
// Push the entity to the appropriate index slot. It's a Copy
44-
// type, so we don't need to clone it (we want to avoid moving it out of the ECS!)
45-
crate::spatial::index_entity(entity, idx, true);
24+
}
25+
if alive {
26+
let idx = map.xy_idx(position.x, position.y);
27+
spatial::index_entity(entity, idx, blockers.get(entity).is_some());
4628
}
4729
}
4830
}

0 commit comments

Comments
 (0)