Skip to content

Commit 08163e2

Browse files
committed
Fixup multi-tile indexing for dragon level.
1 parent c96d967 commit 08163e2

2 files changed

Lines changed: 48 additions & 36 deletions

File tree

book/src/chapter_67.md

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -543,50 +543,47 @@ Fortunately, we can solve a *lot* of this with the `map_indexing_system`. The sy
543543

544544
```rust
545545
use specs::prelude::*;
546-
use super::{Map, Position, BlocksTile, TileSize};
546+
use super::{Map, Position, BlocksTile, Pools, spatial, TileSize};
547547

548548
pub struct MapIndexingSystem {}
549549

550550
impl<'a> System<'a> for MapIndexingSystem {
551-
type SystemData = ( WriteExpect<'a, Map>,
551+
#[allow(clippy::type_complexity)]
552+
type SystemData = ( ReadExpect<'a, Map>,
552553
ReadStorage<'a, Position>,
553554
ReadStorage<'a, BlocksTile>,
555+
ReadStorage<'a, Pools>,
554556
ReadStorage<'a, TileSize>,
555557
Entities<'a>,);
556558

557559
fn run(&mut self, data : Self::SystemData) {
558-
let (mut map, position, blockers, sizes, entities) = data;
560+
let (map, position, blockers, pools, sizes, entities) = data;
559561

560-
map.populate_blocked();
561-
map.clear_content_index();
562+
spatial::clear();
563+
spatial::populate_blocked_from_map(&*map);
562564
for (entity, position) in (&entities, &position).join() {
563-
let idx = map.xy_idx(position.x, position.y);
564-
565-
if let Some(size) = sizes.get(entity) {
566-
// Multi-tile
567-
for y in position.y .. position.y + size.y {
568-
for x in position.x .. position.x + size.x {
569-
if x > 0 && x < map.width-1 && y > 0 && y < map.height-1 {
570-
let idx = map.xy_idx(x, y);
571-
if blockers.get(entity).is_some() {
572-
map.blocked[idx] = true;
565+
let mut alive = true;
566+
if let Some(pools) = pools.get(entity) {
567+
if pools.hit_points.current < 1 {
568+
alive = false;
569+
}
570+
}
571+
if alive {
572+
if let Some(size) = sizes.get(entity) {
573+
// Multi-tile
574+
for y in position.y .. position.y + size.y {
575+
for x in position.x .. position.x + size.x {
576+
if x > 0 && x < map.width-1 && y > 0 && y < map.height-1 {
577+
let idx = map.xy_idx(x, y);
578+
spatial::index_entity(entity, idx, blockers.get(entity).is_some());
573579
}
574-
575-
// Push the entity to the appropriate index slot. It's a Copy
576-
// type, so we don't need to clone it (we want to avoid moving it out of the ECS!)
577-
map.tile_content[idx].push(entity);
578580
}
579581
}
582+
} else {
583+
// Single tile
584+
let idx = map.xy_idx(position.x, position.y);
585+
spatial::index_entity(entity, idx, blockers.get(entity).is_some());
580586
}
581-
} else {
582-
// Single Tile
583-
if blockers.get(entity).is_some() {
584-
map.blocked[idx] = true;
585-
}
586-
587-
// Push the entity to the appropriate index slot. It's a Copy
588-
// type, so we don't need to clone it (we want to avoid moving it out of the ECS!)
589-
map.tile_content[idx].push(entity);
590587
}
591588
}
592589
}
@@ -849,18 +846,18 @@ pub fn populate_blocked_multi(&mut self, width : i32, height : i32) {
849846
for y in 1 .. self.height-1 {
850847
for x in 1 .. self.width - 1 {
851848
let idx = self.xy_idx(x, y);
852-
if !self.blocked[idx] {
849+
if !crate::spatial::is_blocked(idx) {
853850
for cy in 0..height {
854851
for cx in 0..width {
855852
let tx = x + cx;
856853
let ty = y + cy;
857854
if tx < self.width-1 && ty < self.height-1 {
858855
let tidx = self.xy_idx(tx, ty);
859-
if self.blocked[tidx] {
860-
self.blocked[idx] = true;
856+
if crate::spatial::is_blocked(tidx) {
857+
crate::spatial::set_blocked(idx, true);
861858
}
862859
} else {
863-
self.blocked[idx] = true;
860+
crate::spatial::set_blocked(idx, true);
864861
}
865862
}
866863
}

chapter-67-dragon/src/map_indexing_system.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
use specs::prelude::*;
2-
use super::{Map, Position, BlocksTile, Pools, spatial};
2+
use super::{Map, Position, BlocksTile, Pools, spatial, TileSize};
33

44
pub struct MapIndexingSystem {}
55

66
impl<'a> System<'a> for MapIndexingSystem {
7+
#[allow(clippy::type_complexity)]
78
type SystemData = ( ReadExpect<'a, Map>,
89
ReadStorage<'a, Position>,
910
ReadStorage<'a, BlocksTile>,
1011
ReadStorage<'a, Pools>,
12+
ReadStorage<'a, TileSize>,
1113
Entities<'a>,);
1214

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

1618
spatial::clear();
1719
spatial::populate_blocked_from_map(&*map);
@@ -23,8 +25,21 @@ impl<'a> System<'a> for MapIndexingSystem {
2325
}
2426
}
2527
if alive {
26-
let idx = map.xy_idx(position.x, position.y);
27-
spatial::index_entity(entity, idx, blockers.get(entity).is_some());
28+
if let Some(size) = sizes.get(entity) {
29+
// Multi-tile
30+
for y in position.y .. position.y + size.y {
31+
for x in position.x .. position.x + size.x {
32+
if x > 0 && x < map.width-1 && y > 0 && y < map.height-1 {
33+
let idx = map.xy_idx(x, y);
34+
spatial::index_entity(entity, idx, blockers.get(entity).is_some());
35+
}
36+
}
37+
}
38+
} else {
39+
// Single tile
40+
let idx = map.xy_idx(position.x, position.y);
41+
spatial::index_entity(entity, idx, blockers.get(entity).is_some());
42+
}
2843
}
2944
}
3045
}

0 commit comments

Comments
 (0)