Skip to content

Commit 0d4fd84

Browse files
committed
#59 #115 #57 - Spatial ported to chapter 73. Now to go back and bugfix.
1 parent 8000484 commit 0d4fd84

16 files changed

Lines changed: 73 additions & 88 deletions

chapter-73-systems/src/effects/damage.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ pub fn death(ecs: &mut World, effect: &EffectSpawner, target : Entity) {
5858
let mut attributes = ecs.write_storage::<Attributes>();
5959

6060
if let Some(pos) = entity_position(ecs, target) {
61-
let mut map_mut = ecs.fetch_mut::<Map>();
62-
map_mut.blocked[pos as usize] = false;
63-
std::mem::drop(map_mut);
61+
crate::spatial::remove_entity(target, pos as usize);
6462
}
6563

6664
if let Some(source) = effect.creator {

chapter-73-systems/src/effects/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ fn tile_effect_hits_entities(effect: &EffectType) -> bool {
109109

110110
fn affect_tile(ecs: &mut World, effect: &mut EffectSpawner, tile_idx : i32) {
111111
if tile_effect_hits_entities(&effect.effect_type) {
112-
let content = ecs.fetch::<Map>().tile_content[tile_idx as usize].clone();
112+
let content = crate::spatial::get_tile_content_clone(tile_idx as usize);
113113
content.iter().for_each(|entity| affect_entity(ecs, effect, *entity));
114114
}
115115

chapter-73-systems/src/gui/tooltips.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ pub fn draw_tooltips(ecs: &World, ctx : &mut Rltk) {
6666
if !map.visible_tiles[mouse_idx] { return; }
6767

6868
let mut tip_boxes : Vec<Tooltip> = Vec::new();
69-
for entity in map.tile_content[mouse_idx].iter().filter(|e| hidden.get(**e).is_none()) {
69+
crate::spatial::for_each_tile_content(mouse_idx, |entity| {
70+
if hidden.get(entity).is_some() { return; }
7071
let mut tip = Tooltip::new();
71-
tip.add(get_item_display_name(ecs, *entity));
72+
tip.add(get_item_display_name(ecs, entity));
7273

7374
// Comment on attributes
74-
let attr = attributes.get(*entity);
75+
let attr = attributes.get(entity);
7576
if let Some(attr) = attr {
7677
let mut s = "".to_string();
7778
if attr.might.bonus < 0 { s += "Weak. " };
@@ -89,7 +90,7 @@ pub fn draw_tooltips(ecs: &World, ctx : &mut Rltk) {
8990
}
9091

9192
// Comment on pools
92-
let stat = pools.get(*entity);
93+
let stat = pools.get(entity);
9394
if let Some(stat) = stat {
9495
tip.add(format!("Level: {}", stat.level));
9596
}
@@ -99,13 +100,13 @@ pub fn draw_tooltips(ecs: &World, ctx : &mut Rltk) {
99100
let durations = ecs.read_storage::<Duration>();
100101
let names = ecs.read_storage::<Name>();
101102
for (status, duration, name) in (&statuses, &durations, &names).join() {
102-
if status.target == *entity {
103+
if status.target == entity {
103104
tip.add(format!("{} ({})", name.name, duration.turns));
104105
}
105106
}
106107

107108
tip_boxes.push(tip);
108-
}
109+
});
109110

110111
if tip_boxes.is_empty() { return; }
111112

chapter-73-systems/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub mod effects;
2727
extern crate lazy_static;
2828
mod systems;
2929
pub mod rng;
30+
pub mod spatial;
3031

3132
const SHOW_MAPGEN_VISUALIZER : bool = false;
3233
const SHOW_FPS : bool = true;

chapter-73-systems/src/map/dungeon.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ impl MasterDungeonMap {
4444
pub fn get_map(&self, depth : i32) -> Option<Map> {
4545
if self.maps.contains_key(&depth) {
4646
let mut result = self.maps[&depth].clone();
47-
result.tile_content = vec![Vec::new(); (result.width * result.height) as usize];
4847
Some(result)
4948
} else {
5049
None

chapter-73-systems/src/map/mod.rs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,12 @@ pub struct Map {
1717
pub height : i32,
1818
pub revealed_tiles : Vec<bool>,
1919
pub visible_tiles : Vec<bool>,
20-
pub blocked : Vec<bool>,
2120
pub depth : i32,
2221
pub bloodstains : HashSet<usize>,
2322
pub view_blocked : HashSet<usize>,
2423
pub name : String,
2524
pub outdoors : bool,
2625
pub light : Vec<rltk::RGB>,
27-
28-
#[serde(skip_serializing)]
29-
#[serde(skip_deserializing)]
30-
pub tile_content : Vec<Vec<Entity>>
3126
}
3227

3328
impl Map {
@@ -38,32 +33,30 @@ impl Map {
3833
fn is_exit_valid(&self, x:i32, y:i32) -> bool {
3934
if x < 1 || x > self.width-1 || y < 1 || y > self.height-1 { return false; }
4035
let idx = self.xy_idx(x, y);
41-
!self.blocked[idx]
36+
!crate::spatial::is_blocked(idx)
4237
}
4338

4439
pub fn populate_blocked(&mut self) {
45-
for (i,tile) in self.tiles.iter_mut().enumerate() {
46-
self.blocked[i] = !tile_walkable(*tile);
47-
}
40+
crate::spatial::populate_blocked_from_map(self);
4841
}
4942

5043
pub fn populate_blocked_multi(&mut self, width : i32, height : i32) {
5144
self.populate_blocked();
5245
for y in 1 .. self.height-1 {
5346
for x in 1 .. self.width - 1 {
5447
let idx = self.xy_idx(x, y);
55-
if !self.blocked[idx] {
48+
if !crate::spatial::is_blocked(idx) {
5649
for cy in 0..height {
5750
for cx in 0..width {
5851
let tx = x + cx;
5952
let ty = y + cy;
6053
if tx < self.width-1 && ty < self.height-1 {
6154
let tidx = self.xy_idx(tx, ty);
62-
if self.blocked[tidx] {
63-
self.blocked[idx] = true;
55+
if crate::spatial::is_blocked(tidx) {
56+
crate::spatial::set_blocked(idx, true);
6457
}
6558
} else {
66-
self.blocked[idx] = true;
59+
crate::spatial::set_blocked(idx, true);
6760
}
6861
}
6962
}
@@ -73,22 +66,19 @@ impl Map {
7366
}
7467

7568
pub fn clear_content_index(&mut self) {
76-
for content in self.tile_content.iter_mut() {
77-
content.clear();
78-
}
69+
crate::spatial::clear();
7970
}
8071

8172
/// Generates an empty map, consisting entirely of solid walls
8273
pub fn new<S : ToString>(new_depth : i32, width: i32, height: i32, name: S) -> Map {
8374
let map_tile_count = (width*height) as usize;
75+
crate::spatial::set_size(map_tile_count);
8476
Map{
8577
tiles : vec![TileType::Wall; map_tile_count],
8678
width,
8779
height,
8880
revealed_tiles : vec![false; map_tile_count],
8981
visible_tiles : vec![false; map_tile_count],
90-
blocked : vec![false; map_tile_count],
91-
tile_content : vec![Vec::new(); map_tile_count],
9282
depth: new_depth,
9383
bloodstains: HashSet::new(),
9484
view_blocked : HashSet::new(),

chapter-73-systems/src/player.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ fn get_player_target_list(ecs : &mut World) -> Vec<(f32,Entity)> {
2626
let tile_idx = map.xy_idx(tile_point.x, tile_point.y);
2727
let distance_to_target = rltk::DistanceAlg::Pythagoras.distance2d(*tile_point, rltk::Point::new(player_pos.x, player_pos.y));
2828
if distance_to_target < range as f32 {
29-
for possible_target in map.tile_content[tile_idx].iter() {
30-
if *possible_target != *player_entity && factions.get(*possible_target).is_some() {
31-
possible_targets.push((distance_to_target, *possible_target));
29+
crate::spatial::for_each_tile_content(tile_idx, |possible_target| {
30+
if possible_target != *player_entity && factions.get(possible_target).is_some() {
31+
possible_targets.push((distance_to_target, possible_target));
3232
}
33-
}
33+
});
3434
}
3535
}
3636
}
@@ -133,14 +133,14 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState
133133
if pos.x + delta_x < 1 || pos.x + delta_x > map.width-1 || pos.y + delta_y < 1 || pos.y + delta_y > map.height-1 { return RunState::AwaitingInput; }
134134
let destination_idx = map.xy_idx(pos.x + delta_x, pos.y + delta_y);
135135

136-
for potential_target in map.tile_content[destination_idx].iter() {
137-
if let Some(_vendor) = vendors.get(*potential_target) {
138-
return RunState::ShowVendor{ vendor: *potential_target, mode : VendorMode::Sell }
136+
crate::spatial::for_each_tile_content(destination_idx, |potential_target| {
137+
if let Some(_vendor) = vendors.get(potential_target) {
138+
result = RunState::ShowVendor{ vendor: potential_target, mode : VendorMode::Sell }
139139
}
140140

141141
let mut hostile = true;
142-
if combat_stats.get(*potential_target).is_some() {
143-
if let Some(faction) = factions.get(*potential_target) {
142+
if combat_stats.get(potential_target).is_some() {
143+
if let Some(faction) = factions.get(potential_target) {
144144
let reaction = crate::raws::faction_reaction(
145145
&faction.name,
146146
"Player",
@@ -151,7 +151,7 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState
151151
}
152152
if !hostile {
153153
// Note that we want to move the bystander
154-
swap_entities.push((*potential_target, pos.x, pos.y));
154+
swap_entities.push((potential_target, pos.x, pos.y));
155155

156156
// Move the player
157157
pos.x = min(map.width-1 , max(0, pos.x + delta_x));
@@ -162,26 +162,27 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState
162162
let mut ppos = ecs.write_resource::<Point>();
163163
ppos.x = pos.x;
164164
ppos.y = pos.y;
165+
result = RunState::Ticking;
165166
} else {
166-
let target = combat_stats.get(*potential_target);
167+
let target = combat_stats.get(potential_target);
167168
if let Some(_target) = target {
168-
wants_to_melee.insert(entity, WantsToMelee{ target: *potential_target }).expect("Add target failed");
169-
return RunState::Ticking;
169+
wants_to_melee.insert(entity, WantsToMelee{ target: potential_target }).expect("Add target failed");
170+
result = RunState::Ticking;
170171
}
171172
}
172-
let door = doors.get_mut(*potential_target);
173+
let door = doors.get_mut(potential_target);
173174
if let Some(door) = door {
174175
door.open = true;
175-
blocks_visibility.remove(*potential_target);
176-
blocks_movement.remove(*potential_target);
177-
let glyph = renderables.get_mut(*potential_target).unwrap();
176+
blocks_visibility.remove(potential_target);
177+
blocks_movement.remove(potential_target);
178+
let glyph = renderables.get_mut(potential_target).unwrap();
178179
glyph.glyph = rltk::to_cp437('/');
179180
viewshed.dirty = true;
180181
result = RunState::Ticking;
181182
}
182-
}
183+
});
183184

184-
if !map.blocked[destination_idx] {
185+
if !crate::spatial::is_blocked(destination_idx) {
185186
pos.x = min(map.width-1 , max(0, pos.x + delta_x));
186187
pos.y = min(map.height-1, max(0, pos.y + delta_y));
187188
entity_moved.insert(entity, EntityMoved{}).expect("Unable to insert marker");
@@ -268,8 +269,8 @@ fn skip_turn(ecs: &mut World) -> RunState {
268269
let viewshed = viewshed_components.get(*player_entity).unwrap();
269270
for tile in viewshed.visible_tiles.iter() {
270271
let idx = worldmap_resource.xy_idx(tile.x, tile.y);
271-
for entity_id in worldmap_resource.tile_content[idx].iter() {
272-
let faction = factions.get(*entity_id);
272+
crate::spatial::for_each_tile_content(idx, |entity_id| {
273+
let faction = factions.get(entity_id);
273274
match faction {
274275
None => {}
275276
Some(faction) => {
@@ -283,7 +284,7 @@ fn skip_turn(ecs: &mut World) -> RunState {
283284
}
284285
}
285286
}
286-
}
287+
});
287288
}
288289

289290
let hunger_clocks = ecs.read_storage::<HungerClock>();

chapter-73-systems/src/saveload_system.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub fn load_game(ecs: &mut World) {
137137
for (e,h) in (&entities, &helper).join() {
138138
let mut worldmap = ecs.write_resource::<super::map::Map>();
139139
*worldmap = h.map.clone();
140-
worldmap.tile_content = vec![Vec::new(); (worldmap.height * worldmap.width) as usize];
140+
crate::spatial::set_size((worldmap.height * worldmap.width) as usize);
141141
deleteme = Some(e);
142142
}
143143
for (e,h) in (&entities, &helper2).join() {

chapter-73-systems/src/systems/ai/adjacent_ai_system.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ impl<'a> System<'a> for AdjacentAI {
7171
}
7272

7373
fn evaluate(idx : usize, map : &Map, factions : &ReadStorage<Faction>, my_faction : &str, reactions : &mut Vec<(Entity, Reaction)>) {
74-
for other_entity in map.tile_content[idx].iter() {
75-
if let Some(faction) = factions.get(*other_entity) {
74+
crate::spatial::for_each_tile_content(idx, |other_entity| {
75+
if let Some(faction) = factions.get(other_entity) {
7676
reactions.push((
77-
*other_entity,
77+
other_entity,
7878
crate::raws::faction_reaction(my_faction, &faction.name, &crate::raws::RAWS.lock().unwrap())
7979
));
8080
}
81-
}
81+
});
8282
}

chapter-73-systems/src/systems/ai/default_move_system.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ impl<'a> System<'a> for DefaultMoveAI {
4141

4242
if x > 0 && x < map.width-1 && y > 0 && y < map.height-1 {
4343
let dest_idx = map.xy_idx(x, y);
44-
if !map.blocked[dest_idx] {
45-
apply_move.insert(entity, ApplyMove{ dest_idx : dest_idx })
44+
if !crate::spatial::is_blocked(dest_idx) {
45+
apply_move.insert(entity, ApplyMove{ dest_idx })
4646
.expect("Unable to insert");
4747
turn_done.push(entity);
4848
}
@@ -53,7 +53,7 @@ impl<'a> System<'a> for DefaultMoveAI {
5353
if let Some(path) = path {
5454
// We have a target - go there
5555
if path.len()>1 {
56-
if !map.blocked[path[1] as usize] {
56+
if !crate::spatial::is_blocked(path[1] as usize) {
5757
apply_move.insert(entity, ApplyMove{ dest_idx : path[1] })
5858
.expect("Unable to insert");
5959
path.remove(0); // Remove the first step in the path

0 commit comments

Comments
 (0)