veloren/common/src/comp/states/swim.rs

74 lines
2.4 KiB
Rust
Raw Normal View History

2019-12-26 14:43:59 +00:00
use super::{HUMANOID_WATER_ACCEL, HUMANOID_WATER_SPEED};
2020-01-05 18:19:09 +00:00
use crate::comp::{EcsStateData, MoveState::*, RunState, StandState, StateHandler, StateUpdate};
2019-12-26 14:43:59 +00:00
use crate::sys::phys::GRAVITY;
use vek::{Vec2, Vec3};
2020-01-05 18:19:09 +00:00
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
2019-12-28 16:10:39 +00:00
pub struct SwimState;
2019-12-26 14:43:59 +00:00
2020-01-05 18:19:09 +00:00
impl StateHandler for SwimState {
2020-01-05 23:17:22 +00:00
fn new(ecs_data: &EcsStateData) -> Self {
Self {}
}
2019-12-28 16:10:39 +00:00
fn handle(&self, ecs_data: &EcsStateData) -> StateUpdate {
let mut update = StateUpdate {
2019-12-26 14:43:59 +00:00
character: *ecs_data.character,
pos: *ecs_data.pos,
vel: *ecs_data.vel,
ori: *ecs_data.ori,
};
// Update velocity
update.vel.0 += Vec2::broadcast(ecs_data.dt.0)
* ecs_data.inputs.move_dir
* if update.vel.0.magnitude_squared() < HUMANOID_WATER_SPEED.powf(2.0) {
HUMANOID_WATER_ACCEL
} else {
0.0
};
// Set direction based on move direction when on the ground
let ori_dir = if update.character.action_state.is_attacking()
|| update.character.action_state.is_blocking()
{
Vec2::from(ecs_data.inputs.look_dir).normalized()
} else {
Vec2::from(update.vel.0)
};
if ori_dir.magnitude_squared() > 0.0001
&& (update.ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared()
> 0.001
{
update.ori.0 = vek::ops::Slerp::slerp(
update.ori.0,
ori_dir.into(),
if ecs_data.physics.on_ground { 9.0 } else { 2.0 } * ecs_data.dt.0,
);
}
2019-12-28 16:10:39 +00:00
if ecs_data.inputs.jump.is_pressed() && !ecs_data.inputs.jump.is_held_down() {
2019-12-26 14:43:59 +00:00
update.vel.0.z =
(update.vel.0.z + ecs_data.dt.0 * GRAVITY * 1.25).min(HUMANOID_WATER_SPEED);
}
// Not on ground
if !ecs_data.physics.on_ground {
2020-01-05 18:19:09 +00:00
update.character.move_state = Swim(Some(SwimState));
2019-12-26 14:43:59 +00:00
return update;
}
// On ground
else {
// Return to running or standing based on move inputs
2019-12-26 18:01:19 +00:00
update.character.move_state = if ecs_data.inputs.move_dir.magnitude_squared() > 0.0 {
2020-01-05 18:19:09 +00:00
Run(Some(RunState))
2019-12-26 18:01:19 +00:00
} else {
2020-01-05 18:19:09 +00:00
Stand(Some(StandState))
2019-12-26 14:43:59 +00:00
};
return update;
}
}
}