From 3a43150bc5d66bc56bcafbfd28e256e7ddb65c8e Mon Sep 17 00:00:00 2001 From: timokoesters Date: Fri, 2 Aug 2019 22:25:33 +0200 Subject: [PATCH] Make hostile npcs back away when too close --- common/src/sys/agent.rs | 85 +++++++++++++++++++++----------------- common/src/sys/movement.rs | 2 +- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index 82d887e997..e31aeeddbb 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -1,4 +1,4 @@ -use crate::comp::{Agent, Controller, Pos}; +use crate::comp::{Agent, Controller, Pos, Stats}; use rand::{seq::SliceRandom, thread_rng}; use specs::{Entities, Join, ReadStorage, System, WriteStorage}; use vek::*; @@ -8,14 +8,15 @@ pub struct Sys; impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, - WriteStorage<'a, Agent>, ReadStorage<'a, Pos>, + ReadStorage<'a, Stats>, + WriteStorage<'a, Agent>, WriteStorage<'a, Controller>, ); - fn run(&mut self, (entities, mut agents, positions, mut controllers): Self::SystemData) { - for (entity, agent, pos, controller) in - (&entities, &mut agents, &positions, &mut controllers).join() + fn run(&mut self, (entities, positions, stats, mut agents, mut controllers): Self::SystemData) { + for (entity, pos, agent, controller) in + (&entities, &positions, &mut agents, &mut controllers).join() { match agent { Agent::Wanderer(bearing) => { @@ -60,52 +61,58 @@ impl<'a> System<'a> for Sys { } Agent::Enemy { bearing, target } => { const SIGHT_DIST: f32 = 30.0; + let mut choose_new = false; - let choose_new = match target.map(|tgt| positions.get(tgt)).flatten() { - Some(tgt_pos) => { - let dist = Vec2::::from(tgt_pos.0 - pos.0).magnitude(); - if dist < 2.0 { - controller.move_dir = Vec2::zero(); + if let Some((Some(target_pos), Some(target_stats))) = + target.map(|target| (positions.get(target), stats.get(target))) + { + let dist = Vec2::::from(target_pos.0 - pos.0).magnitude(); + if target_stats.is_dead { + choose_new = true; + } else if dist < 3.0 { + // Get more distance + controller.move_dir = + Vec2::::from(target_pos.0 - pos.0).normalized() * -0.96; + } else if dist < 4.0 { + // Fight and slowly move closer + controller.move_dir = + Vec2::::from(target_pos.0 - pos.0).normalized() * 0.01; - if rand::random::() < 0.05 { - controller.attack = true; - } else { - controller.attack = false; - } - - false - } else if dist < SIGHT_DIST { - controller.move_dir = - Vec2::::from(tgt_pos.0 - pos.0).normalized(); - - false + if rand::random::() < 0.1 { + controller.attack = true; } else { - true + controller.attack = false; } + } else if dist < SIGHT_DIST { + controller.move_dir = + Vec2::::from(target_pos.0 - pos.0).normalized() * 0.96; + } else { + choose_new = true; } - None => { - *bearing += - Vec2::new(rand::random::() - 0.5, rand::random::() - 0.5) - * 0.1 - - *bearing * 0.005; + } else { + *bearing += + Vec2::new(rand::random::() - 0.5, rand::random::() - 0.5) + * 0.1 + - *bearing * 0.005; - controller.move_dir = if bearing.magnitude_squared() > 0.1 { - bearing.normalized() - } else { - Vec2::zero() - }; - true - } - }; + controller.move_dir = if bearing.magnitude_squared() > 0.1 { + bearing.normalized() + } else { + Vec2::zero() + }; + + choose_new = true; + } if choose_new && rand::random::() < 0.1 { - let entities = (&entities, &positions) + let entities = (&entities, &positions, &stats) .join() - .filter(|(e, e_pos)| { + .filter(|(e, e_pos, e_stats)| { Vec2::::from(e_pos.0 - pos.0).magnitude() < SIGHT_DIST && *e != entity + && !e_stats.is_dead }) - .map(|(e, _)| e) + .map(|(e, _, _)| e) .collect::>(); let mut rng = thread_rng(); diff --git a/common/src/sys/movement.rs b/common/src/sys/movement.rs index f278655d72..68ab82e9ef 100644 --- a/common/src/sys/movement.rs +++ b/common/src/sys/movement.rs @@ -126,7 +126,7 @@ impl<'a> System<'a> for Sys { } // Set direction based on velocity when on the ground - if Vec2::::from(vel.0).magnitude_squared() > 0.1 { + if Vec2::::from(vel.0).magnitude_squared() > 0.0001 { ori.0 = Lerp::lerp( ori.0, vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0),