diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 725f6d0161..595508de69 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -2268,7 +2268,7 @@ impl<'a> AgentData<'a> { &self, agent: &mut Agent, controller: &mut Controller, - tgt_data: &TargetData, + tgt_pos: Vec3, read_data: &ReadData, path: Path, speed_multiplier: Option, @@ -2277,7 +2277,7 @@ impl<'a> AgentData<'a> { let target_position = |vec3: Vec3| { pos + PARTIAL_PATH_DIST * vec3.try_normalized().unwrap_or_else(Vec3::zero) }; - let distance_to_target = tgt_data.pos.0 - pos; + let distance_to_target = tgt_pos - pos; let pathing_pos = match path { Path::Full => { let mut sep_vec: Vec3 = Vec3::::zero(); @@ -2312,7 +2312,7 @@ impl<'a> AgentData<'a> { sep_vec * SEPARATION_BIAS + distance_to_target * (1.0 - SEPARATION_BIAS), ) }, - Path::Separate => tgt_data.pos.0, + Path::Separate => tgt_pos, Path::Partial => target_position(distance_to_target), }; let speed_multiplier = speed_multiplier.unwrap_or(1.0).min(1.0); diff --git a/server/src/sys/agent/attack.rs b/server/src/sys/agent/attack.rs index 7e392ba0df..07e627ad57 100644 --- a/server/src/sys/agent/attack.rs +++ b/server/src/sys/agent/attack.rs @@ -34,17 +34,16 @@ impl<'a> AgentData<'a> { if attack_data.in_min_range() && attack_data.angle < 30.0 { controller.push_basic_input(InputKind::Primary); controller.inputs.move_dir = Vec2::zero(); - } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Full, None); - - if self.body.map(|b| b.is_humanoid()).unwrap_or(false) + } else { + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Full, None); + if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) + && self.body.map(|b| b.is_humanoid()).unwrap_or(false) && attack_data.dist_sqrd < 16.0f32.powi(2) && rng.gen::() < 0.02 { controller.push_basic_input(InputKind::Roll); } - } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Full, None); } } @@ -73,11 +72,12 @@ impl<'a> AgentData<'a> { .unwrap_or_default(); let dist = attack_data.dist_sqrd.sqrt(); - let in_front_of_target = target_ori.dot(self.pos.0 - tgt_data.pos.0) > 0.0; + let tgt_pos = &tgt_data.pos.0; + let in_front_of_target = target_ori.dot(self.pos.0 - tgt_pos) > 0.0; if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { // If in front of the target, circle to try and get behind, else just make a // beeline for the back of the agent - let vec_to_target = (tgt_data.pos.0 - self.pos.0).xy(); + let vec_to_target = (tgt_pos - self.pos.0).xy(); if in_front_of_target { let theta = (PI / 2. - dist * 0.1).max(0.0); // Checks both CW and CCW rotation @@ -101,13 +101,13 @@ impl<'a> AgentData<'a> { } else { // Aim for a point a given distance behind the target to prevent sideways // movement - let move_target = tgt_data.pos.0.xy() - dist / 2. * target_ori.xy(); + let move_target = tgt_pos.xy() - dist / 2. * target_ori.xy(); controller.inputs.move_dir = (move_target - self.pos.0) .try_normalized() .unwrap_or_default(); } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Full, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Full, None); } } @@ -119,7 +119,8 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { - let elevation = self.pos.0.z - tgt_data.pos.0.z; + let tgt_pos = &tgt_data.pos.0; + let elevation = self.pos.0.z - tgt_pos.z; const PREF_DIST: f32 = 30_f32; if attack_data.angle_xy < 30.0 && (elevation > 10.0 || attack_data.dist_sqrd > PREF_DIST.powi(2)) @@ -137,7 +138,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -169,7 +170,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -187,7 +188,7 @@ impl<'a> AgentData<'a> { -bearing.xy().try_normalized().unwrap_or_else(Vec2::zero); } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Full, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Full, None); } } @@ -222,28 +223,29 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Primary); 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, Path::Separate, None); - if attack_data.dist_sqrd < 32.0f32.powi(2) - && has_leap() - && has_energy(50.0) - && can_see_tgt( - &read_data.terrain, - self.pos, - tgt_data.pos, - attack_data.dist_sqrd, - ) - { - use_leap(controller); - } - if self.body.map(|b| b.is_humanoid()).unwrap_or(false) - && attack_data.dist_sqrd < 16.0f32.powi(2) - && rng.gen::() < 0.02 - { - controller.push_basic_input(InputKind::Roll); - } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); + if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { + if attack_data.dist_sqrd < 32.0f32.powi(2) + && has_leap() + && has_energy(50.0) + && can_see_tgt( + &read_data.terrain, + self.pos, + tgt_data.pos, + attack_data.dist_sqrd, + ) + { + use_leap(controller); + } + if self.body.map(|b| b.is_humanoid()).unwrap_or(false) + && attack_data.dist_sqrd < 16.0f32.powi(2) + && rng.gen::() < 0.02 + { + controller.push_basic_input(InputKind::Roll); + } + } } } @@ -282,28 +284,30 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Primary); 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, Path::Separate, None); - if attack_data.dist_sqrd < 32.0f32.powi(2) - && has_leap() - && has_energy(50.0) - && can_see_tgt( - &read_data.terrain, - self.pos, - tgt_data.pos, - attack_data.dist_sqrd, - ) - { - use_leap(controller); - } - if self.body.map(|b| b.is_humanoid()).unwrap_or(false) - && attack_data.dist_sqrd < 16.0f32.powi(2) - && rng.gen::() < 0.02 - { - controller.push_basic_input(InputKind::Roll); - } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); + + if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { + if attack_data.dist_sqrd < 32.0f32.powi(2) + && has_leap() + && has_energy(50.0) + && can_see_tgt( + &read_data.terrain, + self.pos, + tgt_data.pos, + attack_data.dist_sqrd, + ) + { + use_leap(controller); + } + if self.body.map(|b| b.is_humanoid()).unwrap_or(false) + && attack_data.dist_sqrd < 16.0f32.powi(2) + && rng.gen::() < 0.02 + { + controller.push_basic_input(InputKind::Roll); + } + } } } @@ -316,6 +320,7 @@ impl<'a> AgentData<'a> { read_data: &ReadData, rng: &mut impl Rng, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.in_min_range() && attack_data.angle < 45.0 { controller.inputs.move_dir = Vec2::zero(); if self @@ -333,7 +338,7 @@ impl<'a> AgentData<'a> { agent.action_state.timer += read_data.dt.0; } } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - if self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None) + if self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None) && can_see_tgt( &*read_data.terrain, self.pos, @@ -355,7 +360,7 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Roll); } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -371,6 +376,7 @@ impl<'a> AgentData<'a> { const MIN_CHARGE_FRAC: f32 = 0.5; const OPTIMAL_TARGET_VELOCITY: f32 = 5.0; const DESIRED_ENERGY_LEVEL: f32 = 50.0; + let tgt_pos = &tgt_data.pos.0; // Logic to use abilities if let CharacterState::ChargedRanged(c) = self.char_state { if !matches!(c.stage_section, StageSection::Recover) { @@ -425,7 +431,7 @@ impl<'a> AgentData<'a> { self.path_toward_target( agent, controller, - tgt_data, + tgt_pos, read_data, Path::Separate, None, @@ -459,7 +465,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -474,7 +480,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -510,7 +516,7 @@ impl<'a> AgentData<'a> { } } else { // If too far, move towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -584,13 +590,14 @@ impl<'a> AgentData<'a> { } // Logic to move. Intentionally kept separate from ability logic so duplicated // work is less necessary. + let tgt_pos = &tgt_data.pos.0; if attack_data.dist_sqrd < (2.0 * attack_data.min_attack_dist).powi(2) { // Attempt to move away from target if too close if let Some((bearing, speed)) = agent.chaser.chase( &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -605,7 +612,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -642,7 +649,7 @@ impl<'a> AgentData<'a> { } } else { // If too far, move towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -715,13 +722,14 @@ impl<'a> AgentData<'a> { } // Logic to move. Intentionally kept separate from ability logic where possible // so duplicated work is less necessary. + let tgt_pos = &tgt_data.pos.0; if attack_data.dist_sqrd < (2.0 * attack_data.min_attack_dist).powi(2) { // Attempt to move away from target if too close if let Some((bearing, speed)) = agent.chaser.chase( &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -736,7 +744,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -773,7 +781,7 @@ impl<'a> AgentData<'a> { } } else { // If too far, move towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -785,6 +793,7 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.in_min_range() && attack_data.angle < 90.0 { controller.inputs.move_dir = Vec2::zero(); controller.push_basic_input(InputKind::Primary); @@ -793,7 +802,7 @@ impl<'a> AgentData<'a> { if self.vel.0.is_approx_zero() { controller.push_basic_input(InputKind::Ability(0)); } - if self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None) + if self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None) && can_see_tgt( &*read_data.terrain, self.pos, @@ -810,7 +819,7 @@ impl<'a> AgentData<'a> { } } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -848,11 +857,12 @@ impl<'a> AgentData<'a> { } if agent.action_state.counter < circle_time as f32 { // circle if circle timer not ready + let tgt_pos = &tgt_data.pos.0; let move_dir = match agent.action_state.int_counter { 1 => // circle left if counter is 1 { - (tgt_data.pos.0 - self.pos.0) + (tgt_pos - self.pos.0) .xy() .rotated_z(0.47 * PI) .try_normalized() @@ -861,7 +871,7 @@ impl<'a> AgentData<'a> { 2 => // circle right if counter is 2 { - (tgt_data.pos.0 - self.pos.0) + (tgt_pos - self.pos.0) .xy() .rotated_z(-0.47 * PI) .try_normalized() @@ -892,11 +902,15 @@ impl<'a> AgentData<'a> { agent.action_state.counter += read_data.dt.0; } // 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, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + 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_pos, read_data, path, None); } } @@ -908,10 +922,11 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.dist_sqrd < (3.0 * attack_data.min_attack_dist).powi(2) && attack_data.angle < 90.0 { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .try_normalized() .unwrap_or_else(Vec2::unit_y); @@ -921,7 +936,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -938,7 +953,7 @@ impl<'a> AgentData<'a> { if agent.action_state.timer > 5.0 { agent.action_state.timer = 0.0; } else if agent.action_state.timer > 2.5 { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .rotated_z(1.75 * PI) .try_normalized() @@ -946,7 +961,7 @@ impl<'a> AgentData<'a> { * speed; agent.action_state.timer += read_data.dt.0; } else { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .rotated_z(0.25 * PI) .try_normalized() @@ -967,7 +982,7 @@ impl<'a> AgentData<'a> { agent.target = None; } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -979,6 +994,7 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.angle < 90.0 && attack_data.dist_sqrd < (1.5 * attack_data.min_attack_dist).powi(2) { @@ -992,15 +1008,15 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Secondary); agent.action_state.timer += read_data.dt.0; } - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .try_normalized() .unwrap_or_else(Vec2::unit_y) * 0.1; } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1012,6 +1028,7 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.angle < 90.0 && attack_data.dist_sqrd < (1.5 * attack_data.min_attack_dist).powi(2) { @@ -1022,15 +1039,15 @@ impl<'a> AgentData<'a> { && attack_data.angle < 90.0 { controller.push_basic_input(InputKind::Primary); - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .rotated_z(-0.47 * PI) .try_normalized() .unwrap_or_else(Vec2::unit_y); } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1055,10 +1072,14 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Primary); 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, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + let path = if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { + Path::Separate + } else { + Path::Partial + }; + self.path_toward_target(agent, controller, tgt_pos, read_data, path, None); } } @@ -1070,6 +1091,7 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.angle < 90.0 && attack_data.dist_sqrd < (1.5 * attack_data.min_attack_dist).powi(2) { @@ -1080,7 +1102,7 @@ impl<'a> AgentData<'a> { { controller.push_basic_input(InputKind::Ability(0)); } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - if self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None) + if self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None) && attack_data.angle < 15.0 && can_see_tgt( &*read_data.terrain, @@ -1092,7 +1114,7 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Primary); } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1104,6 +1126,7 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.angle < 90.0 && attack_data.in_min_range() { controller.inputs.move_dir = Vec2::zero(); if agent.action_state.timer < 2.0 { @@ -1116,9 +1139,9 @@ impl<'a> AgentData<'a> { agent.action_state.timer = 0.0; } } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1130,6 +1153,7 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.angle < 90.0 && attack_data.dist_sqrd < (2.5 * attack_data.min_attack_dist).powi(2) { @@ -1139,7 +1163,7 @@ impl<'a> AgentData<'a> { && attack_data.angle < 15.0 { if agent.action_state.timer < 2.0 { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .rotated_z(0.47 * PI) .try_normalized() @@ -1147,7 +1171,7 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Primary); agent.action_state.timer += read_data.dt.0; } else if agent.action_state.timer < 4.0 && attack_data.angle < 15.0 { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .rotated_z(-0.47 * PI) .try_normalized() @@ -1161,9 +1185,9 @@ impl<'a> AgentData<'a> { agent.action_state.timer = 0.0; } } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1175,13 +1199,14 @@ impl<'a> AgentData<'a> { tgt_data: &TargetData, read_data: &ReadData, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.angle < 90.0 && attack_data.in_min_range() { controller.inputs.move_dir = Vec2::zero(); controller.push_basic_input(InputKind::Primary); } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1285,6 +1310,7 @@ impl<'a> AgentData<'a> { agent.action_state.condition = true; } + let tgt_pos = &tgt_data.pos.0; if agent.action_state.counter > health_fraction { // Summon minions at particular thresholds of health controller.push_basic_input(InputKind::Ability(2)); @@ -1321,7 +1347,7 @@ impl<'a> AgentData<'a> { self.path_toward_target( agent, controller, - tgt_data, + tgt_pos, read_data, Path::Separate, None, @@ -1356,9 +1382,9 @@ impl<'a> AgentData<'a> { select_pos: None, }); } - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1371,6 +1397,7 @@ impl<'a> AgentData<'a> { read_data: &ReadData, rng: &mut impl Rng, ) { + let tgt_pos = &tgt_data.pos.0; if attack_data.dist_sqrd > 30.0_f32.powi(2) { let small_chance = rng.gen_bool(0.05); @@ -1391,7 +1418,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -1401,7 +1428,7 @@ impl<'a> AgentData<'a> { controller.inputs.move_dir = bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed; // If less than 20 blocks higher than target - if (self.pos.0.z - tgt_data.pos.0.z) < 20.0 { + if (self.pos.0.z - tgt_pos.z) < 20.0 { // Fly upward controller.push_basic_input(InputKind::Fly); controller.inputs.move_z = 1.0; @@ -1426,7 +1453,7 @@ impl<'a> AgentData<'a> { // is on the ground // Fly to target controller.push_basic_input(InputKind::Fly); - let move_dir = tgt_data.pos.0 - self.pos.0; + let move_dir = tgt_pos - self.pos.0; controller.inputs.move_dir = move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0; controller.inputs.move_z = move_dir.z - 0.5; @@ -1450,7 +1477,7 @@ impl<'a> AgentData<'a> { // If random chance and less than 20 blocks higher than target and further than 4 // blocks else if rng.gen_bool(0.5) - && (self.pos.0.z - tgt_data.pos.0.z) < 15.0 + && (self.pos.0.z - tgt_pos.z) < 15.0 && attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2) { controller.push_basic_input(InputKind::Fly); @@ -1459,7 +1486,7 @@ impl<'a> AgentData<'a> { // If further than 2.5 blocks and random chance else if attack_data.dist_sqrd > (2.5 * attack_data.min_attack_dist).powi(2) { // Walk to target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } // If energy higher than 600 and random chance else if self.energy.current() > 60.0 && rng.gen_bool(0.4) { @@ -1470,7 +1497,7 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Secondary); } else { // Target is behind us. Turn around and chase target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } } @@ -1485,6 +1512,7 @@ impl<'a> AgentData<'a> { ) { // Set fly to false controller.push_cancel_input(InputKind::Fly); + let tgt_pos = &tgt_data.pos.0; if attack_data.dist_sqrd > 30.0_f32.powi(2) { if rng.gen_bool(0.05) && can_see_tgt( @@ -1501,7 +1529,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -1509,7 +1537,7 @@ impl<'a> AgentData<'a> { ) { controller.inputs.move_dir = bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed; - if (self.pos.0.z - tgt_data.pos.0.z) < 20.0 { + if (self.pos.0.z - tgt_pos.z) < 20.0 { controller.push_basic_input(InputKind::Fly); controller.inputs.move_z = 1.0; } else { @@ -1529,7 +1557,7 @@ impl<'a> AgentData<'a> { // The next stage shouldn't trigger until the entity // is on the ground controller.push_basic_input(InputKind::Fly); - let move_dir = tgt_data.pos.0 - self.pos.0; + let move_dir = tgt_pos - self.pos.0; controller.inputs.move_dir = move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0; controller.inputs.move_z = move_dir.z - 0.5; @@ -1545,13 +1573,13 @@ impl<'a> AgentData<'a> { { controller.push_basic_input(InputKind::Primary); } else if rng.gen_bool(0.5) - && (self.pos.0.z - tgt_data.pos.0.z) < 15.0 + && (self.pos.0.z - tgt_pos.z) < 15.0 && attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2) { controller.push_basic_input(InputKind::Fly); controller.inputs.move_z = 1.0; } 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, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } else if self.energy.current() > 60.0 && agent.action_state.timer < 3.0 && attack_data.angle < 15.0 @@ -1562,7 +1590,7 @@ impl<'a> AgentData<'a> { self.path_toward_target( agent, controller, - tgt_data, + tgt_pos, read_data, Path::Separate, Some(0.5), @@ -1579,7 +1607,7 @@ impl<'a> AgentData<'a> { // Reset timer agent.action_state.timer = 0.0; // Target is behind us or the timer needs to be reset. Chase target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } } @@ -1597,6 +1625,7 @@ impl<'a> AgentData<'a> { // Increase action timer agent.action_state.timer += read_data.dt.0; // If higher than 2 blocks + let tgt_pos = &tgt_data.pos.0; if !read_data .terrain .ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0)) @@ -1607,7 +1636,7 @@ impl<'a> AgentData<'a> { { // Fly to target and land controller.push_basic_input(InputKind::Fly); - let move_dir = tgt_data.pos.0 - self.pos.0; + let move_dir = tgt_pos - self.pos.0; controller.inputs.move_dir = move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0; controller.inputs.move_z = move_dir.z - 0.5; @@ -1638,7 +1667,7 @@ impl<'a> AgentData<'a> { agent.action_state.condition = true; } // Make bird move towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } pub fn handle_arthropod_basic_attack( @@ -1666,7 +1695,8 @@ impl<'a> AgentData<'a> { controller.inputs.move_dir = Vec2::zero(); controller.push_basic_input(InputKind::Primary); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1679,6 +1709,7 @@ impl<'a> AgentData<'a> { read_data: &ReadData, ) { agent.action_state.timer += read_data.dt.0; + let tgt_pos = &tgt_data.pos.0; if agent.action_state.timer > 6.0 && attack_data.dist_sqrd < (2.0 * attack_data.min_attack_dist).powi(2) { @@ -1692,7 +1723,7 @@ impl<'a> AgentData<'a> { } else if attack_data.dist_sqrd < (3.0 * attack_data.min_attack_dist).powi(2) && attack_data.angle < 90.0 { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .try_normalized() .unwrap_or_else(Vec2::unit_y); @@ -1702,7 +1733,7 @@ impl<'a> AgentData<'a> { &*read_data.terrain, self.pos.0, self.vel.0, - tgt_data.pos.0, + tgt_pos, TraversalConfig { min_tgt_dist: 1.25, ..self.traversal_config @@ -1719,7 +1750,7 @@ impl<'a> AgentData<'a> { if agent.action_state.timer > 5.0 { agent.action_state.timer = 0.0; } else if agent.action_state.timer > 2.5 { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .rotated_z(1.75 * PI) .try_normalized() @@ -1727,7 +1758,7 @@ impl<'a> AgentData<'a> { * speed; agent.action_state.timer += read_data.dt.0; } else { - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .rotated_z(0.25 * PI) .try_normalized() @@ -1748,7 +1779,7 @@ impl<'a> AgentData<'a> { agent.target = None; } } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1783,7 +1814,8 @@ impl<'a> AgentData<'a> { { controller.push_basic_input(InputKind::Ability(0)); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1811,7 +1843,8 @@ impl<'a> AgentData<'a> { controller.inputs.move_dir = Vec2::zero(); controller.push_basic_input(InputKind::Primary); } else { - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -1867,7 +1900,8 @@ impl<'a> AgentData<'a> { } } // Make minotaur move towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } pub fn handle_clay_golem_attack( @@ -1943,7 +1977,8 @@ impl<'a> AgentData<'a> { } } // Make clay golem move towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Separate, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Separate, None); } pub fn handle_tidal_warrior_attack( @@ -2013,7 +2048,8 @@ impl<'a> AgentData<'a> { } } // Always attempt to path towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } pub fn handle_yeti_attack( @@ -2060,7 +2096,8 @@ impl<'a> AgentData<'a> { } // Always attempt to path towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } pub fn handle_harvester_attack( @@ -2122,7 +2159,8 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Ability(1)); } // Always attempt to path towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } pub fn handle_deadwood( @@ -2135,6 +2173,7 @@ impl<'a> AgentData<'a> { ) { const BEAM_RANGE: f32 = 20.0; const BEAM_TIME: Duration = Duration::from_secs(3); + let tgt_pos = &tgt_data.pos.0; // action_state.condition controls whether or not deadwood should beam or dash if matches!(self.char_state, CharacterState::DashMelee(s) if s.stage_section != StageSection::Recover) { @@ -2154,7 +2193,7 @@ impl<'a> AgentData<'a> { controller.push_basic_input(InputKind::Primary); } else { // If not in angle, apply slight movement so deadwood orients itself correctly - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .try_normalized() .unwrap_or_else(Vec2::zero) @@ -2162,7 +2201,7 @@ impl<'a> AgentData<'a> { } } else { // Otherwise too far, move towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -2205,14 +2244,8 @@ impl<'a> AgentData<'a> { ) { // If in pathing range and can see target, move towards them - self.path_toward_target( - agent, - controller, - tgt_data, - read_data, - Path::Partial, - None, - ); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } else { // Otherwise, go back to sleep agent.action_state.condition = false; @@ -2239,6 +2272,7 @@ impl<'a> AgentData<'a> { agent.action_state.timer = 0.0; } + let tgt_pos = &tgt_data.pos.0; if attack_data.in_min_range() { // If in minimum range if agent.action_state.timer > SPIN_WAIT_TIME { @@ -2251,7 +2285,7 @@ impl<'a> AgentData<'a> { // Else increment spin timer agent.action_state.timer += read_data.dt.0; // If not in angle, apply slight movement so golem orients itself correctly - controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0) + controller.inputs.move_dir = (tgt_pos - self.pos.0) .xy() .try_normalized() .unwrap_or_else(Vec2::zero) @@ -2271,7 +2305,7 @@ impl<'a> AgentData<'a> { } } // And always try to path towards target - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Partial, None); + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Partial, None); } } @@ -2350,6 +2384,7 @@ impl<'a> AgentData<'a> { agent.action_state.counter += read_data.dt.0 * 3.3; } - self.path_toward_target(agent, controller, tgt_data, read_data, Path::Full, None); + let tgt_pos = &tgt_data.pos.0; + self.path_toward_target(agent, controller, tgt_pos, read_data, Path::Full, None); } }