From 69cb2ed84f794bbbba1eb176e3e66096e69d7a75 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 9 Jun 2019 16:20:20 +0200 Subject: [PATCH 01/19] Revamp control system --- chat-cli/src/main.rs | 2 +- client/src/lib.rs | 58 +-- common/src/comp/controller.rs | 15 + common/src/comp/inputs.rs | 11 +- common/src/comp/mod.rs | 3 +- common/src/msg/client.rs | 3 +- common/src/state.rs | 2 +- common/src/sys/actions.rs | 2 +- common/src/sys/agent.rs | 22 +- common/src/sys/controller.rs | 114 +++++ common/src/sys/inputs.rs | 61 +-- common/src/sys/mod.rs | 3 + diff | 578 +++++++++++++++++++++++++ server/src/lib.rs | 27 +- voxygen/src/menu/char_selection/mod.rs | 2 +- voxygen/src/session.rs | 44 +- 16 files changed, 775 insertions(+), 172 deletions(-) create mode 100644 common/src/comp/controller.rs create mode 100644 common/src/sys/controller.rs create mode 100644 diff diff --git a/chat-cli/src/main.rs b/chat-cli/src/main.rs index fdf8607bf9..1a4f099579 100644 --- a/chat-cli/src/main.rs +++ b/chat-cli/src/main.rs @@ -29,7 +29,7 @@ fn main() { client.send_chat("Hello!".to_string()); loop { - let events = match client.tick(comp::Control::default(), clock.get_last_delta()) { + let events = match client.tick(comp::Controller::default(), clock.get_last_delta()) { Ok(events) => events, Err(err) => { error!("Error: {:?}", err); diff --git a/client/src/lib.rs b/client/src/lib.rs index 6d4da2a5e7..01e0abe3d3 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -171,52 +171,6 @@ impl Client { self.postbox.send_message(ClientMsg::Chat(msg)) } - /// Jump locally, the new positions will be synced to the server - #[allow(dead_code)] - pub fn jump(&mut self) { - if self.client_state != ClientState::Character { - return; - } - self.state.write_component(self.entity, comp::Jumping); - } - - /// Start to glide locally, animation will be synced - #[allow(dead_code)] - pub fn glide(&mut self, state: bool) { - if self.client_state != ClientState::Character { - return; - } - if state { - self.state.write_component(self.entity, comp::Gliding); - } else { - self.state - .ecs_mut() - .write_storage::() - .remove(self.entity); - } - } - - /// Start to attack - #[allow(dead_code)] - pub fn attack(&mut self) { - if self.client_state != ClientState::Character { - return; - } - // TODO: Test if attack is possible using timeout - self.state - .write_component(self.entity, comp::Attacking::start()); - self.postbox.send_message(ClientMsg::Attack); - } - - /// Tell the server the client wants to respawn. - #[allow(dead_code)] - pub fn respawn(&mut self) { - if self.client_state != ClientState::Dead { - return; - } - self.postbox.send_message(ClientMsg::Respawn) - } - /// Remove all cached terrain #[allow(dead_code)] pub fn clear_terrain(&mut self) { @@ -226,7 +180,11 @@ impl Client { /// Execute a single client tick, handle input and update the game state by the given duration. #[allow(dead_code)] - pub fn tick(&mut self, control: comp::Control, dt: Duration) -> Result, Error> { + pub fn tick( + &mut self, + controller: comp::Controller, + dt: Duration, + ) -> Result, Error> { // This tick function is the centre of the Veloren universe. Most client-side things are // managed from here, and as such it's important that it stays organised. Please consult // the core developers before making significant changes to this code. Here is the @@ -243,10 +201,8 @@ impl Client { // 1) Handle input from frontend. // Pass character actions from frontend input to the player's entity. - // TODO: Only do this if the entity already has a Inputs component! - if self.client_state == ClientState::Character { - self.state.write_component(self.entity, control.clone()); - } + self.state.write_component(self.entity, controller.clone()); + self.postbox.send_message(ClientMsg::Controller(controller)); // 2) Build up a list of events for this frame, to be passed to the frontend. let mut frontend_events = Vec::new(); diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs new file mode 100644 index 0000000000..72834cc2f9 --- /dev/null +++ b/common/src/comp/controller.rs @@ -0,0 +1,15 @@ +use specs::{Component, FlaggedStorage, NullStorage, VecStorage}; +use vek::*; + +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +pub struct Controller { + pub move_dir: Vec2, + pub jump: bool, + pub glide: bool, + pub attack: bool, + pub respawn: bool, +} + +impl Component for Controller { + type Storage = FlaggedStorage>; +} diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs index ce55110ce0..27b7b75614 100644 --- a/common/src/comp/inputs.rs +++ b/common/src/comp/inputs.rs @@ -1,11 +1,6 @@ use specs::{Component, FlaggedStorage, NullStorage, VecStorage}; use vek::*; -#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] -pub struct Control { - pub move_dir: Vec2, -} - #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct Respawning; @@ -14,16 +9,13 @@ pub struct Attacking { pub time: f32, pub applied: bool, } + #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct Jumping; #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct Gliding; -impl Component for Control { - type Storage = VecStorage; -} - impl Component for Respawning { type Storage = NullStorage; } @@ -36,6 +28,7 @@ impl Attacking { } } } + impl Component for Attacking { type Storage = FlaggedStorage>; } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index ee351db610..cd9b36a153 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -1,6 +1,7 @@ pub mod actor; pub mod agent; pub mod animation; +pub mod controller; pub mod inputs; pub mod phys; pub mod player; @@ -15,8 +16,8 @@ pub use actor::QuadrupedMediumBody; pub use agent::Agent; pub use animation::Animation; pub use animation::AnimationInfo; +pub use controller::Controller; pub use inputs::Attacking; -pub use inputs::Control; pub use inputs::Gliding; pub use inputs::Jumping; pub use inputs::Respawning; diff --git a/common/src/msg/client.rs b/common/src/msg/client.rs index aa765d0a52..1187831d2a 100644 --- a/common/src/msg/client.rs +++ b/common/src/msg/client.rs @@ -11,8 +11,7 @@ pub enum ClientMsg { name: String, body: comp::Body, }, - Attack, - Respawn, + Controller(comp::Controller), RequestState(ClientState), SetViewDistance(u32), Ping, diff --git a/common/src/state.rs b/common/src/state.rs index 9357c60a28..630f7c8f56 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -110,9 +110,9 @@ impl State { ecs.register::(); ecs.register::(); ecs.register::(); + ecs.register::(); // Register client-local components - ecs.register::(); ecs.register::(); // Register server-local components diff --git a/common/src/sys/actions.rs b/common/src/sys/actions.rs index 8e091c5612..feb21a4251 100644 --- a/common/src/sys/actions.rs +++ b/common/src/sys/actions.rs @@ -18,7 +18,7 @@ impl<'a> System<'a> for Sys { let finished_attacks = (&entities, &mut attacks) .join() - .filter(|(_, a)| a.time > 0.25) // TODO: constant + .filter(|(_, a)| a.time > 0.50) // TODO: constant .map(|(e, _)| e) .collect::>(); diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index 55e845ca80..0e5e2f80f9 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -1,4 +1,4 @@ -use crate::comp::{phys::Pos, Agent, Attacking, Control, Jumping}; +use crate::comp::{phys::Pos, Agent, Attacking, Controller, Jumping}; use log::warn; use rand::{seq::SliceRandom, thread_rng}; use specs::{Entities, Join, ReadStorage, System, WriteStorage}; @@ -12,17 +12,17 @@ impl<'a> System<'a> for Sys { Entities<'a>, WriteStorage<'a, Agent>, ReadStorage<'a, Pos>, - WriteStorage<'a, Control>, + WriteStorage<'a, Controller>, WriteStorage<'a, Jumping>, WriteStorage<'a, Attacking>, ); fn run( &mut self, - (entities, mut agents, positions, mut controls, mut jumps, mut attacks): Self::SystemData, + (entities, mut agents, positions, mut controllers, mut jumps, mut attacks): Self::SystemData, ) { - for (entity, agent, pos, control) in - (&entities, &mut agents, &positions, &mut controls).join() + for (entity, agent, pos, controller) in + (&entities, &mut agents, &positions, &mut controllers).join() { match agent { Agent::Wanderer(bearing) => { @@ -32,7 +32,7 @@ impl<'a> System<'a> for Sys { - pos.0 * 0.0002; if bearing.magnitude_squared() != 0.0 { - control.move_dir = bearing.normalized(); + controller.move_dir = bearing.normalized(); } } Agent::Pet { target, offset } => { @@ -49,7 +49,7 @@ impl<'a> System<'a> for Sys { // Move towards the target. let dist: f32 = Vec2::from(tgt_pos - pos.0).magnitude(); - control.move_dir = if dist > 5.0 { + controller.move_dir = if dist > 5.0 { Vec2::from(tgt_pos - pos.0).normalized() } else if dist < 1.5 && dist > 0.0 { Vec2::from(pos.0 - tgt_pos).normalized() @@ -57,7 +57,7 @@ impl<'a> System<'a> for Sys { Vec2::zero() }; } - _ => control.move_dir = Vec2::zero(), + _ => controller.move_dir = Vec2::zero(), } // Change offset occasionally. @@ -72,7 +72,7 @@ impl<'a> System<'a> for Sys { Some(tgt_pos) => { let dist = Vec2::::from(tgt_pos.0 - pos.0).magnitude(); if dist < 2.0 { - control.move_dir = Vec2::zero(); + controller.move_dir = Vec2::zero(); if rand::random::() < 0.2 { attacks @@ -82,7 +82,7 @@ impl<'a> System<'a> for Sys { false } else if dist < 60.0 { - control.move_dir = + controller.move_dir = Vec2::::from(tgt_pos.0 - pos.0).normalized() * 0.96; false @@ -91,7 +91,7 @@ impl<'a> System<'a> for Sys { } } None => { - control.move_dir = Vec2::one(); + controller.move_dir = Vec2::one(); true } }; diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs new file mode 100644 index 0000000000..58ed6fc40e --- /dev/null +++ b/common/src/sys/controller.rs @@ -0,0 +1,114 @@ +use crate::{ + comp::{ + phys::{ForceUpdate, Ori, Pos, Vel}, + Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, Stats, + }, + state::{DeltaTime, Uid}, + terrain::TerrainMap, + vol::{ReadVol, Vox}, +}; +use log::warn; +use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; +use vek::*; + +const HUMANOID_ACCEL: f32 = 100.0; +const HUMANOID_SPEED: f32 = 500.0; +const HUMANOID_AIR_ACCEL: f32 = 10.0; +const HUMANOID_AIR_SPEED: f32 = 100.0; +const HUMANOID_JUMP_ACCEL: f32 = 16.0; +const GLIDE_ACCEL: f32 = 15.0; +const GLIDE_SPEED: f32 = 45.0; +// Gravity is 9.81 * 4, so this makes gravity equal to .15 +const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; + +pub struct Sys; +impl<'a> System<'a> for Sys { + type SystemData = ( + Entities<'a>, + Read<'a, DeltaTime>, + ReadStorage<'a, Controller>, + ReadStorage<'a, Stats>, + ReadExpect<'a, TerrainMap>, + ReadStorage<'a, Pos>, + WriteStorage<'a, Vel>, + WriteStorage<'a, Ori>, + WriteStorage<'a, Jumping>, + WriteStorage<'a, Attacking>, + WriteStorage<'a, Gliding>, + WriteStorage<'a, ForceUpdate>, + ); + + fn run( + &mut self, + ( + entities, + dt, + controllers, + stats, + terrain, + positions, + mut velocities, + mut orientations, + mut jumps, + mut attacks, + mut glides, + mut force_updates, + ): Self::SystemData, + ) { + for (entity, controller, stats, pos, mut vel, mut ori) in ( + &entities, + &controllers, + &stats, + &positions, + &mut velocities, + &mut orientations, + ) + .join() + { + if stats.is_dead { + continue; + } + + let on_ground = terrain + .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) + .map(|vox| !vox.is_empty()) + .unwrap_or(false) + && vel.0.z <= 0.0; + + let gliding = controller.glide && vel.0.z < 0.0; + let move_dir = if controller.move_dir.magnitude() > 1.0 { + controller.move_dir.normalized() + } else { + controller.move_dir + }; + + if on_ground { + // Move player according to move_dir + if vel.0.magnitude() < HUMANOID_SPEED { + vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_ACCEL; + } + + // Jump + if controller.jump && vel.0.z <= 0.0 { + vel.0.z = HUMANOID_JUMP_ACCEL; + } + } else if gliding && vel.0.magnitude() < GLIDE_SPEED { + let anti_grav = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; + vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); + vel.0 += Vec2::broadcast(dt.0) * move_dir * GLIDE_ACCEL; + } else if vel.0.magnitude() < HUMANOID_AIR_SPEED { + vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_AIR_ACCEL; + } + + // Set direction based on velocity + if vel.0.magnitude_squared() != 0.0 { + ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); + } + + // Attack + if controller.attack && attacks.get(entity).is_none() { + attacks.insert(entity, Attacking::start()); + } + } + } +} diff --git a/common/src/sys/inputs.rs b/common/src/sys/inputs.rs index 288a0e0ca0..6365f53ba4 100644 --- a/common/src/sys/inputs.rs +++ b/common/src/sys/inputs.rs @@ -1,7 +1,7 @@ use crate::{ comp::{ phys::{ForceUpdate, Ori, Pos, Vel}, - Animation, AnimationInfo, Attacking, Control, Gliding, HealthSource, Jumping, Stats, + Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, Stats, }, state::{DeltaTime, Uid}, terrain::TerrainMap, @@ -13,17 +13,6 @@ use vek::*; // Basic ECS AI agent system pub struct Sys; - -const HUMANOID_ACCEL: f32 = 100.0; -const HUMANOID_SPEED: f32 = 500.0; -const HUMANOID_AIR_ACCEL: f32 = 10.0; -const HUMANOID_AIR_SPEED: f32 = 100.0; -const HUMANOID_JUMP_ACCEL: f32 = 16.0; -const GLIDE_ACCEL: f32 = 15.0; -const GLIDE_SPEED: f32 = 45.0; -// Gravity is 9.81 * 4, so this makes gravity equal to .15 -const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; - impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, @@ -35,7 +24,7 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, Ori>, WriteStorage<'a, AnimationInfo>, WriteStorage<'a, Stats>, - ReadStorage<'a, Control>, + ReadStorage<'a, Controller>, WriteStorage<'a, Jumping>, WriteStorage<'a, Gliding>, WriteStorage<'a, Attacking>, @@ -54,74 +43,38 @@ impl<'a> System<'a> for Sys { mut orientations, mut animation_infos, mut stats, - controls, + controllers, mut jumps, glides, mut attacks, mut force_updates, ): Self::SystemData, ) { - for (entity, pos, control, stats, mut ori, mut vel) in ( + for (entity, pos, controller, stats, mut ori, mut vel) in ( &entities, &positions, - &controls, + &controllers, &stats, &mut orientations, &mut velocities, ) .join() { - // Disable while dead TODO: Replace with client states - if stats.is_dead { - continue; - } - let on_ground = terrain .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) .map(|vox| !vox.is_empty()) .unwrap_or(false) && vel.0.z <= 0.0; - let gliding = glides.get(entity).is_some() && vel.0.z < 0.0; - let move_dir = if control.move_dir.magnitude() > 1.0 { - control.move_dir.normalized() - } else { - control.move_dir - }; - - if on_ground { - // Move player according to move_dir - if vel.0.magnitude() < HUMANOID_SPEED { - vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_ACCEL; - } - - // Jump - if jumps.get(entity).is_some() && vel.0.z <= 0.0 { - vel.0.z = HUMANOID_JUMP_ACCEL; - jumps.remove(entity); - } - } else if gliding && vel.0.magnitude() < GLIDE_SPEED { - let anti_grav = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; - vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); - vel.0 += Vec2::broadcast(dt.0) * move_dir * GLIDE_ACCEL; - } else if vel.0.magnitude() < HUMANOID_AIR_SPEED { - vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_AIR_ACCEL; - } - - // Set direction based on velocity - if vel.0.magnitude_squared() != 0.0 { - ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); - } - let animation = if on_ground { - if control.move_dir.magnitude() > 0.01 { + if controller.move_dir.magnitude() > 0.01 { Animation::Run } else if attacks.get(entity).is_some() { Animation::Attack } else { Animation::Idle } - } else if glides.get(entity).is_some() { + } else if controller.glide { Animation::Gliding } else { Animation::Jump diff --git a/common/src/sys/mod.rs b/common/src/sys/mod.rs index da6f62958b..e6a5917c5a 100644 --- a/common/src/sys/mod.rs +++ b/common/src/sys/mod.rs @@ -1,6 +1,7 @@ pub mod actions; pub mod agent; pub mod animation; +pub mod controller; pub mod inputs; pub mod phys; mod stats; @@ -10,6 +11,7 @@ use specs::DispatcherBuilder; // System names const AGENT_SYS: &str = "agent_sys"; +const CONTROLLER_SYS: &str = "controller_sys"; const INPUTS_SYS: &str = "inputs_sys"; const ACTIONS_SYS: &str = "actions_sys"; const PHYS_SYS: &str = "phys_sys"; @@ -20,6 +22,7 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) { dispatch_builder.add(agent::Sys, AGENT_SYS, &[]); dispatch_builder.add(phys::Sys, PHYS_SYS, &[]); dispatch_builder.add(actions::Sys, ACTIONS_SYS, &[]); + dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[]); dispatch_builder.add(inputs::Sys, INPUTS_SYS, &[]); dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[]); dispatch_builder.add(stats::Sys, STATS_SYS, &[INPUTS_SYS]); diff --git a/diff b/diff new file mode 100644 index 0000000000..4f91ddd46b --- /dev/null +++ b/diff @@ -0,0 +1,578 @@ +diff --git a/chat-cli/src/main.rs b/chat-cli/src/main.rs +index f68a5b4..8ebd46f 100644 +--- a/chat-cli/src/main.rs ++++ b/chat-cli/src/main.rs +@@ -29,7 +29,7 @@ fn main() { + client.send_chat("Hello!".to_string()); + + loop { +- let events = match client.tick(comp::Control::default(), clock.get_last_delta()) { ++ let events = match client.tick(comp::Controller::default(), clock.get_last_delta()) { + Ok(events) => events, + Err(err) => { + error!("Error: {:?}", err); +diff --git a/client/src/lib.rs b/client/src/lib.rs +index f491359..ee3b62e 100644 +--- a/client/src/lib.rs ++++ b/client/src/lib.rs +@@ -154,52 +154,6 @@ impl Client { + self.postbox.send_message(ClientMsg::Chat(msg)) + } + +- /// Jump locally, the new positions will be synced to the server +- #[allow(dead_code)] +- pub fn jump(&mut self) { +- if self.client_state != ClientState::Character { +- return; +- } +- self.state.write_component(self.entity, comp::Jumping); +- } +- +- /// Start to glide locally, animation will be synced +- #[allow(dead_code)] +- pub fn glide(&mut self, state: bool) { +- if self.client_state != ClientState::Character { +- return; +- } +- if state { +- self.state.write_component(self.entity, comp::Gliding); +- } else { +- self.state +- .ecs_mut() +- .write_storage::() +- .remove(self.entity); +- } +- } +- +- /// Start to attack +- #[allow(dead_code)] +- pub fn attack(&mut self) { +- if self.client_state != ClientState::Character { +- return; +- } +- // TODO: Test if attack is possible using timeout +- self.state +- .write_component(self.entity, comp::Attacking::start()); +- self.postbox.send_message(ClientMsg::Attack); +- } +- +- /// Tell the server the client wants to respawn. +- #[allow(dead_code)] +- pub fn respawn(&mut self) { +- if self.client_state != ClientState::Dead { +- return; +- } +- self.postbox.send_message(ClientMsg::Respawn) +- } +- + /// Remove all cached terrain + #[allow(dead_code)] + pub fn clear_terrain(&mut self) { +@@ -209,7 +163,7 @@ impl Client { + + /// Execute a single client tick, handle input and update the game state by the given duration. + #[allow(dead_code)] +- pub fn tick(&mut self, control: comp::Control, dt: Duration) -> Result, Error> { ++ pub fn tick(&mut self, controller: comp::Controller, dt: Duration) -> Result, Error> { + // This tick function is the centre of the Veloren universe. Most client-side things are + // managed from here, and as such it's important that it stays organised. Please consult + // the core developers before making significant changes to this code. Here is the +@@ -226,10 +180,8 @@ impl Client { + + // 1) Handle input from frontend. + // Pass character actions from frontend input to the player's entity. +- // TODO: Only do this if the entity already has a Inputs component! +- if self.client_state == ClientState::Character { +- self.state.write_component(self.entity, control.clone()); +- } ++ self.state.write_component(self.entity, controller.clone()); ++ self.postbox.send_message(ClientMsg::Controller(controller)); + + // 2) Build up a list of events for this frame, to be passed to the frontend. + let mut frontend_events = Vec::new(); +diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs +index ce55110..27b7b75 100644 +--- a/common/src/comp/inputs.rs ++++ b/common/src/comp/inputs.rs +@@ -1,11 +1,6 @@ + use specs::{Component, FlaggedStorage, NullStorage, VecStorage}; + use vek::*; + +-#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +-pub struct Control { +- pub move_dir: Vec2, +-} +- + #[derive(Clone, Debug, Default, Serialize, Deserialize)] + pub struct Respawning; + +@@ -14,16 +9,13 @@ pub struct Attacking { + pub time: f32, + pub applied: bool, + } ++ + #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] + pub struct Jumping; + + #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] + pub struct Gliding; + +-impl Component for Control { +- type Storage = VecStorage; +-} +- + impl Component for Respawning { + type Storage = NullStorage; + } +@@ -36,6 +28,7 @@ impl Attacking { + } + } + } ++ + impl Component for Attacking { + type Storage = FlaggedStorage>; + } +diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs +index ee351db..2ca2e12 100644 +--- a/common/src/comp/mod.rs ++++ b/common/src/comp/mod.rs +@@ -2,6 +2,7 @@ pub mod actor; + pub mod agent; + pub mod animation; + pub mod inputs; ++pub mod controller; + pub mod phys; + pub mod player; + pub mod stats; +@@ -15,8 +16,8 @@ pub use actor::QuadrupedMediumBody; + pub use agent::Agent; + pub use animation::Animation; + pub use animation::AnimationInfo; ++pub use controller::Controller; + pub use inputs::Attacking; +-pub use inputs::Control; + pub use inputs::Gliding; + pub use inputs::Jumping; + pub use inputs::Respawning; +diff --git a/common/src/msg/client.rs b/common/src/msg/client.rs +index aa765d0..1187831 100644 +--- a/common/src/msg/client.rs ++++ b/common/src/msg/client.rs +@@ -11,8 +11,7 @@ pub enum ClientMsg { + name: String, + body: comp::Body, + }, +- Attack, +- Respawn, ++ Controller(comp::Controller), + RequestState(ClientState), + SetViewDistance(u32), + Ping, +diff --git a/common/src/state.rs b/common/src/state.rs +index 9357c60..630f7c8 100644 +--- a/common/src/state.rs ++++ b/common/src/state.rs +@@ -110,9 +110,9 @@ impl State { + ecs.register::(); + ecs.register::(); + ecs.register::(); ++ ecs.register::(); + + // Register client-local components +- ecs.register::(); + ecs.register::(); + + // Register server-local components +diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs +index 55e845c..0e5e2f8 100644 +--- a/common/src/sys/agent.rs ++++ b/common/src/sys/agent.rs +@@ -1,4 +1,4 @@ +-use crate::comp::{phys::Pos, Agent, Attacking, Control, Jumping}; ++use crate::comp::{phys::Pos, Agent, Attacking, Controller, Jumping}; + use log::warn; + use rand::{seq::SliceRandom, thread_rng}; + use specs::{Entities, Join, ReadStorage, System, WriteStorage}; +@@ -12,17 +12,17 @@ impl<'a> System<'a> for Sys { + Entities<'a>, + WriteStorage<'a, Agent>, + ReadStorage<'a, Pos>, +- WriteStorage<'a, Control>, ++ WriteStorage<'a, Controller>, + WriteStorage<'a, Jumping>, + WriteStorage<'a, Attacking>, + ); + + fn run( + &mut self, +- (entities, mut agents, positions, mut controls, mut jumps, mut attacks): Self::SystemData, ++ (entities, mut agents, positions, mut controllers, mut jumps, mut attacks): Self::SystemData, + ) { +- for (entity, agent, pos, control) in +- (&entities, &mut agents, &positions, &mut controls).join() ++ for (entity, agent, pos, controller) in ++ (&entities, &mut agents, &positions, &mut controllers).join() + { + match agent { + Agent::Wanderer(bearing) => { +@@ -32,7 +32,7 @@ impl<'a> System<'a> for Sys { + - pos.0 * 0.0002; + + if bearing.magnitude_squared() != 0.0 { +- control.move_dir = bearing.normalized(); ++ controller.move_dir = bearing.normalized(); + } + } + Agent::Pet { target, offset } => { +@@ -49,7 +49,7 @@ impl<'a> System<'a> for Sys { + + // Move towards the target. + let dist: f32 = Vec2::from(tgt_pos - pos.0).magnitude(); +- control.move_dir = if dist > 5.0 { ++ controller.move_dir = if dist > 5.0 { + Vec2::from(tgt_pos - pos.0).normalized() + } else if dist < 1.5 && dist > 0.0 { + Vec2::from(pos.0 - tgt_pos).normalized() +@@ -57,7 +57,7 @@ impl<'a> System<'a> for Sys { + Vec2::zero() + }; + } +- _ => control.move_dir = Vec2::zero(), ++ _ => controller.move_dir = Vec2::zero(), + } + + // Change offset occasionally. +@@ -72,7 +72,7 @@ impl<'a> System<'a> for Sys { + Some(tgt_pos) => { + let dist = Vec2::::from(tgt_pos.0 - pos.0).magnitude(); + if dist < 2.0 { +- control.move_dir = Vec2::zero(); ++ controller.move_dir = Vec2::zero(); + + if rand::random::() < 0.2 { + attacks +@@ -82,7 +82,7 @@ impl<'a> System<'a> for Sys { + + false + } else if dist < 60.0 { +- control.move_dir = ++ controller.move_dir = + Vec2::::from(tgt_pos.0 - pos.0).normalized() * 0.96; + + false +@@ -91,7 +91,7 @@ impl<'a> System<'a> for Sys { + } + } + None => { +- control.move_dir = Vec2::one(); ++ controller.move_dir = Vec2::one(); + true + } + }; +diff --git a/common/src/sys/inputs.rs b/common/src/sys/inputs.rs +index 288a0e0..6cadba5 100644 +--- a/common/src/sys/inputs.rs ++++ b/common/src/sys/inputs.rs +@@ -1,7 +1,7 @@ + use crate::{ + comp::{ + phys::{ForceUpdate, Ori, Pos, Vel}, +- Animation, AnimationInfo, Attacking, Control, Gliding, HealthSource, Jumping, Stats, ++ Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, Stats, + }, + state::{DeltaTime, Uid}, + terrain::TerrainMap, +@@ -13,17 +13,6 @@ use vek::*; + + // Basic ECS AI agent system + pub struct Sys; +- +-const HUMANOID_ACCEL: f32 = 100.0; +-const HUMANOID_SPEED: f32 = 500.0; +-const HUMANOID_AIR_ACCEL: f32 = 10.0; +-const HUMANOID_AIR_SPEED: f32 = 100.0; +-const HUMANOID_JUMP_ACCEL: f32 = 16.0; +-const GLIDE_ACCEL: f32 = 15.0; +-const GLIDE_SPEED: f32 = 45.0; +-// Gravity is 9.81 * 4, so this makes gravity equal to .15 +-const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; +- + impl<'a> System<'a> for Sys { + type SystemData = ( + Entities<'a>, +@@ -35,7 +24,7 @@ impl<'a> System<'a> for Sys { + WriteStorage<'a, Ori>, + WriteStorage<'a, AnimationInfo>, + WriteStorage<'a, Stats>, +- ReadStorage<'a, Control>, ++ ReadStorage<'a, Controller>, + WriteStorage<'a, Jumping>, + WriteStorage<'a, Gliding>, + WriteStorage<'a, Attacking>, +@@ -54,67 +43,31 @@ impl<'a> System<'a> for Sys { + mut orientations, + mut animation_infos, + mut stats, +- controls, ++ controllers, + mut jumps, + glides, + mut attacks, + mut force_updates, + ): Self::SystemData, + ) { +- for (entity, pos, control, stats, mut ori, mut vel) in ( ++ for (entity, pos, controller, stats, mut ori, mut vel) in ( + &entities, + &positions, +- &controls, ++ &controllers, + &stats, + &mut orientations, + &mut velocities, + ) + .join() + { +- // Disable while dead TODO: Replace with client states +- if stats.is_dead { +- continue; +- } +- + let on_ground = terrain + .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) + .map(|vox| !vox.is_empty()) + .unwrap_or(false) + && vel.0.z <= 0.0; + +- let gliding = glides.get(entity).is_some() && vel.0.z < 0.0; +- let move_dir = if control.move_dir.magnitude() > 1.0 { +- control.move_dir.normalized() +- } else { +- control.move_dir +- }; +- +- if on_ground { +- // Move player according to move_dir +- if vel.0.magnitude() < HUMANOID_SPEED { +- vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_ACCEL; +- } +- +- // Jump +- if jumps.get(entity).is_some() && vel.0.z <= 0.0 { +- vel.0.z = HUMANOID_JUMP_ACCEL; +- jumps.remove(entity); +- } +- } else if gliding && vel.0.magnitude() < GLIDE_SPEED { +- let anti_grav = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; +- vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); +- vel.0 += Vec2::broadcast(dt.0) * move_dir * GLIDE_ACCEL; +- } else if vel.0.magnitude() < HUMANOID_AIR_SPEED { +- vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_AIR_ACCEL; +- } +- +- // Set direction based on velocity +- if vel.0.magnitude_squared() != 0.0 { +- ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); +- } +- + let animation = if on_ground { +- if control.move_dir.magnitude() > 0.01 { ++ if controller.move_dir.magnitude() > 0.01 { + Animation::Run + } else if attacks.get(entity).is_some() { + Animation::Attack +@@ -149,6 +102,7 @@ impl<'a> System<'a> for Sys { + (&entities, &uids, &positions, &orientations, &mut attacks).join() + { + if !attacking.applied { ++ dbg!(); + for (b, pos_b, stat_b, mut vel_b) in + (&entities, &positions, &mut stats, &mut velocities).join() + { +diff --git a/common/src/sys/mod.rs b/common/src/sys/mod.rs +index da6f629..e6a5917 100644 +--- a/common/src/sys/mod.rs ++++ b/common/src/sys/mod.rs +@@ -1,6 +1,7 @@ + pub mod actions; + pub mod agent; + pub mod animation; ++pub mod controller; + pub mod inputs; + pub mod phys; + mod stats; +@@ -10,6 +11,7 @@ use specs::DispatcherBuilder; + + // System names + const AGENT_SYS: &str = "agent_sys"; ++const CONTROLLER_SYS: &str = "controller_sys"; + const INPUTS_SYS: &str = "inputs_sys"; + const ACTIONS_SYS: &str = "actions_sys"; + const PHYS_SYS: &str = "phys_sys"; +@@ -20,6 +22,7 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) { + dispatch_builder.add(agent::Sys, AGENT_SYS, &[]); + dispatch_builder.add(phys::Sys, PHYS_SYS, &[]); + dispatch_builder.add(actions::Sys, ACTIONS_SYS, &[]); ++ dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[]); + dispatch_builder.add(inputs::Sys, INPUTS_SYS, &[]); + dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[]); + dispatch_builder.add(stats::Sys, STATS_SYS, &[INPUTS_SYS]); +diff --git a/server/src/lib.rs b/server/src/lib.rs +index ead806c..6260f0a 100644 +--- a/server/src/lib.rs ++++ b/server/src/lib.rs +@@ -145,7 +145,7 @@ impl Server { + .with(pos) + .with(comp::phys::Vel(Vec3::zero())) + .with(comp::phys::Ori(Vec3::unit_y())) +- .with(comp::Control::default()) ++ .with(comp::Controller::default()) + .with(comp::AnimationInfo::default()) + .with(comp::Actor::Character { name, body }) + .with(comp::Stats::default()) +@@ -164,6 +164,7 @@ impl Server { + state.write_component(entity, comp::Actor::Character { name, body }); + state.write_component(entity, comp::Stats::default()); + state.write_component(entity, comp::AnimationInfo::default()); ++ state.write_component(entity, comp::Controller::default()); + state.write_component(entity, comp::phys::Pos(spawn_point)); + state.write_component(entity, comp::phys::Vel(Vec3::zero())); + state.write_component(entity, comp::phys::Ori(Vec3::unit_y())); +@@ -492,25 +493,16 @@ impl Server { + } + ClientState::Pending => {} + }, +- ClientMsg::Attack => match client.client_state { +- ClientState::Character => { +- if state +- .ecs() +- .read_storage::() +- .get(entity) +- .is_none() +- { +- state.write_component(entity, comp::Attacking::start()); +- } ++ ClientMsg::Controller(controller) => match client.client_state { ++ ClientState::Connected | ClientState::Registered | ClientState::Spectator => { ++ client.error_state(RequestStateError::Impossible) + } +- _ => client.error_state(RequestStateError::Impossible), +- }, +- ClientMsg::Respawn => match client.client_state { +- ClientState::Dead => { +- state.write_component(entity, comp::Respawning); ++ ClientState::Dead ++ | ClientState::Character => { ++ state.write_component(entity, controller); + } +- _ => client.error_state(RequestStateError::Impossible), +- }, ++ ClientState::Pending => {} ++ } + ClientMsg::Chat(msg) => match client.client_state { + ClientState::Connected => { + client.error_state(RequestStateError::Impossible) +diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs +index 2192ce7..1a3e3e3 100644 +--- a/voxygen/src/menu/char_selection/mod.rs ++++ b/voxygen/src/menu/char_selection/mod.rs +@@ -110,7 +110,7 @@ impl PlayState for CharSelectionState { + if let Err(err) = self + .client + .borrow_mut() +- .tick(comp::Control::default(), clock.get_last_delta()) ++ .tick(comp::Controller::default(), clock.get_last_delta()) + { + error!("Failed to tick the scene: {:?}", err); + return PlayStateResult::Pop; +diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs +index 913e421..bd5d876 100644 +--- a/voxygen/src/session.rs ++++ b/voxygen/src/session.rs +@@ -18,8 +18,9 @@ const FPS: u64 = 60; + pub struct SessionState { + scene: Scene, + client: Rc>, +- key_state: KeyState, + hud: Hud, ++ key_state: KeyState, ++ controller: comp::Controller, + } + + /// Represents an active game session (i.e., the one being played). +@@ -32,6 +33,7 @@ impl SessionState { + scene, + client, + key_state: KeyState::new(), ++ controller: comp::Controller::default(), + hud: Hud::new(window), + } + } +@@ -47,21 +49,11 @@ const BG_COLOR: Rgba = Rgba { + + impl SessionState { + /// Tick the session (and the client attached to it). +- pub fn tick(&mut self, dt: Duration) -> Result<(), Error> { +- // Calculate the movement input vector of the player from the current key presses +- // and the camera direction. +- let ori = self.scene.camera().get_orientation(); +- let unit_vecs = ( +- Vec2::new(ori[0].cos(), -ori[0].sin()), +- Vec2::new(ori[0].sin(), ori[0].cos()), +- ); +- let dir_vec = self.key_state.dir_vec(); +- let move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1]; +- ++ fn tick(&mut self, dt: Duration) -> Result<(), Error> { + for event in self + .client + .borrow_mut() +- .tick(comp::Control { move_dir }, dt)? ++ .tick(self.controller.clone(), dt)? + { + match event { + client::Event::Chat(msg) => { +@@ -121,19 +113,19 @@ impl PlayState for SessionState { + Event::Close => { + return PlayStateResult::Shutdown; + } +- Event::InputUpdate(GameInput::Attack, true) => { +- self.client.borrow_mut().attack(); +- self.client.borrow_mut().respawn(); ++ Event::InputUpdate(GameInput::Attack, state) => { ++ self.controller.attack = state; ++ self.controller.respawn = state; // TODO: Don't do both + } +- Event::InputUpdate(GameInput::Jump, true) => { +- self.client.borrow_mut().jump(); ++ Event::InputUpdate(GameInput::Jump, state) => { ++ self.controller.jump = state; + } + Event::InputUpdate(GameInput::MoveForward, state) => self.key_state.up = state, + Event::InputUpdate(GameInput::MoveBack, state) => self.key_state.down = state, + Event::InputUpdate(GameInput::MoveLeft, state) => self.key_state.left = state, + Event::InputUpdate(GameInput::MoveRight, state) => self.key_state.right = state, + Event::InputUpdate(GameInput::Glide, state) => { +- self.client.borrow_mut().glide(state) ++ self.controller.glide = state; + } + + // Pass all other events to the scene +@@ -143,6 +135,17 @@ impl PlayState for SessionState { + } + } + ++ // Calculate the movement input vector of the player from the current key presses ++ // and the camera direction. ++ let ori = self.scene.camera().get_orientation(); ++ let unit_vecs = ( ++ Vec2::new(ori[0].cos(), -ori[0].sin()), ++ Vec2::new(ori[0].sin(), ori[0].cos()), ++ ); ++ let dir_vec = self.key_state.dir_vec(); ++ self.controller.move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1]; ++ ++ + // Perform an in-game tick. + if let Err(err) = self.tick(clock.get_last_delta()) { + error!("Failed to tick the scene: {:?}", err); diff --git a/server/src/lib.rs b/server/src/lib.rs index ead806c46c..5d5fa38ae6 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -145,7 +145,7 @@ impl Server { .with(pos) .with(comp::phys::Vel(Vec3::zero())) .with(comp::phys::Ori(Vec3::unit_y())) - .with(comp::Control::default()) + .with(comp::Controller::default()) .with(comp::AnimationInfo::default()) .with(comp::Actor::Character { name, body }) .with(comp::Stats::default()) @@ -164,6 +164,7 @@ impl Server { state.write_component(entity, comp::Actor::Character { name, body }); state.write_component(entity, comp::Stats::default()); state.write_component(entity, comp::AnimationInfo::default()); + state.write_component(entity, comp::Controller::default()); state.write_component(entity, comp::phys::Pos(spawn_point)); state.write_component(entity, comp::phys::Vel(Vec3::zero())); state.write_component(entity, comp::phys::Ori(Vec3::unit_y())); @@ -492,24 +493,16 @@ impl Server { } ClientState::Pending => {} }, - ClientMsg::Attack => match client.client_state { - ClientState::Character => { - if state - .ecs() - .read_storage::() - .get(entity) - .is_none() - { - state.write_component(entity, comp::Attacking::start()); - } + ClientMsg::Controller(controller) => match client.client_state { + ClientState::Connected + | ClientState::Registered + | ClientState::Spectator => { + client.error_state(RequestStateError::Impossible) } - _ => client.error_state(RequestStateError::Impossible), - }, - ClientMsg::Respawn => match client.client_state { - ClientState::Dead => { - state.write_component(entity, comp::Respawning); + ClientState::Dead | ClientState::Character => { + state.write_component(entity, controller); } - _ => client.error_state(RequestStateError::Impossible), + ClientState::Pending => {} }, ClientMsg::Chat(msg) => match client.client_state { ClientState::Connected => { diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index e8e34a3247..62f5468959 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -108,7 +108,7 @@ impl PlayState for CharSelectionState { if let Err(err) = self .client .borrow_mut() - .tick(comp::Control::default(), clock.get_last_delta()) + .tick(comp::Controller::default(), clock.get_last_delta()) { error!("Failed to tick the scene: {:?}", err); return PlayStateResult::Pop; diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 1eb563bf8a..dd5f038a75 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -16,8 +16,9 @@ use vek::*; pub struct SessionState { scene: Scene, client: Rc>, - key_state: KeyState, hud: Hud, + key_state: KeyState, + controller: comp::Controller, } /// Represents an active game session (i.e., the one being played). @@ -30,6 +31,7 @@ impl SessionState { scene, client, key_state: KeyState::new(), + controller: comp::Controller::default(), hud: Hud::new(window), } } @@ -45,22 +47,8 @@ const BG_COLOR: Rgba = Rgba { impl SessionState { /// Tick the session (and the client attached to it). - pub fn tick(&mut self, dt: Duration) -> Result<(), Error> { - // Calculate the movement input vector of the player from the current key presses - // and the camera direction. - let ori = self.scene.camera().get_orientation(); - let unit_vecs = ( - Vec2::new(ori[0].cos(), -ori[0].sin()), - Vec2::new(ori[0].sin(), ori[0].cos()), - ); - let dir_vec = self.key_state.dir_vec(); - let move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1]; - - for event in self - .client - .borrow_mut() - .tick(comp::Control { move_dir }, dt)? - { + fn tick(&mut self, dt: Duration) -> Result<(), Error> { + for event in self.client.borrow_mut().tick(self.controller.clone(), dt)? { match event { client::Event::Chat(msg) => { self.hud.new_message(msg); @@ -127,19 +115,19 @@ impl PlayState for SessionState { Event::Close => { return PlayStateResult::Shutdown; } - Event::InputUpdate(GameInput::Attack, true) => { - self.client.borrow_mut().attack(); - self.client.borrow_mut().respawn(); + Event::InputUpdate(GameInput::Attack, state) => { + self.controller.attack = state; + self.controller.respawn = state; // TODO: Don't do both } - Event::InputUpdate(GameInput::Jump, true) => { - self.client.borrow_mut().jump(); + Event::InputUpdate(GameInput::Jump, state) => { + self.controller.jump = state; } Event::InputUpdate(GameInput::MoveForward, state) => self.key_state.up = state, Event::InputUpdate(GameInput::MoveBack, state) => self.key_state.down = state, Event::InputUpdate(GameInput::MoveLeft, state) => self.key_state.left = state, Event::InputUpdate(GameInput::MoveRight, state) => self.key_state.right = state, Event::InputUpdate(GameInput::Glide, state) => { - self.client.borrow_mut().glide(state) + self.controller.glide = state; } // Pass all other events to the scene @@ -149,6 +137,16 @@ impl PlayState for SessionState { } } + // Calculate the movement input vector of the player from the current key presses + // and the camera direction. + let ori = self.scene.camera().get_orientation(); + let unit_vecs = ( + Vec2::new(ori[0].cos(), -ori[0].sin()), + Vec2::new(ori[0].sin(), ori[0].cos()), + ); + let dir_vec = self.key_state.dir_vec(); + self.controller.move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1]; + // Perform an in-game tick. if let Err(err) = self.tick(clock.get_last_delta()) { error!("Failed to tick the scene: {:?}", err); From b947d78dac884b139f20e3ef8fdd1d0e96091f6c Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 9 Jun 2019 21:33:20 +0200 Subject: [PATCH 02/19] Improve organization of controls --- common/src/comp/inputs.rs | 14 +++ common/src/comp/mod.rs | 2 + common/src/state.rs | 2 + common/src/sys/actions.rs | 29 ------ common/src/sys/agent.rs | 3 +- common/src/sys/animation.rs | 67 ++++++++++++-- common/src/sys/controller.rs | 92 +++++++++---------- common/src/sys/inputs.rs | 168 ++++++++++++++++++++--------------- common/src/sys/mod.rs | 7 +- common/src/sys/phys.rs | 44 ++++++--- common/src/sys/stats.rs | 3 +- 11 files changed, 251 insertions(+), 180 deletions(-) delete mode 100644 common/src/sys/actions.rs diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs index 27b7b75614..1ae61033b8 100644 --- a/common/src/comp/inputs.rs +++ b/common/src/comp/inputs.rs @@ -4,12 +4,18 @@ use vek::*; #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct Respawning; +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +pub struct MoveDir(pub Vec2); + #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct Attacking { pub time: f32, pub applied: bool, } +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +pub struct OnGround; + #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct Jumping; @@ -29,10 +35,18 @@ impl Attacking { } } +impl Component for MoveDir { + type Storage = VecStorage; +} + impl Component for Attacking { type Storage = FlaggedStorage>; } +impl Component for OnGround { + type Storage = NullStorage; +} + impl Component for Jumping { type Storage = NullStorage; } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index cd9b36a153..92d785dd77 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -20,6 +20,8 @@ pub use controller::Controller; pub use inputs::Attacking; pub use inputs::Gliding; pub use inputs::Jumping; +pub use inputs::MoveDir; +pub use inputs::OnGround; pub use inputs::Respawning; pub use player::Player; pub use stats::Dying; diff --git a/common/src/state.rs b/common/src/state.rs index 630f7c8f56..de959c47c4 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -109,6 +109,8 @@ impl State { ecs.register::(); ecs.register::(); ecs.register::(); + ecs.register::(); + ecs.register::(); ecs.register::(); ecs.register::(); diff --git a/common/src/sys/actions.rs b/common/src/sys/actions.rs deleted file mode 100644 index feb21a4251..0000000000 --- a/common/src/sys/actions.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::{comp::Attacking, state::DeltaTime}; -use specs::{Entities, Join, Read, System, WriteStorage}; - -// Basic ECS AI agent system -pub struct Sys; - -impl<'a> System<'a> for Sys { - type SystemData = ( - Entities<'a>, - Read<'a, DeltaTime>, - WriteStorage<'a, Attacking>, - ); - - fn run(&mut self, (entities, dt, mut attacks): Self::SystemData) { - for attack in (&mut attacks).join() { - attack.time += dt.0; - } - - let finished_attacks = (&entities, &mut attacks) - .join() - .filter(|(_, a)| a.time > 0.50) // TODO: constant - .map(|(e, _)| e) - .collect::>(); - - for entity in finished_attacks { - attacks.remove(entity); - } - } -} diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index 0e5e2f80f9..0bd445ab1e 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -4,9 +4,8 @@ use rand::{seq::SliceRandom, thread_rng}; use specs::{Entities, Join, ReadStorage, System, WriteStorage}; use vek::*; -// Basic ECS AI agent system +/// This system will allow NPCs to modify their controller pub struct Sys; - impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, diff --git a/common/src/sys/animation.rs b/common/src/sys/animation.rs index 09e194667d..29d5b08d7a 100644 --- a/common/src/sys/animation.rs +++ b/common/src/sys/animation.rs @@ -1,15 +1,68 @@ -use crate::{comp::AnimationInfo, state::DeltaTime}; -use specs::{Join, Read, System, WriteStorage}; +use crate::{ + comp::{phys, Animation, AnimationInfo, Attacking, Gliding, Jumping, OnGround}, + state::DeltaTime, +}; +use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; -// Basic ECS AI agent system +/// This system will apply the animation that fits best to the users actions pub struct Sys; - impl<'a> System<'a> for Sys { - type SystemData = (Read<'a, DeltaTime>, WriteStorage<'a, AnimationInfo>); + type SystemData = ( + Entities<'a>, + Read<'a, DeltaTime>, + ReadStorage<'a, phys::Vel>, + ReadStorage<'a, OnGround>, + ReadStorage<'a, Jumping>, + ReadStorage<'a, Gliding>, + ReadStorage<'a, Attacking>, + WriteStorage<'a, AnimationInfo>, + ); - fn run(&mut self, (dt, mut animation_infos): Self::SystemData) { - for mut animation_info in (&mut animation_infos).join() { + fn run( + &mut self, + (entities, dt, velocities, on_grounds, jumpings, glidings, attackings, mut animation_infos): Self::SystemData, + ) { + for (entity, vel, on_ground, jumping, gliding, attacking, mut animation_info) in ( + &entities, + &velocities, + on_grounds.maybe(), + jumpings.maybe(), + glidings.maybe(), + attackings.maybe(), + &mut animation_infos, + ) + .join() + { animation_info.time += dt.0 as f64; + let moving = vel.0.magnitude() > 3.0; + + fn impossible_animation() -> Animation { + warn!("Impossible animation"); + Animation::Idle + } + + let animation = match ( + on_ground.is_some(), + moving, + attacking.is_some(), + gliding.is_some(), + ) { + (true, false, false, false) => Animation::Idle, + (true, true, false, false) => Animation::Run, + (false, _, false, false) => Animation::Jump, + (_, _, false, true) => Animation::Gliding, + (_, _, true, false) => Animation::Attack, + (_, _, true, true) => impossible_animation(), + }; + + let last = animation_info.clone(); + let changed = last.animation != animation; + + *animation_info = AnimationInfo { + animation, + time: if changed { 0.0 } else { last.time }, + changed, + }; } } } diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 58ed6fc40e..921c4bff23 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -1,7 +1,8 @@ use crate::{ comp::{ phys::{ForceUpdate, Ori, Pos, Vel}, - Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, Stats, + Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, MoveDir, + OnGround, Respawning, Stats, }, state::{DeltaTime, Uid}, terrain::TerrainMap, @@ -11,16 +12,7 @@ use log::warn; use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; use vek::*; -const HUMANOID_ACCEL: f32 = 100.0; -const HUMANOID_SPEED: f32 = 500.0; -const HUMANOID_AIR_ACCEL: f32 = 10.0; -const HUMANOID_AIR_SPEED: f32 = 100.0; -const HUMANOID_JUMP_ACCEL: f32 = 16.0; -const GLIDE_ACCEL: f32 = 15.0; -const GLIDE_SPEED: f32 = 45.0; -// Gravity is 9.81 * 4, so this makes gravity equal to .15 -const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; - +/// This system is responsible for validating controller inputs pub struct Sys; impl<'a> System<'a> for Sys { type SystemData = ( @@ -32,8 +24,11 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Pos>, WriteStorage<'a, Vel>, WriteStorage<'a, Ori>, + WriteStorage<'a, MoveDir>, + WriteStorage<'a, OnGround>, WriteStorage<'a, Jumping>, WriteStorage<'a, Attacking>, + WriteStorage<'a, Respawning>, WriteStorage<'a, Gliding>, WriteStorage<'a, ForceUpdate>, ); @@ -49,65 +44,64 @@ impl<'a> System<'a> for Sys { positions, mut velocities, mut orientations, - mut jumps, - mut attacks, - mut glides, + mut move_dirs, + mut on_grounds, + mut jumpings, + mut attackings, + mut respawns, + mut glidings, mut force_updates, ): Self::SystemData, ) { - for (entity, controller, stats, pos, mut vel, mut ori) in ( + for (entity, controller, stats, pos, mut vel, mut ori, on_ground) in ( &entities, &controllers, &stats, &positions, &mut velocities, &mut orientations, + on_grounds.maybe(), ) .join() { if stats.is_dead { + // Respawn + if controller.respawn { + respawns.insert(entity, Respawning); + } continue; } - let on_ground = terrain - .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) - .map(|vox| !vox.is_empty()) - .unwrap_or(false) - && vel.0.z <= 0.0; - - let gliding = controller.glide && vel.0.z < 0.0; - let move_dir = if controller.move_dir.magnitude() > 1.0 { - controller.move_dir.normalized() + // Glide + if controller.glide && on_ground.is_none() && attackings.get(entity).is_none() { + glidings.insert(entity, Gliding); } else { - controller.move_dir - }; - - if on_ground { - // Move player according to move_dir - if vel.0.magnitude() < HUMANOID_SPEED { - vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_ACCEL; - } - - // Jump - if controller.jump && vel.0.z <= 0.0 { - vel.0.z = HUMANOID_JUMP_ACCEL; - } - } else if gliding && vel.0.magnitude() < GLIDE_SPEED { - let anti_grav = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; - vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); - vel.0 += Vec2::broadcast(dt.0) * move_dir * GLIDE_ACCEL; - } else if vel.0.magnitude() < HUMANOID_AIR_SPEED { - vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_AIR_ACCEL; + glidings.remove(entity); } - // Set direction based on velocity - if vel.0.magnitude_squared() != 0.0 { - ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); - } + // Move dir + move_dirs.insert( + entity, + MoveDir(if controller.move_dir.magnitude() > 1.0 { + controller.move_dir.normalized() + } else { + controller.move_dir + }), + ); // Attack - if controller.attack && attacks.get(entity).is_none() { - attacks.insert(entity, Attacking::start()); + if controller.attack + && attackings.get(entity).is_none() + && glidings.get(entity).is_none() + { + attackings.insert(entity, Attacking::start()); + } + + // Jump + if on_grounds.get(entity).is_some() && controller.jump && vel.0.z <= 0.0 { + jumpings.insert(entity, Jumping); + } else { + jumpings.remove(entity); } } } diff --git a/common/src/sys/inputs.rs b/common/src/sys/inputs.rs index 6365f53ba4..702328de87 100644 --- a/common/src/sys/inputs.rs +++ b/common/src/sys/inputs.rs @@ -1,7 +1,8 @@ use crate::{ comp::{ phys::{ForceUpdate, Ori, Pos, Vel}, - Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, Stats, + Animation, AnimationInfo, Attacking, Gliding, HealthSource, Jumping, MoveDir, OnGround, + Respawning, Stats, }, state::{DeltaTime, Uid}, terrain::TerrainMap, @@ -11,7 +12,17 @@ use log::warn; use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; use vek::*; -// Basic ECS AI agent system +const HUMANOID_ACCEL: f32 = 100.0; +const HUMANOID_SPEED: f32 = 500.0; +const HUMANOID_AIR_ACCEL: f32 = 10.0; +const HUMANOID_AIR_SPEED: f32 = 100.0; +const HUMANOID_JUMP_ACCEL: f32 = 16.0; +const GLIDE_ACCEL: f32 = 15.0; +const GLIDE_SPEED: f32 = 45.0; +// Gravity is 9.81 * 4, so this makes gravity equal to .15 +const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; + +/// This system is responsible for handling accepted inputs like moving or attacking pub struct Sys; impl<'a> System<'a> for Sys { type SystemData = ( @@ -20,11 +31,13 @@ impl<'a> System<'a> for Sys { Read<'a, DeltaTime>, ReadExpect<'a, TerrainMap>, ReadStorage<'a, Pos>, + ReadStorage<'a, OnGround>, + ReadStorage<'a, MoveDir>, WriteStorage<'a, Vel>, WriteStorage<'a, Ori>, WriteStorage<'a, AnimationInfo>, WriteStorage<'a, Stats>, - ReadStorage<'a, Controller>, + WriteStorage<'a, Respawning>, WriteStorage<'a, Jumping>, WriteStorage<'a, Gliding>, WriteStorage<'a, Attacking>, @@ -39,88 +52,99 @@ impl<'a> System<'a> for Sys { dt, terrain, positions, + on_grounds, + move_dirs, mut velocities, mut orientations, mut animation_infos, mut stats, - controllers, - mut jumps, - glides, - mut attacks, + mut respawnings, + mut jumpings, + glidings, + mut attackings, mut force_updates, ): Self::SystemData, ) { - for (entity, pos, controller, stats, mut ori, mut vel) in ( + // Attacks + (&entities, &uids, &positions, &orientations, &mut attackings) + .join() + .filter_map(|(entity, uid, pos, ori, mut attacking)| { + if !attacking.applied { + // Go through all other entities + for (b, pos_b, stat_b, mut vel_b) in + (&entities, &positions, &mut stats, &mut velocities).join() + { + // Check if it is a hit + if entity != b + && !stat_b.is_dead + && pos.0.distance_squared(pos_b.0) < 50.0 + && ori.0.angle_between(pos_b.0 - pos.0).to_degrees() < 70.0 + { + // Deal damage + stat_b.hp.change_by(-10, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon + vel_b.0 += (pos_b.0 - pos.0).normalized() * 10.0; + vel_b.0.z = 15.0; + if let Err(err) = force_updates.insert(b, ForceUpdate) { + warn!("Inserting ForceUpdate for an entity failed: {:?}", err); + } + } + } + attacking.applied = true; + } + + if attacking.time > 0.5 { + Some(entity) + } else { + attacking.time += dt.0; + None + } + }) + .collect::>() + .into_iter() + .for_each(|e| { + attackings.remove(e); + }); + + // Apply movement inputs + for (entity, mut vel, mut ori, on_ground, move_dir, jumping, gliding) in ( &entities, - &positions, - &controllers, - &stats, - &mut orientations, &mut velocities, + &mut orientations, + on_grounds.maybe(), + move_dirs.maybe(), + jumpings.maybe(), + glidings.maybe(), ) .join() { - let on_ground = terrain - .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) - .map(|vox| !vox.is_empty()) - .unwrap_or(false) - && vel.0.z <= 0.0; - - let animation = if on_ground { - if controller.move_dir.magnitude() > 0.01 { - Animation::Run - } else if attacks.get(entity).is_some() { - Animation::Attack - } else { - Animation::Idle - } - } else if controller.glide { - Animation::Gliding - } else { - Animation::Jump - }; - - let last = animation_infos - .get_mut(entity) - .cloned() - .unwrap_or(AnimationInfo::default()); - let changed = last.animation != animation; - - if let Err(err) = animation_infos.insert( - entity, - AnimationInfo { - animation, - time: if changed { 0.0 } else { last.time }, - changed, - }, - ) { - warn!("Inserting AnimationInfo for an entity failed: {:?}", err); - } - } - - for (entity, &uid, pos, ori, attacking) in - (&entities, &uids, &positions, &orientations, &mut attacks).join() - { - if !attacking.applied { - for (b, pos_b, stat_b, mut vel_b) in - (&entities, &positions, &mut stats, &mut velocities).join() - { - // Check if it is a hit - if entity != b - && !stat_b.is_dead - && pos.0.distance_squared(pos_b.0) < 50.0 - && ori.0.angle_between(pos_b.0 - pos.0).to_degrees() < 70.0 - { - // Deal damage - stat_b.hp.change_by(-10, HealthSource::Attack { by: uid }); // TODO: variable damage and weapon - vel_b.0 += (pos_b.0 - pos.0).normalized() * 10.0; - vel_b.0.z = 15.0; - if let Err(err) = force_updates.insert(b, ForceUpdate) { - warn!("Inserting ForceUpdate for an entity failed: {:?}", err); + // Move player according to move_dir + if let Some(move_dir) = move_dir { + vel.0 += Vec2::broadcast(dt.0) + * move_dir.0 + * match (on_ground.is_some(), gliding.is_some()) { + (true, false) if vel.0.magnitude() < HUMANOID_SPEED => HUMANOID_ACCEL, + (false, true) if vel.0.magnitude() < GLIDE_SPEED => GLIDE_ACCEL, + (false, false) if vel.0.magnitude() < HUMANOID_AIR_SPEED => { + HUMANOID_AIR_ACCEL } - } - } - attacking.applied = true; + _ => 0.0, + }; + } + + // Jump + if jumping.is_some() { + vel.0.z = HUMANOID_JUMP_ACCEL; + } + + // Glide + if gliding.is_some() && vel.0.magnitude() < GLIDE_SPEED && vel.0.z < 0.0 { + let anti_grav = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; + vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); + } + + // Set direction based on velocity + if vel.0.magnitude_squared() != 0.0 { + ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); } } } diff --git a/common/src/sys/mod.rs b/common/src/sys/mod.rs index e6a5917c5a..97861dea9f 100644 --- a/common/src/sys/mod.rs +++ b/common/src/sys/mod.rs @@ -1,4 +1,3 @@ -pub mod actions; pub mod agent; pub mod animation; pub mod controller; @@ -12,17 +11,15 @@ use specs::DispatcherBuilder; // System names const AGENT_SYS: &str = "agent_sys"; const CONTROLLER_SYS: &str = "controller_sys"; -const INPUTS_SYS: &str = "inputs_sys"; -const ACTIONS_SYS: &str = "actions_sys"; const PHYS_SYS: &str = "phys_sys"; +const INPUTS_SYS: &str = "inputs_sys"; const ANIMATION_SYS: &str = "animation_sys"; const STATS_SYS: &str = "stats_sys"; pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) { dispatch_builder.add(agent::Sys, AGENT_SYS, &[]); - dispatch_builder.add(phys::Sys, PHYS_SYS, &[]); - dispatch_builder.add(actions::Sys, ACTIONS_SYS, &[]); dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[]); + dispatch_builder.add(phys::Sys, PHYS_SYS, &[]); dispatch_builder.add(inputs::Sys, INPUTS_SYS, &[]); dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[]); dispatch_builder.add(stats::Sys, STATS_SYS, &[INPUTS_SYS]); diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 796b3310e2..270f276964 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -1,18 +1,15 @@ use crate::{ comp::{ phys::{Pos, Vel}, - Stats, + OnGround, Stats, }, state::DeltaTime, terrain::TerrainMap, vol::{ReadVol, Vox}, }; -use specs::{Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; +use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; use vek::*; -// Basic ECS physics system -pub struct Sys; - const GRAVITY: f32 = 9.81 * 4.0; const FRIC_GROUND: f32 = 0.15; const FRIC_AIR: f32 = 0.015; @@ -38,34 +35,53 @@ fn integrate_forces(dt: f32, mut lv: Vec3, damp: f32) -> Vec3 { lv } +/// This system applies forces and calculates new positions and velocities +pub struct Sys; impl<'a> System<'a> for Sys { type SystemData = ( + Entities<'a>, ReadExpect<'a, TerrainMap>, Read<'a, DeltaTime>, ReadStorage<'a, Stats>, WriteStorage<'a, Pos>, WriteStorage<'a, Vel>, + WriteStorage<'a, OnGround>, ); - fn run(&mut self, (terrain, dt, stats, mut positions, mut velocities): Self::SystemData) { - for (stats, pos, vel) in (&stats, &mut positions, &mut velocities).join() { + fn run( + &mut self, + (entities, terrain, dt, stats, mut positions, mut velocities, mut on_grounds): Self::SystemData, + ) { + for (entity, stats, pos, vel) in (&entities, &stats, &mut positions, &mut velocities).join() + { // Disable while dead TODO: Replace with client states if stats.is_dead { continue; } - let on_ground = terrain - .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) - .map(|vox| !vox.is_empty()) - .unwrap_or(false) - && vel.0.z <= 0.0; - // Movement pos.0 += vel.0 * dt.0; + // Update OnGround component + if terrain + .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) + .map(|vox| !vox.is_empty()) + .unwrap_or(false) + && vel.0.z <= 0.0 + { + on_grounds.insert(entity, OnGround); + } else { + on_grounds.remove(entity); + } + // Integrate forces // Friction is assumed to be a constant dependent on location - let friction = 50.0 * if on_ground { FRIC_GROUND } else { FRIC_AIR }; + let friction = 50.0 + * if on_grounds.get(entity).is_some() { + FRIC_GROUND + } else { + FRIC_AIR + }; vel.0 = integrate_forces(dt.0, vel.0, friction); // Basic collision with terrain diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs index 3897da618f..22dc10d48b 100644 --- a/common/src/sys/stats.rs +++ b/common/src/sys/stats.rs @@ -5,9 +5,8 @@ use crate::{ use log::warn; use specs::{Entities, Join, Read, System, WriteStorage}; -// Basic ECS AI agent system +/// This system kills players pub struct Sys; - impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, From 1f6c1188bc0d3243ddd94168da7be4e09addc47b Mon Sep 17 00:00:00 2001 From: Cody Date: Tue, 11 Jun 2019 15:28:25 -0400 Subject: [PATCH 03/19] Removes input sys, moves code to combat and phys --- common/src/comp/controller.rs | 2 +- common/src/sys/combat.rs | 80 +++++ common/src/sys/controller.rs | 50 +-- common/src/sys/inputs.rs | 151 --------- common/src/sys/mod.rs | 8 +- common/src/sys/phys.rs | 90 +++++- diff | 578 ---------------------------------- 7 files changed, 191 insertions(+), 768 deletions(-) create mode 100644 common/src/sys/combat.rs delete mode 100644 common/src/sys/inputs.rs delete mode 100644 diff diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs index 72834cc2f9..83383e5674 100644 --- a/common/src/comp/controller.rs +++ b/common/src/comp/controller.rs @@ -1,4 +1,4 @@ -use specs::{Component, FlaggedStorage, NullStorage, VecStorage}; +use specs::{Component, FlaggedStorage, VecStorage}; use vek::*; #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs new file mode 100644 index 0000000000..39cd73058b --- /dev/null +++ b/common/src/sys/combat.rs @@ -0,0 +1,80 @@ +use crate::{ + comp::{ + phys::{ForceUpdate, Ori, Pos, Vel}, + Attacking, HealthSource, Stats, + }, + state::{DeltaTime, Uid}, +}; +use log::warn; +use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; + +/// This system is responsible for handling accepted inputs like moving or attacking +pub struct Sys; +impl<'a> System<'a> for Sys { + type SystemData = ( + Entities<'a>, + ReadStorage<'a, Uid>, + Read<'a, DeltaTime>, + ReadStorage<'a, Pos>, + WriteStorage<'a, Vel>, + ReadStorage<'a, Ori>, + WriteStorage<'a, Attacking>, + WriteStorage<'a, Stats>, + WriteStorage<'a, ForceUpdate>, + ); + + fn run( + &mut self, + ( + entities, + uids, + dt, + positions, + mut velocities, + orientations, + mut attackings, + mut stats, + mut force_updates, + ): Self::SystemData, + ) { + // Attacks + (&entities, &uids, &positions, &orientations, &mut attackings) + .join() + .filter_map(|(entity, uid, pos, ori, mut attacking)| { + if !attacking.applied { + // Go through all other entities + for (b, pos_b, mut vel_b, mut stat_b) in + (&entities, &positions, &mut velocities, &mut stats).join() + { + // Check if it is a hit + if entity != b + && !stat_b.is_dead + && pos.0.distance_squared(pos_b.0) < 50.0 + && ori.0.angle_between(pos_b.0 - pos.0).to_degrees() < 70.0 + { + // Deal damage + stat_b.hp.change_by(-10, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon + vel_b.0 += (pos_b.0 - pos.0).normalized() * 10.0; + vel_b.0.z = 15.0; + if let Err(err) = force_updates.insert(b, ForceUpdate) { + warn!("Inserting ForceUpdate for an entity failed: {:?}", err); + } + } + } + attacking.applied = true; + } + + if attacking.time > 0.5 { + Some(entity) + } else { + attacking.time += dt.0; + None + } + }) + .collect::>() + .into_iter() + .for_each(|e| { + attackings.remove(e); + }); + } +} diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 921c4bff23..d32cb7eae4 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -1,16 +1,11 @@ use crate::{ comp::{ phys::{ForceUpdate, Ori, Pos, Vel}, - Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, MoveDir, - OnGround, Respawning, Stats, + Attacking, Controller, Gliding, Jumping, MoveDir, OnGround, Respawning, Stats, }, - state::{DeltaTime, Uid}, - terrain::TerrainMap, - vol::{ReadVol, Vox}, + state::DeltaTime, }; -use log::warn; -use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; -use vek::*; +use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; /// This system is responsible for validating controller inputs pub struct Sys; @@ -20,7 +15,6 @@ impl<'a> System<'a> for Sys { Read<'a, DeltaTime>, ReadStorage<'a, Controller>, ReadStorage<'a, Stats>, - ReadExpect<'a, TerrainMap>, ReadStorage<'a, Pos>, WriteStorage<'a, Vel>, WriteStorage<'a, Ori>, @@ -40,7 +34,6 @@ impl<'a> System<'a> for Sys { dt, controllers, stats, - terrain, positions, mut velocities, mut orientations, @@ -50,10 +43,21 @@ impl<'a> System<'a> for Sys { mut attackings, mut respawns, mut glidings, - mut force_updates, + force_updates, ): Self::SystemData, ) { - for (entity, controller, stats, pos, mut vel, mut ori, on_ground) in ( + for ( + entity, + controller, + stats, + pos, + mut vel, + mut ori, + on_ground, + mut attacking, + mut jumping, + mut gliding, + ) in ( &entities, &controllers, &stats, @@ -61,6 +65,9 @@ impl<'a> System<'a> for Sys { &mut velocities, &mut orientations, on_grounds.maybe(), + attackings.maybe(), + jumpings.maybe(), + glidings.maybe(), ) .join() { @@ -73,10 +80,10 @@ impl<'a> System<'a> for Sys { } // Glide - if controller.glide && on_ground.is_none() && attackings.get(entity).is_none() { - glidings.insert(entity, Gliding); + if controller.glide && on_ground.is_none() && attacking.is_none() { + gliding = Some(&Gliding); } else { - glidings.remove(entity); + gliding = None } // Move dir @@ -90,18 +97,15 @@ impl<'a> System<'a> for Sys { ); // Attack - if controller.attack - && attackings.get(entity).is_none() - && glidings.get(entity).is_none() - { - attackings.insert(entity, Attacking::start()); + if controller.attack && attacking.is_none() && gliding.is_none() { + attacking = Some(&Attacking::start()); } // Jump - if on_grounds.get(entity).is_some() && controller.jump && vel.0.z <= 0.0 { - jumpings.insert(entity, Jumping); + if on_ground.is_some() && controller.jump && vel.0.z <= 0.0 { + jumping = Some(&Jumping); } else { - jumpings.remove(entity); + jumping = None; } } } diff --git a/common/src/sys/inputs.rs b/common/src/sys/inputs.rs deleted file mode 100644 index 702328de87..0000000000 --- a/common/src/sys/inputs.rs +++ /dev/null @@ -1,151 +0,0 @@ -use crate::{ - comp::{ - phys::{ForceUpdate, Ori, Pos, Vel}, - Animation, AnimationInfo, Attacking, Gliding, HealthSource, Jumping, MoveDir, OnGround, - Respawning, Stats, - }, - state::{DeltaTime, Uid}, - terrain::TerrainMap, - vol::{ReadVol, Vox}, -}; -use log::warn; -use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; -use vek::*; - -const HUMANOID_ACCEL: f32 = 100.0; -const HUMANOID_SPEED: f32 = 500.0; -const HUMANOID_AIR_ACCEL: f32 = 10.0; -const HUMANOID_AIR_SPEED: f32 = 100.0; -const HUMANOID_JUMP_ACCEL: f32 = 16.0; -const GLIDE_ACCEL: f32 = 15.0; -const GLIDE_SPEED: f32 = 45.0; -// Gravity is 9.81 * 4, so this makes gravity equal to .15 -const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; - -/// This system is responsible for handling accepted inputs like moving or attacking -pub struct Sys; -impl<'a> System<'a> for Sys { - type SystemData = ( - Entities<'a>, - ReadStorage<'a, Uid>, - Read<'a, DeltaTime>, - ReadExpect<'a, TerrainMap>, - ReadStorage<'a, Pos>, - ReadStorage<'a, OnGround>, - ReadStorage<'a, MoveDir>, - WriteStorage<'a, Vel>, - WriteStorage<'a, Ori>, - WriteStorage<'a, AnimationInfo>, - WriteStorage<'a, Stats>, - WriteStorage<'a, Respawning>, - WriteStorage<'a, Jumping>, - WriteStorage<'a, Gliding>, - WriteStorage<'a, Attacking>, - WriteStorage<'a, ForceUpdate>, - ); - - fn run( - &mut self, - ( - entities, - uids, - dt, - terrain, - positions, - on_grounds, - move_dirs, - mut velocities, - mut orientations, - mut animation_infos, - mut stats, - mut respawnings, - mut jumpings, - glidings, - mut attackings, - mut force_updates, - ): Self::SystemData, - ) { - // Attacks - (&entities, &uids, &positions, &orientations, &mut attackings) - .join() - .filter_map(|(entity, uid, pos, ori, mut attacking)| { - if !attacking.applied { - // Go through all other entities - for (b, pos_b, stat_b, mut vel_b) in - (&entities, &positions, &mut stats, &mut velocities).join() - { - // Check if it is a hit - if entity != b - && !stat_b.is_dead - && pos.0.distance_squared(pos_b.0) < 50.0 - && ori.0.angle_between(pos_b.0 - pos.0).to_degrees() < 70.0 - { - // Deal damage - stat_b.hp.change_by(-10, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon - vel_b.0 += (pos_b.0 - pos.0).normalized() * 10.0; - vel_b.0.z = 15.0; - if let Err(err) = force_updates.insert(b, ForceUpdate) { - warn!("Inserting ForceUpdate for an entity failed: {:?}", err); - } - } - } - attacking.applied = true; - } - - if attacking.time > 0.5 { - Some(entity) - } else { - attacking.time += dt.0; - None - } - }) - .collect::>() - .into_iter() - .for_each(|e| { - attackings.remove(e); - }); - - // Apply movement inputs - for (entity, mut vel, mut ori, on_ground, move_dir, jumping, gliding) in ( - &entities, - &mut velocities, - &mut orientations, - on_grounds.maybe(), - move_dirs.maybe(), - jumpings.maybe(), - glidings.maybe(), - ) - .join() - { - // Move player according to move_dir - if let Some(move_dir) = move_dir { - vel.0 += Vec2::broadcast(dt.0) - * move_dir.0 - * match (on_ground.is_some(), gliding.is_some()) { - (true, false) if vel.0.magnitude() < HUMANOID_SPEED => HUMANOID_ACCEL, - (false, true) if vel.0.magnitude() < GLIDE_SPEED => GLIDE_ACCEL, - (false, false) if vel.0.magnitude() < HUMANOID_AIR_SPEED => { - HUMANOID_AIR_ACCEL - } - _ => 0.0, - }; - } - - // Jump - if jumping.is_some() { - vel.0.z = HUMANOID_JUMP_ACCEL; - } - - // Glide - if gliding.is_some() && vel.0.magnitude() < GLIDE_SPEED && vel.0.z < 0.0 { - let anti_grav = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; - vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); - } - - // Set direction based on velocity - if vel.0.magnitude_squared() != 0.0 { - ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); - } - } - } -} diff --git a/common/src/sys/mod.rs b/common/src/sys/mod.rs index 97861dea9f..65b24f12fa 100644 --- a/common/src/sys/mod.rs +++ b/common/src/sys/mod.rs @@ -1,7 +1,7 @@ pub mod agent; pub mod animation; +pub mod combat; pub mod controller; -pub mod inputs; pub mod phys; mod stats; @@ -12,7 +12,7 @@ use specs::DispatcherBuilder; const AGENT_SYS: &str = "agent_sys"; const CONTROLLER_SYS: &str = "controller_sys"; const PHYS_SYS: &str = "phys_sys"; -const INPUTS_SYS: &str = "inputs_sys"; +const COMBAT_SYS: &str = "combat_sys"; const ANIMATION_SYS: &str = "animation_sys"; const STATS_SYS: &str = "stats_sys"; @@ -20,7 +20,7 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) { dispatch_builder.add(agent::Sys, AGENT_SYS, &[]); dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[]); dispatch_builder.add(phys::Sys, PHYS_SYS, &[]); - dispatch_builder.add(inputs::Sys, INPUTS_SYS, &[]); + dispatch_builder.add(combat::Sys, COMBAT_SYS, &[]); dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[]); - dispatch_builder.add(stats::Sys, STATS_SYS, &[INPUTS_SYS]); + dispatch_builder.add(stats::Sys, STATS_SYS, &[COMBAT_SYS]); } diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 270f276964..1fa7d7c848 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -1,7 +1,7 @@ use crate::{ comp::{ - phys::{Pos, Vel}, - OnGround, Stats, + phys::{Ori, Pos, Vel}, + Gliding, Jumping, MoveDir, OnGround, Stats, }, state::DeltaTime, terrain::TerrainMap, @@ -13,6 +13,15 @@ use vek::*; const GRAVITY: f32 = 9.81 * 4.0; const FRIC_GROUND: f32 = 0.15; const FRIC_AIR: f32 = 0.015; +const HUMANOID_ACCEL: f32 = 100.0; +const HUMANOID_SPEED: f32 = 500.0; +const HUMANOID_AIR_ACCEL: f32 = 10.0; +const HUMANOID_AIR_SPEED: f32 = 100.0; +const HUMANOID_JUMP_ACCEL: f32 = 16.0; +const GLIDE_ACCEL: f32 = 15.0; +const GLIDE_SPEED: f32 = 45.0; +// Gravity is 9.81 * 4, so this makes gravity equal to .15 +const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; // Integrates forces, calculates the new velocity based off of the old velocity // dt = delta time @@ -35,30 +44,89 @@ fn integrate_forces(dt: f32, mut lv: Vec3, damp: f32) -> Vec3 { lv } -/// This system applies forces and calculates new positions and velocities +/// This system applies forces and calculates new positions and velocities. pub struct Sys; impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, ReadExpect<'a, TerrainMap>, Read<'a, DeltaTime>, - ReadStorage<'a, Stats>, + WriteStorage<'a, OnGround>, WriteStorage<'a, Pos>, WriteStorage<'a, Vel>, - WriteStorage<'a, OnGround>, + WriteStorage<'a, Ori>, + ReadStorage<'a, MoveDir>, + ReadStorage<'a, Jumping>, + ReadStorage<'a, Gliding>, + WriteStorage<'a, Stats>, ); fn run( &mut self, - (entities, terrain, dt, stats, mut positions, mut velocities, mut on_grounds): Self::SystemData, + ( + entities, + terrain, + dt, + mut on_grounds, + mut positions, + mut velocities, + mut orientations, + move_dirs, + jumpings, + glidings, + stats, + ): Self::SystemData, ) { - for (entity, stats, pos, vel) in (&entities, &stats, &mut positions, &mut velocities).join() + // Apply movement inputs + for (entity, mut pos, mut vel, mut ori, mut on_ground, move_dir, jumping, gliding, stats) in + ( + &entities, + &mut positions, + &mut velocities, + &mut orientations, + on_grounds.maybe(), + move_dirs.maybe(), + jumpings.maybe(), + glidings.maybe(), + &stats, + ) + .join() { - // Disable while dead TODO: Replace with client states + // Disable while dead TODO: Replace with client states? if stats.is_dead { continue; } + // Move player according to move_dir + if let Some(move_dir) = move_dir { + vel.0 += Vec2::broadcast(dt.0) + * move_dir.0 + * match (on_ground.is_some(), gliding.is_some()) { + (true, false) if vel.0.magnitude() < HUMANOID_SPEED => HUMANOID_ACCEL, + (false, true) if vel.0.magnitude() < GLIDE_SPEED => GLIDE_ACCEL, + (false, false) if vel.0.magnitude() < HUMANOID_AIR_SPEED => { + HUMANOID_AIR_ACCEL + } + _ => 0.0, + }; + } + + // Jump + if jumping.is_some() { + vel.0.z = HUMANOID_JUMP_ACCEL; + } + + // Glide + if gliding.is_some() && vel.0.magnitude() < GLIDE_SPEED && vel.0.z < 0.0 { + let lift = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; + vel.0.z += dt.0 * lift * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); + } + + // Set direction based on velocity + if vel.0.magnitude_squared() != 0.0 { + ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); + } + // Movement pos.0 += vel.0 * dt.0; @@ -69,15 +137,15 @@ impl<'a> System<'a> for Sys { .unwrap_or(false) && vel.0.z <= 0.0 { - on_grounds.insert(entity, OnGround); + on_ground = Some(&OnGround); } else { - on_grounds.remove(entity); + on_ground = None; } // Integrate forces // Friction is assumed to be a constant dependent on location let friction = 50.0 - * if on_grounds.get(entity).is_some() { + * if on_ground.is_some() { FRIC_GROUND } else { FRIC_AIR diff --git a/diff b/diff deleted file mode 100644 index 4f91ddd46b..0000000000 --- a/diff +++ /dev/null @@ -1,578 +0,0 @@ -diff --git a/chat-cli/src/main.rs b/chat-cli/src/main.rs -index f68a5b4..8ebd46f 100644 ---- a/chat-cli/src/main.rs -+++ b/chat-cli/src/main.rs -@@ -29,7 +29,7 @@ fn main() { - client.send_chat("Hello!".to_string()); - - loop { -- let events = match client.tick(comp::Control::default(), clock.get_last_delta()) { -+ let events = match client.tick(comp::Controller::default(), clock.get_last_delta()) { - Ok(events) => events, - Err(err) => { - error!("Error: {:?}", err); -diff --git a/client/src/lib.rs b/client/src/lib.rs -index f491359..ee3b62e 100644 ---- a/client/src/lib.rs -+++ b/client/src/lib.rs -@@ -154,52 +154,6 @@ impl Client { - self.postbox.send_message(ClientMsg::Chat(msg)) - } - -- /// Jump locally, the new positions will be synced to the server -- #[allow(dead_code)] -- pub fn jump(&mut self) { -- if self.client_state != ClientState::Character { -- return; -- } -- self.state.write_component(self.entity, comp::Jumping); -- } -- -- /// Start to glide locally, animation will be synced -- #[allow(dead_code)] -- pub fn glide(&mut self, state: bool) { -- if self.client_state != ClientState::Character { -- return; -- } -- if state { -- self.state.write_component(self.entity, comp::Gliding); -- } else { -- self.state -- .ecs_mut() -- .write_storage::() -- .remove(self.entity); -- } -- } -- -- /// Start to attack -- #[allow(dead_code)] -- pub fn attack(&mut self) { -- if self.client_state != ClientState::Character { -- return; -- } -- // TODO: Test if attack is possible using timeout -- self.state -- .write_component(self.entity, comp::Attacking::start()); -- self.postbox.send_message(ClientMsg::Attack); -- } -- -- /// Tell the server the client wants to respawn. -- #[allow(dead_code)] -- pub fn respawn(&mut self) { -- if self.client_state != ClientState::Dead { -- return; -- } -- self.postbox.send_message(ClientMsg::Respawn) -- } -- - /// Remove all cached terrain - #[allow(dead_code)] - pub fn clear_terrain(&mut self) { -@@ -209,7 +163,7 @@ impl Client { - - /// Execute a single client tick, handle input and update the game state by the given duration. - #[allow(dead_code)] -- pub fn tick(&mut self, control: comp::Control, dt: Duration) -> Result, Error> { -+ pub fn tick(&mut self, controller: comp::Controller, dt: Duration) -> Result, Error> { - // This tick function is the centre of the Veloren universe. Most client-side things are - // managed from here, and as such it's important that it stays organised. Please consult - // the core developers before making significant changes to this code. Here is the -@@ -226,10 +180,8 @@ impl Client { - - // 1) Handle input from frontend. - // Pass character actions from frontend input to the player's entity. -- // TODO: Only do this if the entity already has a Inputs component! -- if self.client_state == ClientState::Character { -- self.state.write_component(self.entity, control.clone()); -- } -+ self.state.write_component(self.entity, controller.clone()); -+ self.postbox.send_message(ClientMsg::Controller(controller)); - - // 2) Build up a list of events for this frame, to be passed to the frontend. - let mut frontend_events = Vec::new(); -diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs -index ce55110..27b7b75 100644 ---- a/common/src/comp/inputs.rs -+++ b/common/src/comp/inputs.rs -@@ -1,11 +1,6 @@ - use specs::{Component, FlaggedStorage, NullStorage, VecStorage}; - use vek::*; - --#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] --pub struct Control { -- pub move_dir: Vec2, --} -- - #[derive(Clone, Debug, Default, Serialize, Deserialize)] - pub struct Respawning; - -@@ -14,16 +9,13 @@ pub struct Attacking { - pub time: f32, - pub applied: bool, - } -+ - #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] - pub struct Jumping; - - #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] - pub struct Gliding; - --impl Component for Control { -- type Storage = VecStorage; --} -- - impl Component for Respawning { - type Storage = NullStorage; - } -@@ -36,6 +28,7 @@ impl Attacking { - } - } - } -+ - impl Component for Attacking { - type Storage = FlaggedStorage>; - } -diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs -index ee351db..2ca2e12 100644 ---- a/common/src/comp/mod.rs -+++ b/common/src/comp/mod.rs -@@ -2,6 +2,7 @@ pub mod actor; - pub mod agent; - pub mod animation; - pub mod inputs; -+pub mod controller; - pub mod phys; - pub mod player; - pub mod stats; -@@ -15,8 +16,8 @@ pub use actor::QuadrupedMediumBody; - pub use agent::Agent; - pub use animation::Animation; - pub use animation::AnimationInfo; -+pub use controller::Controller; - pub use inputs::Attacking; --pub use inputs::Control; - pub use inputs::Gliding; - pub use inputs::Jumping; - pub use inputs::Respawning; -diff --git a/common/src/msg/client.rs b/common/src/msg/client.rs -index aa765d0..1187831 100644 ---- a/common/src/msg/client.rs -+++ b/common/src/msg/client.rs -@@ -11,8 +11,7 @@ pub enum ClientMsg { - name: String, - body: comp::Body, - }, -- Attack, -- Respawn, -+ Controller(comp::Controller), - RequestState(ClientState), - SetViewDistance(u32), - Ping, -diff --git a/common/src/state.rs b/common/src/state.rs -index 9357c60..630f7c8 100644 ---- a/common/src/state.rs -+++ b/common/src/state.rs -@@ -110,9 +110,9 @@ impl State { - ecs.register::(); - ecs.register::(); - ecs.register::(); -+ ecs.register::(); - - // Register client-local components -- ecs.register::(); - ecs.register::(); - - // Register server-local components -diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs -index 55e845c..0e5e2f8 100644 ---- a/common/src/sys/agent.rs -+++ b/common/src/sys/agent.rs -@@ -1,4 +1,4 @@ --use crate::comp::{phys::Pos, Agent, Attacking, Control, Jumping}; -+use crate::comp::{phys::Pos, Agent, Attacking, Controller, Jumping}; - use log::warn; - use rand::{seq::SliceRandom, thread_rng}; - use specs::{Entities, Join, ReadStorage, System, WriteStorage}; -@@ -12,17 +12,17 @@ impl<'a> System<'a> for Sys { - Entities<'a>, - WriteStorage<'a, Agent>, - ReadStorage<'a, Pos>, -- WriteStorage<'a, Control>, -+ WriteStorage<'a, Controller>, - WriteStorage<'a, Jumping>, - WriteStorage<'a, Attacking>, - ); - - fn run( - &mut self, -- (entities, mut agents, positions, mut controls, mut jumps, mut attacks): Self::SystemData, -+ (entities, mut agents, positions, mut controllers, mut jumps, mut attacks): Self::SystemData, - ) { -- for (entity, agent, pos, control) in -- (&entities, &mut agents, &positions, &mut controls).join() -+ for (entity, agent, pos, controller) in -+ (&entities, &mut agents, &positions, &mut controllers).join() - { - match agent { - Agent::Wanderer(bearing) => { -@@ -32,7 +32,7 @@ impl<'a> System<'a> for Sys { - - pos.0 * 0.0002; - - if bearing.magnitude_squared() != 0.0 { -- control.move_dir = bearing.normalized(); -+ controller.move_dir = bearing.normalized(); - } - } - Agent::Pet { target, offset } => { -@@ -49,7 +49,7 @@ impl<'a> System<'a> for Sys { - - // Move towards the target. - let dist: f32 = Vec2::from(tgt_pos - pos.0).magnitude(); -- control.move_dir = if dist > 5.0 { -+ controller.move_dir = if dist > 5.0 { - Vec2::from(tgt_pos - pos.0).normalized() - } else if dist < 1.5 && dist > 0.0 { - Vec2::from(pos.0 - tgt_pos).normalized() -@@ -57,7 +57,7 @@ impl<'a> System<'a> for Sys { - Vec2::zero() - }; - } -- _ => control.move_dir = Vec2::zero(), -+ _ => controller.move_dir = Vec2::zero(), - } - - // Change offset occasionally. -@@ -72,7 +72,7 @@ impl<'a> System<'a> for Sys { - Some(tgt_pos) => { - let dist = Vec2::::from(tgt_pos.0 - pos.0).magnitude(); - if dist < 2.0 { -- control.move_dir = Vec2::zero(); -+ controller.move_dir = Vec2::zero(); - - if rand::random::() < 0.2 { - attacks -@@ -82,7 +82,7 @@ impl<'a> System<'a> for Sys { - - false - } else if dist < 60.0 { -- control.move_dir = -+ controller.move_dir = - Vec2::::from(tgt_pos.0 - pos.0).normalized() * 0.96; - - false -@@ -91,7 +91,7 @@ impl<'a> System<'a> for Sys { - } - } - None => { -- control.move_dir = Vec2::one(); -+ controller.move_dir = Vec2::one(); - true - } - }; -diff --git a/common/src/sys/inputs.rs b/common/src/sys/inputs.rs -index 288a0e0..6cadba5 100644 ---- a/common/src/sys/inputs.rs -+++ b/common/src/sys/inputs.rs -@@ -1,7 +1,7 @@ - use crate::{ - comp::{ - phys::{ForceUpdate, Ori, Pos, Vel}, -- Animation, AnimationInfo, Attacking, Control, Gliding, HealthSource, Jumping, Stats, -+ Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, Stats, - }, - state::{DeltaTime, Uid}, - terrain::TerrainMap, -@@ -13,17 +13,6 @@ use vek::*; - - // Basic ECS AI agent system - pub struct Sys; -- --const HUMANOID_ACCEL: f32 = 100.0; --const HUMANOID_SPEED: f32 = 500.0; --const HUMANOID_AIR_ACCEL: f32 = 10.0; --const HUMANOID_AIR_SPEED: f32 = 100.0; --const HUMANOID_JUMP_ACCEL: f32 = 16.0; --const GLIDE_ACCEL: f32 = 15.0; --const GLIDE_SPEED: f32 = 45.0; --// Gravity is 9.81 * 4, so this makes gravity equal to .15 --const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95; -- - impl<'a> System<'a> for Sys { - type SystemData = ( - Entities<'a>, -@@ -35,7 +24,7 @@ impl<'a> System<'a> for Sys { - WriteStorage<'a, Ori>, - WriteStorage<'a, AnimationInfo>, - WriteStorage<'a, Stats>, -- ReadStorage<'a, Control>, -+ ReadStorage<'a, Controller>, - WriteStorage<'a, Jumping>, - WriteStorage<'a, Gliding>, - WriteStorage<'a, Attacking>, -@@ -54,67 +43,31 @@ impl<'a> System<'a> for Sys { - mut orientations, - mut animation_infos, - mut stats, -- controls, -+ controllers, - mut jumps, - glides, - mut attacks, - mut force_updates, - ): Self::SystemData, - ) { -- for (entity, pos, control, stats, mut ori, mut vel) in ( -+ for (entity, pos, controller, stats, mut ori, mut vel) in ( - &entities, - &positions, -- &controls, -+ &controllers, - &stats, - &mut orientations, - &mut velocities, - ) - .join() - { -- // Disable while dead TODO: Replace with client states -- if stats.is_dead { -- continue; -- } -- - let on_ground = terrain - .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) - .map(|vox| !vox.is_empty()) - .unwrap_or(false) - && vel.0.z <= 0.0; - -- let gliding = glides.get(entity).is_some() && vel.0.z < 0.0; -- let move_dir = if control.move_dir.magnitude() > 1.0 { -- control.move_dir.normalized() -- } else { -- control.move_dir -- }; -- -- if on_ground { -- // Move player according to move_dir -- if vel.0.magnitude() < HUMANOID_SPEED { -- vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_ACCEL; -- } -- -- // Jump -- if jumps.get(entity).is_some() && vel.0.z <= 0.0 { -- vel.0.z = HUMANOID_JUMP_ACCEL; -- jumps.remove(entity); -- } -- } else if gliding && vel.0.magnitude() < GLIDE_SPEED { -- let anti_grav = GLIDE_ANTIGRAV + vel.0.z.powf(2.0) * 0.2; -- vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); -- vel.0 += Vec2::broadcast(dt.0) * move_dir * GLIDE_ACCEL; -- } else if vel.0.magnitude() < HUMANOID_AIR_SPEED { -- vel.0 += Vec2::broadcast(dt.0) * move_dir * HUMANOID_AIR_ACCEL; -- } -- -- // Set direction based on velocity -- if vel.0.magnitude_squared() != 0.0 { -- ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); -- } -- - let animation = if on_ground { -- if control.move_dir.magnitude() > 0.01 { -+ if controller.move_dir.magnitude() > 0.01 { - Animation::Run - } else if attacks.get(entity).is_some() { - Animation::Attack -@@ -149,6 +102,7 @@ impl<'a> System<'a> for Sys { - (&entities, &uids, &positions, &orientations, &mut attacks).join() - { - if !attacking.applied { -+ dbg!(); - for (b, pos_b, stat_b, mut vel_b) in - (&entities, &positions, &mut stats, &mut velocities).join() - { -diff --git a/common/src/sys/mod.rs b/common/src/sys/mod.rs -index da6f629..e6a5917 100644 ---- a/common/src/sys/mod.rs -+++ b/common/src/sys/mod.rs -@@ -1,6 +1,7 @@ - pub mod actions; - pub mod agent; - pub mod animation; -+pub mod controller; - pub mod inputs; - pub mod phys; - mod stats; -@@ -10,6 +11,7 @@ use specs::DispatcherBuilder; - - // System names - const AGENT_SYS: &str = "agent_sys"; -+const CONTROLLER_SYS: &str = "controller_sys"; - const INPUTS_SYS: &str = "inputs_sys"; - const ACTIONS_SYS: &str = "actions_sys"; - const PHYS_SYS: &str = "phys_sys"; -@@ -20,6 +22,7 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) { - dispatch_builder.add(agent::Sys, AGENT_SYS, &[]); - dispatch_builder.add(phys::Sys, PHYS_SYS, &[]); - dispatch_builder.add(actions::Sys, ACTIONS_SYS, &[]); -+ dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[]); - dispatch_builder.add(inputs::Sys, INPUTS_SYS, &[]); - dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[]); - dispatch_builder.add(stats::Sys, STATS_SYS, &[INPUTS_SYS]); -diff --git a/server/src/lib.rs b/server/src/lib.rs -index ead806c..6260f0a 100644 ---- a/server/src/lib.rs -+++ b/server/src/lib.rs -@@ -145,7 +145,7 @@ impl Server { - .with(pos) - .with(comp::phys::Vel(Vec3::zero())) - .with(comp::phys::Ori(Vec3::unit_y())) -- .with(comp::Control::default()) -+ .with(comp::Controller::default()) - .with(comp::AnimationInfo::default()) - .with(comp::Actor::Character { name, body }) - .with(comp::Stats::default()) -@@ -164,6 +164,7 @@ impl Server { - state.write_component(entity, comp::Actor::Character { name, body }); - state.write_component(entity, comp::Stats::default()); - state.write_component(entity, comp::AnimationInfo::default()); -+ state.write_component(entity, comp::Controller::default()); - state.write_component(entity, comp::phys::Pos(spawn_point)); - state.write_component(entity, comp::phys::Vel(Vec3::zero())); - state.write_component(entity, comp::phys::Ori(Vec3::unit_y())); -@@ -492,25 +493,16 @@ impl Server { - } - ClientState::Pending => {} - }, -- ClientMsg::Attack => match client.client_state { -- ClientState::Character => { -- if state -- .ecs() -- .read_storage::() -- .get(entity) -- .is_none() -- { -- state.write_component(entity, comp::Attacking::start()); -- } -+ ClientMsg::Controller(controller) => match client.client_state { -+ ClientState::Connected | ClientState::Registered | ClientState::Spectator => { -+ client.error_state(RequestStateError::Impossible) - } -- _ => client.error_state(RequestStateError::Impossible), -- }, -- ClientMsg::Respawn => match client.client_state { -- ClientState::Dead => { -- state.write_component(entity, comp::Respawning); -+ ClientState::Dead -+ | ClientState::Character => { -+ state.write_component(entity, controller); - } -- _ => client.error_state(RequestStateError::Impossible), -- }, -+ ClientState::Pending => {} -+ } - ClientMsg::Chat(msg) => match client.client_state { - ClientState::Connected => { - client.error_state(RequestStateError::Impossible) -diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs -index 2192ce7..1a3e3e3 100644 ---- a/voxygen/src/menu/char_selection/mod.rs -+++ b/voxygen/src/menu/char_selection/mod.rs -@@ -110,7 +110,7 @@ impl PlayState for CharSelectionState { - if let Err(err) = self - .client - .borrow_mut() -- .tick(comp::Control::default(), clock.get_last_delta()) -+ .tick(comp::Controller::default(), clock.get_last_delta()) - { - error!("Failed to tick the scene: {:?}", err); - return PlayStateResult::Pop; -diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs -index 913e421..bd5d876 100644 ---- a/voxygen/src/session.rs -+++ b/voxygen/src/session.rs -@@ -18,8 +18,9 @@ const FPS: u64 = 60; - pub struct SessionState { - scene: Scene, - client: Rc>, -- key_state: KeyState, - hud: Hud, -+ key_state: KeyState, -+ controller: comp::Controller, - } - - /// Represents an active game session (i.e., the one being played). -@@ -32,6 +33,7 @@ impl SessionState { - scene, - client, - key_state: KeyState::new(), -+ controller: comp::Controller::default(), - hud: Hud::new(window), - } - } -@@ -47,21 +49,11 @@ const BG_COLOR: Rgba = Rgba { - - impl SessionState { - /// Tick the session (and the client attached to it). -- pub fn tick(&mut self, dt: Duration) -> Result<(), Error> { -- // Calculate the movement input vector of the player from the current key presses -- // and the camera direction. -- let ori = self.scene.camera().get_orientation(); -- let unit_vecs = ( -- Vec2::new(ori[0].cos(), -ori[0].sin()), -- Vec2::new(ori[0].sin(), ori[0].cos()), -- ); -- let dir_vec = self.key_state.dir_vec(); -- let move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1]; -- -+ fn tick(&mut self, dt: Duration) -> Result<(), Error> { - for event in self - .client - .borrow_mut() -- .tick(comp::Control { move_dir }, dt)? -+ .tick(self.controller.clone(), dt)? - { - match event { - client::Event::Chat(msg) => { -@@ -121,19 +113,19 @@ impl PlayState for SessionState { - Event::Close => { - return PlayStateResult::Shutdown; - } -- Event::InputUpdate(GameInput::Attack, true) => { -- self.client.borrow_mut().attack(); -- self.client.borrow_mut().respawn(); -+ Event::InputUpdate(GameInput::Attack, state) => { -+ self.controller.attack = state; -+ self.controller.respawn = state; // TODO: Don't do both - } -- Event::InputUpdate(GameInput::Jump, true) => { -- self.client.borrow_mut().jump(); -+ Event::InputUpdate(GameInput::Jump, state) => { -+ self.controller.jump = state; - } - Event::InputUpdate(GameInput::MoveForward, state) => self.key_state.up = state, - Event::InputUpdate(GameInput::MoveBack, state) => self.key_state.down = state, - Event::InputUpdate(GameInput::MoveLeft, state) => self.key_state.left = state, - Event::InputUpdate(GameInput::MoveRight, state) => self.key_state.right = state, - Event::InputUpdate(GameInput::Glide, state) => { -- self.client.borrow_mut().glide(state) -+ self.controller.glide = state; - } - - // Pass all other events to the scene -@@ -143,6 +135,17 @@ impl PlayState for SessionState { - } - } - -+ // Calculate the movement input vector of the player from the current key presses -+ // and the camera direction. -+ let ori = self.scene.camera().get_orientation(); -+ let unit_vecs = ( -+ Vec2::new(ori[0].cos(), -ori[0].sin()), -+ Vec2::new(ori[0].sin(), ori[0].cos()), -+ ); -+ let dir_vec = self.key_state.dir_vec(); -+ self.controller.move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1]; -+ -+ - // Perform an in-game tick. - if let Err(err) = self.tick(clock.get_last_delta()) { - error!("Failed to tick the scene: {:?}", err); From 4de5489367c490261c72d50d7438013f904cdd56 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Tue, 11 Jun 2019 00:08:55 -0400 Subject: [PATCH 04/19] groundwork for role, crun, cidle --- common/src/comp/animation.rs | 3 + common/src/comp/controller.rs | 5 +- common/src/comp/inputs.rs | 53 ++++++++++++++ common/src/comp/mod.rs | 3 + common/src/msg/ecs_packet.rs | 8 +++ common/src/state.rs | 3 + common/src/sys/animation.rs | 15 +++- common/src/sys/controller.rs | 16 ++++- common/src/sys/phys.rs | 20 +++++- voxygen/src/anim/character/cidle.rs | 104 ++++++++++++++++++++++++++++ voxygen/src/anim/character/crun.rs | 97 ++++++++++++++++++++++++++ voxygen/src/anim/character/mod.rs | 7 ++ voxygen/src/anim/character/roll.rs | 98 ++++++++++++++++++++++++++ voxygen/src/scene/figure.rs | 15 ++++ voxygen/src/session.rs | 9 +++ voxygen/src/settings.rs | 8 +++ voxygen/src/window.rs | 7 ++ 17 files changed, 463 insertions(+), 8 deletions(-) create mode 100644 voxygen/src/anim/character/cidle.rs create mode 100644 voxygen/src/anim/character/crun.rs create mode 100644 voxygen/src/anim/character/roll.rs diff --git a/common/src/comp/animation.rs b/common/src/comp/animation.rs index 85ec2e1453..d3e89dc18c 100644 --- a/common/src/comp/animation.rs +++ b/common/src/comp/animation.rs @@ -7,6 +7,9 @@ pub enum Animation { Jump, Gliding, Attack, + Roll, + Crun, + Cidle, } #[derive(Copy, Clone, Debug, Serialize, Deserialize)] diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs index 83383e5674..8e5fd5db4f 100644 --- a/common/src/comp/controller.rs +++ b/common/src/comp/controller.rs @@ -5,8 +5,11 @@ use vek::*; pub struct Controller { pub move_dir: Vec2, pub jump: bool, - pub glide: bool, pub attack: bool, + pub roll: bool, + pub crun: bool, + pub cidle: bool, + pub glide: bool, pub respawn: bool, } diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs index 1ae61033b8..c2afea0432 100644 --- a/common/src/comp/inputs.rs +++ b/common/src/comp/inputs.rs @@ -13,6 +13,24 @@ pub struct Attacking { pub applied: bool, } +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +pub struct Rolling { + pub time: f32, + pub applied: bool, +} + +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +pub struct Crunning { + pub time: f32, + pub applied: bool, +} + +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +pub struct Cidling { + pub time: f32, + pub applied: bool, +} + #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct OnGround; @@ -35,6 +53,32 @@ impl Attacking { } } +impl Rolling { + pub fn start() -> Self { + Self { + time: 0.0, + applied: false, + } + } +} + +impl Crunning { + pub fn start() -> Self { + Self { + time: 0.0, + applied: false, + } + } +} +impl Cidling { + pub fn start() -> Self { + Self { + time: 0.0, + applied: false, + } + } +} + impl Component for MoveDir { type Storage = VecStorage; } @@ -43,6 +87,15 @@ impl Component for Attacking { type Storage = FlaggedStorage>; } +impl Component for Rolling { + type Storage = FlaggedStorage>; +} +impl Component for Crunning { + type Storage = FlaggedStorage>; +} +impl Component for Cidling { + type Storage = FlaggedStorage>; +} impl Component for OnGround { type Storage = NullStorage; } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 92d785dd77..88af37d3cb 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -18,6 +18,9 @@ pub use animation::Animation; pub use animation::AnimationInfo; pub use controller::Controller; pub use inputs::Attacking; +pub use inputs::Rolling; +pub use inputs::Crunning; +pub use inputs::Cidling; pub use inputs::Gliding; pub use inputs::Jumping; pub use inputs::MoveDir; diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index 5d860ae85c..6918bfdf89 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -24,6 +24,10 @@ sphynx::sum_type! { Player(comp::Player), Stats(comp::Stats), Attacking(comp::Attacking), + Rolling(comp::Rolling), + Crunning(comp::Crunning), + Cidling(comp::Cidling), + } } // Automatically derive From for EcsCompPhantom @@ -38,6 +42,10 @@ sphynx::sum_type! { Player(PhantomData), Stats(PhantomData), Attacking(PhantomData), + Rolling(PhantomData), + Crunning(PhantomData), + Cidling(PhantomData), + } } impl sphynx::CompPacket for EcsCompPacket { diff --git a/common/src/state.rs b/common/src/state.rs index de959c47c4..dd01b34ac2 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -103,6 +103,9 @@ impl State { ecs.register_synced::(); ecs.register_synced::(); ecs.register_synced::(); // TODO: Don't send this to the client? + ecs.register_synced::(); // TODO: Don't send this to the client? + ecs.register_synced::(); // TODO: Don't send this to the client? + ecs.register_synced::(); // TODO: Don't send this to the client? ecs.register::(); // Register components synced by other means diff --git a/common/src/sys/animation.rs b/common/src/sys/animation.rs index 29d5b08d7a..ea7e617d38 100644 --- a/common/src/sys/animation.rs +++ b/common/src/sys/animation.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{phys, Animation, AnimationInfo, Attacking, Gliding, Jumping, OnGround}, + comp::{phys, Animation, AnimationInfo, Attacking, Rolling, Crunning, Cidling, Gliding, Jumping, OnGround}, state::DeltaTime, }; use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; @@ -15,20 +15,26 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Jumping>, ReadStorage<'a, Gliding>, ReadStorage<'a, Attacking>, + ReadStorage<'a, Rolling>, + ReadStorage<'a, Crunning>, + ReadStorage<'a, Cidling>, WriteStorage<'a, AnimationInfo>, ); fn run( &mut self, - (entities, dt, velocities, on_grounds, jumpings, glidings, attackings, mut animation_infos): Self::SystemData, + (entities, dt, velocities, on_grounds, jumpings, glidings, attackings, rollings, crunnings, cidlings, mut animation_infos): Self::SystemData, ) { - for (entity, vel, on_ground, jumping, gliding, attacking, mut animation_info) in ( + for (entity, vel, on_ground, jumping, gliding, attacking, rolling, crunning, cidling, mut animation_info) in ( &entities, &velocities, on_grounds.maybe(), jumpings.maybe(), glidings.maybe(), attackings.maybe(), + rollings.maybe(), + crunnings.maybe(), + cidlings.maybe(), &mut animation_infos, ) .join() @@ -52,6 +58,9 @@ impl<'a> System<'a> for Sys { (false, _, false, false) => Animation::Jump, (_, _, false, true) => Animation::Gliding, (_, _, true, false) => Animation::Attack, + (true, true, false, false) => Animation::Roll, + (_, true, false, false) => Animation::Crun, + (true, false, false, false) => Animation::Cidle, (_, _, true, true) => impossible_animation(), }; diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index d32cb7eae4..9a01134fae 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -1,7 +1,8 @@ use crate::{ comp::{ phys::{ForceUpdate, Ori, Pos, Vel}, - Attacking, Controller, Gliding, Jumping, MoveDir, OnGround, Respawning, Stats, + Animation, AnimationInfo, Attacking, Rolling, Crunning, Cidling, Controller, Gliding, HealthSource, Jumping, MoveDir, + OnGround, Respawning, Stats, }, state::DeltaTime, }; @@ -22,6 +23,9 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, OnGround>, WriteStorage<'a, Jumping>, WriteStorage<'a, Attacking>, + WriteStorage<'a, Rolling>, + WriteStorage<'a, Crunning>, + WriteStorage<'a, Cidling>, WriteStorage<'a, Respawning>, WriteStorage<'a, Gliding>, WriteStorage<'a, ForceUpdate>, @@ -41,6 +45,9 @@ impl<'a> System<'a> for Sys { mut on_grounds, mut jumpings, mut attackings, + mut rollings, + mut crunnings, + mut cidlings, mut respawns, mut glidings, force_updates, @@ -107,6 +114,13 @@ impl<'a> System<'a> for Sys { } else { jumping = None; } + + // Roll + if on_grounds.get(entity).is_some() && controller.roll { + rollings.insert(entity, Rolling::start()); + } else { + rollings.remove(entity); + } } } } diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 1fa7d7c848..a63837295d 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -1,7 +1,7 @@ use crate::{ comp::{ phys::{Ori, Pos, Vel}, - Gliding, Jumping, MoveDir, OnGround, Stats, + Gliding, Jumping, MoveDir, OnGround, Stats, Rolling, Cidling, Crunning, }, state::DeltaTime, terrain::TerrainMap, @@ -58,7 +58,10 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, MoveDir>, ReadStorage<'a, Jumping>, ReadStorage<'a, Gliding>, - WriteStorage<'a, Stats>, + ReadStorage<'a, Rolling>, + ReadStorage<'a, Crunning>, + ReadStorage<'a, Cidling>, + ReadStorage<'a, Stats>, ); fn run( @@ -74,11 +77,14 @@ impl<'a> System<'a> for Sys { move_dirs, jumpings, glidings, + rollings, + crunnings, + cidlings, stats, ): Self::SystemData, ) { // Apply movement inputs - for (entity, mut pos, mut vel, mut ori, mut on_ground, move_dir, jumping, gliding, stats) in + for (entity, mut pos, mut vel, mut ori, mut on_ground, move_dir, jumping, gliding, rolling, crunning, cidling, stats) in ( &entities, &mut positions, @@ -88,6 +94,9 @@ impl<'a> System<'a> for Sys { move_dirs.maybe(), jumpings.maybe(), glidings.maybe(), + rollings.maybe(), + crunnings.maybe(), + cidlings.maybe(), &stats, ) .join() @@ -122,6 +131,11 @@ impl<'a> System<'a> for Sys { vel.0.z += dt.0 * lift * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); } + // TODO: + if rolling.is_some() {} + if crunning.is_some() {} + if cidling.is_some() {} + // Set direction based on velocity if vel.0.magnitude_squared() != 0.0 { ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); diff --git a/voxygen/src/anim/character/cidle.rs b/voxygen/src/anim/character/cidle.rs new file mode 100644 index 0000000000..e8f44cd1f0 --- /dev/null +++ b/voxygen/src/anim/character/cidle.rs @@ -0,0 +1,104 @@ +use super::{super::Animation, CharacterSkeleton}; +use std::{f32::consts::PI, ops::Mul}; +use vek::*; + +pub struct CidleAnimation; + +impl Animation for CidleAnimation { + type Skeleton = CharacterSkeleton; + type Dependency = f64; + + fn update_skeleton( + skeleton: &Self::Skeleton, + global_time: f64, + anim_time: f64, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let wave_ultra_slow = (anim_time as f32 * 1.0 + PI).sin(); + let wave_ultra_slow_cos = (anim_time as f32 * 1.0 + PI).cos(); + + let head_look = Vec2::new( + ((global_time + anim_time) as f32 / 8.0) + .floor() + .mul(7331.0) + .sin() + * 0.5, + ((global_time + anim_time) as f32 / 8.0) + .floor() + .mul(1337.0) + .sin() + * 0.25, + ); + next.head.offset = Vec3::new(0.0, 2.0, 11.0 + wave_ultra_slow * 0.3); + next.head.ori = Quaternion::rotation_z(head_look.x) * Quaternion::rotation_x(head_look.y); + next.head.scale = Vec3::one(); + + next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_ultra_slow * 0.3); + next.chest.ori = Quaternion::rotation_x(0.0); + next.chest.scale = Vec3::one(); + + next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_ultra_slow * 0.3); + next.belt.ori = Quaternion::rotation_x(0.0); + next.belt.scale = Vec3::one(); + + next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_ultra_slow * 0.3); + next.shorts.ori = Quaternion::rotation_x(0.0); + next.shorts.scale = Vec3::one(); + + next.l_hand.offset = Vec3::new( + -7.5, + -2.0 + wave_ultra_slow_cos * 0.15, + 8.0 + wave_ultra_slow * 0.5, + ) / 11.0; + + next.l_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * 0.06); + next.l_hand.scale = Vec3::one() / 11.0; + + next.r_hand.offset = Vec3::new( + 7.5, + -2.0 + wave_ultra_slow_cos * 0.15, + 8.0 + wave_ultra_slow * 0.5, + ) / 11.0; + next.r_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * 0.06); + next.r_hand.scale = Vec3::one() / 11.; + + next.l_foot.offset = Vec3::new(-3.4, -0.1, 8.0); + next.l_foot.ori = Quaternion::identity(); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new(3.4, -0.1, 8.0); + next.r_foot.ori = Quaternion::identity(); + next.r_foot.scale = Vec3::one(); + + next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0); + next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + next.weapon.scale = Vec3::one(); + + next.l_shoulder.offset = Vec3::new(-10.0, -3.2, 2.5); + next.l_shoulder.ori = Quaternion::rotation_x(0.0); + next.l_shoulder.scale = Vec3::one() * 1.04; + + next.r_shoulder.offset = Vec3::new(0.0, -3.2, 2.5); + next.r_shoulder.ori = Quaternion::rotation_x(0.0); + next.r_shoulder.scale = Vec3::one() * 1.04; + + next.draw.offset = Vec3::new(0.0, 5.0, 0.0); + next.draw.ori = Quaternion::rotation_y(0.0); + next.draw.scale = Vec3::one() * 0.0; + + next.left_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.left_equip.ori = Quaternion::rotation_x(0.0);; + next.left_equip.scale = Vec3::one() * 0.0; + + next.right_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.right_equip.ori = Quaternion::rotation_x(0.0);; + next.right_equip.scale = Vec3::one() * 0.0; + + next.torso.offset = Vec3::new(0.0, -0.2, 0.1); + next.torso.ori = Quaternion::rotation_x(0.0); + next.torso.scale = Vec3::one() / 11.0; + + next + } +} diff --git a/voxygen/src/anim/character/crun.rs b/voxygen/src/anim/character/crun.rs new file mode 100644 index 0000000000..54b7c079a8 --- /dev/null +++ b/voxygen/src/anim/character/crun.rs @@ -0,0 +1,97 @@ +use super::{super::Animation, CharacterSkeleton}; +use std::ops::Mul; +use vek::*; + +pub struct CrunAnimation; + +impl Animation for CrunAnimation { + type Skeleton = CharacterSkeleton; + type Dependency = (f32, f64); + + fn update_skeleton( + skeleton: &Self::Skeleton, + (velocity, global_time): Self::Dependency, + anim_time: f64, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let wave = (anim_time as f32 * 14.0).sin(); + let wave_cos = (anim_time as f32 * 14.0).cos(); + + let head_look = Vec2::new( + ((global_time + anim_time) as f32 / 2.0) + .floor() + .mul(7331.0) + .sin() + * 0.2, + ((global_time + anim_time) as f32 / 2.0) + .floor() + .mul(1337.0) + .sin() + * 0.1, + ); + + next.head.offset = Vec3::new(0.0, 3.0, 12.0 + wave_cos * 1.3); + next.head.ori = Quaternion::rotation_z(head_look.x + wave * 0.1) + * Quaternion::rotation_x(head_look.y + 0.35); + next.head.scale = Vec3::one(); + + next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_cos * 1.1); + next.chest.ori = Quaternion::rotation_z(wave * 0.1); + next.chest.scale = Vec3::one(); + + next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_cos * 1.1); + next.belt.ori = Quaternion::rotation_z(wave * 0.25); + next.belt.scale = Vec3::one(); + + next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_cos * 1.1); + next.shorts.ori = Quaternion::rotation_z(wave * 0.6); + next.shorts.scale = Vec3::one(); + + next.l_hand.offset = Vec3::new(-9.0, 3.0 + wave_cos * 8.0, 12.0 - wave * 1.0) / 11.0; + next.l_hand.ori = Quaternion::rotation_x(wave_cos * 1.1); + next.l_hand.scale = Vec3::one() / 11.0; + + next.r_hand.offset = Vec3::new(9.0, 3.0 - wave_cos * 8.0, 12.0 + wave * 1.0) / 11.0; + next.r_hand.ori = Quaternion::rotation_x(wave_cos * -1.1); + next.r_hand.scale = Vec3::one() / 11.0; + + next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0); + next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.5); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 6.0); + next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.5); + next.r_foot.scale = Vec3::one(); + + next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0); + next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + next.weapon.scale = Vec3::one(); + + next.l_shoulder.offset = Vec3::new(-10.0, -3.2, 2.5); + next.l_shoulder.ori = Quaternion::rotation_x(0.0); + next.l_shoulder.scale = Vec3::one() * 1.04; + + next.r_shoulder.offset = Vec3::new(0.0, -3.2, 2.5); + next.r_shoulder.ori = Quaternion::rotation_x(0.0); + next.r_shoulder.scale = Vec3::one() * 1.04; + + next.draw.offset = Vec3::new(0.0, 5.0, 0.0); + next.draw.ori = Quaternion::rotation_y(0.0); + next.draw.scale = Vec3::one() * 0.0; + + next.left_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.left_equip.ori = Quaternion::rotation_x(0.0);; + next.left_equip.scale = Vec3::one() * 0.0; + + next.right_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.right_equip.ori = Quaternion::rotation_x(0.0);; + next.right_equip.scale = Vec3::one() * 0.0; + + next.torso.offset = Vec3::new(0.0, -0.2, 0.4); + next.torso.ori = Quaternion::rotation_x(-velocity * 0.04 - wave_cos * 0.10); + next.torso.scale = Vec3::one() / 11.0; + + next + } +} diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs index 8311183815..b0c4a4f67d 100644 --- a/voxygen/src/anim/character/mod.rs +++ b/voxygen/src/anim/character/mod.rs @@ -3,6 +3,9 @@ pub mod gliding; pub mod idle; pub mod jump; pub mod run; +pub mod roll; +pub mod crun; +pub mod cidle; // Reexports pub use self::attack::AttackAnimation; @@ -10,6 +13,10 @@ pub use self::gliding::GlidingAnimation; pub use self::idle::IdleAnimation; pub use self::jump::JumpAnimation; pub use self::run::RunAnimation; +pub use self::roll::RollAnimation; +pub use self::crun::CrunAnimation; +pub use self::cidle::CidleAnimation; + use super::{Bone, Skeleton}; use crate::render::FigureBoneData; diff --git a/voxygen/src/anim/character/roll.rs b/voxygen/src/anim/character/roll.rs new file mode 100644 index 0000000000..88b9ca0f54 --- /dev/null +++ b/voxygen/src/anim/character/roll.rs @@ -0,0 +1,98 @@ +use super::{super::Animation, CharacterSkeleton}; +use std::{f32::consts::PI, ops::Mul}; +use vek::*; + +pub struct RollAnimation; + +impl Animation for RollAnimation { + type Skeleton = CharacterSkeleton; + type Dependency = f64; + + fn update_skeleton( + skeleton: &Self::Skeleton, + global_time: f64, + anim_time: f64, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let wave = (anim_time as f32 * 4.0).sin(); + let wave_quick = (anim_time as f32 * 7.0).sin(); + let wave_quick_cos = (anim_time as f32 * 7.0).cos(); + let wave_cos = (anim_time as f32 * 4.0).cos(); + let wave_slow = (anim_time as f32 * 2.0 + PI).sin(); + let wave_dub = (anim_time as f32 * 4.0).sin(); + + next.head.offset = Vec3::new(0.0, -1.0 + wave_slow * -3.0, 16.0 + wave_dub * -3.0); + next.head.ori = Quaternion::rotation_x(wave_dub * -0.4); + next.head.scale = Vec3::one(); + + next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_dub * -1.5); + next.chest.ori = Quaternion::rotation_x(wave_dub * -0.5); + next.chest.scale = Vec3::one() * 1.01; + + next.belt.offset = Vec3::new(0.0, 0.0, 5.0); + next.belt.ori = Quaternion::rotation_x(0.0); + next.belt.scale = Vec3::one(); + + next.shorts.offset = Vec3::new(0.0, 0.0, 2.0); + next.shorts.ori = Quaternion::rotation_x(0.0); + next.shorts.scale = Vec3::one(); + + next.l_hand.offset = Vec3::new( + -5.5 + wave * -0.5, + -2.0 + wave_quick_cos * 5.5, + 8.0 + wave_quick * -5.5, + ) / 11.0; + + next.l_hand.ori = + Quaternion::rotation_x(wave_slow * 6.5) * Quaternion::rotation_y(wave * 0.3); + next.l_hand.scale = Vec3::one() / 11.0; + + next.r_hand.offset = Vec3::new( + 5.5 + wave * 0.5, + -2.0 + wave_quick_cos * 5.5, + 8.0 + wave_quick * -5.5, + ) / 11.0; + next.r_hand.ori = + Quaternion::rotation_x(wave_slow * 6.5) * Quaternion::rotation_y(wave * 0.3); + next.r_hand.scale = Vec3::one() / 11.; + + next.l_foot.offset = Vec3::new(-3.4, -0.1, 9.0 - 0.0 + wave * 1.2); + next.l_foot.ori = Quaternion::rotation_x(wave * 0.6); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new(3.4, -0.1, 9.0 - 0.0 + wave * 1.0); + next.r_foot.ori = Quaternion::rotation_x(wave * -0.4); + next.r_foot.scale = Vec3::one(); + + next.weapon.offset = Vec3::new(-7.0, -7.0, 18.0); + next.weapon.ori = + Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_quick * 1.0); + next.weapon.scale = Vec3::one(); + + next.l_shoulder.offset = Vec3::new(-10.0, -3.2, 2.5); + next.l_shoulder.ori = Quaternion::rotation_x(0.0); + next.l_shoulder.scale = Vec3::one() * 1.04; + + next.r_shoulder.offset = Vec3::new(0.0, -3.2, 2.5); + next.r_shoulder.ori = Quaternion::rotation_x(0.0); + next.r_shoulder.scale = Vec3::one() * 1.04; + + next.draw.offset = Vec3::new(0.0, 5.0, 0.0); + next.draw.ori = Quaternion::rotation_y(0.0); + next.draw.scale = Vec3::one() * 0.0; + + next.left_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.left_equip.ori = Quaternion::rotation_x(0.0);; + next.left_equip.scale = Vec3::one() * 0.0; + + next.right_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.right_equip.ori = Quaternion::rotation_x(0.0);; + next.right_equip.scale = Vec3::one() * 0.0; + + next.torso.offset = Vec3::new(0.0, -2.2, 0.1 + wave_dub * 12.0) / 11.0; + next.torso.ori = Quaternion::rotation_x(wave_slow * 6.0); + next.torso.scale = Vec3::one() / 11.0; + next + } +} diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 815c5bcb42..a92a16e9d7 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -556,6 +556,21 @@ impl FigureMgr { time, animation_info.time, ), + comp::Animation::Roll => character::RollAnimation::update_skeleton( + state.skeleton_mut(), + time, + animation_info.time, + ), + comp::Animation::Crun => character::CrunAnimation::update_skeleton( + state.skeleton_mut(), + (vel.0.magnitude(), time), + animation_info.time, + ), + comp::Animation::Cidle => character::CidleAnimation::update_skeleton( + state.skeleton_mut(), + time, + animation_info.time, + ), comp::Animation::Gliding => { character::GlidingAnimation::update_skeleton( state.skeleton_mut(), diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index dd5f038a75..aad72636c6 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -119,6 +119,15 @@ impl PlayState for SessionState { self.controller.attack = state; self.controller.respawn = state; // TODO: Don't do both } + Event::InputUpdate(GameInput::Roll, state) => { + self.controller.roll = state; + } + Event::InputUpdate(GameInput::Crun, state) => { + self.controller.crun = state; + } + Event::InputUpdate(GameInput::Cidle, state) => { + self.controller.cidle = state; + } Event::InputUpdate(GameInput::Jump, state) => { self.controller.jump = state; } diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 0e8d73cc18..9d116fa124 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -31,6 +31,11 @@ pub struct ControlSettings { pub screenshot: KeyMouse, pub toggle_ingame_ui: KeyMouse, pub attack: KeyMouse, + pub roll: KeyMouse, + pub crun: KeyMouse, + pub cidle: KeyMouse, + + } impl Default for ControlSettings { @@ -59,6 +64,9 @@ impl Default for ControlSettings { screenshot: KeyMouse::Key(VirtualKeyCode::F4), toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6), attack: KeyMouse::Mouse(MouseButton::Left), + roll: KeyMouse::Mouse(MouseButton::Middle), + crun: KeyMouse::Key(VirtualKeyCode::K), + cidle: KeyMouse::Key(VirtualKeyCode::J), } } } diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index fd158a4708..22aef60d8a 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -34,6 +34,9 @@ pub enum GameInput { Screenshot, ToggleIngameUi, Attack, + Roll, + Crun, + Cidle, Respawn, } @@ -134,6 +137,10 @@ impl Window { GameInput::ToggleIngameUi, ); key_map.insert(settings.controls.attack, GameInput::Attack); + key_map.insert(settings.controls.roll, GameInput::Roll); + key_map.insert(settings.controls.crun, GameInput::Crun); + key_map.insert(settings.controls.cidle, GameInput::Cidle); + Ok(Self { events_loop, From e2c81dd036e3ba1b3d14ae90ce7ca239ec7ead3b Mon Sep 17 00:00:00 2001 From: timokoesters Date: Thu, 13 Jun 2019 20:09:50 +0200 Subject: [PATCH 05/19] Fixes for .maybe() and animation --- common/src/comp/mod.rs | 4 +- common/src/sys/animation.rs | 57 +++++++++++++++++++------ common/src/sys/combat.rs | 4 +- common/src/sys/controller.rs | 57 ++++++++++--------------- common/src/sys/phys.rs | 71 ++++++++++++++++++------------- voxygen/src/anim/character/mod.rs | 13 +++--- voxygen/src/settings.rs | 2 - voxygen/src/window.rs | 1 - 8 files changed, 119 insertions(+), 90 deletions(-) diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 88af37d3cb..3ef4a779b2 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -18,14 +18,14 @@ pub use animation::Animation; pub use animation::AnimationInfo; pub use controller::Controller; pub use inputs::Attacking; -pub use inputs::Rolling; -pub use inputs::Crunning; pub use inputs::Cidling; +pub use inputs::Crunning; pub use inputs::Gliding; pub use inputs::Jumping; pub use inputs::MoveDir; pub use inputs::OnGround; pub use inputs::Respawning; +pub use inputs::Rolling; pub use player::Player; pub use stats::Dying; pub use stats::HealthSource; diff --git a/common/src/sys/animation.rs b/common/src/sys/animation.rs index ea7e617d38..20a4cbaeac 100644 --- a/common/src/sys/animation.rs +++ b/common/src/sys/animation.rs @@ -1,5 +1,8 @@ use crate::{ - comp::{phys, Animation, AnimationInfo, Attacking, Rolling, Crunning, Cidling, Gliding, Jumping, OnGround}, + comp::{ + phys, Animation, AnimationInfo, Attacking, Cidling, Crunning, Gliding, Jumping, OnGround, + Rolling, + }, state::DeltaTime, }; use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; @@ -23,9 +26,32 @@ impl<'a> System<'a> for Sys { fn run( &mut self, - (entities, dt, velocities, on_grounds, jumpings, glidings, attackings, rollings, crunnings, cidlings, mut animation_infos): Self::SystemData, + ( + entities, + dt, + velocities, + on_grounds, + jumpings, + glidings, + attackings, + rollings, + crunnings, + cidlings, + mut animation_infos, + ): Self::SystemData, ) { - for (entity, vel, on_ground, jumping, gliding, attacking, rolling, crunning, cidling, mut animation_info) in ( + for ( + entity, + vel, + on_ground, + jumping, + gliding, + attacking, + rolling, + crunning, + cidling, + mut animation_info, + ) in ( &entities, &velocities, on_grounds.maybe(), @@ -52,16 +78,23 @@ impl<'a> System<'a> for Sys { moving, attacking.is_some(), gliding.is_some(), + rolling.is_some(), ) { - (true, false, false, false) => Animation::Idle, - (true, true, false, false) => Animation::Run, - (false, _, false, false) => Animation::Jump, - (_, _, false, true) => Animation::Gliding, - (_, _, true, false) => Animation::Attack, - (true, true, false, false) => Animation::Roll, - (_, true, false, false) => Animation::Crun, - (true, false, false, false) => Animation::Cidle, - (_, _, true, true) => impossible_animation(), + (true, false, false, false, false) => Animation::Idle, + (true, true, false, false, false) => Animation::Run, + (false, _, false, false, false) => Animation::Jump, + (_, _, false, true, false) => Animation::Gliding, + (_, _, true, false, false) => Animation::Attack, + (_, true, false, false, true) => { + dbg!("roll"); + Animation::Roll + } + //(_, true, false, false, false) => Animation::Crun, + //(true, false, false, false, false) => Animation::Cidle, + (_, _, true, true, _) => impossible_animation(), // Attack while gliding + (_, _, true, _, true) => impossible_animation(), // Roll while attacking + (_, _, _, true, true) => impossible_animation(), // Roll while gliding + (_, false, _, _, true) => impossible_animation(), // Roll without moving }; let last = animation_info.clone(); diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index 39cd73058b..be94838023 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -16,8 +16,8 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Uid>, Read<'a, DeltaTime>, ReadStorage<'a, Pos>, - WriteStorage<'a, Vel>, ReadStorage<'a, Ori>, + WriteStorage<'a, Vel>, WriteStorage<'a, Attacking>, WriteStorage<'a, Stats>, WriteStorage<'a, ForceUpdate>, @@ -30,8 +30,8 @@ impl<'a> System<'a> for Sys { uids, dt, positions, - mut velocities, orientations, + mut velocities, mut attackings, mut stats, mut force_updates, diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 9a01134fae..4543a52b15 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -1,8 +1,8 @@ use crate::{ comp::{ phys::{ForceUpdate, Ori, Pos, Vel}, - Animation, AnimationInfo, Attacking, Rolling, Crunning, Cidling, Controller, Gliding, HealthSource, Jumping, MoveDir, - OnGround, Respawning, Stats, + Animation, AnimationInfo, Attacking, Cidling, Controller, Crunning, Gliding, HealthSource, + Jumping, MoveDir, OnGround, Respawning, Rolling, Stats, }, state::DeltaTime, }; @@ -17,10 +17,10 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Controller>, ReadStorage<'a, Stats>, ReadStorage<'a, Pos>, - WriteStorage<'a, Vel>, - WriteStorage<'a, Ori>, + ReadStorage<'a, Vel>, + ReadStorage<'a, Ori>, + ReadStorage<'a, OnGround>, WriteStorage<'a, MoveDir>, - WriteStorage<'a, OnGround>, WriteStorage<'a, Jumping>, WriteStorage<'a, Attacking>, WriteStorage<'a, Rolling>, @@ -28,7 +28,6 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, Cidling>, WriteStorage<'a, Respawning>, WriteStorage<'a, Gliding>, - WriteStorage<'a, ForceUpdate>, ); fn run( @@ -39,10 +38,10 @@ impl<'a> System<'a> for Sys { controllers, stats, positions, - mut velocities, - mut orientations, + velocities, + orientations, + on_grounds, mut move_dirs, - mut on_grounds, mut jumpings, mut attackings, mut rollings, @@ -50,31 +49,16 @@ impl<'a> System<'a> for Sys { mut cidlings, mut respawns, mut glidings, - force_updates, ): Self::SystemData, ) { - for ( - entity, - controller, - stats, - pos, - mut vel, - mut ori, - on_ground, - mut attacking, - mut jumping, - mut gliding, - ) in ( + for (entity, controller, stats, pos, vel, ori, on_ground) in ( &entities, &controllers, &stats, &positions, - &mut velocities, - &mut orientations, + &velocities, + &orientations, on_grounds.maybe(), - attackings.maybe(), - jumpings.maybe(), - glidings.maybe(), ) .join() { @@ -87,10 +71,10 @@ impl<'a> System<'a> for Sys { } // Glide - if controller.glide && on_ground.is_none() && attacking.is_none() { - gliding = Some(&Gliding); + if controller.glide && on_ground.is_none() && attackings.get(entity).is_none() { + glidings.insert(entity, Gliding); } else { - gliding = None + glidings.remove(entity); } // Move dir @@ -104,19 +88,22 @@ impl<'a> System<'a> for Sys { ); // Attack - if controller.attack && attacking.is_none() && gliding.is_none() { - attacking = Some(&Attacking::start()); + if controller.attack + && attackings.get(entity).is_none() + && glidings.get(entity).is_none() + { + attackings.insert(entity, Attacking::start()); } // Jump if on_ground.is_some() && controller.jump && vel.0.z <= 0.0 { - jumping = Some(&Jumping); + jumpings.insert(entity, Jumping); } else { - jumping = None; + jumpings.remove(entity); } // Roll - if on_grounds.get(entity).is_some() && controller.roll { + if on_ground.is_some() && controller.roll { rollings.insert(entity, Rolling::start()); } else { rollings.remove(entity); diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index a63837295d..f1d33a0111 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -1,7 +1,7 @@ use crate::{ comp::{ phys::{Ori, Pos, Vel}, - Gliding, Jumping, MoveDir, OnGround, Stats, Rolling, Cidling, Crunning, + Cidling, Crunning, Gliding, Jumping, MoveDir, OnGround, Rolling, Stats, }, state::DeltaTime, terrain::TerrainMap, @@ -51,10 +51,6 @@ impl<'a> System<'a> for Sys { Entities<'a>, ReadExpect<'a, TerrainMap>, Read<'a, DeltaTime>, - WriteStorage<'a, OnGround>, - WriteStorage<'a, Pos>, - WriteStorage<'a, Vel>, - WriteStorage<'a, Ori>, ReadStorage<'a, MoveDir>, ReadStorage<'a, Jumping>, ReadStorage<'a, Gliding>, @@ -62,6 +58,10 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Crunning>, ReadStorage<'a, Cidling>, ReadStorage<'a, Stats>, + WriteStorage<'a, OnGround>, + WriteStorage<'a, Pos>, + WriteStorage<'a, Vel>, + WriteStorage<'a, Ori>, ); fn run( @@ -70,10 +70,6 @@ impl<'a> System<'a> for Sys { entities, terrain, dt, - mut on_grounds, - mut positions, - mut velocities, - mut orientations, move_dirs, jumpings, glidings, @@ -81,25 +77,39 @@ impl<'a> System<'a> for Sys { crunnings, cidlings, stats, + mut on_grounds, + mut positions, + mut velocities, + mut orientations, ): Self::SystemData, ) { // Apply movement inputs - for (entity, mut pos, mut vel, mut ori, mut on_ground, move_dir, jumping, gliding, rolling, crunning, cidling, stats) in - ( - &entities, - &mut positions, - &mut velocities, - &mut orientations, - on_grounds.maybe(), - move_dirs.maybe(), - jumpings.maybe(), - glidings.maybe(), - rollings.maybe(), - crunnings.maybe(), - cidlings.maybe(), - &stats, - ) - .join() + for ( + entity, + stats, + move_dir, + jumping, + gliding, + rolling, + crunning, + cidling, + mut pos, + mut vel, + mut ori, + ) in ( + &entities, + &stats, + move_dirs.maybe(), + jumpings.maybe(), + glidings.maybe(), + rollings.maybe(), + crunnings.maybe(), + cidlings.maybe(), + &mut positions, + &mut velocities, + &mut orientations, + ) + .join() { // Disable while dead TODO: Replace with client states? if stats.is_dead { @@ -110,7 +120,10 @@ impl<'a> System<'a> for Sys { if let Some(move_dir) = move_dir { vel.0 += Vec2::broadcast(dt.0) * move_dir.0 - * match (on_ground.is_some(), gliding.is_some()) { + * match ( + on_grounds.get(entity).is_some(), + glidings.get(entity).is_some(), + ) { (true, false) if vel.0.magnitude() < HUMANOID_SPEED => HUMANOID_ACCEL, (false, true) if vel.0.magnitude() < GLIDE_SPEED => GLIDE_ACCEL, (false, false) if vel.0.magnitude() < HUMANOID_AIR_SPEED => { @@ -151,15 +164,15 @@ impl<'a> System<'a> for Sys { .unwrap_or(false) && vel.0.z <= 0.0 { - on_ground = Some(&OnGround); + on_grounds.insert(entity, OnGround); } else { - on_ground = None; + on_grounds.remove(entity); } // Integrate forces // Friction is assumed to be a constant dependent on location let friction = 50.0 - * if on_ground.is_some() { + * if on_grounds.get(entity).is_some() { FRIC_GROUND } else { FRIC_AIR diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs index b0c4a4f67d..b50f3e89ea 100644 --- a/voxygen/src/anim/character/mod.rs +++ b/voxygen/src/anim/character/mod.rs @@ -1,22 +1,21 @@ pub mod attack; +pub mod cidle; +pub mod crun; pub mod gliding; pub mod idle; pub mod jump; -pub mod run; pub mod roll; -pub mod crun; -pub mod cidle; +pub mod run; // Reexports pub use self::attack::AttackAnimation; +pub use self::cidle::CidleAnimation; +pub use self::crun::CrunAnimation; pub use self::gliding::GlidingAnimation; pub use self::idle::IdleAnimation; pub use self::jump::JumpAnimation; -pub use self::run::RunAnimation; pub use self::roll::RollAnimation; -pub use self::crun::CrunAnimation; -pub use self::cidle::CidleAnimation; - +pub use self::run::RunAnimation; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 9d116fa124..14cc677d61 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -34,8 +34,6 @@ pub struct ControlSettings { pub roll: KeyMouse, pub crun: KeyMouse, pub cidle: KeyMouse, - - } impl Default for ControlSettings { diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 22aef60d8a..bbc7310298 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -141,7 +141,6 @@ impl Window { key_map.insert(settings.controls.crun, GameInput::Crun); key_map.insert(settings.controls.cidle, GameInput::Cidle); - Ok(Self { events_loop, renderer: Renderer::new(device, factory, win_color_view, win_depth_view)?, From 955c20fa61c3404e52a6c0dfc390016200afdb65 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Thu, 13 Jun 2019 21:19:13 +0200 Subject: [PATCH 06/19] Remove crun and cidle components and inputs --- common/src/comp/controller.rs | 2 -- common/src/comp/inputs.rs | 36 +---------------------------- common/src/comp/mod.rs | 2 -- common/src/msg/ecs_packet.rs | 4 ---- common/src/state.rs | 2 -- common/src/sys/animation.rs | 43 ++++++++--------------------------- common/src/sys/controller.rs | 8 ++----- common/src/sys/phys.rs | 24 ++----------------- voxygen/src/session.rs | 6 ----- voxygen/src/settings.rs | 4 ---- voxygen/src/window.rs | 4 ---- 11 files changed, 14 insertions(+), 121 deletions(-) diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs index 8e5fd5db4f..7cd5eba3a4 100644 --- a/common/src/comp/controller.rs +++ b/common/src/comp/controller.rs @@ -7,8 +7,6 @@ pub struct Controller { pub jump: bool, pub attack: bool, pub roll: bool, - pub crun: bool, - pub cidle: bool, pub glide: bool, pub respawn: bool, } diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs index c2afea0432..0e021094f7 100644 --- a/common/src/comp/inputs.rs +++ b/common/src/comp/inputs.rs @@ -19,18 +19,6 @@ pub struct Rolling { pub applied: bool, } -#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] -pub struct Crunning { - pub time: f32, - pub applied: bool, -} - -#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] -pub struct Cidling { - pub time: f32, - pub applied: bool, -} - #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct OnGround; @@ -62,23 +50,6 @@ impl Rolling { } } -impl Crunning { - pub fn start() -> Self { - Self { - time: 0.0, - applied: false, - } - } -} -impl Cidling { - pub fn start() -> Self { - Self { - time: 0.0, - applied: false, - } - } -} - impl Component for MoveDir { type Storage = VecStorage; } @@ -90,12 +61,7 @@ impl Component for Attacking { impl Component for Rolling { type Storage = FlaggedStorage>; } -impl Component for Crunning { - type Storage = FlaggedStorage>; -} -impl Component for Cidling { - type Storage = FlaggedStorage>; -} + impl Component for OnGround { type Storage = NullStorage; } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 3ef4a779b2..c876143a22 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -18,8 +18,6 @@ pub use animation::Animation; pub use animation::AnimationInfo; pub use controller::Controller; pub use inputs::Attacking; -pub use inputs::Cidling; -pub use inputs::Crunning; pub use inputs::Gliding; pub use inputs::Jumping; pub use inputs::MoveDir; diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index 6918bfdf89..2e723fbabe 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -25,8 +25,6 @@ sphynx::sum_type! { Stats(comp::Stats), Attacking(comp::Attacking), Rolling(comp::Rolling), - Crunning(comp::Crunning), - Cidling(comp::Cidling), } } @@ -43,8 +41,6 @@ sphynx::sum_type! { Stats(PhantomData), Attacking(PhantomData), Rolling(PhantomData), - Crunning(PhantomData), - Cidling(PhantomData), } } diff --git a/common/src/state.rs b/common/src/state.rs index dd01b34ac2..4dec08d899 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -104,8 +104,6 @@ impl State { ecs.register_synced::(); ecs.register_synced::(); // TODO: Don't send this to the client? ecs.register_synced::(); // TODO: Don't send this to the client? - ecs.register_synced::(); // TODO: Don't send this to the client? - ecs.register_synced::(); // TODO: Don't send this to the client? ecs.register::(); // Register components synced by other means diff --git a/common/src/sys/animation.rs b/common/src/sys/animation.rs index 20a4cbaeac..6571547f34 100644 --- a/common/src/sys/animation.rs +++ b/common/src/sys/animation.rs @@ -1,8 +1,5 @@ use crate::{ - comp::{ - phys, Animation, AnimationInfo, Attacking, Cidling, Crunning, Gliding, Jumping, OnGround, - Rolling, - }, + comp::{phys, Animation, AnimationInfo, Attacking, Gliding, Jumping, OnGround, Rolling}, state::DeltaTime, }; use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; @@ -19,8 +16,6 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Gliding>, ReadStorage<'a, Attacking>, ReadStorage<'a, Rolling>, - ReadStorage<'a, Crunning>, - ReadStorage<'a, Cidling>, WriteStorage<'a, AnimationInfo>, ); @@ -35,23 +30,10 @@ impl<'a> System<'a> for Sys { glidings, attackings, rollings, - crunnings, - cidlings, mut animation_infos, ): Self::SystemData, ) { - for ( - entity, - vel, - on_ground, - jumping, - gliding, - attacking, - rolling, - crunning, - cidling, - mut animation_info, - ) in ( + for (entity, vel, on_ground, jumping, gliding, attacking, rolling, mut animation_info) in ( &entities, &velocities, on_grounds.maybe(), @@ -59,8 +41,6 @@ impl<'a> System<'a> for Sys { glidings.maybe(), attackings.maybe(), rollings.maybe(), - crunnings.maybe(), - cidlings.maybe(), &mut animation_infos, ) .join() @@ -68,8 +48,8 @@ impl<'a> System<'a> for Sys { animation_info.time += dt.0 as f64; let moving = vel.0.magnitude() > 3.0; - fn impossible_animation() -> Animation { - warn!("Impossible animation"); + fn impossible_animation(message: &str) -> Animation { + warn!("{}", message); Animation::Idle } @@ -80,21 +60,16 @@ impl<'a> System<'a> for Sys { gliding.is_some(), rolling.is_some(), ) { + (_, _, true, true, _) => impossible_animation("Attack while gliding"), + (_, _, true, _, true) => impossible_animation("Roll while attacking"), + (_, _, _, true, true) => impossible_animation("Roll while gliding"), + (_, false, _, _, true) => impossible_animation("Roll without moving"), + (_, true, false, false, true) => Animation::Roll, (true, false, false, false, false) => Animation::Idle, (true, true, false, false, false) => Animation::Run, (false, _, false, false, false) => Animation::Jump, (_, _, false, true, false) => Animation::Gliding, (_, _, true, false, false) => Animation::Attack, - (_, true, false, false, true) => { - dbg!("roll"); - Animation::Roll - } - //(_, true, false, false, false) => Animation::Crun, - //(true, false, false, false, false) => Animation::Cidle, - (_, _, true, true, _) => impossible_animation(), // Attack while gliding - (_, _, true, _, true) => impossible_animation(), // Roll while attacking - (_, _, _, true, true) => impossible_animation(), // Roll while gliding - (_, false, _, _, true) => impossible_animation(), // Roll without moving }; let last = animation_info.clone(); diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 4543a52b15..69404fc576 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -1,8 +1,8 @@ use crate::{ comp::{ phys::{ForceUpdate, Ori, Pos, Vel}, - Animation, AnimationInfo, Attacking, Cidling, Controller, Crunning, Gliding, HealthSource, - Jumping, MoveDir, OnGround, Respawning, Rolling, Stats, + Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, MoveDir, + OnGround, Respawning, Rolling, Stats, }, state::DeltaTime, }; @@ -24,8 +24,6 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, Jumping>, WriteStorage<'a, Attacking>, WriteStorage<'a, Rolling>, - WriteStorage<'a, Crunning>, - WriteStorage<'a, Cidling>, WriteStorage<'a, Respawning>, WriteStorage<'a, Gliding>, ); @@ -45,8 +43,6 @@ impl<'a> System<'a> for Sys { mut jumpings, mut attackings, mut rollings, - mut crunnings, - mut cidlings, mut respawns, mut glidings, ): Self::SystemData, diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index f1d33a0111..e98303c035 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -1,7 +1,7 @@ use crate::{ comp::{ phys::{Ori, Pos, Vel}, - Cidling, Crunning, Gliding, Jumping, MoveDir, OnGround, Rolling, Stats, + Gliding, Jumping, MoveDir, OnGround, Rolling, Stats, }, state::DeltaTime, terrain::TerrainMap, @@ -55,8 +55,6 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Jumping>, ReadStorage<'a, Gliding>, ReadStorage<'a, Rolling>, - ReadStorage<'a, Crunning>, - ReadStorage<'a, Cidling>, ReadStorage<'a, Stats>, WriteStorage<'a, OnGround>, WriteStorage<'a, Pos>, @@ -74,8 +72,6 @@ impl<'a> System<'a> for Sys { jumpings, glidings, rollings, - crunnings, - cidlings, stats, mut on_grounds, mut positions, @@ -84,27 +80,13 @@ impl<'a> System<'a> for Sys { ): Self::SystemData, ) { // Apply movement inputs - for ( - entity, - stats, - move_dir, - jumping, - gliding, - rolling, - crunning, - cidling, - mut pos, - mut vel, - mut ori, - ) in ( + for (entity, stats, move_dir, jumping, gliding, rolling, mut pos, mut vel, mut ori) in ( &entities, &stats, move_dirs.maybe(), jumpings.maybe(), glidings.maybe(), rollings.maybe(), - crunnings.maybe(), - cidlings.maybe(), &mut positions, &mut velocities, &mut orientations, @@ -146,8 +128,6 @@ impl<'a> System<'a> for Sys { // TODO: if rolling.is_some() {} - if crunning.is_some() {} - if cidling.is_some() {} // Set direction based on velocity if vel.0.magnitude_squared() != 0.0 { diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index aad72636c6..11ce68a2d1 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -122,12 +122,6 @@ impl PlayState for SessionState { Event::InputUpdate(GameInput::Roll, state) => { self.controller.roll = state; } - Event::InputUpdate(GameInput::Crun, state) => { - self.controller.crun = state; - } - Event::InputUpdate(GameInput::Cidle, state) => { - self.controller.cidle = state; - } Event::InputUpdate(GameInput::Jump, state) => { self.controller.jump = state; } diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 14cc677d61..37a61c2140 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -32,8 +32,6 @@ pub struct ControlSettings { pub toggle_ingame_ui: KeyMouse, pub attack: KeyMouse, pub roll: KeyMouse, - pub crun: KeyMouse, - pub cidle: KeyMouse, } impl Default for ControlSettings { @@ -63,8 +61,6 @@ impl Default for ControlSettings { toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6), attack: KeyMouse::Mouse(MouseButton::Left), roll: KeyMouse::Mouse(MouseButton::Middle), - crun: KeyMouse::Key(VirtualKeyCode::K), - cidle: KeyMouse::Key(VirtualKeyCode::J), } } } diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index bbc7310298..dfc635f477 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -35,8 +35,6 @@ pub enum GameInput { ToggleIngameUi, Attack, Roll, - Crun, - Cidle, Respawn, } @@ -138,8 +136,6 @@ impl Window { ); key_map.insert(settings.controls.attack, GameInput::Attack); key_map.insert(settings.controls.roll, GameInput::Roll); - key_map.insert(settings.controls.crun, GameInput::Crun); - key_map.insert(settings.controls.cidle, GameInput::Cidle); Ok(Self { events_loop, From 7deb3da1af7020dccec48313cecf7966f483c4fd Mon Sep 17 00:00:00 2001 From: timokoesters Date: Fri, 14 Jun 2019 17:27:05 +0200 Subject: [PATCH 07/19] Add `pub use phys::` and remove most `pub mod`s --- client/src/lib.rs | 4 +-- common/src/comp/mod.rs | 36 ++++++++-------------- common/src/comp/phys.rs | 4 --- common/src/msg/client.rs | 6 ++-- common/src/msg/ecs_packet.rs | 12 ++++---- common/src/msg/server.rs | 6 ++-- common/src/state.rs | 8 ++--- common/src/sys/agent.rs | 2 +- common/src/sys/animation.rs | 7 +++-- common/src/sys/combat.rs | 3 +- common/src/sys/controller.rs | 3 +- common/src/sys/phys.rs | 5 +--- server/src/cmd.rs | 34 ++++++--------------- server/src/lib.rs | 58 ++++++++++++++++-------------------- voxygen/src/hud/mod.rs | 6 ++-- voxygen/src/scene/figure.rs | 16 +++++----- voxygen/src/scene/mod.rs | 2 +- voxygen/src/session.rs | 2 +- 18 files changed, 86 insertions(+), 128 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 01e0abe3d3..655e7179be 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -153,7 +153,7 @@ impl Client { pub fn current_chunk(&self) -> Option> { let chunk_pos = Vec2::from( self.state - .read_storage::() + .read_storage::() .get(self.entity) .cloned()? .0, @@ -218,7 +218,7 @@ impl Client { // 5) Terrain let pos = self .state - .read_storage::() + .read_storage::() .get(self.entity) .cloned(); if let (Some(pos), Some(view_distance)) = (pos, self.view_distance) { diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index c876143a22..9f1c20f910 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -1,30 +1,18 @@ pub mod actor; -pub mod agent; -pub mod animation; -pub mod controller; -pub mod inputs; -pub mod phys; -pub mod player; -pub mod stats; +mod agent; +mod animation; +mod controller; +mod inputs; +mod phys; +mod player; +mod stats; // Reexports -pub use actor::Actor; -pub use actor::Body; -pub use actor::HumanoidBody; -pub use actor::QuadrupedBody; -pub use actor::QuadrupedMediumBody; +pub use actor::{Actor, Body, HumanoidBody, QuadrupedBody, QuadrupedMediumBody}; pub use agent::Agent; -pub use animation::Animation; -pub use animation::AnimationInfo; +pub use animation::{Animation, AnimationInfo}; pub use controller::Controller; -pub use inputs::Attacking; -pub use inputs::Gliding; -pub use inputs::Jumping; -pub use inputs::MoveDir; -pub use inputs::OnGround; -pub use inputs::Respawning; -pub use inputs::Rolling; +pub use inputs::{Attacking, Gliding, Jumping, MoveDir, OnGround, Respawning, Rolling}; +pub use phys::{ForceUpdate, Ori, Pos, Vel}; pub use player::Player; -pub use stats::Dying; -pub use stats::HealthSource; -pub use stats::Stats; +pub use stats::{Dying, HealthSource, Stats}; diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index adfc64ffe0..6fe1e603bb 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -2,7 +2,6 @@ use specs::{Component, NullStorage, VecStorage}; use vek::*; // Position - #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct Pos(pub Vec3); @@ -11,7 +10,6 @@ impl Component for Pos { } // Velocity - #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct Vel(pub Vec3); @@ -20,7 +18,6 @@ impl Component for Vel { } // Orientation - #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct Ori(pub Vec3); @@ -29,7 +26,6 @@ impl Component for Ori { } // ForceUpdate - #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] pub struct ForceUpdate; diff --git a/common/src/msg/client.rs b/common/src/msg/client.rs index 1187831d2a..47ec6fae5b 100644 --- a/common/src/msg/client.rs +++ b/common/src/msg/client.rs @@ -19,9 +19,9 @@ pub enum ClientMsg { Chat(String), PlayerAnimation(comp::AnimationInfo), PlayerPhysics { - pos: comp::phys::Pos, - vel: comp::phys::Vel, - ori: comp::phys::Ori, + pos: comp::Pos, + vel: comp::Vel, + ori: comp::Ori, }, TerrainChunkRequest { key: Vec2, diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index 2e723fbabe..899579b8c3 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -17,9 +17,9 @@ impl sphynx::ResPacket for EcsResPacket {} sphynx::sum_type! { #[derive(Clone, Debug, Serialize, Deserialize)] pub enum EcsCompPacket { - Pos(comp::phys::Pos), - Vel(comp::phys::Vel), - Ori(comp::phys::Ori), + Pos(comp::Pos), + Vel(comp::Vel), + Ori(comp::Ori), Actor(comp::Actor), Player(comp::Player), Stats(comp::Stats), @@ -33,9 +33,9 @@ sphynx::sum_type! { sphynx::sum_type! { #[derive(Clone, Debug, Serialize, Deserialize)] pub enum EcsCompPhantom { - Pos(PhantomData), - Vel(PhantomData), - Ori(PhantomData), + Pos(PhantomData), + Vel(PhantomData), + Ori(PhantomData), Actor(PhantomData), Player(PhantomData), Stats(PhantomData), diff --git a/common/src/msg/server.rs b/common/src/msg/server.rs index c82f94b2a1..f3604fb839 100644 --- a/common/src/msg/server.rs +++ b/common/src/msg/server.rs @@ -32,9 +32,9 @@ pub enum ServerMsg { EcsSync(sphynx::SyncPackage), EntityPhysics { entity: u64, - pos: comp::phys::Pos, - vel: comp::phys::Vel, - ori: comp::phys::Ori, + pos: comp::Pos, + vel: comp::Vel, + ori: comp::Ori, }, EntityAnimation { entity: u64, diff --git a/common/src/state.rs b/common/src/state.rs index 4dec08d899..6e1f2dde1e 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -104,12 +104,12 @@ impl State { ecs.register_synced::(); ecs.register_synced::(); // TODO: Don't send this to the client? ecs.register_synced::(); // TODO: Don't send this to the client? - ecs.register::(); + ecs.register::(); // Register components synced by other means - ecs.register::(); - ecs.register::(); - ecs.register::(); + ecs.register::(); + ecs.register::(); + ecs.register::(); ecs.register::(); ecs.register::(); ecs.register::(); diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index 0bd445ab1e..3ff07be4ab 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -1,4 +1,4 @@ -use crate::comp::{phys::Pos, Agent, Attacking, Controller, Jumping}; +use crate::comp::{Agent, Attacking, Controller, Jumping, Pos}; use log::warn; use rand::{seq::SliceRandom, thread_rng}; use specs::{Entities, Join, ReadStorage, System, WriteStorage}; diff --git a/common/src/sys/animation.rs b/common/src/sys/animation.rs index 6571547f34..2ccc5cff18 100644 --- a/common/src/sys/animation.rs +++ b/common/src/sys/animation.rs @@ -1,5 +1,8 @@ use crate::{ - comp::{phys, Animation, AnimationInfo, Attacking, Gliding, Jumping, OnGround, Rolling}, + comp::{ + Animation, AnimationInfo, Attacking, ForceUpdate, Gliding, Jumping, OnGround, Ori, Pos, + Rolling, Vel, + }, state::DeltaTime, }; use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; @@ -10,7 +13,7 @@ impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, Read<'a, DeltaTime>, - ReadStorage<'a, phys::Vel>, + ReadStorage<'a, Vel>, ReadStorage<'a, OnGround>, ReadStorage<'a, Jumping>, ReadStorage<'a, Gliding>, diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index be94838023..a3106bfcda 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -1,7 +1,6 @@ use crate::{ comp::{ - phys::{ForceUpdate, Ori, Pos, Vel}, - Attacking, HealthSource, Stats, + Attacking, HealthSource, Stats, {ForceUpdate, Ori, Pos, Vel}, }, state::{DeltaTime, Uid}, }; diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 69404fc576..aa3b68c81e 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -1,8 +1,7 @@ use crate::{ comp::{ - phys::{ForceUpdate, Ori, Pos, Vel}, Animation, AnimationInfo, Attacking, Controller, Gliding, HealthSource, Jumping, MoveDir, - OnGround, Respawning, Rolling, Stats, + OnGround, Respawning, Rolling, Stats, {ForceUpdate, Ori, Pos, Vel}, }, state::DeltaTime, }; diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index e98303c035..d756b66ca1 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -1,8 +1,5 @@ use crate::{ - comp::{ - phys::{Ori, Pos, Vel}, - Gliding, Jumping, MoveDir, OnGround, Rolling, Stats, - }, + comp::{Gliding, Jumping, MoveDir, OnGround, Ori, Pos, Rolling, Stats, Vel}, state::DeltaTime, terrain::TerrainMap, vol::{ReadVol, Vox}, diff --git a/server/src/cmd.rs b/server/src/cmd.rs index ba8480420d..510a171ff9 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -100,18 +100,12 @@ fn handle_jump(server: &mut Server, entity: EcsEntity, args: String, action: &Ch let (opt_x, opt_y, opt_z) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32); match (opt_x, opt_y, opt_z) { (Some(x), Some(y), Some(z)) => { - match server - .state - .read_component_cloned::(entity) - { + match server.state.read_component_cloned::(entity) { Some(current_pos) => { - server.state.write_component( - entity, - comp::phys::Pos(current_pos.0 + Vec3::new(x, y, z)), - ); server .state - .write_component(entity, comp::phys::ForceUpdate); + .write_component(entity, comp::Pos(current_pos.0 + Vec3::new(x, y, z))); + server.state.write_component(entity, comp::ForceUpdate); } None => server.clients.notify( entity, @@ -131,10 +125,8 @@ fn handle_goto(server: &mut Server, entity: EcsEntity, args: String, action: &Ch (Some(x), Some(y), Some(z)) => { server .state - .write_component(entity, comp::phys::Pos(Vec3::new(x, y, z))); - server - .state - .write_component(entity, comp::phys::ForceUpdate); + .write_component(entity, comp::Pos(Vec3::new(x, y, z))); + server.state.write_component(entity, comp::ForceUpdate); } _ => server .clients @@ -173,20 +165,15 @@ fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &Chat match opt_alias { Some(alias) => { let ecs = server.state.ecs(); - let opt_player = (&ecs.entities(), &ecs.read_storage::()) + let opt_player = (&ecs.entities(), &ecs.read_storage::()) .join() .find(|(_, player)| player.alias == alias) .map(|(entity, _)| entity); match opt_player { - Some(player) => match server - .state - .read_component_cloned::(player) - { + Some(player) => match server.state.read_component_cloned::(player) { Some(pos) => { server.state.write_component(entity, pos); - server - .state - .write_component(entity, comp::phys::ForceUpdate); + server.state.write_component(entity, comp::ForceUpdate); } None => server.clients.notify( entity, @@ -222,10 +209,7 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C match (opt_agent, opt_id, opt_amount) { (Some(agent), Some(id), Some(amount)) => { - match server - .state - .read_component_cloned::(entity) - { + match server.state.read_component_cloned::(entity) { Some(mut pos) => { pos.0.x += 1.0; // Temp fix TODO: Solve NaN issue with positions of pets let body = kind_to_body(id); diff --git a/server/src/lib.rs b/server/src/lib.rs index 5d5fa38ae6..194fa2b908 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -135,7 +135,7 @@ impl Server { #[allow(dead_code)] pub fn create_npc( &mut self, - pos: comp::phys::Pos, + pos: comp::Pos, name: String, body: comp::Body, ) -> EcsEntityBuilder { @@ -143,13 +143,13 @@ impl Server { .ecs_mut() .create_entity_synced() .with(pos) - .with(comp::phys::Vel(Vec3::zero())) - .with(comp::phys::Ori(Vec3::unit_y())) + .with(comp::Vel(Vec3::zero())) + .with(comp::Ori(Vec3::unit_y())) .with(comp::Controller::default()) .with(comp::AnimationInfo::default()) .with(comp::Actor::Character { name, body }) .with(comp::Stats::default()) - .with(comp::phys::ForceUpdate) + .with(comp::ForceUpdate) } pub fn create_player_character( @@ -165,11 +165,11 @@ impl Server { state.write_component(entity, comp::Stats::default()); state.write_component(entity, comp::AnimationInfo::default()); state.write_component(entity, comp::Controller::default()); - state.write_component(entity, comp::phys::Pos(spawn_point)); - state.write_component(entity, comp::phys::Vel(Vec3::zero())); - state.write_component(entity, comp::phys::Ori(Vec3::unit_y())); + state.write_component(entity, comp::Pos(spawn_point)); + state.write_component(entity, comp::Vel(Vec3::zero())); + state.write_component(entity, comp::Ori(Vec3::unit_y())); // Make sure physics are accepted. - state.write_component(entity, comp::phys::ForceUpdate); + state.write_component(entity, comp::ForceUpdate); // Tell the client its request was successful. client.allow_state(ClientState::Character); @@ -246,9 +246,8 @@ impl Server { // Actually kill them for entity in todo_kill { if let Some(client) = self.clients.get_mut(&entity) { - self.state - .write_component(entity, comp::phys::Vel(Vec3::zero())); - self.state.write_component(entity, comp::phys::ForceUpdate); + self.state.write_component(entity, comp::Vel(Vec3::zero())); + self.state.write_component(entity, comp::ForceUpdate); client.force_state(ClientState::Dead); } else { if let Err(err) = self.state.ecs_mut().delete_entity_synced(entity) { @@ -273,12 +272,11 @@ impl Server { self.state.write_component(entity, comp::Stats::default()); self.state .ecs_mut() - .write_storage::() + .write_storage::() .get_mut(entity) .map(|pos| pos.0.z += 100.0); - self.state - .write_component(entity, comp::phys::Vel(Vec3::zero())); - self.state.write_component(entity, comp::phys::ForceUpdate); + self.state.write_component(entity, comp::Vel(Vec3::zero())); + self.state.write_component(entity, comp::ForceUpdate); } } @@ -289,7 +287,7 @@ impl Server { for (entity, view_distance, pos) in ( &self.state.ecs().entities(), &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), + &self.state.ecs().read_storage::(), ) .join() .filter_map(|(entity, player, pos)| { @@ -324,7 +322,7 @@ impl Server { // For each player with a position, calculate the distance. for (player, pos) in ( &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), + &self.state.ecs().read_storage::(), ) .join() { @@ -632,9 +630,9 @@ impl Server { // Sync physics for (&uid, &pos, &vel, &ori) in ( &state.ecs().read_storage::(), - &state.ecs().read_storage::(), - &state.ecs().read_storage::(), - &state.ecs().read_storage::(), + &state.ecs().read_storage::(), + &state.ecs().read_storage::(), + &state.ecs().read_storage::(), ) .join() { @@ -673,13 +671,10 @@ impl Server { for (entity, &uid, &pos, &vel, &ori, force_update) in ( &self.state.ecs().entities(), &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), - self.state - .ecs() - .read_storage::() - .maybe(), + &self.state.ecs().read_storage::(), + &self.state.ecs().read_storage::(), + &self.state.ecs().read_storage::(), + self.state.ecs().read_storage::().maybe(), ) .join() { @@ -695,7 +690,7 @@ impl Server { let in_vd = |entity| { // Get client position. - let client_pos = match state.ecs().read_storage::().get(entity) { + let client_pos = match state.ecs().read_storage::().get(entity) { Some(pos) => pos.0, None => return false, }; @@ -726,10 +721,7 @@ impl Server { &self.state.ecs().entities(), &self.state.ecs().read_storage::(), &self.state.ecs().read_storage::(), - self.state - .ecs() - .read_storage::() - .maybe(), + self.state.ecs().read_storage::().maybe(), ) .join() { @@ -748,7 +740,7 @@ impl Server { // Remove all force flags. self.state .ecs_mut() - .write_storage::() + .write_storage::() .clear(); } diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index ccafa92385..34ecf90771 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -103,7 +103,7 @@ font_ids! { pub struct DebugInfo { pub tps: f64, pub ping_ms: f64, - pub coordinates: Option, + pub coordinates: Option, } pub enum Event { @@ -312,7 +312,7 @@ impl Hud { if self.show.ingame { let ecs = client.state().ecs(); let actor = ecs.read_storage::(); - let pos = ecs.read_storage::(); + let pos = ecs.read_storage::(); let stats = ecs.read_storage::(); let player = ecs.read_storage::(); let entities = ecs.entities(); @@ -322,7 +322,7 @@ impl Hud { let player_pos = client .state() .ecs() - .read_storage::() + .read_storage::() .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); let mut name_id_walker = self.ids.name_tags.walk(); diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index a92a16e9d7..547be1e146 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -477,15 +477,15 @@ impl FigureMgr { let player_pos = client .state() .ecs() - .read_storage::() + .read_storage::() .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); for (entity, pos, vel, ori, actor, animation_info, stats) in ( &ecs.entities(), - &ecs.read_storage::(), - &ecs.read_storage::(), - &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), ecs.read_storage::().maybe(), @@ -676,15 +676,15 @@ impl FigureMgr { let player_pos = client .state() .ecs() - .read_storage::() + .read_storage::() .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); for (entity, _, _, _, actor, _, _) in ( &ecs.entities(), - &ecs.read_storage::(), - &ecs.read_storage::(), - &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), ecs.read_storage::().maybe(), diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 9d7c09f608..55fe9c7498 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -110,7 +110,7 @@ impl Scene { let player_pos = client .state() .ecs() - .read_storage::() + .read_storage::() .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 11ce68a2d1..3bf9504d51 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -8,7 +8,7 @@ use crate::{ Direction, Error, GlobalState, PlayState, PlayStateResult, }; use client::{self, Client}; -use common::{clock::Clock, comp, comp::phys::Pos, msg::ClientState}; +use common::{clock::Clock, comp, comp::Pos, msg::ClientState}; use log::{error, warn}; use std::{cell::RefCell, rc::Rc, time::Duration}; use vek::*; From ecf0d9647c3ee143f112857ba134157f97ec14b6 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Sat, 15 Jun 2019 22:16:22 -0400 Subject: [PATCH 08/19] added roll physics, improved anims for roll, glide, run, attached hands to torso --- common/src/sys/phys.rs | 13 +++++-- voxygen/src/anim/character/attack.rs | 4 +-- voxygen/src/anim/character/cidle.rs | 2 +- voxygen/src/anim/character/crun.rs | 2 +- voxygen/src/anim/character/gliding.rs | 52 ++++++++++++--------------- voxygen/src/anim/character/idle.rs | 20 +++++------ voxygen/src/anim/character/jump.rs | 8 ++--- voxygen/src/anim/character/mod.rs | 4 +-- voxygen/src/anim/character/roll.rs | 28 +++++++-------- voxygen/src/anim/character/run.rs | 30 +++++++++++----- voxygen/src/scene/figure.rs | 2 +- 11 files changed, 89 insertions(+), 76 deletions(-) diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index d756b66ca1..55e1044b81 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -15,6 +15,8 @@ const HUMANOID_SPEED: f32 = 500.0; const HUMANOID_AIR_ACCEL: f32 = 10.0; const HUMANOID_AIR_SPEED: f32 = 100.0; const HUMANOID_JUMP_ACCEL: f32 = 16.0; +const ROLL_ACCEL: f32 = 200.0; +const ROLL_SPEED: f32 = 800.0; const GLIDE_ACCEL: f32 = 15.0; const GLIDE_SPEED: f32 = 45.0; // Gravity is 9.81 * 4, so this makes gravity equal to .15 @@ -102,12 +104,17 @@ impl<'a> System<'a> for Sys { * match ( on_grounds.get(entity).is_some(), glidings.get(entity).is_some(), + rollings.get(entity).is_some(), ) { - (true, false) if vel.0.magnitude() < HUMANOID_SPEED => HUMANOID_ACCEL, - (false, true) if vel.0.magnitude() < GLIDE_SPEED => GLIDE_ACCEL, - (false, false) if vel.0.magnitude() < HUMANOID_AIR_SPEED => { + (true, false, false) if vel.0.magnitude() < HUMANOID_SPEED => { + HUMANOID_ACCEL + } + (false, true, false) if vel.0.magnitude() < GLIDE_SPEED => GLIDE_ACCEL, + (false, false, false) if vel.0.magnitude() < HUMANOID_AIR_SPEED => { HUMANOID_AIR_ACCEL } + (true, false, true) if vel.0.magnitude() < ROLL_SPEED => ROLL_ACCEL, + _ => 0.0, }; } diff --git a/voxygen/src/anim/character/attack.rs b/voxygen/src/anim/character/attack.rs index ab8e7bf109..4676411c0c 100644 --- a/voxygen/src/anim/character/attack.rs +++ b/voxygen/src/anim/character/attack.rs @@ -46,11 +46,11 @@ impl Animation for AttackAnimation { -8.0 + wave_quicken_slow * 10.0, 4.0 + wave_quicken_double * 3.0, 9.0, - ) / 11.0; + ); next.l_hand.ori = Quaternion::rotation_z(-0.8) * Quaternion::rotation_x(0.0 + wave_quicken * -0.8) * Quaternion::rotation_y(0.0 + wave_quicken * -0.4); - next.l_hand.scale = Vec3::one() / 11.0; + next.l_hand.scale = Vec3::one(); next.r_hand.offset = Vec3::new(0.0, -2.0, 6.5) / 11.0; next.r_hand.ori = Quaternion::rotation_x(0.0); diff --git a/voxygen/src/anim/character/cidle.rs b/voxygen/src/anim/character/cidle.rs index e8f44cd1f0..7baff85c1e 100644 --- a/voxygen/src/anim/character/cidle.rs +++ b/voxygen/src/anim/character/cidle.rs @@ -73,7 +73,7 @@ impl Animation for CidleAnimation { next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0); next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); - next.weapon.scale = Vec3::one(); + next.weapon.scale = Vec3::one() * 0.0; next.l_shoulder.offset = Vec3::new(-10.0, -3.2, 2.5); next.l_shoulder.ori = Quaternion::rotation_x(0.0); diff --git a/voxygen/src/anim/character/crun.rs b/voxygen/src/anim/character/crun.rs index 54b7c079a8..7b1adb5047 100644 --- a/voxygen/src/anim/character/crun.rs +++ b/voxygen/src/anim/character/crun.rs @@ -66,7 +66,7 @@ impl Animation for CrunAnimation { next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0); next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); - next.weapon.scale = Vec3::one(); + next.weapon.scale = Vec3::one() * 0.0; next.l_shoulder.offset = Vec3::new(-10.0, -3.2, 2.5); next.l_shoulder.ori = Quaternion::rotation_x(0.0); diff --git a/voxygen/src/anim/character/gliding.rs b/voxygen/src/anim/character/gliding.rs index 8c21326638..82edf35f15 100644 --- a/voxygen/src/anim/character/gliding.rs +++ b/voxygen/src/anim/character/gliding.rs @@ -6,11 +6,11 @@ pub struct GlidingAnimation; impl Animation for GlidingAnimation { type Skeleton = CharacterSkeleton; - type Dependency = f64; + type Dependency = (f32, f64); fn update_skeleton( skeleton: &Self::Skeleton, - global_time: f64, + (velocity, global_time): Self::Dependency, anim_time: f64, ) -> Self::Skeleton { let mut next = (*skeleton).clone(); @@ -35,48 +35,40 @@ impl Animation for GlidingAnimation { .sin() * 0.25, ); - next.head.offset = Vec3::new(0.0, 2.0, 12.0); + next.head.offset = Vec3::new(0.0, 2.0, 2.0); next.head.ori = Quaternion::rotation_x(0.35 - wave_very_slow * 0.10 + head_look.y) * Quaternion::rotation_z(head_look.x + wave_very_slow_cos * 0.15); next.head.scale = Vec3::one(); - next.chest.offset = Vec3::new(0.0, 0.0, 8.0); + next.chest.offset = Vec3::new(0.0, 0.0, -2.0); next.chest.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.15); next.chest.scale = Vec3::one(); - next.belt.offset = Vec3::new(0.0, 0.0, 6.0); + next.belt.offset = Vec3::new(0.0, 0.0, -4.0); next.belt.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.20); next.belt.scale = Vec3::one(); - next.shorts.offset = Vec3::new(0.0, 0.0, 3.0); + next.shorts.offset = Vec3::new(0.0, 0.0, -7.0); next.shorts.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.25); next.shorts.scale = Vec3::one(); - next.l_hand.offset = Vec3::new( - -10.0, - 6.0 - wave_very_slow * 1.50, - 15.0 + wave_very_slow * 0.50, - ) / 11.0; - next.l_hand.ori = Quaternion::rotation_x(0.2 + wave_very_slow_cos * 0.05); - next.l_hand.scale = Vec3::one() / 11.0; + next.l_hand.offset = Vec3::new(-10.0, -2.0 + wave_very_slow * 0.10, 10.5); + next.l_hand.ori = Quaternion::rotation_x(1.0 + wave_very_slow_cos * -0.10); + next.l_hand.scale = Vec3::one(); - next.r_hand.offset = Vec3::new( - 10.0, - 6.0 - wave_very_slow * 1.50, - 14.5 + wave_very_slow * 0.50, - ) / 11.0; - next.r_hand.ori = Quaternion::rotation_x(0.1 + wave_very_slow * 0.05); - next.r_hand.scale = Vec3::one() / 11.0; + next.r_hand.offset = Vec3::new(10.0, -2.0 + wave_very_slow * 0.10, 10.5); + next.r_hand.ori = Quaternion::rotation_x(1.0 + wave_very_slow_cos * -0.10); + next.r_hand.scale = Vec3::one(); - next.l_foot.offset = Vec3::new(-3.4, 1.0, 8.0); + next.l_foot.offset = Vec3::new(-3.4, 1.0, -2.0); next.l_foot.ori = Quaternion::rotation_x( - wave_stop * -0.7 - wave_slow_cos * -0.21 + wave_very_slow * 0.19, + (wave_stop * -0.7 - wave_slow_cos * -0.21 + wave_very_slow * 0.19) * velocity * 0.07, ); next.l_foot.scale = Vec3::one(); - next.r_foot.offset = Vec3::new(3.4, 1.0, 8.0); + next.r_foot.offset = Vec3::new(3.4, 1.0, -2.0); next.r_foot.ori = Quaternion::rotation_x( - wave_stop * -0.8 + wave_slow * -0.25 + wave_very_slow_alt * 0.13, + (wave_stop * -0.8 + wave_slow * -0.25 + wave_very_slow_alt * 0.13) * velocity * 0.07, ); next.r_foot.scale = Vec3::one(); @@ -92,21 +84,21 @@ impl Animation for GlidingAnimation { next.r_shoulder.ori = Quaternion::rotation_x(0.0); next.r_shoulder.scale = Vec3::one() * 1.04; - next.draw.offset = Vec3::new(0.0, -9.0 + wave_very_slow * 0.10, 18.0); - next.draw.ori = Quaternion::rotation_x(0.95 - wave_very_slow * 0.15) + next.draw.offset = Vec3::new(0.0, -9.0 + wave_very_slow * 0.10, 8.0); + next.draw.ori = Quaternion::rotation_x(1.0)//0.95 - wave_very_slow * 0.08) * Quaternion::rotation_y(wave_very_slow_cos * 0.04); next.draw.scale = Vec3::one(); - next.left_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.left_equip.offset = Vec3::new(0.0, 0.0, -5.0) / 11.0; next.left_equip.ori = Quaternion::rotation_x(0.0);; next.left_equip.scale = Vec3::one() * 0.0; - next.right_equip.offset = Vec3::new(0.0, 0.0, 5.0) / 11.0; + next.right_equip.offset = Vec3::new(0.0, 0.0, -5.0) / 11.0; next.right_equip.ori = Quaternion::rotation_x(0.0);; next.right_equip.scale = Vec3::one() * 0.0; - next.torso.offset = Vec3::new(0.0, -0.2, 0.0); - next.torso.ori = Quaternion::rotation_x(-0.8 + wave_very_slow * 0.10); + next.torso.offset = Vec3::new(0.0, -0.2, 10.0) / 11.0; + next.torso.ori = Quaternion::rotation_x(-0.05 * velocity + wave_very_slow * 0.10); next.torso.scale = Vec3::one() / 11.0; next diff --git a/voxygen/src/anim/character/idle.rs b/voxygen/src/anim/character/idle.rs index 9203c8b99d..8b68ff656b 100644 --- a/voxygen/src/anim/character/idle.rs +++ b/voxygen/src/anim/character/idle.rs @@ -51,20 +51,20 @@ impl Animation for IdleAnimation { next.l_hand.offset = Vec3::new( -7.5, - -2.0 + wave_ultra_slow_cos * 0.15, - 8.0 + wave_ultra_slow * 0.5, - ) / 11.0; + 0.0 + wave_ultra_slow_cos * 0.15, + 7.0 + wave_ultra_slow * 0.5, + ); - next.l_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * 0.06); - next.l_hand.scale = Vec3::one() / 11.0; + next.l_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * -0.06); + next.l_hand.scale = Vec3::one(); next.r_hand.offset = Vec3::new( 7.5, - -2.0 + wave_ultra_slow_cos * 0.15, - 8.0 + wave_ultra_slow * 0.5, - ) / 11.0; - next.r_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * 0.06); - next.r_hand.scale = Vec3::one() / 11.; + 0.0 + wave_ultra_slow_cos * 0.15, + 7.0 + wave_ultra_slow * 0.5, + ); + next.r_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * -0.06); + next.r_hand.scale = Vec3::one(); next.l_foot.offset = Vec3::new(-3.4, -0.1, 8.0); next.l_foot.ori = Quaternion::identity(); diff --git a/voxygen/src/anim/character/jump.rs b/voxygen/src/anim/character/jump.rs index 6a1e7d95fc..d3487b388f 100644 --- a/voxygen/src/anim/character/jump.rs +++ b/voxygen/src/anim/character/jump.rs @@ -39,17 +39,17 @@ impl Animation for JumpAnimation { -8.0, 0.0 + wave_stop * 3.8, 7.0 + wave_stop * 3.2 - wave * 0.4, - ) / 11.0; + ); next.l_hand.ori = Quaternion::rotation_x(wave_stop_alt * 0.6); - next.l_hand.scale = Vec3::one() / 11.0; + next.l_hand.scale = Vec3::one(); next.r_hand.offset = Vec3::new( 8.0, 0.0 + wave_stop * -3.8, 7.0 + wave_stop * 3.2 - wave * 0.4, - ) / 11.0; + ); next.r_hand.ori = Quaternion::rotation_x(-wave_stop_alt * 0.6); - next.r_hand.scale = Vec3::one() / 11.0; + next.r_hand.scale = Vec3::one(); next.l_foot.offset = Vec3::new(-3.4, 1.0, 6.0); next.l_foot.ori = Quaternion::rotation_x(wave_stop * -1.2 - wave_slow * 0.2); diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs index b50f3e89ea..e570b7cf0a 100644 --- a/voxygen/src/anim/character/mod.rs +++ b/voxygen/src/anim/character/mod.rs @@ -74,8 +74,8 @@ impl Skeleton for CharacterSkeleton { FigureBoneData::new(torso_mat * chest_mat), FigureBoneData::new(torso_mat * self.belt.compute_base_matrix()), FigureBoneData::new(torso_mat * self.shorts.compute_base_matrix()), - FigureBoneData::new(l_hand_mat), - FigureBoneData::new(self.r_hand.compute_base_matrix()), + FigureBoneData::new(torso_mat * l_hand_mat), + FigureBoneData::new(torso_mat * self.r_hand.compute_base_matrix()), FigureBoneData::new(torso_mat * self.l_foot.compute_base_matrix()), FigureBoneData::new(torso_mat * self.r_foot.compute_base_matrix()), FigureBoneData::new(torso_mat * chest_mat * weapon_mat), diff --git a/voxygen/src/anim/character/roll.rs b/voxygen/src/anim/character/roll.rs index 88b9ca0f54..48e5ca8d46 100644 --- a/voxygen/src/anim/character/roll.rs +++ b/voxygen/src/anim/character/roll.rs @@ -22,11 +22,11 @@ impl Animation for RollAnimation { let wave_slow = (anim_time as f32 * 2.0 + PI).sin(); let wave_dub = (anim_time as f32 * 4.0).sin(); - next.head.offset = Vec3::new(0.0, -1.0 + wave_slow * -3.0, 16.0 + wave_dub * -3.0); + next.head.offset = Vec3::new(0.0, 0.0 + wave_slow * -3.0, 9.0 + wave_dub * -5.0); next.head.ori = Quaternion::rotation_x(wave_dub * -0.4); next.head.scale = Vec3::one(); - next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_dub * -1.5); + next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_dub * -2.5); next.chest.ori = Quaternion::rotation_x(wave_dub * -0.5); next.chest.scale = Vec3::one() * 1.01; @@ -40,32 +40,32 @@ impl Animation for RollAnimation { next.l_hand.offset = Vec3::new( -5.5 + wave * -0.5, - -2.0 + wave_quick_cos * 5.5, - 8.0 + wave_quick * -5.5, - ) / 11.0; + -2.0 + wave_quick_cos * -5.5, + 8.0 + wave_quick * 0.5, + ); next.l_hand.ori = Quaternion::rotation_x(wave_slow * 6.5) * Quaternion::rotation_y(wave * 0.3); - next.l_hand.scale = Vec3::one() / 11.0; + next.l_hand.scale = Vec3::one(); next.r_hand.offset = Vec3::new( 5.5 + wave * 0.5, - -2.0 + wave_quick_cos * 5.5, - 8.0 + wave_quick * -5.5, - ) / 11.0; + -2.0 + wave_quick_cos * 2.5, + 8.0 + wave_quick * 3.0, + ); next.r_hand.ori = Quaternion::rotation_x(wave_slow * 6.5) * Quaternion::rotation_y(wave * 0.3); - next.r_hand.scale = Vec3::one() / 11.; + next.r_hand.scale = Vec3::one(); - next.l_foot.offset = Vec3::new(-3.4, -0.1, 9.0 - 0.0 + wave * 1.2); + next.l_foot.offset = Vec3::new(-3.4, -0.1, 9.0 - 0.0 + wave_dub * -1.2); next.l_foot.ori = Quaternion::rotation_x(wave * 0.6); next.l_foot.scale = Vec3::one(); - next.r_foot.offset = Vec3::new(3.4, -0.1, 9.0 - 0.0 + wave * 1.0); + next.r_foot.offset = Vec3::new(3.4, -0.1, 9.0 - 0.0 + wave_dub * -1.0); next.r_foot.ori = Quaternion::rotation_x(wave * -0.4); next.r_foot.scale = Vec3::one(); - next.weapon.offset = Vec3::new(-7.0, -7.0, 18.0); + next.weapon.offset = Vec3::new(-7.0, -7.0, 15.0); next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_quick * 1.0); next.weapon.scale = Vec3::one(); @@ -90,7 +90,7 @@ impl Animation for RollAnimation { next.right_equip.ori = Quaternion::rotation_x(0.0);; next.right_equip.scale = Vec3::one() * 0.0; - next.torso.offset = Vec3::new(0.0, -2.2, 0.1 + wave_dub * 12.0) / 11.0; + next.torso.offset = Vec3::new(0.0, -2.2, 0.1 + wave_dub * 16.0) / 11.0; next.torso.ori = Quaternion::rotation_x(wave_slow * 6.0); next.torso.scale = Vec3::one() / 11.0; next diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index 0c188fde45..b5405cfdc7 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -1,4 +1,5 @@ use super::{super::Animation, CharacterSkeleton}; +use std::f32::consts::PI; use std::ops::Mul; use vek::*; @@ -17,6 +18,9 @@ impl Animation for RunAnimation { let wave = (anim_time as f32 * 14.0).sin(); let wave_cos = (anim_time as f32 * 14.0).cos(); + let wave_diff = (anim_time as f32 * 14.0 + PI / 2.0).sin(); + let wave_cos_dub = (anim_time as f32 * 28.0).cos(); + let wave_stop = (anim_time as f32 * 3.0).min(PI / 2.0).sin(); let head_look = Vec2::new( ((global_time + anim_time) as f32 / 2.0) @@ -48,13 +52,21 @@ impl Animation for RunAnimation { next.shorts.ori = Quaternion::rotation_z(wave * 0.6); next.shorts.scale = Vec3::one(); - next.l_hand.offset = Vec3::new(-9.0, 3.0 + wave_cos * 8.0, 12.0 - wave * 1.0) / 11.0; - next.l_hand.ori = Quaternion::rotation_x(wave_cos * 1.1); - next.l_hand.scale = Vec3::one() / 11.0; + next.l_hand.offset = Vec3::new( + -8.5 + wave_cos_dub * 0.8, + 2.0 + wave_cos * 6.0, + 7.0 - wave * 1.0, + ); + next.l_hand.ori = Quaternion::rotation_x(wave_cos * 0.8); + next.l_hand.scale = Vec3::one(); - next.r_hand.offset = Vec3::new(9.0, 3.0 - wave_cos * 8.0, 12.0 + wave * 1.0) / 11.0; - next.r_hand.ori = Quaternion::rotation_x(wave_cos * -1.1); - next.r_hand.scale = Vec3::one() / 11.0; + next.r_hand.offset = Vec3::new( + 8.5 - wave_cos_dub * 0.8, + 2.0 - wave_cos * 6.0, + 7.0 + wave * 1.0, + ); + next.r_hand.ori = Quaternion::rotation_x(wave_cos * -0.8); + next.r_hand.scale = Vec3::one(); next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0); next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.5); @@ -65,7 +77,8 @@ impl Animation for RunAnimation { next.r_foot.scale = Vec3::one(); next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0); - next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + next.weapon.ori = + Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25); next.weapon.scale = Vec3::one(); next.l_shoulder.offset = Vec3::new(-10.0, -3.2, 2.5); @@ -89,7 +102,8 @@ impl Animation for RunAnimation { next.right_equip.scale = Vec3::one() * 0.0; next.torso.offset = Vec3::new(0.0, -0.2, 0.4); - next.torso.ori = Quaternion::rotation_x(-velocity * 0.04 - wave_cos * 0.10); + next.torso.ori = + Quaternion::rotation_x(wave_stop * velocity * -0.04 + wave_diff * velocity * -0.005); next.torso.scale = Vec3::one() / 11.0; next diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 547be1e146..8d07489fa6 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -574,7 +574,7 @@ impl FigureMgr { comp::Animation::Gliding => { character::GlidingAnimation::update_skeleton( state.skeleton_mut(), - time, + (vel.0.magnitude(), time), animation_info.time, ) } From ae081b8f67f562363850329d05c3d5c6272cf537 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 16 Jun 2019 14:56:07 +0200 Subject: [PATCH 09/19] Make roll timed --- common/src/sys/controller.rs | 4 +--- common/src/sys/phys.rs | 15 +++++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index aa3b68c81e..9df950c144 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -98,10 +98,8 @@ impl<'a> System<'a> for Sys { } // Roll - if on_ground.is_some() && controller.roll { + if controller.roll && rollings.get(entity).is_none() && on_ground.is_some() { rollings.insert(entity, Rolling::start()); - } else { - rollings.remove(entity); } } } diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 55e1044b81..75d9d5ca7e 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -53,8 +53,8 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, MoveDir>, ReadStorage<'a, Jumping>, ReadStorage<'a, Gliding>, - ReadStorage<'a, Rolling>, ReadStorage<'a, Stats>, + WriteStorage<'a, Rolling>, WriteStorage<'a, OnGround>, WriteStorage<'a, Pos>, WriteStorage<'a, Vel>, @@ -70,8 +70,8 @@ impl<'a> System<'a> for Sys { move_dirs, jumpings, glidings, - rollings, stats, + mut rollings, mut on_grounds, mut positions, mut velocities, @@ -79,13 +79,12 @@ impl<'a> System<'a> for Sys { ): Self::SystemData, ) { // Apply movement inputs - for (entity, stats, move_dir, jumping, gliding, rolling, mut pos, mut vel, mut ori) in ( + for (entity, stats, move_dir, jumping, gliding, mut pos, mut vel, mut ori) in ( &entities, &stats, move_dirs.maybe(), jumpings.maybe(), glidings.maybe(), - rollings.maybe(), &mut positions, &mut velocities, &mut orientations, @@ -130,8 +129,12 @@ impl<'a> System<'a> for Sys { vel.0.z += dt.0 * lift * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); } - // TODO: - if rolling.is_some() {} + if let Some(time) = rollings.get_mut(entity).map(|r| &mut r.time) { + *time += dt.0; + if *time > 0.7 { + rollings.remove(entity); + } + } // Set direction based on velocity if vel.0.magnitude_squared() != 0.0 { From e066d987626ecf2948f6233a960d0be4f74c6ccf Mon Sep 17 00:00:00 2001 From: jshipsey Date: Sun, 16 Jun 2019 09:57:01 -0400 Subject: [PATCH 10/19] slight roll tweak, altered speeds in physics --- common/src/sys/phys.rs | 9 +++++---- voxygen/src/anim/character/roll.rs | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 75d9d5ca7e..a7496282d5 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -10,13 +10,13 @@ use vek::*; const GRAVITY: f32 = 9.81 * 4.0; const FRIC_GROUND: f32 = 0.15; const FRIC_AIR: f32 = 0.015; -const HUMANOID_ACCEL: f32 = 100.0; -const HUMANOID_SPEED: f32 = 500.0; +const HUMANOID_ACCEL: f32 = 70.0; +const HUMANOID_SPEED: f32 = 120.0; const HUMANOID_AIR_ACCEL: f32 = 10.0; const HUMANOID_AIR_SPEED: f32 = 100.0; const HUMANOID_JUMP_ACCEL: f32 = 16.0; -const ROLL_ACCEL: f32 = 200.0; -const ROLL_SPEED: f32 = 800.0; +const ROLL_ACCEL: f32 = 140.0; +const ROLL_SPEED: f32 = 450.0; const GLIDE_ACCEL: f32 = 15.0; const GLIDE_SPEED: f32 = 45.0; // Gravity is 9.81 * 4, so this makes gravity equal to .15 @@ -129,6 +129,7 @@ impl<'a> System<'a> for Sys { vel.0.z += dt.0 * lift * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); } + // Roll if let Some(time) = rollings.get_mut(entity).map(|r| &mut r.time) { *time += dt.0; if *time > 0.7 { diff --git a/voxygen/src/anim/character/roll.rs b/voxygen/src/anim/character/roll.rs index 48e5ca8d46..2dc242ac0b 100644 --- a/voxygen/src/anim/character/roll.rs +++ b/voxygen/src/anim/character/roll.rs @@ -57,11 +57,11 @@ impl Animation for RollAnimation { Quaternion::rotation_x(wave_slow * 6.5) * Quaternion::rotation_y(wave * 0.3); next.r_hand.scale = Vec3::one(); - next.l_foot.offset = Vec3::new(-3.4, -0.1, 9.0 - 0.0 + wave_dub * -1.2); + next.l_foot.offset = Vec3::new(-3.4, -0.1, 9.0 - 0.0 + wave_dub * -1.2 + wave_slow * 4.0); next.l_foot.ori = Quaternion::rotation_x(wave * 0.6); next.l_foot.scale = Vec3::one(); - next.r_foot.offset = Vec3::new(3.4, -0.1, 9.0 - 0.0 + wave_dub * -1.0); + next.r_foot.offset = Vec3::new(3.4, -0.1, 9.0 - 0.0 + wave_dub * -1.0 + wave_slow * 4.0); next.r_foot.ori = Quaternion::rotation_x(wave * -0.4); next.r_foot.scale = Vec3::one(); From 0c534efddd18e0020db70f3cfd3b4bd03d3240a9 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Sun, 16 Jun 2019 11:37:31 -0400 Subject: [PATCH 11/19] adjusted v-tilt, roll speed, run animation tempo --- common/src/sys/phys.rs | 4 ++-- voxygen/src/anim/character/run.rs | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index a7496282d5..a72d338c48 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -15,8 +15,8 @@ const HUMANOID_SPEED: f32 = 120.0; const HUMANOID_AIR_ACCEL: f32 = 10.0; const HUMANOID_AIR_SPEED: f32 = 100.0; const HUMANOID_JUMP_ACCEL: f32 = 16.0; -const ROLL_ACCEL: f32 = 140.0; -const ROLL_SPEED: f32 = 450.0; +const ROLL_ACCEL: f32 = 160.0; +const ROLL_SPEED: f32 = 550.0; const GLIDE_ACCEL: f32 = 15.0; const GLIDE_SPEED: f32 = 45.0; // Gravity is 9.81 * 4, so this makes gravity equal to .15 diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index b5405cfdc7..f3e21f8022 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -16,11 +16,11 @@ impl Animation for RunAnimation { ) -> Self::Skeleton { let mut next = (*skeleton).clone(); - let wave = (anim_time as f32 * 14.0).sin(); - let wave_cos = (anim_time as f32 * 14.0).cos(); - let wave_diff = (anim_time as f32 * 14.0 + PI / 2.0).sin(); - let wave_cos_dub = (anim_time as f32 * 28.0).cos(); - let wave_stop = (anim_time as f32 * 3.0).min(PI / 2.0).sin(); + let wave = (anim_time as f32 * 12.0).sin(); + let wave_cos = (anim_time as f32 * 12.0).cos(); + let wave_diff = (anim_time as f32 * 12.0 + PI / 2.0).sin(); + let wave_cos_dub = (anim_time as f32 * 24.0).cos(); + let wave_stop = (anim_time as f32 * 2.6).min(PI / 2.0).sin(); let head_look = Vec2::new( ((global_time + anim_time) as f32 / 2.0) @@ -54,7 +54,7 @@ impl Animation for RunAnimation { next.l_hand.offset = Vec3::new( -8.5 + wave_cos_dub * 0.8, - 2.0 + wave_cos * 6.0, + 2.0 + wave_cos * 5.0, 7.0 - wave * 1.0, ); next.l_hand.ori = Quaternion::rotation_x(wave_cos * 0.8); @@ -62,18 +62,18 @@ impl Animation for RunAnimation { next.r_hand.offset = Vec3::new( 8.5 - wave_cos_dub * 0.8, - 2.0 - wave_cos * 6.0, + 2.0 - wave_cos * 5.0, 7.0 + wave * 1.0, ); next.r_hand.ori = Quaternion::rotation_x(wave_cos * -0.8); next.r_hand.scale = Vec3::one(); - next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0); - next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.5); + next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 7.0); + next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.3); next.l_foot.scale = Vec3::one(); - next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 6.0); - next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.5); + next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 7.0); + next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.3); next.r_foot.scale = Vec3::one(); next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0); @@ -103,7 +103,7 @@ impl Animation for RunAnimation { next.torso.offset = Vec3::new(0.0, -0.2, 0.4); next.torso.ori = - Quaternion::rotation_x(wave_stop * velocity * -0.04 + wave_diff * velocity * -0.005); + Quaternion::rotation_x(wave_stop * velocity * -0.06 + wave_diff * velocity * -0.005); next.torso.scale = Vec3::one() / 11.0; next From 2afc45617d703262926d5a2e9476eb557676ce41 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 16 Jun 2019 17:40:47 +0200 Subject: [PATCH 12/19] More input validation --- common/src/sys/animation.rs | 3 +-- common/src/sys/controller.rs | 44 +++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/common/src/sys/animation.rs b/common/src/sys/animation.rs index 2ccc5cff18..95bb562f90 100644 --- a/common/src/sys/animation.rs +++ b/common/src/sys/animation.rs @@ -49,7 +49,6 @@ impl<'a> System<'a> for Sys { .join() { animation_info.time += dt.0 as f64; - let moving = vel.0.magnitude() > 3.0; fn impossible_animation(message: &str) -> Animation { warn!("{}", message); @@ -58,7 +57,7 @@ impl<'a> System<'a> for Sys { let animation = match ( on_ground.is_some(), - moving, + vel.0.magnitude() > 3.0, // Moving attacking.is_some(), gliding.is_some(), rolling.is_some(), diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 9df950c144..cf518f7cb1 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -65,40 +65,58 @@ impl<'a> System<'a> for Sys { continue; } + // Move dir + if rollings.get(entity).is_none() { + move_dirs.insert( + entity, + MoveDir(if controller.move_dir.magnitude() > 1.0 { + controller.move_dir.normalized() + } else { + controller.move_dir + }), + ); + } + // Glide - if controller.glide && on_ground.is_none() && attackings.get(entity).is_none() { + if controller.glide + && glidings.get(entity).is_none() + && on_ground.is_none() + && attackings.get(entity).is_none() + && rollings.get(entity).is_none() + { glidings.insert(entity, Gliding); } else { glidings.remove(entity); } - // Move dir - move_dirs.insert( - entity, - MoveDir(if controller.move_dir.magnitude() > 1.0 { - controller.move_dir.normalized() - } else { - controller.move_dir - }), - ); - // Attack if controller.attack && attackings.get(entity).is_none() && glidings.get(entity).is_none() + && rollings.get(entity).is_none() { attackings.insert(entity, Attacking::start()); } // Jump - if on_ground.is_some() && controller.jump && vel.0.z <= 0.0 { + if controller.jump + && jumpings.get(entity).is_none() + && on_ground.is_some() + && vel.0.z <= 0.0 + { jumpings.insert(entity, Jumping); } else { jumpings.remove(entity); } // Roll - if controller.roll && rollings.get(entity).is_none() && on_ground.is_some() { + if controller.roll + && rollings.get(entity).is_none() + && attackings.get(entity).is_none() + && glidings.get(entity).is_none() + && on_ground.is_some() + && vel.0.magnitude() > 5.0 + { rollings.insert(entity, Rolling::start()); } } From 14ff03377049976efc6a2683bbe8358067344afa Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 16 Jun 2019 17:52:44 +0200 Subject: [PATCH 13/19] Fix glider --- common/src/sys/controller.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index cf518f7cb1..dc65eed02b 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -79,7 +79,6 @@ impl<'a> System<'a> for Sys { // Glide if controller.glide - && glidings.get(entity).is_none() && on_ground.is_none() && attackings.get(entity).is_none() && rollings.get(entity).is_none() From 8e019cdbecb0d898945043d69fe3b7f98f5d1d54 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Sun, 16 Jun 2019 11:54:02 -0400 Subject: [PATCH 14/19] lowered roll duration --- common/src/sys/phys.rs | 2 +- voxygen/src/anim/character/roll.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index a72d338c48..09d0b7a794 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -132,7 +132,7 @@ impl<'a> System<'a> for Sys { // Roll if let Some(time) = rollings.get_mut(entity).map(|r| &mut r.time) { *time += dt.0; - if *time > 0.7 { + if *time > 0.55 { rollings.remove(entity); } } diff --git a/voxygen/src/anim/character/roll.rs b/voxygen/src/anim/character/roll.rs index 2dc242ac0b..f5fa454ab8 100644 --- a/voxygen/src/anim/character/roll.rs +++ b/voxygen/src/anim/character/roll.rs @@ -15,12 +15,12 @@ impl Animation for RollAnimation { ) -> Self::Skeleton { let mut next = (*skeleton).clone(); - let wave = (anim_time as f32 * 4.0).sin(); - let wave_quick = (anim_time as f32 * 7.0).sin(); - let wave_quick_cos = (anim_time as f32 * 7.0).cos(); - let wave_cos = (anim_time as f32 * 4.0).cos(); - let wave_slow = (anim_time as f32 * 2.0 + PI).sin(); - let wave_dub = (anim_time as f32 * 4.0).sin(); + let wave = (anim_time as f32 * 5.5).sin(); + let wave_quick = (anim_time as f32 * 9.5).sin(); + let wave_quick_cos = (anim_time as f32 * 9.5).cos(); + let wave_cos = (anim_time as f32 * 5.5).cos(); + let wave_slow = (anim_time as f32 * 2.8 + PI).sin(); + let wave_dub = (anim_time as f32 * 5.5).sin(); next.head.offset = Vec3::new(0.0, 0.0 + wave_slow * -3.0, 9.0 + wave_dub * -5.0); next.head.ori = Quaternion::rotation_x(wave_dub * -0.4); From ed2773fbcabd61cc9c111b767a87e0b85e3de2ee Mon Sep 17 00:00:00 2001 From: jshipsey Date: Sun, 16 Jun 2019 12:29:59 -0400 Subject: [PATCH 15/19] changed hand motion on run animation --- voxygen/src/anim/character/run.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index f3e21f8022..22f74cc059 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -53,20 +53,20 @@ impl Animation for RunAnimation { next.shorts.scale = Vec3::one(); next.l_hand.offset = Vec3::new( - -8.5 + wave_cos_dub * 0.8, + -9.0 + wave_cos_dub * 1.0, 2.0 + wave_cos * 5.0, - 7.0 - wave * 1.0, + 7.0 - wave * 1.5, ); next.l_hand.ori = Quaternion::rotation_x(wave_cos * 0.8); - next.l_hand.scale = Vec3::one(); + next.l_hand.scale = Vec3::one() * 1.2; next.r_hand.offset = Vec3::new( - 8.5 - wave_cos_dub * 0.8, + 9.0 - wave_cos_dub * 1.0, 2.0 - wave_cos * 5.0, - 7.0 + wave * 1.0, + 7.0 + wave * 1.5, ); next.r_hand.ori = Quaternion::rotation_x(wave_cos * -0.8); - next.r_hand.scale = Vec3::one(); + next.r_hand.scale = Vec3::one() * 1.2; next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 7.0); next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.3); From 8dd1e46883253bf4d988a6b2782d49e3bbf72f41 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Sun, 16 Jun 2019 12:57:31 -0400 Subject: [PATCH 16/19] run tweaks --- voxygen/src/anim/character/run.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index 22f74cc059..0e2cf4474f 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -53,20 +53,20 @@ impl Animation for RunAnimation { next.shorts.scale = Vec3::one(); next.l_hand.offset = Vec3::new( - -9.0 + wave_cos_dub * 1.0, + -7.5 + wave_cos_dub * 1.0, 2.0 + wave_cos * 5.0, 7.0 - wave * 1.5, ); next.l_hand.ori = Quaternion::rotation_x(wave_cos * 0.8); - next.l_hand.scale = Vec3::one() * 1.2; + next.l_hand.scale = Vec3::one() * 1.0; next.r_hand.offset = Vec3::new( - 9.0 - wave_cos_dub * 1.0, + 7.5 - wave_cos_dub * 1.0, 2.0 - wave_cos * 5.0, 7.0 + wave * 1.5, ); next.r_hand.ori = Quaternion::rotation_x(wave_cos * -0.8); - next.r_hand.scale = Vec3::one() * 1.2; + next.r_hand.scale = Vec3::one() * 1.0; next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 7.0); next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.3); From f0e6e764235f26add01d28d118aa72aa1e1888df Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 16 Jun 2019 19:00:44 +0200 Subject: [PATCH 17/19] Don't sync animations, just sync components used to construct them --- client/src/lib.rs | 13 ------------- common/src/comp/inputs.rs | 2 +- common/src/msg/client.rs | 1 - common/src/msg/ecs_packet.rs | 4 ++-- common/src/state.rs | 10 +++++----- common/src/sys/controller.rs | 3 --- common/src/sys/phys.rs | 10 +++++----- server/src/lib.rs | 9 --------- 8 files changed, 13 insertions(+), 39 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 655e7179be..0d50cb51a6 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -292,19 +292,6 @@ impl Client { _ => {} } - // Update the server about the player's current animation. - if let Some(animation_info) = self - .state - .ecs_mut() - .write_storage::() - .get_mut(self.entity) - { - if animation_info.changed { - self.postbox - .send_message(ClientMsg::PlayerAnimation(animation_info.clone())); - } - } - // Output debug metrics if log_enabled!(log::Level::Info) && self.tick % 600 == 0 { let metrics = self diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs index 0e021094f7..66c51d634b 100644 --- a/common/src/comp/inputs.rs +++ b/common/src/comp/inputs.rs @@ -71,5 +71,5 @@ impl Component for Jumping { } impl Component for Gliding { - type Storage = NullStorage; + type Storage = FlaggedStorage>; } diff --git a/common/src/msg/client.rs b/common/src/msg/client.rs index 47ec6fae5b..db1c40d4c7 100644 --- a/common/src/msg/client.rs +++ b/common/src/msg/client.rs @@ -17,7 +17,6 @@ pub enum ClientMsg { Ping, Pong, Chat(String), - PlayerAnimation(comp::AnimationInfo), PlayerPhysics { pos: comp::Pos, vel: comp::Vel, diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index 899579b8c3..841b0d5a8e 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -25,7 +25,7 @@ sphynx::sum_type! { Stats(comp::Stats), Attacking(comp::Attacking), Rolling(comp::Rolling), - + Gliding(comp::Gliding), } } // Automatically derive From for EcsCompPhantom @@ -41,7 +41,7 @@ sphynx::sum_type! { Stats(PhantomData), Attacking(PhantomData), Rolling(PhantomData), - + Gliding(PhantomData), } } impl sphynx::CompPacket for EcsCompPacket { diff --git a/common/src/state.rs b/common/src/state.rs index 6e1f2dde1e..974c841258 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -98,13 +98,13 @@ impl State { // Create a new Sphynx ECS world. fn setup_sphynx_world(ecs: &mut sphynx::World) { - // Register synced components. + // Register server->client synced components. ecs.register_synced::(); ecs.register_synced::(); ecs.register_synced::(); - ecs.register_synced::(); // TODO: Don't send this to the client? - ecs.register_synced::(); // TODO: Don't send this to the client? - ecs.register::(); + ecs.register_synced::(); + ecs.register_synced::(); + ecs.register_synced::(); // Register components synced by other means ecs.register::(); @@ -121,8 +121,8 @@ impl State { // Register server-local components ecs.register::(); ecs.register::(); - ecs.register::(); ecs.register::(); + ecs.register::(); ecs.register::(); // Register synced resources used by the ECS. diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index dc65eed02b..d643b960fe 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -99,13 +99,10 @@ impl<'a> System<'a> for Sys { // Jump if controller.jump - && jumpings.get(entity).is_none() && on_ground.is_some() && vel.0.z <= 0.0 { jumpings.insert(entity, Jumping); - } else { - jumpings.remove(entity); } // Roll diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 09d0b7a794..44dfdeecd3 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -51,9 +51,9 @@ impl<'a> System<'a> for Sys { ReadExpect<'a, TerrainMap>, Read<'a, DeltaTime>, ReadStorage<'a, MoveDir>, - ReadStorage<'a, Jumping>, ReadStorage<'a, Gliding>, ReadStorage<'a, Stats>, + WriteStorage<'a, Jumping>, WriteStorage<'a, Rolling>, WriteStorage<'a, OnGround>, WriteStorage<'a, Pos>, @@ -68,9 +68,9 @@ impl<'a> System<'a> for Sys { terrain, dt, move_dirs, - jumpings, glidings, stats, + mut jumpings, mut rollings, mut on_grounds, mut positions, @@ -79,11 +79,10 @@ impl<'a> System<'a> for Sys { ): Self::SystemData, ) { // Apply movement inputs - for (entity, stats, move_dir, jumping, gliding, mut pos, mut vel, mut ori) in ( + for (entity, stats, move_dir, gliding, mut pos, mut vel, mut ori) in ( &entities, &stats, move_dirs.maybe(), - jumpings.maybe(), glidings.maybe(), &mut positions, &mut velocities, @@ -119,8 +118,9 @@ impl<'a> System<'a> for Sys { } // Jump - if jumping.is_some() { + if jumpings.get(entity).is_some() { vel.0.z = HUMANOID_JUMP_ACCEL; + jumpings.remove(entity); } // Glide diff --git a/server/src/lib.rs b/server/src/lib.rs index 194fa2b908..79a382feae 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -512,15 +512,6 @@ impl Server { | ClientState::Character => new_chat_msgs.push((Some(entity), msg)), ClientState::Pending => {} }, - ClientMsg::PlayerAnimation(animation_info) => { - match client.client_state { - ClientState::Character => { - state.write_component(entity, animation_info) - } - // Only characters can send animations. - _ => client.error_state(RequestStateError::Impossible), - } - } ClientMsg::PlayerPhysics { pos, vel, ori } => match client.client_state { ClientState::Character => { state.write_component(entity, pos); From eb10389eb611ce1554afbe7e777f05dbdaa55241 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sun, 16 Jun 2019 19:56:55 +0200 Subject: [PATCH 18/19] cargo fmt --- common/src/sys/controller.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index d643b960fe..5bd45ac7c7 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -98,10 +98,7 @@ impl<'a> System<'a> for Sys { } // Jump - if controller.jump - && on_ground.is_some() - && vel.0.z <= 0.0 - { + if controller.jump && on_ground.is_some() && vel.0.z <= 0.0 { jumpings.insert(entity, Jumping); } From 9ad2feb037763a813044b049332815dfbe17b9b2 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 16 Jun 2019 20:53:10 +0100 Subject: [PATCH 19/19] Ignore ForcedUpdate insertion --- common/src/sys/combat.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs index a3106bfcda..5aefa31c0d 100644 --- a/common/src/sys/combat.rs +++ b/common/src/sys/combat.rs @@ -55,9 +55,7 @@ impl<'a> System<'a> for Sys { stat_b.hp.change_by(-10, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon vel_b.0 += (pos_b.0 - pos.0).normalized() * 10.0; vel_b.0.z = 15.0; - if let Err(err) = force_updates.insert(b, ForceUpdate) { - warn!("Inserting ForceUpdate for an entity failed: {:?}", err); - } + let _ = force_updates.insert(b, ForceUpdate); } } attacking.applied = true;