mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Adjusted masses; less excessive knockbacks; prevent loot shooting off
This commit is contained in:
committed by
Samuel Keiffer
parent
abca6de49b
commit
46d1bb5f18
@ -184,18 +184,24 @@ impl Body {
|
|||||||
},
|
},
|
||||||
Body::BipedSmall(_) => 50.0,
|
Body::BipedSmall(_) => 50.0,
|
||||||
|
|
||||||
// ravens are 0.69-2 kg, crows are 0.51 kg on average
|
// ravens are 0.69-2 kg, crows are 0.51 kg on average.
|
||||||
Body::BirdMedium(_) => 1.0,
|
Body::BirdMedium(body) => match body.species {
|
||||||
Body::BirdLarge(_) => 200.0,
|
bird_medium::Species::Chicken => 2.0, // ~✅ Red junglefowl are 1-1.5 kg
|
||||||
|
bird_medium::Species::Duck => 2.0,
|
||||||
|
bird_medium::Species::Eagle => 10.0, // ~✅ Steller's sea eagle are 5-9 kg
|
||||||
|
bird_medium::Species::Goose => 3.5, // ~✅ Swan geese are 2.8-3.5 kg
|
||||||
|
bird_medium::Species::Owl => 2.0,
|
||||||
|
bird_medium::Species::Parrot => 2.0,
|
||||||
|
bird_medium::Species::Peacock => 5.0,
|
||||||
|
},
|
||||||
|
Body::BirdLarge(_) => 100.0,
|
||||||
|
|
||||||
Body::Dragon(_) => 20_000.0,
|
Body::Dragon(_) => 20_000.0,
|
||||||
Body::FishMedium(_) => 2.5,
|
Body::FishMedium(_) => 5.0,
|
||||||
Body::FishSmall(_) => 1.0,
|
Body::FishSmall(_) => 1.0,
|
||||||
Body::Golem(_) => 10_000.0,
|
Body::Golem(_) => 10_000.0,
|
||||||
Body::Humanoid(humanoid) => {
|
Body::Humanoid(humanoid) => {
|
||||||
// humanoids are quite a bit larger than in real life, so we multiply their mass
|
match (humanoid.species, humanoid.body_type) {
|
||||||
// to scale it up proportionally (remember cube law)
|
|
||||||
1.0 * match (humanoid.species, humanoid.body_type) {
|
|
||||||
(humanoid::Species::Orc, humanoid::BodyType::Male) => 120.0,
|
(humanoid::Species::Orc, humanoid::BodyType::Male) => 120.0,
|
||||||
(humanoid::Species::Orc, humanoid::BodyType::Female) => 120.0,
|
(humanoid::Species::Orc, humanoid::BodyType::Female) => 120.0,
|
||||||
(humanoid::Species::Human, humanoid::BodyType::Male) => 77.0, // ~✅
|
(humanoid::Species::Human, humanoid::BodyType::Male) => 77.0, // ~✅
|
||||||
@ -240,13 +246,33 @@ impl Body {
|
|||||||
_ => 200.0,
|
_ => 200.0,
|
||||||
},
|
},
|
||||||
Body::QuadrupedSmall(body) => match body.species {
|
Body::QuadrupedSmall(body) => match body.species {
|
||||||
quadruped_small::Species::Batfox => 50.0,
|
quadruped_small::Species::Axolotl => 1.0,
|
||||||
|
quadruped_small::Species::Batfox => 10.0,
|
||||||
|
quadruped_small::Species::Beaver => 10.0,
|
||||||
quadruped_small::Species::Boar => 80.0, // ~✅ (60-100 kg)
|
quadruped_small::Species::Boar => 80.0, // ~✅ (60-100 kg)
|
||||||
quadruped_small::Species::Dodarock => 150.0,
|
quadruped_small::Species::Cat => 4.0, // ~✅ (4-5 kg)
|
||||||
quadruped_small::Species::Holladon => 150.0,
|
quadruped_small::Species::Dodarock => 500.0,
|
||||||
|
quadruped_small::Species::Dog => 30.0, // ~✅ (German Shepherd: 30-40 kg)
|
||||||
|
quadruped_small::Species::Fox => 10.0,
|
||||||
|
quadruped_small::Species::Frog => 1.0,
|
||||||
|
quadruped_small::Species::Fungome => 10.0,
|
||||||
|
quadruped_small::Species::Gecko => 1.0,
|
||||||
|
quadruped_small::Species::Goat => 50.0,
|
||||||
|
quadruped_small::Species::Hare => 10.0,
|
||||||
|
quadruped_small::Species::Holladon => 60.0,
|
||||||
quadruped_small::Species::Hyena => 70.0, // ~✅ (vaguely)
|
quadruped_small::Species::Hyena => 70.0, // ~✅ (vaguely)
|
||||||
quadruped_small::Species::Truffler => 150.0,
|
quadruped_small::Species::Jackalope => 10.0,
|
||||||
_ => 80.0,
|
quadruped_small::Species::Pig => 20.0,
|
||||||
|
quadruped_small::Species::Porcupine => 5.0,
|
||||||
|
quadruped_small::Species::Quokka => 10.0,
|
||||||
|
quadruped_small::Species::Rabbit => 2.0,
|
||||||
|
quadruped_small::Species::Raccoon => 30.0,
|
||||||
|
quadruped_small::Species::Rat => 1.0,
|
||||||
|
quadruped_small::Species::Sheep => 50.0,
|
||||||
|
quadruped_small::Species::Skunk => 5.0,
|
||||||
|
quadruped_small::Species::Squirrel => 1.0,
|
||||||
|
quadruped_small::Species::Truffler => 70.0,
|
||||||
|
quadruped_small::Species::Turtle => 40.0,
|
||||||
},
|
},
|
||||||
Body::Theropod(body) => match body.species {
|
Body::Theropod(body) => match body.species {
|
||||||
// for reference, elephants are in the range of 2.6-6.9 tons
|
// for reference, elephants are in the range of 2.6-6.9 tons
|
||||||
|
@ -349,7 +349,7 @@ impl Body {
|
|||||||
Body::BoltFire => Vec3::new(0.1, 0.1, 0.1),
|
Body::BoltFire => Vec3::new(0.1, 0.1, 0.1),
|
||||||
Body::Crossbow => Vec3::new(3.0, 3.0, 1.5),
|
Body::Crossbow => Vec3::new(3.0, 3.0, 1.5),
|
||||||
Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4),
|
Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4),
|
||||||
_ => Vec3::broadcast(0.2),
|
_ => Vec3::broadcast(0.5),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
body::{object, Body},
|
body::{object, Body},
|
||||||
CharacterState, Density, Ori, Vel,
|
Density, Ori, Vel,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
consts::{AIR_DENSITY, WATER_DENSITY},
|
consts::{AIR_DENSITY, WATER_DENSITY},
|
||||||
@ -87,12 +87,18 @@ impl Default for Fluid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Wings {
|
||||||
|
pub aspect_ratio: f32,
|
||||||
|
pub planform_area: f32,
|
||||||
|
pub ori: Ori,
|
||||||
|
}
|
||||||
|
|
||||||
impl Body {
|
impl Body {
|
||||||
pub fn aerodynamic_forces(
|
pub fn aerodynamic_forces(
|
||||||
&self,
|
&self,
|
||||||
rel_flow: &Vel,
|
rel_flow: &Vel,
|
||||||
fluid_density: f32,
|
fluid_density: f32,
|
||||||
character_state: Option<&CharacterState>,
|
wings: Option<&Wings>,
|
||||||
) -> Vec3<f32> {
|
) -> Vec3<f32> {
|
||||||
let v_sq = rel_flow.0.magnitude_squared();
|
let v_sq = rel_flow.0.magnitude_squared();
|
||||||
if v_sq < 0.25 {
|
if v_sq < 0.25 {
|
||||||
@ -103,31 +109,27 @@ impl Body {
|
|||||||
// All the coefficients come pre-multiplied by their reference area
|
// All the coefficients come pre-multiplied by their reference area
|
||||||
0.5 * fluid_density
|
0.5 * fluid_density
|
||||||
* v_sq
|
* v_sq
|
||||||
* character_state
|
* match wings {
|
||||||
.and_then(|cs| match cs {
|
Some(&Wings {
|
||||||
CharacterState::Glide(data) => {
|
aspect_ratio,
|
||||||
Some((data.aspect_ratio, data.planform_area, data.ori))
|
planform_area,
|
||||||
},
|
ori,
|
||||||
_ => None,
|
}) => {
|
||||||
})
|
if aspect_ratio > 25.0 {
|
||||||
.map(|(ar, area, ori)| {
|
|
||||||
if ar > 25.0 {
|
|
||||||
tracing::warn!(
|
tracing::warn!(
|
||||||
"Calculating lift for wings with an aspect ratio of {}. The \
|
"Calculating lift for wings with an aspect ratio of {}. The \
|
||||||
formulas are only valid for aspect ratios below 25.",
|
formulas are only valid for aspect ratios below 25.",
|
||||||
ar
|
aspect_ratio
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
(ar.min(24.0), area, ori)
|
let ar = aspect_ratio.min(24.0);
|
||||||
})
|
|
||||||
.map(|(ar, area, ori)| {
|
|
||||||
// We have an elliptical wing; proceed to calculate its lift and drag
|
// We have an elliptical wing; proceed to calculate its lift and drag
|
||||||
|
|
||||||
// aoa will be positive when we're pitched up and negative otherwise
|
// aoa will be positive when we're pitched up and negative otherwise
|
||||||
let aoa = angle_of_attack(&ori, &rel_flow_dir);
|
let aoa = angle_of_attack(&ori, &rel_flow_dir);
|
||||||
// c_l will be positive when aoa is positive (we have positive lift,
|
// c_l will be positive when aoa is positive (we have positive lift,
|
||||||
// producing an upward force) and negative otherwise
|
// producing an upward force) and negative otherwise
|
||||||
let c_l = lift_coefficient(ar, area, aoa);
|
let c_l = lift_coefficient(ar, planform_area, aoa);
|
||||||
|
|
||||||
// lift dir will be orthogonal to the local relative flow vector.
|
// lift dir will be orthogonal to the local relative flow vector.
|
||||||
// Local relative flow is the resulting vector of (relative) freestream
|
// Local relative flow is the resulting vector of (relative) freestream
|
||||||
@ -151,22 +153,26 @@ impl Body {
|
|||||||
ori.pitched_down(aoa_eff).up()
|
ori.pitched_down(aoa_eff).up()
|
||||||
};
|
};
|
||||||
|
|
||||||
// drag coefficient due to lift
|
// drag coefficient
|
||||||
let c_d = {
|
let c_d = {
|
||||||
// Oswald's efficiency factor (empirically derived--very magical)
|
// Oswald's efficiency factor (empirically derived--very magical)
|
||||||
// (this definition should not be used for aspect ratios > 25)
|
// (this definition should not be used for aspect ratios > 25)
|
||||||
let e = 1.78 * (1.0 - 0.045 * ar.powf(0.68)) - 0.64;
|
let e = 1.78 * (1.0 - 0.045 * ar.powf(0.68)) - 0.64;
|
||||||
|
// induced drag coefficient (drag due to lift)
|
||||||
|
let cdi = c_l.powi(2) / (PI * e * ar);
|
||||||
|
|
||||||
zero_lift_drag_coefficient(area)
|
zero_lift_drag_coefficient(planform_area)
|
||||||
+ self.parasite_drag_coefficient()
|
+ self.parasite_drag_coefficient(wings)
|
||||||
+ c_l.powi(2) / (PI * e * ar)
|
+ cdi
|
||||||
};
|
};
|
||||||
debug_assert!(c_d.is_sign_positive());
|
debug_assert!(c_d.is_sign_positive());
|
||||||
debug_assert!(c_l.is_sign_positive() || aoa.is_sign_negative());
|
debug_assert!(c_l.is_sign_positive() || aoa.is_sign_negative());
|
||||||
|
|
||||||
c_l * *lift_dir + c_d * *rel_flow_dir
|
c_l * *lift_dir + c_d * *rel_flow_dir
|
||||||
})
|
},
|
||||||
.unwrap_or_else(|| self.parasite_drag_coefficient() * *rel_flow_dir)
|
|
||||||
|
_ => self.parasite_drag_coefficient(wings) * *rel_flow_dir,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,14 +180,15 @@ impl Body {
|
|||||||
/// Skin friction is the drag arising from the shear forces between a fluid
|
/// Skin friction is the drag arising from the shear forces between a fluid
|
||||||
/// and a surface, while pressure drag is due to flow separation. Both are
|
/// and a surface, while pressure drag is due to flow separation. Both are
|
||||||
/// viscous effects.
|
/// viscous effects.
|
||||||
fn parasite_drag_coefficient(&self) -> f32 {
|
fn parasite_drag_coefficient(&self, wings: Option<&Wings>) -> f32 {
|
||||||
// Reference area and drag coefficient assumes best-case scenario of the
|
// Reference area and drag coefficient assumes best-case scenario of the
|
||||||
// orientation producing least amount of drag
|
// orientation producing least amount of drag
|
||||||
match self {
|
match self {
|
||||||
// Cross-section, head/feet first
|
// Cross-section, head/feet first
|
||||||
Body::BipedLarge(_) | Body::BipedSmall(_) | Body::Golem(_) | Body::Humanoid(_) => {
|
Body::BipedLarge(_) | Body::BipedSmall(_) | Body::Golem(_) | Body::Humanoid(_) => {
|
||||||
let dim = self.dimensions().xy().map(|a| a * 0.5);
|
let dim = self.dimensions().xy().map(|a| a * 0.5);
|
||||||
0.7 * PI * dim.x * dim.y
|
const CD: f32 = 0.7;
|
||||||
|
CD * PI * dim.x * dim.y
|
||||||
},
|
},
|
||||||
|
|
||||||
// Cross-section, nose/tail first
|
// Cross-section, nose/tail first
|
||||||
@ -190,7 +197,7 @@ impl Body {
|
|||||||
| Body::QuadrupedSmall(_)
|
| Body::QuadrupedSmall(_)
|
||||||
| Body::QuadrupedLow(_) => {
|
| Body::QuadrupedLow(_) => {
|
||||||
let dim = self.dimensions().map(|a| a * 0.5);
|
let dim = self.dimensions().map(|a| a * 0.5);
|
||||||
let cd = if matches!(self, Body::QuadrupedLow(_)) {
|
let cd: f32 = if matches!(self, Body::QuadrupedLow(_)) {
|
||||||
0.7
|
0.7
|
||||||
} else {
|
} else {
|
||||||
1.0
|
1.0
|
||||||
@ -201,12 +208,16 @@ impl Body {
|
|||||||
// Cross-section, zero-lift angle; exclude the wings (width * 0.2)
|
// Cross-section, zero-lift angle; exclude the wings (width * 0.2)
|
||||||
Body::BirdMedium(_) | Body::BirdLarge(_) | Body::Dragon(_) => {
|
Body::BirdMedium(_) | Body::BirdLarge(_) | Body::Dragon(_) => {
|
||||||
let dim = self.dimensions().map(|a| a * 0.5);
|
let dim = self.dimensions().map(|a| a * 0.5);
|
||||||
|
let cd: f32 = if wings.is_none() {
|
||||||
|
0.7
|
||||||
|
} else {
|
||||||
// "Field Estimates of Body Drag Coefficient on the Basis of Dives in Passerine
|
// "Field Estimates of Body Drag Coefficient on the Basis of Dives in Passerine
|
||||||
// Birds", Anders Hedenström and Felix Liechti, 2001
|
// Birds", Anders Hedenström and Felix Liechti, 2001
|
||||||
let cd = match self {
|
match self {
|
||||||
Body::BirdLarge(_) | Body::BirdMedium(_) => 0.2,
|
Body::BirdLarge(_) | Body::BirdMedium(_) => 0.2,
|
||||||
// arbitrary
|
// arbitrary
|
||||||
_ => 0.7,
|
_ => 0.7,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
cd * PI * dim.x * 0.2 * dim.z
|
cd * PI * dim.x * 0.2 * dim.z
|
||||||
},
|
},
|
||||||
@ -216,7 +227,8 @@ impl Body {
|
|||||||
let dim = self.dimensions().map(|a| a * 0.5);
|
let dim = self.dimensions().map(|a| a * 0.5);
|
||||||
// "A Simple Method to Determine Drag Coefficients in Aquatic Animals",
|
// "A Simple Method to Determine Drag Coefficients in Aquatic Animals",
|
||||||
// D. Bilo and W. Nachtigall, 1980
|
// D. Bilo and W. Nachtigall, 1980
|
||||||
0.031 * PI * dim.x * 0.2 * dim.z
|
const CD: f32 = 0.031;
|
||||||
|
CD * PI * dim.x * 0.2 * dim.z
|
||||||
},
|
},
|
||||||
|
|
||||||
Body::Object(object) => match object {
|
Body::Object(object) => match object {
|
||||||
@ -232,7 +244,8 @@ impl Body {
|
|||||||
| object::Body::FireworkYellow
|
| object::Body::FireworkYellow
|
||||||
| object::Body::MultiArrow => {
|
| object::Body::MultiArrow => {
|
||||||
let dim = self.dimensions().map(|a| a * 0.5);
|
let dim = self.dimensions().map(|a| a * 0.5);
|
||||||
0.02 * PI * dim.x * dim.z
|
const CD: f32 = 0.02;
|
||||||
|
CD * PI * dim.x * dim.z
|
||||||
},
|
},
|
||||||
|
|
||||||
// spherical-ish objects
|
// spherical-ish objects
|
||||||
@ -250,12 +263,14 @@ impl Body {
|
|||||||
| object::Body::Pumpkin4
|
| object::Body::Pumpkin4
|
||||||
| object::Body::Pumpkin5 => {
|
| object::Body::Pumpkin5 => {
|
||||||
let dim = self.dimensions().map(|a| a * 0.5);
|
let dim = self.dimensions().map(|a| a * 0.5);
|
||||||
0.5 * PI * dim.x * dim.z
|
const CD: f32 = 0.5;
|
||||||
|
CD * PI * dim.x * dim.z
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let dim = self.dimensions();
|
let dim = self.dimensions();
|
||||||
2.0 * (PI / 6.0 * dim.x * dim.y * dim.z).powf(2.0 / 3.0)
|
const CD: f32 = 2.0;
|
||||||
|
CD * (PI / 6.0 * dim.x * dim.y * dim.z).powf(2.0 / 3.0)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
body::ship::figuredata::{VoxelCollider, VOXEL_COLLIDER_MANIFEST},
|
body::ship::figuredata::{VoxelCollider, VOXEL_COLLIDER_MANIFEST},
|
||||||
BeamSegment, Body, CharacterState, Collider, Density, Fluid, Mass, Mounting, Ori,
|
fluid_dynamics::{Fluid, Wings},
|
||||||
PhysicsState, Pos, PosVelDefer, PreviousPhysCache, Projectile, Scale, Shockwave, Sticky,
|
BeamSegment, Body, CharacterState, Collider, Density, Mass, Mounting, Ori, PhysicsState,
|
||||||
Vel,
|
Pos, PosVelDefer, PreviousPhysCache, Projectile, Scale, Shockwave, Sticky, Vel,
|
||||||
},
|
},
|
||||||
consts::{AIR_DENSITY, FRIC_GROUND, GRAVITY},
|
consts::{AIR_DENSITY, FRIC_GROUND, GRAVITY},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
|
states,
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, TerrainGrid},
|
||||||
uid::Uid,
|
uid::Uid,
|
||||||
util::{Projection, SpatialGrid},
|
util::{Projection, SpatialGrid},
|
||||||
@ -42,10 +43,9 @@ fn fluid_density(height: f32, fluid: &Fluid) -> Density {
|
|||||||
fn integrate_forces(
|
fn integrate_forces(
|
||||||
dt: &DeltaTime,
|
dt: &DeltaTime,
|
||||||
mut vel: Vel,
|
mut vel: Vel,
|
||||||
body: &Body,
|
(body, wings): (&Body, Option<&Wings>),
|
||||||
density: &Density,
|
density: &Density,
|
||||||
mass: &Mass,
|
mass: &Mass,
|
||||||
character_state: Option<&CharacterState>,
|
|
||||||
fluid: &Fluid,
|
fluid: &Fluid,
|
||||||
gravity: f32,
|
gravity: f32,
|
||||||
) -> Vel {
|
) -> Vel {
|
||||||
@ -59,7 +59,7 @@ fn integrate_forces(
|
|||||||
// Aerodynamic/hydrodynamic forces
|
// Aerodynamic/hydrodynamic forces
|
||||||
if !rel_flow.0.is_approx_zero() {
|
if !rel_flow.0.is_approx_zero() {
|
||||||
debug_assert!(!rel_flow.0.map(|a| a.is_nan()).reduce_or());
|
debug_assert!(!rel_flow.0.map(|a| a.is_nan()).reduce_or());
|
||||||
let impulse = dt.0 * body.aerodynamic_forces(&rel_flow, fluid_density.0, character_state);
|
let impulse = dt.0 * body.aerodynamic_forces(&rel_flow, fluid_density.0, wings);
|
||||||
debug_assert!(!impulse.map(|a| a.is_nan()).reduce_or());
|
debug_assert!(!impulse.map(|a| a.is_nan()).reduce_or());
|
||||||
if !impulse.is_approx_zero() {
|
if !impulse.is_approx_zero() {
|
||||||
let new_v = vel.0 + impulse / mass.0;
|
let new_v = vel.0 + impulse / mass.0;
|
||||||
@ -71,7 +71,7 @@ fn integrate_forces(
|
|||||||
if new_v.dot(vel.0) < 0.0 {
|
if new_v.dot(vel.0) < 0.0 {
|
||||||
// Multiply by a factor to prevent full stop, as this can cause things to get
|
// Multiply by a factor to prevent full stop, as this can cause things to get
|
||||||
// stuck in high-density medium
|
// stuck in high-density medium
|
||||||
vel.0 -= vel.0.projected(&impulse) * 0.7;
|
vel.0 -= vel.0.projected(&impulse) * 0.9;
|
||||||
} else {
|
} else {
|
||||||
vel.0 = new_v;
|
vel.0 = new_v;
|
||||||
}
|
}
|
||||||
@ -616,13 +616,26 @@ impl<'a> PhysicsData<'a> {
|
|||||||
vel.0.z -= dt.0 * GRAVITY;
|
vel.0.z -= dt.0 * GRAVITY;
|
||||||
},
|
},
|
||||||
Some(fluid) => {
|
Some(fluid) => {
|
||||||
|
let wings = match character_state {
|
||||||
|
Some(&CharacterState::Glide(states::glide::Data {
|
||||||
|
aspect_ratio,
|
||||||
|
planform_area,
|
||||||
|
ori,
|
||||||
|
..
|
||||||
|
})) => Some(Wings {
|
||||||
|
aspect_ratio,
|
||||||
|
planform_area,
|
||||||
|
ori,
|
||||||
|
}),
|
||||||
|
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
vel.0 = integrate_forces(
|
vel.0 = integrate_forces(
|
||||||
&dt,
|
&dt,
|
||||||
*vel,
|
*vel,
|
||||||
body,
|
(body, wings.as_ref()),
|
||||||
density,
|
density,
|
||||||
mass,
|
mass,
|
||||||
character_state,
|
|
||||||
&fluid,
|
&fluid,
|
||||||
GRAVITY,
|
GRAVITY,
|
||||||
)
|
)
|
||||||
|
@ -75,7 +75,8 @@ pub fn handle_knockback(server: &Server, entity: EcsEntity, impulse: Vec3<f32>)
|
|||||||
0.4
|
0.4
|
||||||
};
|
};
|
||||||
if let Some(mass) = ecs.read_storage::<comp::Mass>().get(entity) {
|
if let Some(mass) = ecs.read_storage::<comp::Mass>().get(entity) {
|
||||||
impulse /= mass.0;
|
// we go easy on the little ones (because they fly so far)
|
||||||
|
impulse /= mass.0.max(40.0);
|
||||||
}
|
}
|
||||||
let mut velocities = ecs.write_storage::<comp::Vel>();
|
let mut velocities = ecs.write_storage::<comp::Vel>();
|
||||||
if let Some(vel) = velocities.get_mut(entity) {
|
if let Some(vel) = velocities.get_mut(entity) {
|
||||||
|
Reference in New Issue
Block a user