mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Impl #1357: Agent chase abort
- Adds util funcs to calculate benefit of continue pursue vs letting target escape - Hooks util funcs into agent's hostile tree
This commit is contained in:
parent
9a3b5d3ec8
commit
0037518472
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Waypoints saved between sessions and shared with group members.
|
- Waypoints saved between sessions and shared with group members.
|
||||||
- New rocks
|
- New rocks
|
||||||
- Weapon trails
|
- Weapon trails
|
||||||
|
- Hostile agent will now abort pursuing their target based on multiple metrics
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||||||
data::{AgentData, AttackData, Path, 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, stop_pursuing, try_owner_alignment,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -613,6 +613,20 @@ impl<'a> AgentData<'a> {
|
|||||||
|
|
||||||
if let Some(tgt_pos) = read_data.positions.get(target) {
|
if let Some(tgt_pos) = read_data.positions.get(target) {
|
||||||
let dist_sqrd = self.pos.0.distance_squared(tgt_pos.0);
|
let dist_sqrd = self.pos.0.distance_squared(tgt_pos.0);
|
||||||
|
let origin_dist_sqrd = match agent.patrol_origin {
|
||||||
|
Some(pos) => pos.distance_squared(self.pos.0),
|
||||||
|
None => 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let own_health_fraction = match self.health {
|
||||||
|
Some(val) => val.fraction(),
|
||||||
|
None => 1.0,
|
||||||
|
};
|
||||||
|
let target_health_fraction = match read_data.healths.get(target) {
|
||||||
|
Some(val) => val.fraction(),
|
||||||
|
None => 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
let in_aggro_range = agent
|
let in_aggro_range = agent
|
||||||
.psyche
|
.psyche
|
||||||
.aggro_dist
|
.aggro_dist
|
||||||
@ -645,7 +659,16 @@ impl<'a> AgentData<'a> {
|
|||||||
self.exclaim_relief_about_enemy_dead(agent, event_emitter);
|
self.exclaim_relief_about_enemy_dead(agent, event_emitter);
|
||||||
agent.target = None;
|
agent.target = None;
|
||||||
self.idle(agent, controller, read_data, rng);
|
self.idle(agent, controller, read_data, rng);
|
||||||
} else if is_invulnerable(target, read_data) {
|
} else if is_invulnerable(target, read_data)
|
||||||
|
|| stop_pursuing(
|
||||||
|
dist_sqrd,
|
||||||
|
origin_dist_sqrd,
|
||||||
|
own_health_fraction,
|
||||||
|
target_health_fraction,
|
||||||
|
read_data.time.0 - selected_at,
|
||||||
|
&agent.psyche,
|
||||||
|
)
|
||||||
|
{
|
||||||
agent.target = None;
|
agent.target = None;
|
||||||
self.idle(agent, controller, read_data, rng);
|
self.idle(agent, controller, read_data, rng);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::sys::agent::{AgentData, ReadData};
|
use crate::sys::agent::{AgentData, ReadData};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{buff::BuffKind, Alignment, Pos},
|
comp::{agent::Psyche, buff::BuffKind, Alignment, Pos},
|
||||||
consts::GRAVITY,
|
consts::GRAVITY,
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, TerrainGrid},
|
||||||
util::Dir,
|
util::Dir,
|
||||||
@ -79,3 +79,45 @@ impl<'a> AgentData<'a> {
|
|||||||
.map_or(false, |b| b.kinds.contains_key(&buff))
|
.map_or(false, |b| b.kinds.contains_key(&buff))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates whether the agent should continue chase or let the target escape.
|
||||||
|
///
|
||||||
|
/// Will return true when score of letting target escape is higher then the
|
||||||
|
/// score of continuing the pursue, false otherwise.
|
||||||
|
pub fn stop_pursuing(
|
||||||
|
dist_to_target_sqrd: f32,
|
||||||
|
dist_to_home_sqrd: f32,
|
||||||
|
own_health_fraction: f32,
|
||||||
|
target_health_fraction: f32,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Scores the benefit of continuing the pursue in value from 0 to infinity.
|
||||||
|
fn should_continue_to_pursue(
|
||||||
|
dist_to_target_sqrd: f32,
|
||||||
|
psyche: &Psyche,
|
||||||
|
target_health_fraction: f32,
|
||||||
|
) -> f32 {
|
||||||
|
let aggression_score = (1.0 / psyche.flee_health.max(0.25))
|
||||||
|
* psyche.aggro_dist.unwrap_or(psyche.sight_dist)
|
||||||
|
* psyche.sight_dist;
|
||||||
|
|
||||||
|
(100.0 * aggression_score) / (dist_to_target_sqrd * target_health_fraction)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Scores the benefit of letting the target escape in a value from 0 to
|
||||||
|
/// infinity.
|
||||||
|
fn should_let_target_escape(
|
||||||
|
dist_to_home_sqrd: f32,
|
||||||
|
dur_since_last_attacked: f64,
|
||||||
|
own_health_fraction: f32,
|
||||||
|
) -> f32 {
|
||||||
|
(dist_to_home_sqrd / own_health_fraction) * dur_since_last_attacked as f32 * 0.005
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user