mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix non-humanoid pathfinding and movement in water
This commit is contained in:
parent
a0ad6fc779
commit
cfdf184c4c
@ -79,6 +79,9 @@ impl Link for Mounting {
|
|||||||
// relationship
|
// relationship
|
||||||
if !is_mounts.contains(mount)
|
if !is_mounts.contains(mount)
|
||||||
&& !is_riders.contains(rider)
|
&& !is_riders.contains(rider)
|
||||||
|
&& !is_riders.contains(rider)
|
||||||
|
// TODO: Does this definitely prevent mount cycles?
|
||||||
|
&& (!is_mounts.contains(rider) || !is_riders.contains(mount))
|
||||||
&& !is_volume_rider.contains(rider)
|
&& !is_volume_rider.contains(rider)
|
||||||
{
|
{
|
||||||
let _ = is_mounts.insert(mount, this.make_role());
|
let _ = is_mounts.insert(mount, this.make_role());
|
||||||
|
@ -143,7 +143,14 @@ impl Route {
|
|||||||
// Determine whether we're close enough to the next to to consider it completed
|
// Determine whether we're close enough to the next to to consider it completed
|
||||||
let dist_sqrd = pos.xy().distance_squared(closest_tgt.xy());
|
let dist_sqrd = pos.xy().distance_squared(closest_tgt.xy());
|
||||||
if dist_sqrd
|
if dist_sqrd
|
||||||
< traversal_cfg.node_tolerance.powi(2) * if be_precise { 0.25 } else { 1.0 }
|
< traversal_cfg.node_tolerance.powi(2)
|
||||||
|
* if be_precise {
|
||||||
|
0.25
|
||||||
|
} else if traversal_cfg.in_liquid {
|
||||||
|
2.5
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
}
|
||||||
&& (((pos.z - closest_tgt.z > 1.2 || (pos.z - closest_tgt.z > -0.2 && traversal_cfg.on_ground))
|
&& (((pos.z - closest_tgt.z > 1.2 || (pos.z - closest_tgt.z > -0.2 && traversal_cfg.on_ground))
|
||||||
&& (pos.z - closest_tgt.z < 1.2 || (pos.z - closest_tgt.z < 2.9 && vel.z < -0.05))
|
&& (pos.z - closest_tgt.z < 1.2 || (pos.z - closest_tgt.z < 2.9 && vel.z < -0.05))
|
||||||
&& vel.z <= 0.0
|
&& vel.z <= 0.0
|
||||||
|
@ -230,13 +230,13 @@ impl Body {
|
|||||||
match self {
|
match self {
|
||||||
Body::Object(_) => None,
|
Body::Object(_) => None,
|
||||||
Body::ItemDrop(_) => None,
|
Body::ItemDrop(_) => None,
|
||||||
Body::BipedLarge(_) | Body::Golem(_) => Some(200.0 * self.mass().0),
|
Body::BipedLarge(_) | Body::Golem(_) => Some(3000.0 * self.mass().0),
|
||||||
Body::BipedSmall(_) => Some(100.0 * self.mass().0),
|
Body::BipedSmall(_) => Some(1000.0 * self.mass().0),
|
||||||
Body::BirdMedium(_) => Some(50.0 * self.mass().0),
|
Body::BirdMedium(_) => Some(1200.0 * self.mass().0),
|
||||||
Body::BirdLarge(_) => Some(50.0 * self.mass().0),
|
Body::BirdLarge(_) => Some(750.0 * self.mass().0),
|
||||||
Body::FishMedium(_) => Some(50.0 * self.mass().0),
|
Body::FishMedium(_) => Some(50.0 * self.mass().0),
|
||||||
Body::FishSmall(_) => Some(50.0 * self.mass().0),
|
Body::FishSmall(_) => Some(50.0 * self.mass().0),
|
||||||
Body::Dragon(_) => Some(200.0 * self.mass().0),
|
Body::Dragon(_) => Some(3000.0 * self.mass().0),
|
||||||
Body::Humanoid(_) => Some(2500.0 * self.mass().0),
|
Body::Humanoid(_) => Some(2500.0 * self.mass().0),
|
||||||
Body::Theropod(body) => match body.species {
|
Body::Theropod(body) => match body.species {
|
||||||
theropod::Species::Sandraptor
|
theropod::Species::Sandraptor
|
||||||
@ -244,12 +244,12 @@ impl Body {
|
|||||||
| theropod::Species::Sunlizard
|
| theropod::Species::Sunlizard
|
||||||
| theropod::Species::Woodraptor
|
| theropod::Species::Woodraptor
|
||||||
| theropod::Species::Dodarock
|
| theropod::Species::Dodarock
|
||||||
| theropod::Species::Yale => Some(200.0 * self.mass().0),
|
| theropod::Species::Yale => Some(2500.0 * self.mass().0),
|
||||||
_ => Some(100.0 * self.mass().0),
|
_ => Some(100.0 * self.mass().0),
|
||||||
},
|
},
|
||||||
Body::QuadrupedLow(_) => Some(300.0 * self.mass().0),
|
Body::QuadrupedLow(_) => Some(2500.0 * self.mass().0),
|
||||||
Body::QuadrupedMedium(_) => Some(300.0 * self.mass().0),
|
Body::QuadrupedMedium(_) => Some(3000.0 * self.mass().0),
|
||||||
Body::QuadrupedSmall(_) => Some(300.0 * self.mass().0),
|
Body::QuadrupedSmall(_) => Some(3000.0 * self.mass().0),
|
||||||
Body::Ship(ship) if ship.has_water_thrust() => Some(3500.0 * self.mass().0),
|
Body::Ship(ship) if ship.has_water_thrust() => Some(3500.0 * self.mass().0),
|
||||||
Body::Ship(_) => None,
|
Body::Ship(_) => None,
|
||||||
Body::Arthropod(_) => Some(300.0 * self.mass().0),
|
Body::Arthropod(_) => Some(300.0 * self.mass().0),
|
||||||
@ -275,7 +275,7 @@ impl Body {
|
|||||||
match self {
|
match self {
|
||||||
Body::Object(_) | Body::Ship(_) | Body::ItemDrop(_) => None,
|
Body::Object(_) | Body::Ship(_) | Body::ItemDrop(_) => None,
|
||||||
Body::BipedLarge(_) | Body::Dragon(_) | Body::Golem(_) | Body::QuadrupedLow(_) => {
|
Body::BipedLarge(_) | Body::Dragon(_) | Body::Golem(_) | Body::QuadrupedLow(_) => {
|
||||||
Some(0.1 * self.mass().0)
|
Some(0.4 * self.mass().0)
|
||||||
},
|
},
|
||||||
Body::QuadrupedMedium(_) => Some(0.4 * self.mass().0),
|
Body::QuadrupedMedium(_) => Some(0.4 * self.mass().0),
|
||||||
Body::Theropod(body) => match body.species {
|
Body::Theropod(body) => match body.species {
|
||||||
@ -284,7 +284,7 @@ impl Body {
|
|||||||
| theropod::Species::Woodraptor => Some(0.4 * self.mass().0),
|
| theropod::Species::Woodraptor => Some(0.4 * self.mass().0),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Body::Arthropod(_) => Some(2.0 * self.mass().0),
|
Body::Arthropod(_) => Some(1.0 * self.mass().0),
|
||||||
_ => Some(0.4 * self.mass().0),
|
_ => Some(0.4 * self.mass().0),
|
||||||
}
|
}
|
||||||
.map(|f| f * GRAVITY)
|
.map(|f| f * GRAVITY)
|
||||||
@ -593,6 +593,8 @@ pub fn handle_orientation(
|
|||||||
* efficiency
|
* efficiency
|
||||||
* if data.physics.on_ground.is_some() {
|
* if data.physics.on_ground.is_some() {
|
||||||
1.0
|
1.0
|
||||||
|
} else if data.physics.in_liquid().is_some() {
|
||||||
|
0.4
|
||||||
} else {
|
} else {
|
||||||
0.2
|
0.2
|
||||||
}
|
}
|
||||||
@ -1098,9 +1100,22 @@ pub fn handle_jump(
|
|||||||
_update: &mut StateUpdate,
|
_update: &mut StateUpdate,
|
||||||
strength: f32,
|
strength: f32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
(input_is_pressed(data, InputKind::Jump) && data.physics.on_ground.is_some())
|
input_is_pressed(data, InputKind::Jump)
|
||||||
.then(|| data.body.jump_impulse())
|
.then(|| data.body.jump_impulse())
|
||||||
.flatten()
|
.flatten()
|
||||||
|
.and_then(|impulse| {
|
||||||
|
if data.physics.on_ground.is_some() {
|
||||||
|
Some(impulse)
|
||||||
|
} else if data.physics.in_liquid().map_or(false, |h| h < 1.0)
|
||||||
|
&& data.physics.on_wall.is_some()
|
||||||
|
{
|
||||||
|
// Allow entities to make a small jump when at the edge of a body of water,
|
||||||
|
// allowing them to path out of it
|
||||||
|
Some(impulse * 0.75)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
.map(|impulse| {
|
.map(|impulse| {
|
||||||
output_events.emit_local(LocalEvent::Jump(
|
output_events.emit_local(LocalEvent::Jump(
|
||||||
data.entity,
|
data.entity,
|
||||||
|
@ -152,16 +152,23 @@ impl<'a> AgentData<'a> {
|
|||||||
..self.traversal_config
|
..self.traversal_config
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
controller.inputs.move_dir =
|
self.traverse(controller, bearing, speed * speed_multiplier);
|
||||||
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed * speed_multiplier;
|
|
||||||
self.jump_if(bearing.z > 1.5, controller);
|
|
||||||
controller.inputs.move_z = bearing.z;
|
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn traverse(&self, controller: &mut Controller, bearing: Vec3<f32>, speed: f32) {
|
||||||
|
controller.inputs.move_dir =
|
||||||
|
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
|
||||||
|
let climbing_out_of_water = self.physics_state.in_liquid().map_or(false, |h| h < 1.0)
|
||||||
|
&& bearing.z > 0.0
|
||||||
|
&& self.physics_state.on_wall.is_some();
|
||||||
|
self.jump_if(bearing.z > 1.5 || climbing_out_of_water, controller);
|
||||||
|
controller.inputs.move_z = bearing.z;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn jump_if(&self, condition: bool, controller: &mut Controller) {
|
pub fn jump_if(&self, condition: bool, controller: &mut Controller) {
|
||||||
if condition {
|
if condition {
|
||||||
controller.push_basic_input(InputKind::Jump);
|
controller.push_basic_input(InputKind::Jump);
|
||||||
@ -265,12 +272,9 @@ impl<'a> AgentData<'a> {
|
|||||||
..self.traversal_config
|
..self.traversal_config
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
controller.inputs.move_dir =
|
self.traverse(controller, bearing, speed.min(speed_factor));
|
||||||
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero)
|
self.jump_if(self.traversal_config.can_fly, controller);
|
||||||
* speed.min(speed_factor);
|
|
||||||
self.jump_if(bearing.z > 1.5 || self.traversal_config.can_fly, controller);
|
|
||||||
controller.inputs.climb = Some(comp::Climb::Up);
|
controller.inputs.climb = Some(comp::Climb::Up);
|
||||||
//.filter(|_| bearing.z > 0.1 || self.physics_state.in_liquid().is_some());
|
|
||||||
|
|
||||||
let height_offset = bearing.z
|
let height_offset = bearing.z
|
||||||
+ if self.traversal_config.can_fly {
|
+ if self.traversal_config.can_fly {
|
||||||
@ -552,10 +556,11 @@ impl<'a> AgentData<'a> {
|
|||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
let dist_sqrd = self.pos.0.distance_squared(tgt_pos.0);
|
let dist_sqrd = self.pos.0.distance_squared(tgt_pos.0);
|
||||||
controller.inputs.move_dir = bearing.xy().try_normalized().unwrap_or_else(Vec2::zero)
|
self.traverse(
|
||||||
* speed.min(0.2 + (dist_sqrd - AVG_FOLLOW_DIST.powi(2)) / 8.0);
|
controller,
|
||||||
self.jump_if(bearing.z > 1.5, controller);
|
bearing,
|
||||||
controller.inputs.move_z = bearing.z;
|
speed.min(0.2 + (dist_sqrd - AVG_FOLLOW_DIST.powi(2)) / 8.0),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,10 +622,7 @@ impl<'a> AgentData<'a> {
|
|||||||
..self.traversal_config
|
..self.traversal_config
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
controller.inputs.move_dir = bearing.xy().try_normalized().unwrap_or_else(Vec2::zero)
|
self.traverse(controller, bearing, speed.min(MAX_FLEE_SPEED));
|
||||||
* speed.min(MAX_FLEE_SPEED);
|
|
||||||
self.jump_if(bearing.z > 1.5, controller);
|
|
||||||
controller.inputs.move_z = bearing.z;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user