mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Update common/src/sys/controller.rs, common/src/sys/movement.rs files
Deleted energy.rs, movement.rs files
This commit is contained in:
parent
1aa98dbb62
commit
a49482503d
@ -576,8 +576,7 @@ impl<'a> System<'a> for Sys {
|
||||
&& can_climb(body),
|
||||
physics.on_wall,)
|
||||
{
|
||||
|
||||
character.movement = Climb;
|
||||
character.movement = Climb;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -627,8 +626,6 @@ impl<'a> System<'a> for Sys {
|
||||
time_left: ROLL_DURATION,
|
||||
was_wielding: character.action.is_wield(),
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -233,11 +233,17 @@ impl<'a> System<'a> for Sys {
|
||||
physics.on_wall,
|
||||
) {
|
||||
if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() {
|
||||
if energy.get_mut_unchecked().try_change_by(-CLIMB_COST, EnergySource::Climb).is_ok(){
|
||||
if energy
|
||||
.get_mut_unchecked()
|
||||
.try_change_by(-CLIMB_COST, EnergySource::Climb)
|
||||
.is_ok(){
|
||||
vel.0 -= dt.0 * vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0);
|
||||
}
|
||||
} else if inputs.climb.is_pressed() && !inputs.climb_down.is_pressed() {
|
||||
if energy.get_mut_unchecked().try_change_by(-CLIMB_COST, EnergySource::Climb).is_ok(){
|
||||
if energy
|
||||
.get_mut_unchecked()
|
||||
.try_change_by(-CLIMB_COST, EnergySource::Climb)
|
||||
.is_ok(){
|
||||
vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED).max(0.0);
|
||||
}
|
||||
} else {
|
||||
|
77
energy.rs
77
energy.rs
@ -1,77 +0,0 @@
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub struct Energy {
|
||||
current: u32,
|
||||
maximum: u32,
|
||||
pub regen_rate: f32,
|
||||
pub last_change: Option<(i32, f64, EnergySource)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub enum EnergySource {
|
||||
CastSpell,
|
||||
Roll,
|
||||
Climb,
|
||||
LevelUp,
|
||||
Regen,
|
||||
Revive,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum StatChangeError {
|
||||
Underflow,
|
||||
Overflow,
|
||||
}
|
||||
|
||||
impl Energy {
|
||||
pub fn new(amount: u32) -> Energy {
|
||||
Energy {
|
||||
current: amount,
|
||||
maximum: amount,
|
||||
regen_rate: 0.0,
|
||||
last_change: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current(&self) -> u32 { self.current }
|
||||
|
||||
pub fn maximum(&self) -> u32 { self.maximum }
|
||||
|
||||
pub fn set_to(&mut self, amount: u32, cause: EnergySource) {
|
||||
let amount = amount.min(self.maximum);
|
||||
self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause));
|
||||
self.current = amount;
|
||||
}
|
||||
|
||||
pub fn change_by(&mut self, amount: i32, cause: EnergySource) {
|
||||
self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum);
|
||||
self.last_change = Some((amount, 0.0, cause));
|
||||
}
|
||||
|
||||
pub fn try_change_by(
|
||||
&mut self,
|
||||
amount: i32,
|
||||
cause: EnergySource,
|
||||
) -> Result<(), StatChangeError> {
|
||||
if self.current as i32 + amount < 0 {
|
||||
Err(StatChangeError::Underflow)
|
||||
} else if self.current as i32 + amount > self.maximum as i32 {
|
||||
Err(StatChangeError::Overflow)
|
||||
} else {
|
||||
self.change_by(amount, cause);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_maximum(&mut self, amount: u32) {
|
||||
self.maximum = amount;
|
||||
self.current = self.current.min(self.maximum);
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Energy {
|
||||
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
||||
}
|
253
movement.rs
253
movement.rs
@ -1,253 +0,0 @@
|
||||
use super::phys::GRAVITY;
|
||||
use crate::{
|
||||
comp::{
|
||||
ActionState, CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState,
|
||||
Pos, Stats, Vel, Energy, EnergySource
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::DeltaTime,
|
||||
sync::Uid,
|
||||
terrain::TerrainGrid,
|
||||
};
|
||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage};
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
pub const ROLL_DURATION: Duration = Duration::from_millis(600);
|
||||
|
||||
const BASE_HUMANOID_ACCEL: f32 = 100.0;
|
||||
const BASE_HUMANOID_SPEED: f32 = 120.0;
|
||||
const BASE_HUMANOID_AIR_ACCEL: f32 = 15.0;
|
||||
const BASE_HUMANOID_AIR_SPEED: f32 = 100.0;
|
||||
const BASE_HUMANOID_WATER_ACCEL: f32 = 70.0;
|
||||
const BASE_HUMANOID_WATER_SPEED: f32 = 120.0;
|
||||
const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0;
|
||||
const ROLL_SPEED: f32 = 17.0;
|
||||
const CHARGE_SPEED: f32 = 20.0;
|
||||
const GLIDE_ACCEL: f32 = 15.0;
|
||||
const GLIDE_SPEED: f32 = 45.0;
|
||||
const BLOCK_ACCEL: f32 = 30.0;
|
||||
const BLOCK_SPEED: f32 = 75.0;
|
||||
// Gravity is 9.81 * 4, so this makes gravity equal to .15
|
||||
const GLIDE_ANTIGRAV: f32 = GRAVITY * 0.96;
|
||||
const CLIMB_SPEED: f32 = 5.0;
|
||||
const CLIMB_COST: i32 = 5;
|
||||
|
||||
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
|
||||
|
||||
/// # Movement System
|
||||
/// #### Applies forces, calculates new positions and velocities,7
|
||||
/// #### based on Controller(Inputs) and CharacterState.
|
||||
/// ----
|
||||
///
|
||||
/// **Writes:**
|
||||
/// Pos, Vel, Ori
|
||||
///
|
||||
/// **Reads:**
|
||||
/// Uid, Stats, Controller, PhysicsState, CharacterState, Mounting
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
ReadExpect<'a, TerrainGrid>,
|
||||
Read<'a, EventBus<ServerEvent>>,
|
||||
Read<'a, DeltaTime>,
|
||||
WriteStorage<'a, Pos>,
|
||||
WriteStorage<'a, Vel>,
|
||||
WriteStorage<'a, Ori>,
|
||||
WriteStorage<'a, Energy>,
|
||||
ReadStorage<'a, Uid>,
|
||||
ReadStorage<'a, Stats>,
|
||||
ReadStorage<'a, Controller>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
ReadStorage<'a, CharacterState>,
|
||||
ReadStorage<'a, Mounting>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(
|
||||
entities,
|
||||
_terrain,
|
||||
_server_bus,
|
||||
dt,
|
||||
mut positions,
|
||||
mut velocities,
|
||||
mut orientations,
|
||||
mut energies,
|
||||
uids,
|
||||
stats,
|
||||
controllers,
|
||||
physics_states,
|
||||
character_states,
|
||||
mountings,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
// Apply movement inputs
|
||||
for (
|
||||
_entity,
|
||||
mut _pos,
|
||||
mut vel,
|
||||
mut ori,
|
||||
mut energy,
|
||||
_uid,
|
||||
stats,
|
||||
controller,
|
||||
physics,
|
||||
character,
|
||||
mount,
|
||||
) in (
|
||||
&entities,
|
||||
&mut positions,
|
||||
&mut velocities,
|
||||
&mut orientations,
|
||||
&mut energies.restrict_mut(),
|
||||
&uids,
|
||||
&stats,
|
||||
&controllers,
|
||||
&physics_states,
|
||||
&character_states,
|
||||
mountings.maybe(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
if stats.is_dead {
|
||||
continue;
|
||||
}
|
||||
|
||||
if mount.is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let inputs = &controller.inputs;
|
||||
|
||||
if character.action.is_roll() {
|
||||
vel.0 = Vec3::new(0.0, 0.0, vel.0.z)
|
||||
+ (vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||
+ 1.5 * inputs.move_dir.try_normalized().unwrap_or_default())
|
||||
.try_normalized()
|
||||
.unwrap_or_default()
|
||||
* ROLL_SPEED;
|
||||
} else if character.action.is_charge() {
|
||||
vel.0 = Vec3::new(0.0, 0.0, vel.0.z)
|
||||
+ (vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||
+ 1.5 * inputs.move_dir.try_normalized().unwrap_or_default())
|
||||
.try_normalized()
|
||||
.unwrap_or_default()
|
||||
* CHARGE_SPEED;
|
||||
} else if character.action.is_block() {
|
||||
vel.0 += Vec2::broadcast(dt.0)
|
||||
* inputs.move_dir
|
||||
* match physics.on_ground {
|
||||
true if vel.0.magnitude_squared() < BLOCK_SPEED.powf(2.0) => BLOCK_ACCEL,
|
||||
_ => 0.0,
|
||||
}
|
||||
} else {
|
||||
// Move player according to move_dir
|
||||
vel.0 += Vec2::broadcast(dt.0)
|
||||
* inputs.move_dir
|
||||
* match (physics.on_ground, &character.movement) {
|
||||
(true, Run)
|
||||
if vel.0.magnitude_squared()
|
||||
< (BASE_HUMANOID_SPEED + stats.fitness as f32 * 50.0).powf(2.0) =>
|
||||
{
|
||||
BASE_HUMANOID_ACCEL
|
||||
},
|
||||
(false, Climb)
|
||||
if vel.0.magnitude_squared() < BASE_HUMANOID_SPEED.powf(2.0) =>
|
||||
{
|
||||
BASE_HUMANOID_CLIMB_ACCEL
|
||||
},
|
||||
(false, Glide) if vel.0.magnitude_squared() < GLIDE_SPEED.powf(2.0) => {
|
||||
GLIDE_ACCEL
|
||||
},
|
||||
(false, Fall) | (false, Jump)
|
||||
if vel.0.magnitude_squared()
|
||||
< (BASE_HUMANOID_AIR_SPEED + stats.fitness as f32 * 10.0)
|
||||
.powf(2.0) =>
|
||||
{
|
||||
BASE_HUMANOID_AIR_ACCEL
|
||||
},
|
||||
(false, Swim)
|
||||
if vel.0.magnitude_squared()
|
||||
< (BASE_HUMANOID_WATER_SPEED + stats.fitness as f32 * 30.0)
|
||||
.powf(2.0) =>
|
||||
{
|
||||
BASE_HUMANOID_WATER_ACCEL + stats.fitness as f32 * 10.0
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
}
|
||||
|
||||
// Set direction based on move direction when on the ground
|
||||
let ori_dir = if
|
||||
//character.action.is_wield() ||
|
||||
character.action.is_attack() || character.action.is_block() {
|
||||
Vec2::from(inputs.look_dir).normalized()
|
||||
} else if let (Climb, Some(wall_dir)) = (character.movement, physics.on_wall) {
|
||||
if Vec2::<f32>::from(wall_dir).magnitude_squared() > 0.001 {
|
||||
Vec2::from(wall_dir).normalized()
|
||||
} else {
|
||||
Vec2::from(inputs.move_dir)
|
||||
}
|
||||
} else if let Glide = character.movement {
|
||||
// Note: non-gliding forces will also affect velocity and thus orientation
|
||||
// producing potentially unexpected changes in direction
|
||||
Vec2::from(vel.0)
|
||||
} else {
|
||||
if let ActionState::Roll { .. } = character.action {
|
||||
// So can can't spin/slip around while rolling
|
||||
Vec2::from(vel.0)
|
||||
} else {
|
||||
Vec2::from(inputs.move_dir)
|
||||
}
|
||||
};
|
||||
|
||||
if ori_dir.magnitude_squared() > 0.0001
|
||||
&& (ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared()
|
||||
> 0.001
|
||||
{
|
||||
ori.0 = vek::ops::Slerp::slerp(
|
||||
ori.0,
|
||||
ori_dir.into(),
|
||||
if physics.on_ground { 9.0 } else { 2.0 } * dt.0,
|
||||
);
|
||||
}
|
||||
|
||||
// Glide
|
||||
if character.movement == Glide
|
||||
&& Vec2::<f32>::from(vel.0).magnitude_squared() < GLIDE_SPEED.powf(2.0)
|
||||
&& vel.0.z < 0.0
|
||||
{
|
||||
let lift = GLIDE_ANTIGRAV + vel.0.z.abs().powf(2.0) * 0.15;
|
||||
vel.0.z += dt.0
|
||||
* lift
|
||||
* (Vec2::<f32>::from(vel.0).magnitude() * 0.075)
|
||||
.min(1.0)
|
||||
.max(0.2);
|
||||
}
|
||||
|
||||
// Climb
|
||||
if let (true, Some(_wall_dir)) = (
|
||||
character.movement == Climb && vel.0.z <= CLIMB_SPEED,
|
||||
physics.on_wall,
|
||||
) {
|
||||
if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() {
|
||||
if energy.get_mut_unchecked().try_change_by(-CLIMB_COST, EnergySource::Climb).is_ok(){
|
||||
vel.0 -= dt.0 * vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0);
|
||||
}
|
||||
} else if inputs.climb.is_pressed() && !inputs.climb_down.is_pressed() {
|
||||
if energy.get_mut_unchecked().try_change_by(-CLIMB_COST, EnergySource::Climb).is_ok(){
|
||||
vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED).max(0.0);
|
||||
}
|
||||
} else {
|
||||
vel.0.z = (vel.0.z - dt.0 * GRAVITY * 0.01).min(CLIMB_SPEED);
|
||||
}
|
||||
}
|
||||
|
||||
if character.movement == Swim && inputs.jump.is_pressed() {
|
||||
vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(BASE_HUMANOID_WATER_SPEED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user