mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Ensnaring vines now ensnare you.
This commit is contained in:
parent
ed503236d6
commit
763461ebef
@ -15,5 +15,6 @@ BasicBeam(
|
|||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
energy_drain: 0,
|
energy_drain: 0,
|
||||||
orientation_behavior: Normal,
|
orientation_behavior: Normal,
|
||||||
|
ori_rate: 0.6,
|
||||||
specifier: Flamethrower,
|
specifier: Flamethrower,
|
||||||
)
|
)
|
||||||
|
@ -337,7 +337,7 @@ impl CharacterAbility {
|
|||||||
pub fn requirements_paid(&self, data: &JoinData, update: &mut StateUpdate) -> bool {
|
pub fn requirements_paid(&self, data: &JoinData, update: &mut StateUpdate) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CharacterAbility::Roll { energy_cost, .. } => {
|
CharacterAbility::Roll { energy_cost, .. } => {
|
||||||
data.physics.on_ground
|
data.physics.on_ground.is_some()
|
||||||
&& data.vel.0.xy().magnitude_squared() > 0.5
|
&& data.vel.0.xy().magnitude_squared() > 0.5
|
||||||
&& update
|
&& update
|
||||||
.energy
|
.energy
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::Fluid;
|
use super::Fluid;
|
||||||
use crate::{consts::WATER_DENSITY, uid::Uid};
|
use crate::{consts::WATER_DENSITY, terrain::Block, uid::Uid};
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage, NullStorage};
|
use specs::{Component, DerefFlaggedStorage, NullStorage};
|
||||||
@ -142,7 +142,7 @@ impl Component for Sticky {
|
|||||||
// PhysicsState
|
// PhysicsState
|
||||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct PhysicsState {
|
pub struct PhysicsState {
|
||||||
pub on_ground: bool,
|
pub on_ground: Option<Block>,
|
||||||
pub on_ceiling: bool,
|
pub on_ceiling: bool,
|
||||||
pub on_wall: Option<Vec3<f32>>,
|
pub on_wall: Option<Vec3<f32>>,
|
||||||
pub touch_entities: HashSet<Uid>,
|
pub touch_entities: HashSet<Uid>,
|
||||||
@ -165,7 +165,7 @@ impl PhysicsState {
|
|||||||
|
|
||||||
pub fn on_surface(&self) -> Option<Vec3<f32>> {
|
pub fn on_surface(&self) -> Option<Vec3<f32>> {
|
||||||
self.on_ground
|
self.on_ground
|
||||||
.then_some(-Vec3::unit_z())
|
.map(|_| -Vec3::unit_z())
|
||||||
.or_else(|| self.on_ceiling.then_some(Vec3::unit_z()))
|
.or_else(|| self.on_ceiling.then_some(Vec3::unit_z()))
|
||||||
.or(self.on_wall)
|
.or(self.on_wall)
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ impl CharacterBehavior for Data {
|
|||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
|
|
||||||
// If no wall is in front of character or we stopped climbing;
|
// If no wall is in front of character or we stopped climbing;
|
||||||
let (wall_dir, climb) = if let (Some(wall_dir), Some(climb), false) = (
|
let (wall_dir, climb) = if let (Some(wall_dir), Some(climb), None) = (
|
||||||
data.physics.on_wall,
|
data.physics.on_wall,
|
||||||
data.inputs.climb,
|
data.inputs.climb,
|
||||||
data.physics.on_ground,
|
data.physics.on_ground,
|
||||||
@ -105,7 +105,11 @@ impl CharacterBehavior for Data {
|
|||||||
// Smooth orientation
|
// Smooth orientation
|
||||||
update.ori = update.ori.slerped_towards(
|
update.ori = update.ori.slerped_towards(
|
||||||
Ori::from(ori_dir),
|
Ori::from(ori_dir),
|
||||||
if data.physics.on_ground { 9.0 } else { 2.0 } * data.dt.0,
|
if data.physics.on_ground.is_some() {
|
||||||
|
9.0
|
||||||
|
} else {
|
||||||
|
2.0
|
||||||
|
} * data.dt.0,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_jump(data, &mut update, 1.0);
|
handle_jump(data, &mut update, 1.0);
|
||||||
|
|
||||||
// Try to Fall/Stand up/Move
|
// Try to Fall/Stand up/Move
|
||||||
if !data.physics.on_ground || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
if data.physics.on_ground.is_none() || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
||||||
update.character = CharacterState::Idle;
|
update.character = CharacterState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ impl CharacterBehavior for Data {
|
|||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
|
|
||||||
// If player is on ground, end glide
|
// If player is on ground, end glide
|
||||||
if data.physics.on_ground
|
if data.physics.on_ground.is_some()
|
||||||
&& (data.vel.0 - data.physics.ground_vel).magnitude_squared() < 2_f32.powi(2)
|
&& (data.vel.0 - data.physics.ground_vel).magnitude_squared() < 2_f32.powi(2)
|
||||||
{
|
{
|
||||||
update.character = CharacterState::GlideWield;
|
update.character = CharacterState::GlideWield;
|
||||||
@ -163,7 +163,13 @@ impl CharacterBehavior for Data {
|
|||||||
let accel_factor = accel.magnitude_squared().min(1.0) / 1.0;
|
let accel_factor = accel.magnitude_squared().min(1.0) / 1.0;
|
||||||
|
|
||||||
Quaternion::rotation_3d(
|
Quaternion::rotation_3d(
|
||||||
PI / 2.0 * accel_factor * if data.physics.on_ground { -1.0 } else { 1.0 },
|
PI / 2.0
|
||||||
|
* accel_factor
|
||||||
|
* if data.physics.on_ground.is_some() {
|
||||||
|
-1.0
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
},
|
||||||
ori.up()
|
ori.up()
|
||||||
.cross(accel)
|
.cross(accel)
|
||||||
.try_normalized()
|
.try_normalized()
|
||||||
|
@ -20,7 +20,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_wield(data, &mut update);
|
handle_wield(data, &mut update);
|
||||||
|
|
||||||
// If not on the ground while wielding glider enter gliding state
|
// If not on the ground while wielding glider enter gliding state
|
||||||
if !data.physics.on_ground {
|
if data.physics.on_ground.is_none() {
|
||||||
update.character = CharacterState::Glide(glide::Data::new(10.0, 0.6, *data.ori));
|
update.character = CharacterState::Glide(glide::Data::new(10.0, 0.6, *data.ori));
|
||||||
}
|
}
|
||||||
if data
|
if data
|
||||||
|
@ -101,7 +101,7 @@ impl CharacterBehavior for Data {
|
|||||||
timer: tick_attack_or_default(data, self.timer, None),
|
timer: tick_attack_or_default(data, self.timer, None),
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
} else if data.physics.on_ground {
|
} else if data.physics.on_ground.is_some() {
|
||||||
// Transitions to swing portion of state upon hitting ground
|
// Transitions to swing portion of state upon hitting ground
|
||||||
update.character = CharacterState::LeapMelee(Data {
|
update.character = CharacterState::LeapMelee(Data {
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
|
@ -16,7 +16,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_jump(data, &mut update, 1.0);
|
handle_jump(data, &mut update, 1.0);
|
||||||
|
|
||||||
// Try to Fall/Stand up/Move
|
// Try to Fall/Stand up/Move
|
||||||
if !data.physics.on_ground || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
if data.physics.on_ground.is_none() || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
||||||
update.character = CharacterState::Idle;
|
update.character = CharacterState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_dodge_input(data, &mut update);
|
handle_dodge_input(data, &mut update);
|
||||||
|
|
||||||
// Try to Fall/Stand up/Move
|
// Try to Fall/Stand up/Move
|
||||||
if !data.physics.on_ground {
|
if data.physics.on_ground.is_none() {
|
||||||
update.character = CharacterState::Idle;
|
update.character = CharacterState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,11 +96,9 @@ impl CharacterBehavior for Data {
|
|||||||
sprite_pos.map(|x| x as f32 + 0.5) - Vec3::unit_z() * 25.0,
|
sprite_pos.map(|x| x as f32 + 0.5) - Vec3::unit_z() * 25.0,
|
||||||
)
|
)
|
||||||
.until(|b| {
|
.until(|b| {
|
||||||
|
// Until reaching a solid block that is not the created sprite
|
||||||
Block::is_solid(b)
|
Block::is_solid(b)
|
||||||
&& !matches!(
|
&& b.get_sprite() != Some(self.static_data.sprite)
|
||||||
b.get_sprite(),
|
|
||||||
Some(SpriteKind::EnsnaringVines)
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.cast()
|
.cast()
|
||||||
.0;
|
.0;
|
||||||
|
@ -233,11 +233,12 @@ pub fn handle_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
|||||||
|
|
||||||
if input_is_pressed(data, InputKind::Fly)
|
if input_is_pressed(data, InputKind::Fly)
|
||||||
&& submersion.map_or(true, |sub| sub < 1.0)
|
&& submersion.map_or(true, |sub| sub < 1.0)
|
||||||
&& (!data.physics.on_ground || data.body.jump_impulse().is_none())
|
&& (data.physics.on_ground.is_none() || data.body.jump_impulse().is_none())
|
||||||
&& data.body.fly_thrust().is_some()
|
&& data.body.fly_thrust().is_some()
|
||||||
{
|
{
|
||||||
fly_move(data, update, efficiency);
|
fly_move(data, update, efficiency);
|
||||||
} else if let Some(submersion) = (!data.physics.on_ground && data.body.swim_thrust().is_some())
|
} else if let Some(submersion) = (data.physics.on_ground.is_none()
|
||||||
|
&& data.body.swim_thrust().is_some())
|
||||||
.then_some(submersion)
|
.then_some(submersion)
|
||||||
.flatten()
|
.flatten()
|
||||||
{
|
{
|
||||||
@ -252,7 +253,7 @@ pub fn handle_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
|||||||
fn basic_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
fn basic_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
||||||
let efficiency = efficiency * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
let efficiency = efficiency * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
||||||
|
|
||||||
let accel = if data.physics.on_ground {
|
let accel = if data.physics.on_ground.is_some() {
|
||||||
data.body.base_accel()
|
data.body.base_accel()
|
||||||
} else {
|
} else {
|
||||||
data.body.air_accel()
|
data.body.air_accel()
|
||||||
@ -294,7 +295,7 @@ pub fn handle_forced_movement(data: &JoinData, update: &mut StateUpdate, movemen
|
|||||||
match movement {
|
match movement {
|
||||||
ForcedMovement::Forward { strength } => {
|
ForcedMovement::Forward { strength } => {
|
||||||
let strength = strength * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
let strength = strength * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
||||||
if let Some(accel) = data.physics.on_ground.then_some(data.body.base_accel()) {
|
if let Some(accel) = data.physics.on_ground.map(|_| data.body.base_accel()) {
|
||||||
update.vel.0 += Vec2::broadcast(data.dt.0)
|
update.vel.0 += Vec2::broadcast(data.dt.0)
|
||||||
* accel
|
* accel
|
||||||
* (data.inputs.move_dir + Vec2::from(update.ori))
|
* (data.inputs.move_dir + Vec2::from(update.ori))
|
||||||
@ -499,25 +500,25 @@ pub fn attempt_wield(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
|
|
||||||
/// Checks that player can `Sit` and updates `CharacterState` if so
|
/// Checks that player can `Sit` and updates `CharacterState` if so
|
||||||
pub fn attempt_sit(data: &JoinData, update: &mut StateUpdate) {
|
pub fn attempt_sit(data: &JoinData, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground {
|
if data.physics.on_ground.is_some() {
|
||||||
update.character = CharacterState::Sit;
|
update.character = CharacterState::Sit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attempt_dance(data: &JoinData, update: &mut StateUpdate) {
|
pub fn attempt_dance(data: &JoinData, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground && data.body.is_humanoid() {
|
if data.physics.on_ground.is_some() && data.body.is_humanoid() {
|
||||||
update.character = CharacterState::Dance;
|
update.character = CharacterState::Dance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attempt_talk(data: &JoinData, update: &mut StateUpdate) {
|
pub fn attempt_talk(data: &JoinData, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground {
|
if data.physics.on_ground.is_some() {
|
||||||
update.character = CharacterState::Talk;
|
update.character = CharacterState::Talk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attempt_sneak(data: &JoinData, update: &mut StateUpdate) {
|
pub fn attempt_sneak(data: &JoinData, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground && data.body.is_humanoid() {
|
if data.physics.on_ground.is_some() && data.body.is_humanoid() {
|
||||||
update.character = CharacterState::Sneak;
|
update.character = CharacterState::Sneak;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +527,7 @@ pub fn attempt_sneak(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
pub fn handle_climb(data: &JoinData, update: &mut StateUpdate) -> bool {
|
pub fn handle_climb(data: &JoinData, update: &mut StateUpdate) -> bool {
|
||||||
if data.inputs.climb.is_some()
|
if data.inputs.climb.is_some()
|
||||||
&& data.physics.on_wall.is_some()
|
&& data.physics.on_wall.is_some()
|
||||||
&& !data.physics.on_ground
|
&& data.physics.on_ground.is_none()
|
||||||
&& !data
|
&& !data
|
||||||
.physics
|
.physics
|
||||||
.in_liquid()
|
.in_liquid()
|
||||||
@ -585,7 +586,7 @@ pub fn attempt_glide_wield(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
|
|
||||||
/// Checks that player can jump and sends jump event if so
|
/// Checks that player can jump and sends jump event if so
|
||||||
pub fn handle_jump(data: &JoinData, update: &mut StateUpdate, strength: f32) -> bool {
|
pub fn handle_jump(data: &JoinData, update: &mut StateUpdate, strength: f32) -> bool {
|
||||||
(input_is_pressed(data, InputKind::Jump) && data.physics.on_ground)
|
(input_is_pressed(data, InputKind::Jump) && data.physics.on_ground.is_some())
|
||||||
.then(|| data.body.jump_impulse())
|
.then(|| data.body.jump_impulse())
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|impulse| {
|
.map(|impulse| {
|
||||||
|
@ -10,7 +10,7 @@ use common::{
|
|||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
states,
|
states,
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, SpriteKind, TerrainGrid},
|
||||||
uid::Uid,
|
uid::Uid,
|
||||||
util::{Projection, SpatialGrid},
|
util::{Projection, SpatialGrid},
|
||||||
vol::{BaseVol, ReadVol},
|
vol::{BaseVol, ReadVol},
|
||||||
@ -319,7 +319,8 @@ impl<'a> PhysicsData<'a> {
|
|||||||
char_state_maybe,
|
char_state_maybe,
|
||||||
)| {
|
)| {
|
||||||
let is_sticky = sticky.is_some();
|
let is_sticky = sticky.is_some();
|
||||||
let is_mid_air = physics.on_wall.is_none() && physics.on_ground;
|
// Code reviewers: remind me to check why on_ground was true instead of false here?
|
||||||
|
let is_mid_air = physics.on_wall.is_none() && physics.on_ground.is_some();
|
||||||
let mut entity_entity_collision_checks = 0;
|
let mut entity_entity_collision_checks = 0;
|
||||||
let mut entity_entity_collisions = 0;
|
let mut entity_entity_collisions = 0;
|
||||||
|
|
||||||
@ -753,7 +754,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
// velocities or entirely broken position snapping.
|
// velocities or entirely broken position snapping.
|
||||||
let mut tgt_pos = pos.0 + pos_delta;
|
let mut tgt_pos = pos.0 + pos_delta;
|
||||||
|
|
||||||
let was_on_ground = physics_state.on_ground;
|
let was_on_ground = physics_state.on_ground.is_some();
|
||||||
let block_snap =
|
let block_snap =
|
||||||
body.map_or(false, |b| !matches!(b, Body::Object(_) | Body::Ship(_)));
|
body.map_or(false, |b| !matches!(b, Body::Object(_) | Body::Ship(_)));
|
||||||
let climbing =
|
let climbing =
|
||||||
@ -879,7 +880,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
> block_rpos.xy().map(|e| e.abs()).reduce_partial_max()
|
> block_rpos.xy().map(|e| e.abs()).reduce_partial_max()
|
||||||
{
|
{
|
||||||
if block_rpos.z > 0.0 {
|
if block_rpos.z > 0.0 {
|
||||||
physics_state.on_ground = true;
|
physics_state.on_ground = block.copied();
|
||||||
} else {
|
} else {
|
||||||
physics_state.on_ceiling = true;
|
physics_state.on_ceiling = true;
|
||||||
}
|
}
|
||||||
@ -1068,10 +1069,11 @@ impl<'a> PhysicsData<'a> {
|
|||||||
// union in the state updates, so that the state isn't just
|
// union in the state updates, so that the state isn't just
|
||||||
// based on the most
|
// based on the most
|
||||||
// recent terrain that collision was attempted with
|
// recent terrain that collision was attempted with
|
||||||
if physics_state_delta.on_ground {
|
if physics_state_delta.on_ground.is_some() {
|
||||||
physics_state.ground_vel = vel_other;
|
physics_state.ground_vel = vel_other;
|
||||||
}
|
}
|
||||||
physics_state.on_ground |= physics_state_delta.on_ground;
|
physics_state.on_ground =
|
||||||
|
physics_state.on_ground.or(physics_state_delta.on_ground);
|
||||||
physics_state.on_ceiling |= physics_state_delta.on_ceiling;
|
physics_state.on_ceiling |= physics_state_delta.on_ceiling;
|
||||||
physics_state.on_wall = physics_state.on_wall.or_else(|| {
|
physics_state.on_wall = physics_state.on_wall.or_else(|| {
|
||||||
physics_state_delta
|
physics_state_delta
|
||||||
@ -1339,10 +1341,10 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
.is_some()
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
physics_state.on_ground = false;
|
physics_state.on_ground = None;
|
||||||
physics_state.on_ceiling = false;
|
physics_state.on_ceiling = false;
|
||||||
|
|
||||||
let mut on_ground = false;
|
let mut on_ground = None;
|
||||||
let mut on_ceiling = false;
|
let mut on_ceiling = false;
|
||||||
let mut attempts = 0; // Don't loop infinitely here
|
let mut attempts = 0; // Don't loop infinitely here
|
||||||
|
|
||||||
@ -1360,7 +1362,7 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
const MAX_ATTEMPTS: usize = 16;
|
const MAX_ATTEMPTS: usize = 16;
|
||||||
|
|
||||||
// While the player is colliding with the terrain...
|
// While the player is colliding with the terrain...
|
||||||
while let Some((_block_pos, block_aabb, block_height)) =
|
while let Some((_block_pos, block_aabb, block_height, block)) =
|
||||||
(attempts < MAX_ATTEMPTS).then(|| {
|
(attempts < MAX_ATTEMPTS).then(|| {
|
||||||
// Calculate the player's AABB
|
// Calculate the player's AABB
|
||||||
let player_aabb = Aabb {
|
let player_aabb = Aabb {
|
||||||
@ -1391,12 +1393,13 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
max: block_pos.map(|e| e as f32) + Vec3::new(1.0, 1.0, block.solid_height()),
|
max: block_pos.map(|e| e as f32) + Vec3::new(1.0, 1.0, block.solid_height()),
|
||||||
},
|
},
|
||||||
block.solid_height(),
|
block.solid_height(),
|
||||||
|
block,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
// Determine whether the block's AABB collides with the player's AABB
|
// Determine whether the block's AABB collides with the player's AABB
|
||||||
.filter(|(_, block_aabb, _)| block_aabb.collides_with_aabb(player_aabb))
|
.filter(|(_, block_aabb, _, _)| block_aabb.collides_with_aabb(player_aabb))
|
||||||
// Find the maximum of the minimum collision axes (this bit is weird, trust me that it works)
|
// Find the maximum of the minimum collision axes (this bit is weird, trust me that it works)
|
||||||
.min_by_key(|(_, block_aabb, _)| {
|
.min_by_key(|(_, block_aabb, _, _)| {
|
||||||
ordered_float::OrderedFloat((block_aabb.center() - player_aabb.center() - Vec3::unit_z() * 0.5)
|
ordered_float::OrderedFloat((block_aabb.center() - player_aabb.center() - Vec3::unit_z() * 0.5)
|
||||||
.map(f32::abs)
|
.map(f32::abs)
|
||||||
.sum())
|
.sum())
|
||||||
@ -1428,7 +1431,7 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
if resolve_dir.z > 0.0
|
if resolve_dir.z > 0.0
|
||||||
/* && vel.0.z <= 0.0 */
|
/* && vel.0.z <= 0.0 */
|
||||||
{
|
{
|
||||||
on_ground = true;
|
on_ground = Some(block).copied();
|
||||||
|
|
||||||
if !was_on_ground {
|
if !was_on_ground {
|
||||||
land_on_ground(entity, *vel);
|
land_on_ground(entity, *vel);
|
||||||
@ -1466,7 +1469,7 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
if (vel.0 * resolve_dir).xy().magnitude_squared() < 1.0f32.powi(2) {
|
if (vel.0 * resolve_dir).xy().magnitude_squared() < 1.0f32.powi(2) {
|
||||||
pos.0 -= resolve_dir.normalized() * 0.05;
|
pos.0 -= resolve_dir.normalized() * 0.05;
|
||||||
}
|
}
|
||||||
on_ground = true;
|
on_ground = Some(block).copied();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// Correct the velocity
|
// Correct the velocity
|
||||||
@ -1497,8 +1500,8 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
physics_state.on_ceiling = true;
|
physics_state.on_ceiling = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if on_ground {
|
if on_ground.is_some() {
|
||||||
physics_state.on_ground = true;
|
physics_state.on_ground = on_ground;
|
||||||
// If the space below us is free, then "snap" to the ground
|
// If the space below us is free, then "snap" to the ground
|
||||||
} else if collision_with(
|
} else if collision_with(
|
||||||
pos.0 - Vec3::unit_z() * 1.1,
|
pos.0 - Vec3::unit_z() * 1.1,
|
||||||
@ -1519,7 +1522,7 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
.unwrap_or(0.0);
|
.unwrap_or(0.0);
|
||||||
vel.0.z = 0.0;
|
vel.0.z = 0.0;
|
||||||
pos.0.z = (pos.0.z - 0.1).floor() + snap_height;
|
pos.0.z = (pos.0.z - 0.1).floor() + snap_height;
|
||||||
physics_state.on_ground = true;
|
physics_state.on_ground = on_ground;
|
||||||
}
|
}
|
||||||
|
|
||||||
let player_aabb = Aabb {
|
let player_aabb = Aabb {
|
||||||
@ -1593,8 +1596,14 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
physics_state.on_wall = on_wall;
|
physics_state.on_wall = on_wall;
|
||||||
let fric_mod = read.stats.get(entity).map_or(1.0, |s| s.friction_modifier);
|
let fric_mod = read.stats.get(entity).map_or(1.0, |s| s.friction_modifier)
|
||||||
if physics_state.on_ground || (physics_state.on_wall.is_some() && climbing) {
|
* physics_state
|
||||||
|
.on_ground
|
||||||
|
.map_or(1.0, |b| match b.get_sprite() {
|
||||||
|
Some(SpriteKind::EnsnaringVines) => 5.0,
|
||||||
|
_ => 1.0,
|
||||||
|
});
|
||||||
|
if physics_state.on_ground.is_some() || (physics_state.on_wall.is_some() && climbing) {
|
||||||
vel.0 *= (1.0 - FRIC_GROUND.min(1.0) * fric_mod).powf(dt.0 * 60.0);
|
vel.0 *= (1.0 - FRIC_GROUND.min(1.0) * fric_mod).powf(dt.0 * 60.0);
|
||||||
physics_state.ground_vel = ground_vel;
|
physics_state.ground_vel = ground_vel;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
arc_strip.collides_with_circle(Disk::new(pos_b2, rad_b))
|
arc_strip.collides_with_circle(Disk::new(pos_b2, rad_b))
|
||||||
}
|
}
|
||||||
&& (pos_b_ground - pos.0).angle_between(pos_b.0 - pos.0) < max_angle
|
&& (pos_b_ground - pos.0).angle_between(pos_b.0 - pos.0) < max_angle
|
||||||
&& (!shockwave.requires_ground || physics_state_b.on_ground);
|
&& (!shockwave.requires_ground || physics_state_b.on_ground.is_some());
|
||||||
|
|
||||||
if hit {
|
if hit {
|
||||||
let dir = Dir::from_unnormalized(pos_b.0 - pos.0).unwrap_or(look_dir);
|
let dir = Dir::from_unnormalized(pos_b.0 - pos.0).unwrap_or(look_dir);
|
||||||
|
@ -280,7 +280,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
let is_gliding = matches!(
|
let is_gliding = matches!(
|
||||||
read_data.char_states.get(entity),
|
read_data.char_states.get(entity),
|
||||||
Some(CharacterState::GlideWield) | Some(CharacterState::Glide(_))
|
Some(CharacterState::GlideWield) | Some(CharacterState::Glide(_))
|
||||||
) && !physics_state.on_ground;
|
) && physics_state.on_ground.is_none();
|
||||||
|
|
||||||
if let Some(pid) = agent.position_pid_controller.as_mut() {
|
if let Some(pid) = agent.position_pid_controller.as_mut() {
|
||||||
pid.add_measurement(read_data.time.0, pos.0);
|
pid.add_measurement(read_data.time.0, pos.0);
|
||||||
@ -295,7 +295,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
let traversal_config = TraversalConfig {
|
let traversal_config = TraversalConfig {
|
||||||
node_tolerance,
|
node_tolerance,
|
||||||
slow_factor,
|
slow_factor,
|
||||||
on_ground: physics_state.on_ground,
|
on_ground: physics_state.on_ground.is_some(),
|
||||||
in_liquid: physics_state.in_liquid().is_some(),
|
in_liquid: physics_state.in_liquid().is_some(),
|
||||||
min_tgt_dist: 1.0,
|
min_tgt_dist: 1.0,
|
||||||
can_climb: body.map(|b| b.can_climb()).unwrap_or(false),
|
can_climb: body.map(|b| b.can_climb()).unwrap_or(false),
|
||||||
@ -365,7 +365,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
// inputs.
|
// inputs.
|
||||||
|
|
||||||
// If falling fast and can glide, save yourself!
|
// If falling fast and can glide, save yourself!
|
||||||
if data.glider_equipped && !data.physics_state.on_ground {
|
if data.glider_equipped && data.physics_state.on_ground.is_none() {
|
||||||
// toggle glider when vertical velocity is above some threshold (here ~
|
// toggle glider when vertical velocity is above some threshold (here ~
|
||||||
// glider fall vertical speed)
|
// glider fall vertical speed)
|
||||||
data.glider_fall(agent, controller, &read_data);
|
data.glider_fall(agent, controller, &read_data);
|
||||||
|
@ -121,7 +121,7 @@ impl EventMapper for MovementEventMapper {
|
|||||||
// update state to determine the next event. We only record the time (above) if
|
// update state to determine the next event. We only record the time (above) if
|
||||||
// it was dispatched
|
// it was dispatched
|
||||||
internal_state.event = mapped_event;
|
internal_state.event = mapped_event;
|
||||||
internal_state.on_ground = physics.on_ground;
|
internal_state.on_ground = physics.on_ground.is_some();
|
||||||
internal_state.in_water = physics.in_liquid().is_some();
|
internal_state.in_water = physics.in_liquid().is_some();
|
||||||
let dt = ecs.fetch::<DeltaTime>().0;
|
let dt = ecs.fetch::<DeltaTime>().0;
|
||||||
internal_state.distance_travelled += vel.0.magnitude() * dt;
|
internal_state.distance_travelled += vel.0.magnitude() * dt;
|
||||||
@ -197,8 +197,8 @@ impl MovementEventMapper {
|
|||||||
|| !previous_state.in_water && physics_state.in_liquid().is_some()
|
|| !previous_state.in_water && physics_state.in_liquid().is_some()
|
||||||
{
|
{
|
||||||
return SfxEvent::Swim;
|
return SfxEvent::Swim;
|
||||||
} else if physics_state.on_ground && vel.magnitude() > 0.1
|
} else if physics_state.on_ground.is_some() && vel.magnitude() > 0.1
|
||||||
|| !previous_state.on_ground && physics_state.on_ground
|
|| !previous_state.on_ground && physics_state.on_ground.is_some()
|
||||||
{
|
{
|
||||||
return if matches!(character_state, CharacterState::Roll(_)) {
|
return if matches!(character_state, CharacterState::Roll(_)) {
|
||||||
SfxEvent::Roll
|
SfxEvent::Roll
|
||||||
@ -238,7 +238,7 @@ impl MovementEventMapper {
|
|||||||
) -> SfxEvent {
|
) -> SfxEvent {
|
||||||
if physics_state.in_liquid().is_some() && vel.magnitude() > 0.1 {
|
if physics_state.in_liquid().is_some() && vel.magnitude() > 0.1 {
|
||||||
SfxEvent::Swim
|
SfxEvent::Swim
|
||||||
} else if physics_state.on_ground && vel.magnitude() > 0.1 {
|
} else if physics_state.on_ground.is_some() && vel.magnitude() > 0.1 {
|
||||||
match underfoot_block_kind {
|
match underfoot_block_kind {
|
||||||
BlockKind::Snow => SfxEvent::Run(BlockKind::Snow),
|
BlockKind::Snow => SfxEvent::Run(BlockKind::Snow),
|
||||||
BlockKind::Rock | BlockKind::WeakRock => SfxEvent::Run(BlockKind::Rock),
|
BlockKind::Rock | BlockKind::WeakRock => SfxEvent::Run(BlockKind::Rock),
|
||||||
@ -259,7 +259,7 @@ impl MovementEventMapper {
|
|||||||
) -> SfxEvent {
|
) -> SfxEvent {
|
||||||
if physics_state.in_liquid().is_some() && vel.magnitude() > 0.1 {
|
if physics_state.in_liquid().is_some() && vel.magnitude() > 0.1 {
|
||||||
SfxEvent::Swim
|
SfxEvent::Swim
|
||||||
} else if physics_state.on_ground && vel.magnitude() > 0.1 {
|
} else if physics_state.on_ground.is_some() && vel.magnitude() > 0.1 {
|
||||||
match underfoot_block_kind {
|
match underfoot_block_kind {
|
||||||
BlockKind::Snow => SfxEvent::QuadRun(BlockKind::Snow),
|
BlockKind::Snow => SfxEvent::QuadRun(BlockKind::Snow),
|
||||||
BlockKind::Rock | BlockKind::WeakRock => SfxEvent::QuadRun(BlockKind::Rock),
|
BlockKind::Rock | BlockKind::WeakRock => SfxEvent::QuadRun(BlockKind::Rock),
|
||||||
|
@ -800,7 +800,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -1596,7 +1596,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -1798,7 +1798,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > 0.25, // Moving
|
rel_vel.magnitude_squared() > 0.25, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -2125,7 +2125,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -2484,7 +2484,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -2594,7 +2594,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -2683,7 +2683,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -3028,7 +3028,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -3123,7 +3123,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -3309,7 +3309,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -3396,7 +3396,7 @@ impl FigureMgr {
|
|||||||
Some(s.stage_section),
|
Some(s.stage_section),
|
||||||
state.state_time,
|
state.state_time,
|
||||||
look_dir,
|
look_dir,
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
),
|
),
|
||||||
stage_progress,
|
stage_progress,
|
||||||
&mut state_animation_rate,
|
&mut state_animation_rate,
|
||||||
@ -3434,7 +3434,7 @@ impl FigureMgr {
|
|||||||
Some(s.stage_section),
|
Some(s.stage_section),
|
||||||
ori * anim::vek::Vec3::<f32>::unit_y(),
|
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||||
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
),
|
),
|
||||||
stage_progress,
|
stage_progress,
|
||||||
&mut state_animation_rate,
|
&mut state_animation_rate,
|
||||||
@ -3461,7 +3461,7 @@ impl FigureMgr {
|
|||||||
Some(s.stage_section),
|
Some(s.stage_section),
|
||||||
state.state_time,
|
state.state_time,
|
||||||
look_dir,
|
look_dir,
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
),
|
),
|
||||||
stage_progress,
|
stage_progress,
|
||||||
&mut state_animation_rate,
|
&mut state_animation_rate,
|
||||||
@ -3484,7 +3484,7 @@ impl FigureMgr {
|
|||||||
};
|
};
|
||||||
anim::bird_large::ShockwaveAnimation::update_skeleton(
|
anim::bird_large::ShockwaveAnimation::update_skeleton(
|
||||||
&target_base,
|
&target_base,
|
||||||
(Some(s.stage_section), physics.on_ground),
|
(Some(s.stage_section), physics.on_ground.is_some()),
|
||||||
stage_progress,
|
stage_progress,
|
||||||
&mut state_animation_rate,
|
&mut state_animation_rate,
|
||||||
skeleton_attr,
|
skeleton_attr,
|
||||||
@ -3513,7 +3513,7 @@ impl FigureMgr {
|
|||||||
Some(s.stage_section),
|
Some(s.stage_section),
|
||||||
state.state_time,
|
state.state_time,
|
||||||
look_dir,
|
look_dir,
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
),
|
),
|
||||||
stage_progress,
|
stage_progress,
|
||||||
&mut state_animation_rate,
|
&mut state_animation_rate,
|
||||||
@ -3637,7 +3637,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -3726,7 +3726,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -4327,7 +4327,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -4581,7 +4581,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
@ -4710,7 +4710,7 @@ impl FigureMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let target_base = match (
|
let target_base = match (
|
||||||
physics.on_ground,
|
physics.on_ground.is_some(),
|
||||||
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
physics.in_liquid().is_some(), // In water
|
physics.in_liquid().is_some(), // In water
|
||||||
) {
|
) {
|
||||||
|
@ -469,7 +469,7 @@ impl Scene {
|
|||||||
let on_ground = ecs
|
let on_ground = ecs
|
||||||
.read_storage::<comp::PhysicsState>()
|
.read_storage::<comp::PhysicsState>()
|
||||||
.get(scene_data.player_entity)
|
.get(scene_data.player_entity)
|
||||||
.map(|p| p.on_ground);
|
.map(|p| p.on_ground.is_some());
|
||||||
|
|
||||||
let (player_height, player_eye_height) = scene_data
|
let (player_height, player_eye_height) = scene_data
|
||||||
.state
|
.state
|
||||||
|
Loading…
Reference in New Issue
Block a user