mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'zesterer/fixes' into 'master'
Various non-humanoid fixes and tweaks See merge request veloren/veloren!3935
This commit is contained in:
commit
8b835a91d0
@ -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],
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user