diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index d850f9a120..41dd6feabd 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -274,6 +274,10 @@ pub struct Psyche { /// wandering behavior in the idle state, and scaling `aggro_dist` in /// certain situations. pub aggro_range_multiplier: f32, + /// Whether this entity should *intelligently* decide to loose aggro based + /// on distance from agent home and health, this is not suitable for world + /// bosses and roaming entities + pub should_stop_pursuing: bool, } impl<'a> From<&'a Body> for Psyche { @@ -425,6 +429,13 @@ impl<'a> From<&'a Body> for Psyche { }, idle_wander_factor: 1.0, aggro_range_multiplier: 1.0, + should_stop_pursuing: match body { + Body::BirdLarge(_) => false, + Body::BipedLarge(biped_large) => { + !matches!(biped_large.species, biped_large::Species::Gigasfrost) + }, + _ => true, + }, } } } diff --git a/server/agent/src/action_nodes.rs b/server/agent/src/action_nodes.rs index 0bf2c20bca..1ac323cb21 100644 --- a/server/agent/src/action_nodes.rs +++ b/server/agent/src/action_nodes.rs @@ -994,14 +994,15 @@ impl<'a> AgentData<'a> { controller.push_utterance(UtteranceKind::Surprised); } } - - agent.target = target.map(|(entity, attack_target)| Target { - target: entity, - hostile: attack_target, - selected_at: read_data.time.0, - aggro_on, - last_known_pos: get_pos(entity).map(|pos| pos.0), - }) + if agent.psyche.should_stop_pursuing || target.is_some() { + agent.target = target.map(|(entity, attack_target)| Target { + target: entity, + hostile: attack_target, + selected_at: read_data.time.0, + aggro_on, + last_known_pos: get_pos(entity).map(|pos| pos.0), + }) + } } pub fn attack( diff --git a/server/agent/src/util.rs b/server/agent/src/util.rs index f0c3382e9a..a2cdd8a99d 100644 --- a/server/agent/src/util.rs +++ b/server/agent/src/util.rs @@ -80,11 +80,12 @@ pub fn stop_pursuing( dur_since_last_attacked: f64, psyche: &Psyche, ) -> bool { - should_let_target_escape( - dist_to_home_sqrd, - dur_since_last_attacked, - own_health_fraction, - ) > should_continue_to_pursue(dist_to_target_sqrd, psyche, target_health_fraction) + psyche.should_stop_pursuing + && should_let_target_escape( + dist_to_home_sqrd, + dur_since_last_attacked, + own_health_fraction, + ) > should_continue_to_pursue(dist_to_target_sqrd, psyche, target_health_fraction) } /// Scores the benefit of continuing the pursue in value from 0 to infinity. diff --git a/server/src/sys/agent/behavior_tree.rs b/server/src/sys/agent/behavior_tree.rs index 97ec2293e2..0fcebfa35e 100755 --- a/server/src/sys/agent/behavior_tree.rs +++ b/server/src/sys/agent/behavior_tree.rs @@ -855,7 +855,7 @@ fn do_combat(bdata: &mut BehaviorData) -> bool { let is_time_to_retarget = read_data.time.0 - selected_at > RETARGETING_THRESHOLD_SECONDS; - if !in_aggro_range && is_time_to_retarget { + if (!agent.psyche.should_stop_pursuing || !in_aggro_range) && is_time_to_retarget { agent_data.choose_target( agent, controller, @@ -889,6 +889,10 @@ fn do_combat(bdata: &mut BehaviorData) -> bool { } } } + // make sure world bosses and roaming entities stay aware, to continue pursuit + if !agent.psyche.should_stop_pursuing { + bdata.agent.awareness.set_maximally_aware(); + } } false }