Merge branch 'tygyh/Refactor-path_toward_target' into 'master'

Tygyh/refactor path toward target

See merge request veloren/veloren!3241
This commit is contained in:
Samuel Keiffer 2022-03-08 16:43:37 +00:00
commit a411db17bf
3 changed files with 452 additions and 127 deletions

View File

@ -12,7 +12,7 @@ use crate::{
IDLE_HEALING_ITEM_THRESHOLD, MAX_FLEE_DIST, MAX_FOLLOW_DIST, PARTIAL_PATH_DIST, IDLE_HEALING_ITEM_THRESHOLD, MAX_FLEE_DIST, MAX_FOLLOW_DIST, PARTIAL_PATH_DIST,
RETARGETING_THRESHOLD_SECONDS, SEPARATION_BIAS, SEPARATION_DIST, RETARGETING_THRESHOLD_SECONDS, SEPARATION_BIAS, SEPARATION_DIST,
}, },
data::{AgentData, AttackData, ReadData, Tactic, TargetData}, data::{AgentData, AttackData, Path, ReadData, Tactic, TargetData},
util::{ util::{
aim_projectile, can_see_tgt, get_entity_by_id, is_dead, is_dead_or_invulnerable, aim_projectile, can_see_tgt, get_entity_by_id, is_dead, is_dead_or_invulnerable,
is_invulnerable, try_owner_alignment, is_invulnerable, try_owner_alignment,
@ -2243,7 +2243,7 @@ impl<'a> AgentData<'a> {
} }
/// Directs the entity to path and move toward the target /// Directs the entity to path and move toward the target
/// If full_path is false, the entity will path to a location 50 units along /// If path is not Full, the entity will path to a location 50 units along
/// the vector between the entity and the target. The speed multiplier /// the vector between the entity and the target. The speed multiplier
/// multiplies the movement speed by a value less than 1.0. /// multiplies the movement speed by a value less than 1.0.
/// A `None` value implies a multiplier of 1.0. /// A `None` value implies a multiplier of 1.0.
@ -2252,57 +2252,51 @@ impl<'a> AgentData<'a> {
&self, &self,
agent: &mut Agent, agent: &mut Agent,
controller: &mut Controller, controller: &mut Controller,
tgt_data: &TargetData, tgt_pos: Vec3<f32>,
read_data: &ReadData, read_data: &ReadData,
full_path: bool, path: Path,
separate: bool,
speed_multiplier: Option<f32>, speed_multiplier: Option<f32>,
) -> bool { ) -> bool {
let pathing_pos = if separate { let partial_path_tgt_pos = |pos_difference: Vec3<f32>| {
let mut sep_vec: Vec3<f32> = Vec3::<f32>::zero(); self.pos.0
+ PARTIAL_PATH_DIST * pos_difference.try_normalized().unwrap_or_else(Vec3::zero)
};
let pos_difference = tgt_pos - self.pos.0;
let pathing_pos = match path {
Path::Separate => {
let mut sep_vec: Vec3<f32> = Vec3::<f32>::zero();
for entity in read_data for entity in read_data
.cached_spatial_grid .cached_spatial_grid
.0 .0
.in_circle_aabr(self.pos.0.xy(), SEPARATION_DIST) .in_circle_aabr(self.pos.0.xy(), SEPARATION_DIST)
{
if let (Some(alignment), Some(other_alignment)) =
(self.alignment, read_data.alignments.get(entity))
{ {
if Alignment::passive_towards(*alignment, *other_alignment) { if let (Some(alignment), Some(other_alignment)) =
if let (Some(pos), Some(body), Some(other_body)) = ( (self.alignment, read_data.alignments.get(entity))
read_data.positions.get(entity), {
self.body, if Alignment::passive_towards(*alignment, *other_alignment) {
read_data.bodies.get(entity), if let (Some(pos), Some(body), Some(other_body)) = (
) { read_data.positions.get(entity),
if self.pos.0.xy().distance(pos.0.xy()) self.body,
< body.spacing_radius() + other_body.spacing_radius() read_data.bodies.get(entity),
{ ) {
sep_vec += (self.pos.0.xy() - pos.0.xy()) let dist_xy = self.pos.0.xy().distance(pos.0.xy());
.try_normalized() let spacing = body.spacing_radius() + other_body.spacing_radius();
.unwrap_or_else(Vec2::zero) if dist_xy < spacing {
* (((body.spacing_radius() + other_body.spacing_radius()) let pos_diff = self.pos.0.xy() - pos.0.xy();
- self.pos.0.xy().distance(pos.0.xy())) sep_vec += pos_diff.try_normalized().unwrap_or_else(Vec2::zero)
/ (body.spacing_radius() + other_body.spacing_radius())); * ((spacing - dist_xy) / spacing);
}
} }
} }
} }
} }
} partial_path_tgt_pos(
self.pos.0 sep_vec * SEPARATION_BIAS + pos_difference * (1.0 - SEPARATION_BIAS),
+ PARTIAL_PATH_DIST )
* (sep_vec * SEPARATION_BIAS },
+ (tgt_data.pos.0 - self.pos.0) * (1.0 - SEPARATION_BIAS)) Path::Full => tgt_pos,
.try_normalized() Path::Partial => partial_path_tgt_pos(pos_difference),
.unwrap_or_else(Vec3::zero)
} else if full_path {
tgt_data.pos.0
} else {
self.pos.0
+ PARTIAL_PATH_DIST
* (tgt_data.pos.0 - self.pos.0)
.try_normalized()
.unwrap_or_else(Vec3::zero)
}; };
let speed_multiplier = speed_multiplier.unwrap_or(1.0).min(1.0); let speed_multiplier = speed_multiplier.unwrap_or(1.0).min(1.0);
if let Some((bearing, speed)) = agent.chaser.chase( if let Some((bearing, speed)) = agent.chaser.chase(

View File

@ -1,5 +1,6 @@
use crate::sys::agent::{ use crate::sys::agent::{
consts::MAX_PATH_DIST, util::can_see_tgt, AgentData, AttackData, ReadData, TargetData, consts::MAX_PATH_DIST, data::Path, util::can_see_tgt, AgentData, AttackData, ReadData,
TargetData,
}; };
use common::{ use common::{
comp::{ comp::{
@ -33,17 +34,21 @@ impl<'a> AgentData<'a> {
if attack_data.in_min_range() && attack_data.angle < 30.0 { if attack_data.in_min_range() && attack_data.angle < 30.0 {
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
controller.inputs.move_dir = Vec2::zero(); controller.inputs.move_dir = Vec2::zero();
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, true, true, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Full,
None,
);
if self.body.map(|b| b.is_humanoid()).unwrap_or(false) if self.body.map(|b| b.is_humanoid()).unwrap_or(false)
&& attack_data.dist_sqrd < 16.0f32.powi(2) && attack_data.dist_sqrd < 16.0f32.powi(2)
&& rng.gen::<f32>() < 0.02 && rng.gen::<f32>() < 0.02
{ {
controller.push_basic_input(InputKind::Roll); controller.push_basic_input(InputKind::Roll);
} }
} else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, true, None);
} }
} }
@ -106,7 +111,14 @@ impl<'a> AgentData<'a> {
.unwrap_or_default(); .unwrap_or_default();
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, true, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Full,
None,
);
} }
} }
@ -186,7 +198,14 @@ impl<'a> AgentData<'a> {
-bearing.xy().try_normalized().unwrap_or_else(Vec2::zero); -bearing.xy().try_normalized().unwrap_or_else(Vec2::zero);
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, true, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Full,
None,
);
} }
} }
@ -221,8 +240,16 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
agent.action_state.timer += read_data.dt.0; agent.action_state.timer += read_data.dt.0;
} }
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
if attack_data.dist_sqrd < 32.0f32.powi(2) if attack_data.dist_sqrd < 32.0f32.powi(2)
&& has_leap() && has_leap()
&& has_energy(50.0) && has_energy(50.0)
@ -241,8 +268,6 @@ impl<'a> AgentData<'a> {
{ {
controller.push_basic_input(InputKind::Roll); controller.push_basic_input(InputKind::Roll);
} }
} else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
} }
} }
@ -281,8 +306,16 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
agent.action_state.timer += read_data.dt.0; agent.action_state.timer += read_data.dt.0;
} }
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
if attack_data.dist_sqrd < 32.0f32.powi(2) if attack_data.dist_sqrd < 32.0f32.powi(2)
&& has_leap() && has_leap()
&& has_energy(50.0) && has_energy(50.0)
@ -301,8 +334,6 @@ impl<'a> AgentData<'a> {
{ {
controller.push_basic_input(InputKind::Roll); controller.push_basic_input(InputKind::Roll);
} }
} else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
} }
} }
@ -332,14 +363,19 @@ impl<'a> AgentData<'a> {
agent.action_state.timer += read_data.dt.0; agent.action_state.timer += read_data.dt.0;
} }
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
if self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None) if self.path_toward_target(
&& can_see_tgt( agent,
&*read_data.terrain, controller,
self.pos, tgt_data.pos.0,
tgt_data.pos, read_data,
attack_data.dist_sqrd, Path::Separate,
) None,
{ ) && can_see_tgt(
&*read_data.terrain,
self.pos,
tgt_data.pos,
attack_data.dist_sqrd,
) {
if agent.action_state.timer > 4.0 && attack_data.angle < 45.0 { if agent.action_state.timer > 4.0 && attack_data.angle < 45.0 {
controller.push_basic_input(InputKind::Secondary); controller.push_basic_input(InputKind::Secondary);
agent.action_state.timer = 0.0; agent.action_state.timer = 0.0;
@ -354,7 +390,14 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Roll); controller.push_basic_input(InputKind::Roll);
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -421,7 +464,14 @@ impl<'a> AgentData<'a> {
// (other 2 attacks have interrupt handled above) unless in recover // (other 2 attacks have interrupt handled above) unless in recover
controller.push_basic_input(InputKind::Roll); controller.push_basic_input(InputKind::Roll);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
if attack_data.angle < 15.0 { if attack_data.angle < 15.0 {
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
} }
@ -502,7 +552,14 @@ impl<'a> AgentData<'a> {
} }
} else { } else {
// If too far, move towards target // If too far, move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -634,7 +691,14 @@ impl<'a> AgentData<'a> {
} }
} else { } else {
// If too far, move towards target // If too far, move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -765,7 +829,14 @@ impl<'a> AgentData<'a> {
} }
} else { } else {
// If too far, move towards target // If too far, move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -785,14 +856,19 @@ impl<'a> AgentData<'a> {
if self.vel.0.is_approx_zero() { if self.vel.0.is_approx_zero() {
controller.push_basic_input(InputKind::Ability(0)); controller.push_basic_input(InputKind::Ability(0));
} }
if self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None) if self.path_toward_target(
&& can_see_tgt( agent,
&*read_data.terrain, controller,
self.pos, tgt_data.pos.0,
tgt_data.pos, read_data,
attack_data.dist_sqrd, Path::Separate,
) None,
&& attack_data.angle < 90.0 ) && can_see_tgt(
&*read_data.terrain,
self.pos,
tgt_data.pos,
attack_data.dist_sqrd,
) && attack_data.angle < 90.0
{ {
if agent.action_state.timer > 5.0 { if agent.action_state.timer > 5.0 {
controller.push_basic_input(InputKind::Secondary); controller.push_basic_input(InputKind::Secondary);
@ -802,7 +878,14 @@ impl<'a> AgentData<'a> {
} }
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -884,11 +967,14 @@ impl<'a> AgentData<'a> {
agent.action_state.counter += read_data.dt.0; agent.action_state.counter += read_data.dt.0;
} }
// activating charge once circle timer expires is handled above // activating charge once circle timer expires is handled above
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
// if too far away from target, move towards them
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); let path = if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
// if too far away from target, move towards them
Path::Separate
} else {
Path::Partial
};
self.path_toward_target(agent, controller, tgt_data.pos.0, read_data, path, None);
} }
} }
@ -959,7 +1045,14 @@ impl<'a> AgentData<'a> {
agent.target = None; agent.target = None;
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -990,9 +1083,23 @@ impl<'a> AgentData<'a> {
.unwrap_or_else(Vec2::unit_y) .unwrap_or_else(Vec2::unit_y)
* 0.1; * 0.1;
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1020,9 +1127,23 @@ impl<'a> AgentData<'a> {
.try_normalized() .try_normalized()
.unwrap_or_else(Vec2::unit_y); .unwrap_or_else(Vec2::unit_y);
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1047,10 +1168,13 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
agent.action_state.timer += read_data.dt.0; agent.action_state.timer += read_data.dt.0;
} }
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); let path = if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
Path::Separate
} else {
Path::Partial
};
self.path_toward_target(agent, controller, tgt_data.pos.0, read_data, path, None);
} }
} }
@ -1072,8 +1196,14 @@ impl<'a> AgentData<'a> {
{ {
controller.push_basic_input(InputKind::Ability(0)); controller.push_basic_input(InputKind::Ability(0));
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
if self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None) if self.path_toward_target(
&& attack_data.angle < 15.0 agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
) && attack_data.angle < 15.0
&& can_see_tgt( && can_see_tgt(
&*read_data.terrain, &*read_data.terrain,
self.pos, self.pos,
@ -1084,7 +1214,14 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1108,9 +1245,23 @@ impl<'a> AgentData<'a> {
agent.action_state.timer = 0.0; agent.action_state.timer = 0.0;
} }
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1153,9 +1304,23 @@ impl<'a> AgentData<'a> {
agent.action_state.timer = 0.0; agent.action_state.timer = 0.0;
} }
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1171,9 +1336,23 @@ impl<'a> AgentData<'a> {
controller.inputs.move_dir = Vec2::zero(); controller.inputs.move_dir = Vec2::zero();
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1310,7 +1489,14 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Secondary); controller.push_basic_input(InputKind::Secondary);
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
// If too far from target, throw a random number of necrotic spheres at them and // If too far from target, throw a random number of necrotic spheres at them and
@ -1341,9 +1527,23 @@ impl<'a> AgentData<'a> {
select_pos: None, select_pos: None,
}); });
} }
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1444,7 +1644,14 @@ impl<'a> AgentData<'a> {
// If further than 2.5 blocks and random chance // If further than 2.5 blocks and random chance
else if attack_data.dist_sqrd > (2.5 * attack_data.min_attack_dist).powi(2) { else if attack_data.dist_sqrd > (2.5 * attack_data.min_attack_dist).powi(2) {
// Walk to target // Walk to target
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
// If energy higher than 600 and random chance // If energy higher than 600 and random chance
else if self.energy.current() > 60.0 && rng.gen_bool(0.4) { else if self.energy.current() > 60.0 && rng.gen_bool(0.4) {
@ -1455,7 +1662,14 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Secondary); controller.push_basic_input(InputKind::Secondary);
} else { } else {
// Target is behind us. Turn around and chase target // Target is behind us. Turn around and chase target
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
} }
@ -1536,7 +1750,14 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Fly); controller.push_basic_input(InputKind::Fly);
controller.inputs.move_z = 1.0; controller.inputs.move_z = 1.0;
} else if attack_data.dist_sqrd > (3.0 * attack_data.min_attack_dist).powi(2) { } else if attack_data.dist_sqrd > (3.0 * attack_data.min_attack_dist).powi(2) {
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} else if self.energy.current() > 60.0 } else if self.energy.current() > 60.0
&& agent.action_state.timer < 3.0 && agent.action_state.timer < 3.0
&& attack_data.angle < 15.0 && attack_data.angle < 15.0
@ -1547,10 +1768,9 @@ impl<'a> AgentData<'a> {
self.path_toward_target( self.path_toward_target(
agent, agent,
controller, controller,
tgt_data, tgt_data.pos.0,
read_data, read_data,
true, Path::Separate,
false,
Some(0.5), Some(0.5),
); );
agent.action_state.timer += read_data.dt.0; agent.action_state.timer += read_data.dt.0;
@ -1565,7 +1785,14 @@ impl<'a> AgentData<'a> {
// Reset timer // Reset timer
agent.action_state.timer = 0.0; agent.action_state.timer = 0.0;
// Target is behind us or the timer needs to be reset. Chase target // Target is behind us or the timer needs to be reset. Chase target
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
} }
@ -1624,7 +1851,14 @@ impl<'a> AgentData<'a> {
agent.action_state.condition = true; agent.action_state.condition = true;
} }
// Make bird move towards target // Make bird move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
pub fn handle_arthropod_basic_attack( pub fn handle_arthropod_basic_attack(
@ -1652,7 +1886,14 @@ impl<'a> AgentData<'a> {
controller.inputs.move_dir = Vec2::zero(); controller.inputs.move_dir = Vec2::zero();
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1734,7 +1975,14 @@ impl<'a> AgentData<'a> {
agent.target = None; agent.target = None;
} }
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1769,7 +2017,14 @@ impl<'a> AgentData<'a> {
{ {
controller.push_basic_input(InputKind::Ability(0)); controller.push_basic_input(InputKind::Ability(0));
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1797,7 +2052,14 @@ impl<'a> AgentData<'a> {
controller.inputs.move_dir = Vec2::zero(); controller.inputs.move_dir = Vec2::zero();
controller.push_basic_input(InputKind::Primary); controller.push_basic_input(InputKind::Primary);
} else { } else {
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -1853,7 +2115,14 @@ impl<'a> AgentData<'a> {
} }
} }
// Make minotaur move towards target // Make minotaur move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
pub fn handle_clay_golem_attack( pub fn handle_clay_golem_attack(
@ -1929,7 +2198,14 @@ impl<'a> AgentData<'a> {
} }
} }
// Make clay golem move towards target // Make clay golem move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, true, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
pub fn handle_tidal_warrior_attack( pub fn handle_tidal_warrior_attack(
@ -1999,7 +2275,14 @@ impl<'a> AgentData<'a> {
} }
} }
// Always attempt to path towards target // Always attempt to path towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
pub fn handle_yeti_attack( pub fn handle_yeti_attack(
@ -2046,7 +2329,14 @@ impl<'a> AgentData<'a> {
} }
// Always attempt to path towards target // Always attempt to path towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
pub fn handle_harvester_attack( pub fn handle_harvester_attack(
@ -2108,7 +2398,14 @@ impl<'a> AgentData<'a> {
controller.push_basic_input(InputKind::Ability(1)); controller.push_basic_input(InputKind::Ability(1));
} }
// Always attempt to path towards target // Always attempt to path towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
pub fn handle_deadwood( pub fn handle_deadwood(
@ -2148,7 +2445,14 @@ impl<'a> AgentData<'a> {
} }
} else { } else {
// Otherwise too far, move towards target // Otherwise too far, move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -2191,7 +2495,14 @@ impl<'a> AgentData<'a> {
) )
{ {
// If in pathing range and can see target, move towards them // If in pathing range and can see target, move towards them
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} else { } else {
// Otherwise, go back to sleep // Otherwise, go back to sleep
agent.action_state.condition = false; agent.action_state.condition = false;
@ -2250,7 +2561,14 @@ impl<'a> AgentData<'a> {
} }
} }
// And always try to path towards target // And always try to path towards target
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Partial,
None,
);
} }
} }
@ -2329,6 +2647,13 @@ impl<'a> AgentData<'a> {
agent.action_state.counter += read_data.dt.0 * 3.3; agent.action_state.counter += read_data.dt.0 * 3.3;
} }
self.path_toward_target(agent, controller, tgt_data, read_data, false, true, None); self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Full,
None,
);
} }
} }

View File

@ -154,3 +154,9 @@ pub struct ReadData<'a> {
pub combos: ReadStorage<'a, Combo>, pub combos: ReadStorage<'a, Combo>,
pub active_abilities: ReadStorage<'a, ActiveAbilities>, pub active_abilities: ReadStorage<'a, ActiveAbilities>,
} }
pub enum Path {
Full,
Separate,
Partial,
}