Merge branch 'zesterer/fixes' into 'master'

Various non-humanoid fixes and tweaks

See merge request veloren/veloren!3935
This commit is contained in:
Joshua Barretto 2023-05-16 23:52:09 +00:00
commit 8b835a91d0
9 changed files with 127 additions and 71 deletions

View File

@ -337,15 +337,23 @@ impl Body {
// alligator or smaller, so whatever
quadruped_low::Species::Crocodile => 360.0,
quadruped_low::Species::SeaCrocodile => 410.0,
quadruped_low::Species::Deadwood => 400.0,
quadruped_low::Species::Lavadrake => 500.0,
quadruped_low::Species::Monitor => 100.0,
quadruped_low::Species::Pangolin => 100.0,
quadruped_low::Species::Salamander => 65.0,
quadruped_low::Species::Deadwood => 150.0,
quadruped_low::Species::Monitor => 200.0,
quadruped_low::Species::Pangolin => 300.0,
quadruped_low::Species::Salamander => 350.0,
quadruped_low::Species::Elbst => 65.0,
quadruped_low::Species::Tortoise => 200.0,
quadruped_low::Species::Tortoise => 300.0,
quadruped_low::Species::Lavadrake => 500.0,
quadruped_low::Species::Icedrake => 500.0,
quadruped_low::Species::Mossdrake => 500.0,
_ => 200.0,
quadruped_low::Species::Rocksnapper => 450.0,
quadruped_low::Species::Rootsnapper => 450.0,
quadruped_low::Species::Reefsnapper => 450.0,
quadruped_low::Species::Maneater => 350.0,
quadruped_low::Species::Sandshark => 450.0,
quadruped_low::Species::Hakulaq => 300.0,
quadruped_low::Species::Dagon => 400.0,
quadruped_low::Species::Basilisk => 500.0,
},
Body::QuadrupedMedium(body) => match body.species {
quadruped_medium::Species::Bear => 500.0, // ~✅ (350-700 kg)
@ -1022,9 +1030,10 @@ impl Body {
/// Component of the mounting offset specific to the mount
pub fn mount_offset(&self) -> Vec3<f32> {
match self {
Body::Humanoid(_) | Body::BipedLarge(_) => {
(self.dimensions() * Vec3::new(0.5, 0.0, 0.6)).into_array()
},
Body::Humanoid(_) => (self.dimensions() * Vec3::new(0.5, 0.0, 0.6)).into_array(),
Body::BipedLarge(_) => (self.dimensions() * Vec3::new(0.5, 0.0, 0.7)).into_array(),
Body::BirdLarge(_) => (self.dimensions() * Vec3::new(0.0, 0.2, 0.7)).into_array(),
Body::QuadrupedLow(_) => (self.dimensions() * Vec3::new(0.0, 0.15, 0.4)).into_array(),
Body::QuadrupedMedium(quadruped_medium) => {
match (quadruped_medium.species, quadruped_medium.body_type) {
(quadruped_medium::Species::Grolgar, _) => [0.0, 0.5, 1.8],

View File

@ -1,4 +1,4 @@
use crate::comp::{body::Body, phys::Mass, quadruped_low, quadruped_medium, quadruped_small};
use crate::comp::{body::Body, phys::Mass, quadruped_medium, quadruped_small};
use crossbeam_utils::atomic::AtomicCell;
use specs::Component;
use std::{num::NonZeroU64, sync::Arc};
@ -64,6 +64,7 @@ pub fn is_mountable(mount: &Body, rider: Option<&Body>) -> bool {
match mount {
Body::Humanoid(_) => matches!(rider, Some(Body::BirdMedium(_))),
Body::BipedLarge(_) => is_light_enough(rider),
Body::BirdLarge(_) => is_light_enough(rider),
Body::QuadrupedMedium(body) => match body.species {
quadruped_medium::Species::Alpaca
| quadruped_medium::Species::Antelope
@ -79,7 +80,11 @@ pub fn is_mountable(mount: &Body, rider: Option<&Body>) -> bool {
| quadruped_medium::Species::Moose
| quadruped_medium::Species::Tuskram
| quadruped_medium::Species::Yak
| quadruped_medium::Species::Zebra => true,
| quadruped_medium::Species::Zebra
| quadruped_medium::Species::Grolgar
| quadruped_medium::Species::Wolf
| quadruped_medium::Species::Saber
| quadruped_medium::Species::Tiger => true,
quadruped_medium::Species::Mouflon => is_light_enough(rider),
_ => false,
},
@ -90,12 +95,7 @@ pub fn is_mountable(mount: &Body, rider: Option<&Body>) -> bool {
},
_ => false,
},
Body::QuadrupedLow(body) => matches!(
body.species,
quadruped_low::Species::Salamander
| quadruped_low::Species::Elbst
| quadruped_low::Species::Tortoise
),
Body::QuadrupedLow(_) => mount.mass() >= Mass(300.0) && is_light_enough(rider),
Body::Ship(_) => true,
_ => false,
}

View File

@ -79,6 +79,9 @@ impl Link for Mounting {
// relationship
if !is_mounts.contains(mount)
&& !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)
{
let _ = is_mounts.insert(mount, this.make_role());

View File

@ -143,7 +143,14 @@ impl Route {
// Determine whether we're close enough to the next to to consider it completed
let dist_sqrd = pos.xy().distance_squared(closest_tgt.xy());
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 < 2.9 && vel.z < -0.05))
&& vel.z <= 0.0

View File

@ -230,13 +230,13 @@ impl Body {
match self {
Body::Object(_) => None,
Body::ItemDrop(_) => None,
Body::BipedLarge(_) | Body::Golem(_) => Some(200.0 * self.mass().0),
Body::BipedSmall(_) => Some(100.0 * self.mass().0),
Body::BirdMedium(_) => Some(50.0 * self.mass().0),
Body::BirdLarge(_) => Some(50.0 * self.mass().0),
Body::BipedLarge(_) | Body::Golem(_) => Some(3000.0 * self.mass().0),
Body::BipedSmall(_) => Some(1000.0 * self.mass().0),
Body::BirdMedium(_) => Some(1200.0 * self.mass().0),
Body::BirdLarge(_) => Some(750.0 * self.mass().0),
Body::FishMedium(_) => 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::Theropod(body) => match body.species {
theropod::Species::Sandraptor
@ -244,12 +244,12 @@ impl Body {
| theropod::Species::Sunlizard
| theropod::Species::Woodraptor
| 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),
},
Body::QuadrupedLow(_) => Some(300.0 * self.mass().0),
Body::QuadrupedMedium(_) => Some(300.0 * self.mass().0),
Body::QuadrupedSmall(_) => Some(300.0 * self.mass().0),
Body::QuadrupedLow(_) => Some(2500.0 * self.mass().0),
Body::QuadrupedMedium(_) => Some(3000.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(_) => None,
Body::Arthropod(_) => Some(300.0 * self.mass().0),
@ -274,9 +274,8 @@ impl Body {
pub fn jump_impulse(&self) -> Option<f32> {
match self {
Body::Object(_) | Body::Ship(_) | Body::ItemDrop(_) => None,
Body::BipedLarge(_) | Body::Dragon(_) | Body::Golem(_) | Body::QuadrupedLow(_) => {
Some(0.1 * self.mass().0)
},
Body::BipedLarge(_) | Body::Dragon(_) => Some(0.6 * self.mass().0),
Body::Golem(_) | Body::QuadrupedLow(_) => Some(0.4 * self.mass().0),
Body::QuadrupedMedium(_) => Some(0.4 * self.mass().0),
Body::Theropod(body) => match body.species {
theropod::Species::Snowraptor
@ -284,7 +283,7 @@ impl Body {
| theropod::Species::Woodraptor => Some(0.4 * self.mass().0),
_ => None,
},
Body::Arthropod(_) => Some(2.0 * self.mass().0),
Body::Arthropod(_) => Some(1.0 * self.mass().0),
_ => Some(0.4 * self.mass().0),
}
.map(|f| f * GRAVITY)
@ -593,6 +592,8 @@ pub fn handle_orientation(
* efficiency
* if data.physics.on_ground.is_some() {
1.0
} else if data.physics.in_liquid().is_some() {
0.4
} else {
0.2
}
@ -1098,9 +1099,22 @@ pub fn handle_jump(
_update: &mut StateUpdate,
strength: f32,
) -> bool {
(input_is_pressed(data, InputKind::Jump) && data.physics.on_ground.is_some())
input_is_pressed(data, InputKind::Jump)
.then(|| data.body.jump_impulse())
.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| {
output_events.emit_local(LocalEvent::Jump(
data.entity,

View File

@ -152,16 +152,23 @@ impl<'a> AgentData<'a> {
..self.traversal_config
},
) {
controller.inputs.move_dir =
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;
self.traverse(controller, bearing, speed * speed_multiplier);
true
} else {
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) {
if condition {
controller.push_basic_input(InputKind::Jump);
@ -265,12 +272,9 @@ impl<'a> AgentData<'a> {
..self.traversal_config
},
) {
controller.inputs.move_dir =
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero)
* speed.min(speed_factor);
self.jump_if(bearing.z > 1.5 || self.traversal_config.can_fly, controller);
self.traverse(controller, bearing, speed.min(speed_factor));
self.jump_if(self.traversal_config.can_fly, controller);
controller.inputs.climb = Some(comp::Climb::Up);
//.filter(|_| bearing.z > 0.1 || self.physics_state.in_liquid().is_some());
let height_offset = bearing.z
+ 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);
controller.inputs.move_dir = bearing.xy().try_normalized().unwrap_or_else(Vec2::zero)
* speed.min(0.2 + (dist_sqrd - AVG_FOLLOW_DIST.powi(2)) / 8.0);
self.jump_if(bearing.z > 1.5, controller);
controller.inputs.move_z = bearing.z;
self.traverse(
controller,
bearing,
speed.min(0.2 + (dist_sqrd - AVG_FOLLOW_DIST.powi(2)) / 8.0),
);
}
}
@ -617,10 +622,7 @@ impl<'a> AgentData<'a> {
..self.traversal_config
},
) {
controller.inputs.move_dir = bearing.xy().try_normalized().unwrap_or_else(Vec2::zero)
* speed.min(MAX_FLEE_SPEED);
self.jump_if(bearing.z > 1.5, controller);
controller.inputs.move_z = bearing.z;
self.traverse(controller, bearing, speed.min(MAX_FLEE_SPEED));
}
}

View File

@ -96,16 +96,22 @@ impl Skeleton for BirdLargeSkeleton {
make_bone(foot_l_mat),
make_bone(foot_r_mat),
];
// Offset from the mounted bone's origin.
let mount_position = (neck_mat * Vec4::from_point(mount_point(&body)))
.homogenized()
.xyz();
// NOTE: We apply the ori from base_mat externally so we don't need to worry
// about it here for now.
let mount_orientation = self.neck.orientation;
Offsets {
lantern: None,
viewpoint: Some((head_mat * Vec4::new(0.0, 3.0, 6.0, 1.0)).xyz()),
// TODO: see quadruped_medium for how to animate this
mount_bone: Transform {
position: comp::Body::BirdLarge(body)
.mount_offset()
.into_tuple()
.into(),
..Default::default()
position: mount_position,
orientation: mount_orientation,
scale: Vec3::one(),
},
primary_trail_mat: None,
secondary_trail_mat: None,
@ -307,3 +313,18 @@ impl<'a> From<&'a Body> for SkeletonAttr {
}
}
}
fn mount_point(body: &Body) -> Vec3<f32> {
use comp::bird_large::Species::*;
match (body.species, body.body_type) {
(Phoenix, _) => (0.0, -2.0, 6.0),
(Cockatrice, _) => (0.0, 0.0, 6.0),
(Roc, _) => (0.0, 6.0, 3.0),
(FlameWyvern, _) => (0.0, 0.0, 2.5),
(FrostWyvern, _) => (0.0, 2.0, 3.0),
(CloudWyvern, _) => (0.0, 1.0, 3.0),
(SeaWyvern, _) => (0.0, -3.0, 4.0),
(WealdWyvern, _) => (0.0, 0.0, 5.0),
}
.into()
}

View File

@ -391,27 +391,27 @@ impl<'a> From<&'a Body> for SkeletonAttr {
fn mount_point(body: &Body) -> Vec3<f32> {
use comp::quadruped_low::Species::*;
match (body.species, body.body_type) {
(Crocodile, _) => (0.0, 4.5, -2.0),
(SeaCrocodile, _) => (0.0, 4.5, -2.0),
(Alligator, _) => (0.0, 4.25, -2.0),
(Crocodile, _) => (0.0, 3.5, 4.5),
(SeaCrocodile, _) => (0.0, 3.5, 5.0),
(Alligator, _) => (0.0, 2.5, 3.0),
(Salamander, _) => (0.0, 5.0, -1.0),
(Elbst, _) => (0.0, 5.0, -1.0),
(Monitor, _) => (0.0, 2.0, -2.0),
(Asp, _) => (0.0, 2.0, 0.0),
(Tortoise, _) => (0.0, -7.0, -1.0),
(Rocksnapper, _) => (0.0, -7.0, 4.5),
(Rootsnapper, _) => (0.0, -7.0, 4.5),
(Reefsnapper, _) => (0.0, -7.0, 4.5),
(Pangolin, _) => (0.0, -6.5, -2.0),
(Tortoise, _) => (0.0, 0.0, 3.0),
(Rocksnapper, _) => (0.0, 7.0, 5.0),
(Rootsnapper, _) => (0.0, -2.0, 9.0),
(Reefsnapper, _) => (0.0, 2.0, 2.0),
(Pangolin, _) => (0.0, -1.0, 0.5),
(Maneater, _) => (0.0, 4.0, -11.5),
(Sandshark, _) => (0.0, -4.0, -2.0),
(Hakulaq, _) => (0.0, 4.0, -4.5),
(Hakulaq, _) => (0.0, 4.0, -2.5),
(Dagon, _) => (0.0, 4.0, -4.5),
(Lavadrake, _) => (0.0, 2.0, -2.5),
(Icedrake, _) => (0.0, -8.0, 2.5),
(Basilisk, _) => (0.0, -2.0, 2.0),
(Basilisk, _) => (0.0, -2.0, 5.0),
(Deadwood, _) => (0.0, -2.0, -3.0),
(Mossdrake, _) => (0.0, 2.0, -2.5),
(Mossdrake, _) => (0.0, 2.0, -0.5),
}
.into()
}

View File

@ -756,14 +756,14 @@ impl<'a> From<&'a Body> for SkeletonAttr {
fn mount_point(body: &Body) -> Vec3<f32> {
use comp::quadruped_medium::{BodyType::*, Species::*};
match (body.species, body.body_type) {
(Grolgar, _) => (0.0, -6.0, 3.0),
(Saber, _) => (0.0, -12.0, 1.0),
(Grolgar, _) => (0.0, -6.0, 5.0),
(Saber, _) => (0.0, -17.0, 2.5),
(Tuskram, _) => (0.0, -17.0, -1.0),
(Lion, Male) => (0.0, -8.0, 1.0),
(Lion, Female) => (0.0, -8.0, 1.0),
(Tarasque, _) => (0.0, -6.0, 1.0),
(Tiger, _) => (0.0, -8.0, 1.0),
(Wolf, _) => (0.0, -9.0, 0.0),
(Tiger, _) => (0.0, -8.0, 2.0),
(Wolf, _) => (0.0, -9.0, 1.5),
(Frostfang, _) => (0.0, -6.0, -1.0),
(Mouflon, _) => (0.0, -8.0, -1.0),
(Catoblepas, _) => (0.0, -8.0, -1.0),