summaryrefslogtreecommitdiff
path: root/src/systems
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
parentd246537a28a7a71dfb2487d31d6fac3ccab5053d (diff)
added monster ai
Diffstat (limited to 'src/systems')
-rw-r--r--src/systems/controlai.rs81
-rw-r--r--src/systems/controlinput.rs1
-rw-r--r--src/systems/fight.rs12
-rw-r--r--src/systems/mod.rs4
-rw-r--r--src/systems/updatecooldowns.rs8
5 files changed, 100 insertions, 6 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
+ }
+ }
+ }
+}
+
diff --git a/src/systems/controlinput.rs b/src/systems/controlinput.rs
index 6d5b4ea..1a582e4 100644
--- a/src/systems/controlinput.rs
+++ b/src/systems/controlinput.rs
@@ -26,7 +26,6 @@ impl <'a> System<'a> for ControlInput {
WriteStorage<'a, Autofight>
);
fn run(&mut self, (entities, mut input, mut controllers, players, cooldowns, mut autofighters): Self::SystemData) {
- controllers.clear();
for (player, entity, ()) in (&players, &entities, !&cooldowns).join() {
if let Some(control) = input.actions.remove(&player.id){
diff --git a/src/systems/fight.rs b/src/systems/fight.rs
index 182dba6..703ea4a 100644
--- a/src/systems/fight.rs
+++ b/src/systems/fight.rs
@@ -52,7 +52,17 @@ impl <'a> System<'a> for Fight {
}
}
}
- Control::AttackTarget(t) => {target = Some(*t);}
+ Control::AttackTarget(t) => {
+ if *t == entity { // don't knock yourself out
+ if let Some(autofighter) = autofighters.get_mut(entity){
+ autofighter.target = None;
+ }
+ } else if let Some(target_position) = positions.get(*t){
+ if position.pos.distance_to(target_position.pos) <= fighter.range {
+ target = Some(*t);
+ }
+ }
+ }
_ => {}
}
if let Some(ent) = target {
diff --git a/src/systems/mod.rs b/src/systems/mod.rs
index 24ed3df..221ffc4 100644
--- a/src/systems/mod.rs
+++ b/src/systems/mod.rs
@@ -14,6 +14,7 @@ mod fight;
mod heal;
mod volate;
mod updatecooldowns;
+mod controlai;
pub use self::{
controlinput::ControlInput,
@@ -30,5 +31,6 @@ pub use self::{
fight::Fight,
heal::Heal,
volate::Volate,
- updatecooldowns::UpdateCooldowns
+ updatecooldowns::UpdateCooldowns,
+ controlai::ControlAI
};
diff --git a/src/systems/updatecooldowns.rs b/src/systems/updatecooldowns.rs
index 73ca770..705561d 100644
--- a/src/systems/updatecooldowns.rs
+++ b/src/systems/updatecooldowns.rs
@@ -6,16 +6,18 @@ use specs::{
Join
};
-use crate::components::ControlCooldown;
+use crate::components::{Controller, ControlCooldown};
pub struct UpdateCooldowns;
impl <'a> System<'a> for UpdateCooldowns {
type SystemData = (
Entities<'a>,
- WriteStorage<'a, ControlCooldown>
+ WriteStorage<'a, ControlCooldown>,
+ WriteStorage<'a, Controller>
);
- fn run(&mut self, (entities, mut cooldowns): Self::SystemData) {
+ fn run(&mut self, (entities, mut cooldowns, mut controllers): Self::SystemData) {
+ controllers.clear();
let mut to_remove = Vec::new();
for (entity, cooldown) in (&entities, &mut cooldowns).join() {
if cooldown.amount > 0 {