From e93573f3a02f6c325c0ee5c0c85e3307b3050173 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 24 Dec 2021 14:44:48 -0500 Subject: [PATCH] Complete section 5.5 by swapping locations with non-hostile NPCs --- src/main.rs | 3 ++- src/player.rs | 49 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 40e0003..44bce10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -402,7 +402,8 @@ impl State { } // Build a new map and place the player - let current_depth; + #[allow(unused_assignments)] + let mut current_depth = 1; { let worldmap_resource = self.ecs.fetch::(); current_depth = worldmap_resource.depth; diff --git a/src/player.rs b/src/player.rs index 0bbefd0..02f9e36 100644 --- a/src/player.rs +++ b/src/player.rs @@ -8,7 +8,7 @@ use crate::components::{ Monster, Player, Position, Renderable, Viewshed, WantsToMelee, WantsToPickupItem, }; use crate::game_log::GameLog; -use crate::{Map, RunState, State, TileType}; +use crate::{Bystander, Map, RunState, State, TileType}; pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) { let mut positions = ecs.write_storage::(); @@ -23,6 +23,9 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) { let mut blocks_visibility = ecs.write_storage::(); let mut blocks_movement = ecs.write_storage::(); let mut renderables = ecs.write_storage::(); + let bystanders = ecs.read_storage::(); + + let mut swap_entities: Vec<(Entity, i32, i32)> = Vec::new(); for (entity, _player, pos, viewshed) in (&entities, &players, &mut positions, &mut viewsheds).join() @@ -37,16 +40,33 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) { let destination_idx = map.xy_idx(pos.x + delta_x, pos.y + delta_y); for potential_target in map.tile_content[destination_idx].iter() { - if let Some(_target) = combat_stats.get(*potential_target) { - wants_to_melee - .insert( - entity, - WantsToMelee { - target: *potential_target, - }, - ) - .expect("Add target failed"); - return; + if bystanders.get(*potential_target).is_some() { + // Note that we want to move the bystander + swap_entities.push((*potential_target, pos.x, pos.y)); + + // Move the player + pos.x = min(map.width - 1, max(0, pos.x + delta_x)); + pos.y = min(map.height - 1, max(0, pos.y + delta_y)); + entity_moved + .insert(entity, EntityMoved {}) + .expect("Unable to insert moved entity marker"); + + viewshed.dirty = true; + let mut ppos = ecs.write_resource::(); + ppos.x = pos.x; + ppos.y = pos.y + } else { + if combat_stats.get(*potential_target).is_some() { + wants_to_melee + .insert( + entity, + WantsToMelee { + target: *potential_target, + }, + ) + .expect("Add target failed"); + return; + } } if let Some(door) = doors.get_mut(*potential_target) { @@ -73,6 +93,13 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) { ppos.y = pos.y; } } + + for m in swap_entities.iter() { + if let Some(their_pos) = positions.get_mut(m.0) { + their_pos.x = m.1; + their_pos.y = m.2; + } + } } pub fn try_next_level(ecs: &mut World) -> bool {