diff --git a/Cargo.toml b/Cargo.toml index 543c203..32c5f54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,12 @@ criterion = { version = "^0.5" } [[bench]] name = "systems_benchmark" -harness = false \ No newline at end of file +harness = false + +# Enable max optimizations for dependencies, but not for our code: +[profile.dev.package."*"] +opt-level = 3 + +# Enable only a small amount of optimization in debug mode +# [profile.dev] +# opt-level = 1 \ No newline at end of file diff --git a/src/ai/approach_ai_system.rs b/src/ai/approach_ai_system.rs new file mode 100644 index 0000000..2b54286 --- /dev/null +++ b/src/ai/approach_ai_system.rs @@ -0,0 +1,60 @@ +use crate::{EntityMoved, Map, Position, TakingTurn, Telepath, Viewshed, WantsToApproach}; +use rltk::prelude::*; +use specs::prelude::*; + +pub struct ApproachAI {} + +impl<'a> System<'a> for ApproachAI { + #[allow(clippy::type_complexity)] + type SystemData = ( + WriteStorage<'a, TakingTurn>, + WriteStorage<'a, WantsToApproach>, + WriteStorage<'a, Position>, + WriteExpect<'a, Map>, + WriteStorage<'a, Viewshed>, + WriteStorage<'a, Telepath>, + WriteStorage<'a, EntityMoved>, + Entities<'a>, + ); + + fn run(&mut self, data: Self::SystemData) { + let ( + mut turns, + mut wants_to_approach, + mut positions, + mut map, + mut viewsheds, + mut telepaths, + mut entity_moved, + entities, + ) = data; + let mut turn_done: Vec = Vec::new(); + for (entity, mut pos, approach, mut viewshed, _turn) in + (&entities, &mut positions, &wants_to_approach, &mut viewsheds, &turns).join() + { + turn_done.push(entity); + let path = a_star_search( + map.xy_idx(pos.x, pos.y) as i32, + map.xy_idx(approach.idx % map.width, approach.idx / map.width) as i32, + &mut *map, + ); + if path.success && path.steps.len() > 1 { + let mut idx = map.xy_idx(pos.x, pos.y); + map.blocked[idx] = false; + pos.x = path.steps[1] as i32 % map.width; + pos.y = path.steps[1] as i32 / map.width; + entity_moved.insert(entity, EntityMoved {}).expect("Unable to insert EntityMoved"); + idx = map.xy_idx(pos.x, pos.y); + map.blocked[idx] = true; + viewshed.dirty = true; + if let Some(telepath) = telepaths.get_mut(entity) { + telepath.dirty = true; + } + } + } + wants_to_approach.clear(); + for done in turn_done.iter() { + turns.remove(*done); + } + } +} diff --git a/src/ai/mod.rs b/src/ai/mod.rs index 0b54d07..8703344 100644 --- a/src/ai/mod.rs +++ b/src/ai/mod.rs @@ -16,3 +16,5 @@ mod adjacent_ai_system; pub use adjacent_ai_system::AdjacentAI; mod visible_ai_system; pub use visible_ai_system::VisibleAI; +mod approach_ai_system; +pub use approach_ai_system::ApproachAI; diff --git a/src/ai/visible_ai_system.rs b/src/ai/visible_ai_system.rs index b675d0b..720d74e 100644 --- a/src/ai/visible_ai_system.rs +++ b/src/ai/visible_ai_system.rs @@ -9,7 +9,7 @@ pub struct VisibleAI {} impl<'a> System<'a> for VisibleAI { #[allow(clippy::type_complexity)] type SystemData = ( - WriteStorage<'a, TakingTurn>, + ReadStorage<'a, TakingTurn>, ReadStorage<'a, Faction>, ReadStorage<'a, Position>, ReadExpect<'a, Map>, @@ -24,7 +24,7 @@ impl<'a> System<'a> for VisibleAI { fn run(&mut self, data: Self::SystemData) { let ( - mut turns, + turns, factions, positions, map, diff --git a/src/main.rs b/src/main.rs index 73713b4..8a605a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -98,6 +98,7 @@ impl State { let mut quip_system = ai::QuipSystem {}; let mut adjacent_ai = ai::AdjacentAI {}; let mut visible_ai = ai::VisibleAI {}; + let mut approach_ai = ai::ApproachAI {}; let mut mob = ai::MonsterAI {}; let mut bystanders = ai::BystanderAI {}; let mut trigger_system = trigger_system::TriggerSystem {}; @@ -120,6 +121,7 @@ impl State { quip_system.run_now(&self.ecs); adjacent_ai.run_now(&self.ecs); visible_ai.run_now(&self.ecs); + approach_ai.run_now(&self.ecs); mob.run_now(&self.ecs); bystanders.run_now(&self.ecs); trigger_system.run_now(&self.ecs);