From 1ab09220b0c5dc73ce6e39084ede7baced497557 Mon Sep 17 00:00:00 2001 From: AdamWhitehurst Date: Sat, 21 Dec 2019 07:57:15 -0800 Subject: [PATCH] Rudimentary Stand State handle() move --- common/src/comp/character_state.rs | 159 +----------------- common/src/comp/mod.rs | 2 +- common/src/sys/character_state.rs | 232 ++++++++++++++++++++++++-- common/src/sys/movement.rs | 7 +- voxygen/src/audio/sfx/event_mapper.rs | 2 +- voxygen/src/scene/figure/mod.rs | 54 +++--- 6 files changed, 253 insertions(+), 203 deletions(-) diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 192af702ef..1df20ddde1 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -1,173 +1,16 @@ -use crate::comp::{ - Body, CharacterState, Controller, ControllerInputs, ItemKind, PhysicsState, Stats, -}; +use crate::comp::{Body, Controller, ControllerInputs, ItemKind, PhysicsState, Stats}; use specs::{Component, FlaggedStorage, HashMapStorage}; use specs::{Entities, Join, LazyUpdate, Read, ReadStorage, System}; use sphynx::{Uid, UidAllocator}; //use specs_idvs::IDVStorage; use self::{ActionState::*, MovementState::*}; use std::time::Duration; -pub trait State { - fn handle( - &self, - character: &CharacterState, - inputs: &ControllerInputs, - stats: &Stats, - body: &Body, - physics: &PhysicsState, - ) -> CharacterState; -} #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] pub struct RunData; #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] pub struct StandData; -impl State for StandData { - fn handle( - &self, - character: &CharacterState, - inputs: &ControllerInputs, - stats: &Stats, - body: &Body, - physics: &PhysicsState, - ) -> CharacterState { - let mut new_move: MovementState = if inputs.move_dir.magnitude_squared() > 0.0 { - MovementState::Run(RunData) - } else { - MovementState::Stand(StandData) - }; - - // Try to sit - if inputs.sit.is_pressed() && physics.on_ground && body.is_humanoid() { - return CharacterState { - movement: Sit, - action: Idle, - }; - } - - // Try to climb - if let (true, Some(_wall_dir)) = ( - inputs.climb.is_pressed() | inputs.climb_down.is_pressed() && body.is_humanoid(), - physics.on_wall, - ) { - return CharacterState { - movement: Climb, - action: Idle, - }; - } - - // Try to swim - if !physics.on_ground && physics.in_fluid { - return CharacterState { - action: character.action, - movement: Swim, - }; - } - - // While on ground ... - if physics.on_ground { - // Try to jump - if inputs.jump.is_pressed() && !inputs.jump.is_held_down() { - return CharacterState { - action: character.action, - movement: Jump, - }; - } - - // Try to charge - if inputs.charge.is_pressed() && !inputs.charge.is_held_down() { - return CharacterState { - action: Charge { - time_left: Duration::from_millis(250), - }, - movement: Run(RunData), - }; - } - - // Try to roll - if inputs.roll.is_pressed() && body.is_humanoid() { - return CharacterState { - action: Roll { - time_left: Duration::from_millis(600), - was_wielding: character.action.is_wield(), - }, - movement: Run(RunData), - }; - } - } - // While not on ground ... - else { - // Try to glide - if physics.on_wall == None - && inputs.glide.is_pressed() - && !inputs.glide.is_held_down() - && body.is_humanoid() - { - return CharacterState { - action: Idle, - movement: Glide, - }; - } - return CharacterState { - action: character.action, - movement: Fall, - }; - } - - // Tool Actions - if inputs.toggle_wield.is_just_pressed() { - match character.action { - Wield { .. } | Attack { .. } => { - // Prevent instantaneous reequipping by checking - // for done wielding - if character.action.is_action_finished() { - return CharacterState { - action: Idle, - movement: character.movement, - }; - } - } - Idle => { - return CharacterState { - // Try to wield if an item is equipped in main hand - action: if let Some(ItemKind::Tool { kind, .. }) = - stats.equipment.main.as_ref().map(|i| &i.kind) - { - let wield_duration = kind.wield_duration(); - Wield { - time_left: wield_duration, - } - } else { - Idle - }, - movement: character.movement, - }; - } - Charge { .. } | Roll { .. } | Block { .. } => {} - } - } - if inputs.primary.is_pressed() { - // TODO: PrimaryStart - } else if inputs.secondary.is_pressed() { - // TODO: SecondaryStart - } - - if inputs.move_dir.magnitude_squared() > 0.0 { - return CharacterState { - action: character.action, - movement: Run(RunData), - }; - } else { - return CharacterState { - action: character.action, - movement: Stand(StandData), - }; - } - return character; - } -} - #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] pub enum MovementState { Stand(StandData), diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 42f8e6e161..a119bf10a6 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -20,7 +20,7 @@ pub use body::{ biped_large, bird_medium, bird_small, dragon, fish_medium, fish_small, humanoid, object, quadruped_medium, quadruped_small, Body, }; -pub use character_state::{ActionState, CharacterState, MovementState}; +pub use character_state::{ActionState, CharacterState, MovementState, RunData, StandData}; pub use controller::{ ControlEvent, Controller, ControllerInputs, Input, InputState, InventoryManip, MountState, Mounting, diff --git a/common/src/sys/character_state.rs b/common/src/sys/character_state.rs index c6fb92407e..8a26c82e5b 100644 --- a/common/src/sys/character_state.rs +++ b/common/src/sys/character_state.rs @@ -1,14 +1,12 @@ use super::movement::ROLL_DURATION; +const HUMANOID_ACCEL: f32 = 50.0; +const HUMANOID_SPEED: f32 = 120.0; use crate::{ comp::{ - self, item, projectile, ActionState, - ActionState::*, - Body, CharacterState, - CharacterState::{RunData, StandData}, - ControlEvent, Controller, ControllerInputs, HealthChange, HealthSource, ItemKind, Mounting, - MovementState, - MovementState::*, - PhysicsState, Projectile, Stats, Vel, + self, item, projectile, ActionState, ActionState::*, Body, CharacterState, ControlEvent, + Controller, ControllerInputs, HealthChange, HealthSource, ItemKind, Mounting, + MovementState, MovementState::*, Ori, PhysicsState, Pos, Projectile, RunData, StandData, + Stats, Vel, }, event::{Emitter, EventBus, LocalEvent, ServerEvent}, state::DeltaTime, @@ -33,10 +31,12 @@ impl<'a> System<'a> for Sys { Read<'a, EventBus>, Read<'a, DeltaTime>, WriteStorage<'a, CharacterState>, + WriteStorage<'a, Pos>, + WriteStorage<'a, Vel>, + WriteStorage<'a, Ori>, ReadStorage<'a, Controller>, ReadStorage<'a, Stats>, ReadStorage<'a, Body>, - ReadStorage<'a, Vel>, ReadStorage<'a, PhysicsState>, ReadStorage<'a, Uid>, ReadStorage<'a, Mounting>, @@ -50,10 +50,12 @@ impl<'a> System<'a> for Sys { local_bus, dt, mut character_states, + mut positions, + mut velocities, + mut orientations, controllers, stats, bodies, - velocities, physics_states, uids, mountings, @@ -61,14 +63,28 @@ impl<'a> System<'a> for Sys { ) { let mut server_emitter = server_bus.emitter(); let mut local_emitter = local_bus.emitter(); - for (entity, uid, mut character, controller, stats, body, vel, physics, mount) in ( + for ( + entity, + uid, + mut character, + mut pos, + mut vel, + mut ori, + controller, + stats, + body, + physics, + mount, + ) in ( &entities, &uids, &mut character_states, + &mut positions, + &mut velocities, + &mut orientations, &controllers, &stats, &bodies, - &velocities, &physics_states, mountings.maybe(), ) @@ -382,7 +398,7 @@ impl<'a> System<'a> for Sys { } if physics.on_ground { - character.movement = Stand(Stand) + character.movement = Stand(StandData) } } // Any Action + Climbing, shouldnt care about action, @@ -397,9 +413,197 @@ impl<'a> System<'a> for Sys { } } if physics.on_ground { - character.movement = Stand(Stand); + character.movement = Stand(StandData); } } + (_, Stand(data)) => { + let mut new_char = + data.handle(character, pos, vel, ori, &dt, inputs, stats, body, physics); + println!("{:?}", new_char); + character = &mut new_char; + } + (_, _) => { + character.movement = Stand(StandData); + } + }; + } + } +} + +pub trait State { + fn handle( + &self, + character: &CharacterState, + pos: &mut Pos, + vel: &mut Vel, + ori: &mut Ori, + dt: &DeltaTime, + inputs: &ControllerInputs, + stats: &Stats, + body: &Body, + physics: &PhysicsState, + ) -> CharacterState; +} + +impl State for StandData { + fn handle( + &self, + character: &CharacterState, + pos: &mut Pos, + vel: &mut Vel, + ori: &mut Ori, + dt: &DeltaTime, + inputs: &ControllerInputs, + stats: &Stats, + body: &Body, + physics: &PhysicsState, + ) -> CharacterState { + // Move player according to move_dir + vel.0 += Vec2::broadcast(dt.0) + * inputs.move_dir + * if vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) { + HUMANOID_ACCEL + } else { + 0.0 + }; + + // Set direction based on move direction when on the ground + let ori_dir = if character.action.is_attack() || character.action.is_block() { + Vec2::from(inputs.look_dir).normalized() + } else { + Vec2::from(vel.0) + }; + + if ori_dir.magnitude_squared() > 0.0001 + && (ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared() > 0.001 + { + ori.0 = vek::ops::Slerp::slerp(ori.0, ori_dir.into(), 9.0 * dt.0); + } + + // Try to sit + if inputs.sit.is_pressed() && physics.on_ground && body.is_humanoid() { + return CharacterState { + movement: Sit, + action: Idle, + }; + } + + // Try to climb + if let (true, Some(_wall_dir)) = ( + inputs.climb.is_pressed() | inputs.climb_down.is_pressed() && body.is_humanoid(), + physics.on_wall, + ) { + return CharacterState { + movement: Climb, + action: Idle, + }; + } + + // Try to swim + if !physics.on_ground && physics.in_fluid { + return CharacterState { + action: character.action, + movement: Swim, + }; + } + + // While on ground ... + if physics.on_ground { + // Try to jump + if inputs.jump.is_pressed() && !inputs.jump.is_held_down() { + return CharacterState { + action: character.action, + movement: Jump, + }; + } + + // Try to charge + if inputs.charge.is_pressed() && !inputs.charge.is_held_down() { + return CharacterState { + action: Charge { + time_left: Duration::from_millis(250), + }, + movement: Run(RunData), + }; + } + + // Try to roll + if inputs.roll.is_pressed() && body.is_humanoid() { + return CharacterState { + action: Roll { + time_left: Duration::from_millis(600), + was_wielding: character.action.is_wield(), + }, + movement: Run(RunData), + }; + } + } + // While not on ground ... + else { + // Try to glide + if physics.on_wall == None + && inputs.glide.is_pressed() + && !inputs.glide.is_held_down() + && body.is_humanoid() + { + return CharacterState { + action: Idle, + movement: Glide, + }; + } + return CharacterState { + action: character.action, + movement: Fall, + }; + } + + // Tool Actions + if inputs.toggle_wield.is_just_pressed() { + match character.action { + Wield { .. } | Attack { .. } => { + // Prevent instantaneous reequipping by checking + // for done wielding + if character.action.is_action_finished() { + return CharacterState { + action: Idle, + movement: character.movement, + }; + } + } + Idle => { + return CharacterState { + // Try to wield if an item is equipped in main hand + action: if let Some(ItemKind::Tool { kind, .. }) = + stats.equipment.main.as_ref().map(|i| &i.kind) + { + let wield_duration = kind.wield_duration(); + Wield { + time_left: wield_duration, + } + } else { + Idle + }, + movement: character.movement, + }; + } + Charge { .. } | Roll { .. } | Block { .. } => {} + } + } + if inputs.primary.is_pressed() { + // TODO: PrimaryStart + } else if inputs.secondary.is_pressed() { + // TODO: SecondaryStart + } + + if inputs.move_dir.magnitude_squared() > 0.0 { + return CharacterState { + action: character.action, + movement: Run(RunData), + }; + } else { + return CharacterState { + action: character.action, + movement: Stand(StandData), }; } } diff --git a/common/src/sys/movement.rs b/common/src/sys/movement.rs index 531acc9da0..bcbb29436b 100644 --- a/common/src/sys/movement.rs +++ b/common/src/sys/movement.rs @@ -1,7 +1,8 @@ use super::phys::GRAVITY; use crate::{ comp::{ - CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState, Pos, Stats, Vel, + CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState, Pos, RunData, + StandData, Stats, Vel, }, event::{EventBus, ServerEvent}, state::DeltaTime, @@ -105,7 +106,7 @@ impl<'a> System<'a> for Sys { ) .join() { - if character.movement == Run || character.movement == Stand { + if character.movement == Run(RunData) || character.movement == Stand(StandData) { continue; } @@ -145,7 +146,7 @@ impl<'a> System<'a> for Sys { vel.0 += Vec2::broadcast(dt.0) * inputs.move_dir * match (physics.on_ground, &character.movement) { - (true, Run) if vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) => { + (true, Run(_)) if vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) => { HUMANOID_ACCEL } (false, Climb) if vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) => { diff --git a/voxygen/src/audio/sfx/event_mapper.rs b/voxygen/src/audio/sfx/event_mapper.rs index 8524f04fc8..2873f2d590 100644 --- a/voxygen/src/audio/sfx/event_mapper.rs +++ b/voxygen/src/audio/sfx/event_mapper.rs @@ -162,7 +162,7 @@ impl SfxEventMapper { (_, ActionState::Roll { .. }, ..) => SfxEvent::Roll, (MovementState::Climb, ..) => SfxEvent::Climb, (MovementState::Swim, ..) => SfxEvent::Swim, - (MovementState::Run, ..) => SfxEvent::Run, + (MovementState::Run(_), ..) => SfxEvent::Run, (MovementState::Fall, _, previous_event, _) => { if previous_event != SfxEvent::Glide { SfxEvent::Fall diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index ddecd67043..7c7319f74e 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -197,14 +197,14 @@ impl FigureMgr { } let target_base = match &character.movement { - Stand => anim::character::StandAnimation::update_skeleton( + Stand(_) => anim::character::StandAnimation::update_skeleton( &CharacterSkeleton::new(), (active_tool_kind, time), state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::character::RunAnimation::update_skeleton( + Run(_) => anim::character::RunAnimation::update_skeleton( &CharacterSkeleton::new(), (active_tool_kind, vel.0, ori.0, state.last_ori, time), state.movement_time, @@ -248,14 +248,16 @@ impl FigureMgr { ), }; let target_bones = match (&character.movement, &character.action) { - (Stand, Wield { .. }) => anim::character::CidleAnimation::update_skeleton( - &target_base, - (active_tool_kind, time), - state.action_time, - &mut action_animation_rate, - skeleton_attr, - ), - (Stand, Block { .. }) => { + (Stand(_), Wield { .. }) => { + anim::character::CidleAnimation::update_skeleton( + &target_base, + (active_tool_kind, time), + state.action_time, + &mut action_animation_rate, + skeleton_attr, + ) + } + (Stand(_), Block { .. }) => { anim::character::BlockIdleAnimation::update_skeleton( &target_base, (active_tool_kind, time), @@ -333,14 +335,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::quadruped_small::IdleAnimation::update_skeleton( + Stand(_) => anim::quadruped_small::IdleAnimation::update_skeleton( &QuadrupedSmallSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::quadruped_small::RunAnimation::update_skeleton( + Run(_) => anim::quadruped_small::RunAnimation::update_skeleton( &QuadrupedSmallSkeleton::new(), (vel.0.magnitude(), time), state.movement_time, @@ -390,14 +392,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::quadruped_medium::IdleAnimation::update_skeleton( + Stand(_) => anim::quadruped_medium::IdleAnimation::update_skeleton( &QuadrupedMediumSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::quadruped_medium::RunAnimation::update_skeleton( + Run(_) => anim::quadruped_medium::RunAnimation::update_skeleton( &QuadrupedMediumSkeleton::new(), (vel.0.magnitude(), time), state.movement_time, @@ -445,14 +447,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::bird_medium::IdleAnimation::update_skeleton( + Stand(_) => anim::bird_medium::IdleAnimation::update_skeleton( &BirdMediumSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::bird_medium::RunAnimation::update_skeleton( + Run(_) => anim::bird_medium::RunAnimation::update_skeleton( &BirdMediumSkeleton::new(), (vel.0.magnitude(), time), state.movement_time, @@ -500,14 +502,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::fish_medium::IdleAnimation::update_skeleton( + Stand(_) => anim::fish_medium::IdleAnimation::update_skeleton( &FishMediumSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::fish_medium::RunAnimation::update_skeleton( + Run(_) => anim::fish_medium::RunAnimation::update_skeleton( &FishMediumSkeleton::new(), (vel.0.magnitude(), time), state.movement_time, @@ -555,14 +557,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::dragon::IdleAnimation::update_skeleton( + Stand(_) => anim::dragon::IdleAnimation::update_skeleton( &DragonSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::dragon::RunAnimation::update_skeleton( + Run(_) => anim::dragon::RunAnimation::update_skeleton( &DragonSkeleton::new(), (vel.0.magnitude(), time), state.movement_time, @@ -610,14 +612,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::bird_small::IdleAnimation::update_skeleton( + Stand(_) => anim::bird_small::IdleAnimation::update_skeleton( &BirdSmallSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::bird_small::RunAnimation::update_skeleton( + Run(_) => anim::bird_small::RunAnimation::update_skeleton( &BirdSmallSkeleton::new(), (vel.0.magnitude(), time), state.movement_time, @@ -665,14 +667,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::fish_small::IdleAnimation::update_skeleton( + Stand(_) => anim::fish_small::IdleAnimation::update_skeleton( &FishSmallSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::fish_small::RunAnimation::update_skeleton( + Run(_) => anim::fish_small::RunAnimation::update_skeleton( &FishSmallSkeleton::new(), (vel.0.magnitude(), time), state.movement_time, @@ -720,14 +722,14 @@ impl FigureMgr { } let target_base = match character.movement { - Stand => anim::biped_large::IdleAnimation::update_skeleton( + Stand(_) => anim::biped_large::IdleAnimation::update_skeleton( &BipedLargeSkeleton::new(), time, state.movement_time, &mut movement_animation_rate, skeleton_attr, ), - Run => anim::biped_large::RunAnimation::update_skeleton( + Run(_) => anim::biped_large::RunAnimation::update_skeleton( &BipedLargeSkeleton::new(), (vel.0.magnitude(), time), state.movement_time,