summaryrefslogtreecommitdiff
path: root/src/systems/controlai.rs
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-03-02 12:02:54 +0100
committertroido <troido@protonmail.com>2020-03-02 12:02:54 +0100
commit27c0795fb70739ce5609a0f424d80491d4a8c5a1 (patch)
tree1a6ab802edb717a42ca67a8d997cf960d7f4f5ed /src/systems/controlai.rs
parentd246537a28a7a71dfb2487d31d6fac3ccab5053d (diff)
added monster ai
Diffstat (limited to 'src/systems/controlai.rs')
-rw-r--r--src/systems/controlai.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/systems/controlai.rs b/src/systems/controlai.rs
new file mode 100644
index 0000000..9d49b41
--- /dev/null
+++ b/src/systems/controlai.rs
@@ -0,0 +1,81 @@
+
+
+use rand::Rng;
+
+use specs::{
+ ReadStorage,
+ WriteStorage,
+ Entities,
+ System,
+ Join
+};
+
+use crate::{
+ components::{Controller, ControlCooldown, Fighter, MonsterAI, Home, Health, Position},
+ controls::{Control, Direction::{North, South, East, West}}
+};
+
+
+pub struct ControlAI;
+impl <'a> System<'a> for ControlAI {
+ type SystemData = (
+ Entities<'a>,
+ WriteStorage<'a, Controller>,
+ ReadStorage<'a, ControlCooldown>,
+ ReadStorage<'a, MonsterAI>,
+ ReadStorage<'a, Fighter>,
+ ReadStorage<'a, Home>,
+ ReadStorage<'a, Health>,
+ ReadStorage<'a, Position>
+ );
+ fn run(&mut self, (entities, mut controllers, cooldowns, ais, fighters, homes, healths, positions): Self::SystemData) {
+
+ for (entity, ai, position, ()) in (&entities, &ais, &positions, !&cooldowns).join() {
+ if let Some(fighter) = fighters.get(entity) {
+ let mut closest_distance = ai.view_distance + 1;
+ let mut closest = None;
+ let mut closest_position = None;
+ for (target, target_position, _) in (&entities, &positions, &healths).join() {
+ if target == entity {
+ continue;
+ }
+ let distance = position.pos.distance_to(target_position.pos);
+ if distance < closest_distance {
+ closest_distance = distance;
+ closest = Some(target);
+ closest_position = Some(target_position);
+ }
+ }
+ if let Some(target) = closest {
+ if closest_distance <= fighter.range {
+ controllers.insert(entity, Controller{control: Control::AttackTarget(target)}).unwrap();
+ } else {
+ let p = position.pos;
+ let t = closest_position.unwrap().pos;
+ let mut directions = Vec::new();
+ if t.x > p.x {directions.push(East);}
+ else if t.x < p.x {directions.push(West);}
+ if t.y > p.y {directions.push(South);}
+ else if t.y < p.y {directions.push(North);}
+ if !directions.is_empty() {
+ let direction = directions[rand::thread_rng().gen_range(0, directions.len())];
+ controllers.insert(entity, Controller{control: Control::Move(direction)}).unwrap();
+ }
+ }
+ return;
+ }
+ }
+ if rand::thread_rng().gen_range(0.0, 1.0) < ai.move_chance {
+ let direction = [North, South, East, West][rand::thread_rng().gen_range(0, 4)];
+ controllers.insert(entity, Controller{control: Control::Move(direction)}).unwrap();
+// home = roomData.getComponent(obj, Home)
+// if home is not None and home.home.inRoom() and random.random() < (ai.homesickness * pathfinding.distanceBetween(obj, home.home)):
+// direction = pathfinding.stepTo(obj, home.home)
+// else:
+// direction = random.choice(["north", "south", "east", "west"])
+// movable.direction = direction
+ }
+ }
+ }
+}
+