mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better non-climbing NPC pathfinding in rivers
This commit is contained in:
@ -69,6 +69,8 @@ pub struct TraversalConfig {
|
|||||||
pub in_liquid: bool,
|
pub in_liquid: bool,
|
||||||
/// The distance to the target below which it is considered reached.
|
/// The distance to the target below which it is considered reached.
|
||||||
pub min_tgt_dist: f32,
|
pub min_tgt_dist: f32,
|
||||||
|
/// Whether the agent can climb.
|
||||||
|
pub can_climb: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DIAGONALS: [Vec2<i32>; 8] = [
|
const DIAGONALS: [Vec2<i32>; 8] = [
|
||||||
@ -389,7 +391,7 @@ impl Chaser {
|
|||||||
{
|
{
|
||||||
self.last_search_tgt = Some(tgt);
|
self.last_search_tgt = Some(tgt);
|
||||||
|
|
||||||
let (path, complete) = find_path(&mut self.astar, vol, pos, tgt);
|
let (path, complete) = find_path(&mut self.astar, vol, pos, tgt, &traversal_cfg);
|
||||||
|
|
||||||
self.route = path.map(|path| {
|
self.route = path.map(|path| {
|
||||||
let start_index = path
|
let start_index = path
|
||||||
@ -455,6 +457,7 @@ fn find_path<V>(
|
|||||||
vol: &V,
|
vol: &V,
|
||||||
startf: Vec3<f32>,
|
startf: Vec3<f32>,
|
||||||
endf: Vec3<f32>,
|
endf: Vec3<f32>,
|
||||||
|
traversal_cfg: &TraversalConfig,
|
||||||
) -> (Option<Path<Vec3<i32>>>, bool)
|
) -> (Option<Path<Vec3<i32>>>, bool)
|
||||||
where
|
where
|
||||||
V: BaseVol<Vox = Block> + ReadVol,
|
V: BaseVol<Vox = Block> + ReadVol,
|
||||||
@ -483,30 +486,33 @@ where
|
|||||||
let heuristic = |pos: &Vec3<i32>| (pos.distance_squared(end) as f32).sqrt();
|
let heuristic = |pos: &Vec3<i32>| (pos.distance_squared(end) as f32).sqrt();
|
||||||
let neighbors = |pos: &Vec3<i32>| {
|
let neighbors = |pos: &Vec3<i32>| {
|
||||||
let pos = *pos;
|
let pos = *pos;
|
||||||
const DIRS: [Vec3<i32>; 21] = [
|
const DIRS: [Vec3<i32>; 17] = [
|
||||||
Vec3::new(0, 1, 0), // Forward
|
Vec3::new(0, 1, 0), // Forward
|
||||||
Vec3::new(0, 1, 1), // Forward upward
|
Vec3::new(0, 1, 1), // Forward upward
|
||||||
Vec3::new(0, 1, 2), // Forward Upwardx2
|
|
||||||
Vec3::new(0, 1, -1), // Forward downward
|
Vec3::new(0, 1, -1), // Forward downward
|
||||||
Vec3::new(0, 1, -2), // Forward downwardx2
|
Vec3::new(0, 1, -2), // Forward downwardx2
|
||||||
Vec3::new(1, 0, 0), // Right
|
Vec3::new(1, 0, 0), // Right
|
||||||
Vec3::new(1, 0, 1), // Right upward
|
Vec3::new(1, 0, 1), // Right upward
|
||||||
Vec3::new(1, 0, 2), // Right Upwardx2
|
|
||||||
Vec3::new(1, 0, -1), // Right downward
|
Vec3::new(1, 0, -1), // Right downward
|
||||||
Vec3::new(1, 0, -2), // Right downwardx2
|
Vec3::new(1, 0, -2), // Right downwardx2
|
||||||
Vec3::new(0, -1, 0), // Backwards
|
Vec3::new(0, -1, 0), // Backwards
|
||||||
Vec3::new(0, -1, 1), // Backward Upward
|
Vec3::new(0, -1, 1), // Backward Upward
|
||||||
Vec3::new(0, -1, 2), // Backward Upwardx2
|
|
||||||
Vec3::new(0, -1, -1), // Backward downward
|
Vec3::new(0, -1, -1), // Backward downward
|
||||||
Vec3::new(0, -1, -2), // Backward downwardx2
|
Vec3::new(0, -1, -2), // Backward downwardx2
|
||||||
Vec3::new(-1, 0, 0), // Left
|
Vec3::new(-1, 0, 0), // Left
|
||||||
Vec3::new(-1, 0, 1), // Left upward
|
Vec3::new(-1, 0, 1), // Left upward
|
||||||
Vec3::new(-1, 0, 2), // Left Upwardx2
|
|
||||||
Vec3::new(-1, 0, -1), // Left downward
|
Vec3::new(-1, 0, -1), // Left downward
|
||||||
Vec3::new(-1, 0, -2), // Left downwardx2
|
Vec3::new(-1, 0, -2), // Left downwardx2
|
||||||
Vec3::new(0, 0, -1), // Downwards
|
Vec3::new(0, 0, -1), // Downwards
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const JUMPS: [Vec3<i32>; 4] = [
|
||||||
|
Vec3::new(0, 1, 2), // Forward Upwardx2
|
||||||
|
Vec3::new(1, 0, 2), // Right Upwardx2
|
||||||
|
Vec3::new(0, -1, 2), // Backward Upwardx2
|
||||||
|
Vec3::new(-1, 0, 2), // Left Upwardx2
|
||||||
|
];
|
||||||
|
|
||||||
// let walkable = [
|
// let walkable = [
|
||||||
// is_walkable(&(pos + Vec3::new(1, 0, 0))),
|
// is_walkable(&(pos + Vec3::new(1, 0, 0))),
|
||||||
// is_walkable(&(pos + Vec3::new(-1, 0, 0))),
|
// is_walkable(&(pos + Vec3::new(-1, 0, 0))),
|
||||||
@ -526,6 +532,13 @@ where
|
|||||||
// ];
|
// ];
|
||||||
|
|
||||||
DIRS.iter()
|
DIRS.iter()
|
||||||
|
.chain(Some(JUMPS.iter())
|
||||||
|
.filter(|_| vol
|
||||||
|
.get(pos)
|
||||||
|
.map(|b| !b.is_liquid())
|
||||||
|
.unwrap_or(true) || traversal_cfg.can_climb)
|
||||||
|
.into_iter()
|
||||||
|
.flatten())
|
||||||
.map(move |dir| (pos, dir))
|
.map(move |dir| (pos, dir))
|
||||||
.filter(move |(pos, dir)| {
|
.filter(move |(pos, dir)| {
|
||||||
is_walkable(pos)
|
is_walkable(pos)
|
||||||
|
@ -94,6 +94,13 @@ impl Body {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_climb(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Body::Humanoid(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles updating `Components` to move player based on state of `JoinData`
|
/// Handles updating `Components` to move player based on state of `JoinData`
|
||||||
@ -284,7 +291,7 @@ pub fn handle_climb(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
.map(|depth| depth > 1.0)
|
.map(|depth| depth > 1.0)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
//&& update.vel.0.z < 0.0
|
//&& update.vel.0.z < 0.0
|
||||||
&& data.body.is_humanoid()
|
&& data.body.can_climb()
|
||||||
&& update.energy.current() > 100
|
&& update.energy.current() > 100
|
||||||
{
|
{
|
||||||
update.character = CharacterState::Climb;
|
update.character = CharacterState::Climb;
|
||||||
|
@ -207,6 +207,15 @@ impl<'a> System<'a> for Sys {
|
|||||||
let node_tolerance = scale * 1.5;
|
let node_tolerance = scale * 1.5;
|
||||||
let slow_factor = body.map(|b| b.base_accel() / 250.0).unwrap_or(0.0).min(1.0);
|
let slow_factor = body.map(|b| b.base_accel() / 250.0).unwrap_or(0.0).min(1.0);
|
||||||
|
|
||||||
|
let traversal_config = TraversalConfig {
|
||||||
|
node_tolerance,
|
||||||
|
slow_factor,
|
||||||
|
on_ground: physics_state.on_ground,
|
||||||
|
in_liquid: physics_state.in_liquid.is_some(),
|
||||||
|
min_tgt_dist: 1.0,
|
||||||
|
can_climb: body.map(|b| b.can_climb()).unwrap_or(false),
|
||||||
|
};
|
||||||
|
|
||||||
let mut do_idle = false;
|
let mut do_idle = false;
|
||||||
let mut choose_target = false;
|
let mut choose_target = false;
|
||||||
|
|
||||||
@ -220,11 +229,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
vel.0,
|
vel.0,
|
||||||
travel_to,
|
travel_to,
|
||||||
TraversalConfig {
|
TraversalConfig {
|
||||||
node_tolerance,
|
|
||||||
slow_factor,
|
|
||||||
on_ground: physics_state.on_ground,
|
|
||||||
in_liquid: physics_state.in_liquid.is_some(),
|
|
||||||
min_tgt_dist: 1.25,
|
min_tgt_dist: 1.25,
|
||||||
|
..traversal_config
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
inputs.move_dir = bearing
|
inputs.move_dir = bearing
|
||||||
@ -279,10 +285,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put away weapon
|
|
||||||
if thread_rng().gen::<f32>() < 0.005 {
|
|
||||||
controller.actions.push(ControlAction::Unwield);
|
controller.actions.push(ControlAction::Unwield);
|
||||||
}
|
|
||||||
|
|
||||||
// Sometimes try searching for new targets
|
// Sometimes try searching for new targets
|
||||||
if thread_rng().gen::<f32>() < 0.1 {
|
if thread_rng().gen::<f32>() < 0.1 {
|
||||||
@ -302,11 +305,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
vel.0,
|
vel.0,
|
||||||
tgt_pos.0,
|
tgt_pos.0,
|
||||||
TraversalConfig {
|
TraversalConfig {
|
||||||
node_tolerance,
|
|
||||||
slow_factor,
|
|
||||||
on_ground: physics_state.on_ground,
|
|
||||||
in_liquid: physics_state.in_liquid.is_some(),
|
|
||||||
min_tgt_dist: AVG_FOLLOW_DIST,
|
min_tgt_dist: AVG_FOLLOW_DIST,
|
||||||
|
..traversal_config
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
inputs.move_dir =
|
inputs.move_dir =
|
||||||
@ -429,11 +429,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
.unwrap_or_else(Vec3::unit_y)
|
.unwrap_or_else(Vec3::unit_y)
|
||||||
* 8.0,
|
* 8.0,
|
||||||
TraversalConfig {
|
TraversalConfig {
|
||||||
node_tolerance,
|
|
||||||
slow_factor,
|
|
||||||
on_ground: physics_state.on_ground,
|
|
||||||
in_liquid: physics_state.in_liquid.is_some(),
|
|
||||||
min_tgt_dist: 1.25,
|
min_tgt_dist: 1.25,
|
||||||
|
..traversal_config
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
inputs.move_dir =
|
inputs.move_dir =
|
||||||
@ -591,11 +588,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
vel.0,
|
vel.0,
|
||||||
tgt_pos.0,
|
tgt_pos.0,
|
||||||
TraversalConfig {
|
TraversalConfig {
|
||||||
node_tolerance,
|
|
||||||
slow_factor,
|
|
||||||
on_ground: physics_state.on_ground,
|
|
||||||
in_liquid: physics_state.in_liquid.is_some(),
|
|
||||||
min_tgt_dist: 1.25,
|
min_tgt_dist: 1.25,
|
||||||
|
..traversal_config
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if can_see_tgt {
|
if can_see_tgt {
|
||||||
|
Reference in New Issue
Block a user