diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index f691e8df9c..5f5daacb72 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -306,9 +306,9 @@ impl CharacterAbility { pub fn default_roll() -> CharacterAbility { CharacterAbility::Roll { energy_cost: 150, - buildup_duration: 100, - movement_duration: 180, - recover_duration: 150, + buildup_duration: 50, + movement_duration: 280, + recover_duration: 125, roll_strength: 1.8, immune_melee: false, } diff --git a/common/src/states/roll.rs b/common/src/states/roll.rs index dbabdf4702..e36d80a6cb 100644 --- a/common/src/states/roll.rs +++ b/common/src/states/roll.rs @@ -74,7 +74,12 @@ impl CharacterBehavior for Data { data, &mut update, ForcedMovement::Forward { - strength: self.static_data.roll_strength, + strength: self.static_data.roll_strength + * ((1.0 + - self.timer.as_secs_f32() + / self.static_data.movement_duration.as_secs_f32()) + / 2.0 + + 0.5), }, 0.0, ); diff --git a/voxygen/anim/src/character/roll.rs b/voxygen/anim/src/character/roll.rs index 3621311641..c002c98065 100644 --- a/voxygen/anim/src/character/roll.rs +++ b/voxygen/anim/src/character/roll.rs @@ -2,18 +2,22 @@ use super::{ super::{vek::*, Animation}, CharacterSkeleton, SkeletonAttr, }; -use common::comp::item::ToolKind; +use common::{comp::item::ToolKind, states::utils::StageSection}; +use std::f32::consts::PI; pub struct RollAnimation; +type RollAnimationDependency = ( + Option, + Option, + Vec3, + Vec3, + f64, + Option, +); + impl Animation for RollAnimation { - type Dependency = ( - Option, - Option, - Vec3, - Vec3, - f64, - ); + type Dependency = RollAnimationDependency; type Skeleton = CharacterSkeleton; #[cfg(feature = "use-dyn-lib")] @@ -23,7 +27,7 @@ impl Animation for RollAnimation { fn update_skeleton_inner( skeleton: &Self::Skeleton, - (_active_tool_kind, _second_tool_kind, orientation, last_ori, _global_time): Self::Dependency, + (_active_tool_kind, _second_tool_kind, orientation, last_ori, _global_time, stage_section): Self::Dependency, anim_time: f64, rate: &mut f32, s_a: &SkeletonAttr, @@ -31,8 +35,6 @@ impl Animation for RollAnimation { *rate = 1.0; let mut next = (*skeleton).clone(); - let spin = anim_time as f32 * 1.1; - let ori: Vec2 = Vec2::from(orientation); let last_ori = Vec2::from(last_ori); let tilt = if ::vek::Vec2::new(ori, last_ori) @@ -47,36 +49,69 @@ impl Animation for RollAnimation { 0.0 }; - next.head.position = Vec3::new(0.0, s_a.head.0 + 3.0, s_a.head.1 - 1.0); - next.head.orientation = Quaternion::rotation_x(-0.75); + let (movement1base, movement2, movement3) = match stage_section { + Some(StageSection::Buildup) => ((anim_time as f32).powf(2.0), 0.0, 0.0), + Some(StageSection::Movement) => (1.0, (anim_time as f32).powf(0.75), 0.0), + Some(StageSection::Recover) => (1.0, 1.0, (anim_time as f32).powf(0.75)), + _ => (0.0, 0.0, 0.0), + }; + let movement1 = movement1base * (1.0 - movement3); + next.head.position = Vec3::new( + 0.0, + s_a.head.0 + 3.0 * movement1, + s_a.head.1 - 1.0 * movement1, + ); + next.head.orientation = Quaternion::rotation_x(-0.75 * movement1base + 0.75 * movement2); - next.chest.position = Vec3::new(0.0, s_a.chest.0, -9.5 + s_a.chest.1); - next.chest.orientation = Quaternion::rotation_x(-0.2); + next.chest.position = Vec3::new(0.0, s_a.chest.0, -9.5 * movement1 + s_a.chest.1); + next.chest.orientation = Quaternion::rotation_x(-0.2 * movement1); - next.belt.position = Vec3::new(0.0, s_a.belt.0 + 1.0, s_a.belt.1 + 1.0); - next.belt.orientation = Quaternion::rotation_x(0.55); + next.belt.position = Vec3::new( + 0.0, + s_a.belt.0 + 1.0 * movement1, + s_a.belt.1 + 1.0 * movement1, + ); + next.belt.orientation = Quaternion::rotation_x(0.55 * movement1); - next.back.position = Vec3::new(0.0, s_a.back.0, s_a.back.1); + next.shorts.position = Vec3::new( + 0.0, + s_a.shorts.0 + 4.5 * movement1, + s_a.shorts.1 + 2.5 * movement1, + ); + next.shorts.orientation = Quaternion::rotation_x(0.8 * movement1); - next.shorts.position = Vec3::new(0.0, s_a.shorts.0 + 4.5, s_a.shorts.1 + 2.5); - next.shorts.orientation = Quaternion::rotation_x(0.8); + next.hand_l.position = Vec3::new( + -s_a.hand.0, + s_a.hand.1 + 1.0 * movement1, + s_a.hand.2 + 2.0 * movement1, + ); - next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1 + 1.0, s_a.hand.2 + 2.0); + next.hand_l.orientation = Quaternion::rotation_x(0.6 * movement1); - next.hand_l.orientation = Quaternion::rotation_x(0.6); + next.hand_r.position = Vec3::new( + -1.0 * movement1 + s_a.hand.0, + s_a.hand.1 + 1.0 * movement1, + s_a.hand.2 + 2.0 * movement1, + ); + next.hand_r.orientation = Quaternion::rotation_x(0.6 * movement1); - next.hand_r.position = Vec3::new(-1.0 + s_a.hand.0, s_a.hand.1 + 1.0, s_a.hand.2 + 2.0); - next.hand_r.orientation = Quaternion::rotation_x(0.6); + next.foot_l.position = Vec3::new( + 1.0 * movement1 - s_a.foot.0, + s_a.foot.1 + 5.5 * movement1, + s_a.foot.2 - 5.0 * movement1, + ); + next.foot_l.orientation = Quaternion::rotation_x(0.9 * movement1); - next.foot_l.position = Vec3::new(1.0 - s_a.foot.0, s_a.foot.1 + 5.5, s_a.foot.2 - 5.0); - next.foot_l.orientation = Quaternion::rotation_x(0.9); + next.foot_r.position = Vec3::new( + 1.0 * movement1 + s_a.foot.0, + s_a.foot.1 + 5.5 * movement1, + s_a.foot.2 - 5.0 * movement1, + ); + next.foot_r.orientation = Quaternion::rotation_x(0.9 * movement1); - next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1 + 5.5, s_a.foot.2 - 5.0); - next.foot_r.orientation = Quaternion::rotation_x(0.9); - - next.torso.position = Vec3::new(0.0, 0.0, 8.0) / 11.0 * s_a.scaler; - next.torso.orientation = - Quaternion::rotation_x(spin * -10.0) * Quaternion::rotation_z(tilt * -10.0); + next.torso.position = Vec3::new(0.0, 0.0, 8.0 * movement1) / 11.0 * s_a.scaler; + next.torso.orientation = Quaternion::rotation_x(movement1 * -0.4 + movement2 * -2.0 * PI) + * Quaternion::rotation_z(tilt * -10.0); next } diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 3f518b51ee..d12c8e1be2 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -796,7 +796,21 @@ impl FigureMgr { ), }; let target_bones = match &character { - CharacterState::Roll { .. } => { + CharacterState::Roll(s) => { + let stage_time = s.timer.as_secs_f64(); + + let stage_progress = match s.stage_section { + StageSection::Buildup => { + stage_time / s.static_data.buildup_duration.as_secs_f64() + }, + StageSection::Movement => { + stage_time / s.static_data.movement_duration.as_secs_f64() + }, + StageSection::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f64() + }, + _ => 0.0, + }; anim::character::RollAnimation::update_skeleton( &target_base, ( @@ -805,8 +819,9 @@ impl FigureMgr { ori, state.last_ori, time, + Some(s.stage_section), ), - state.state_time, + stage_progress, &mut state_animation_rate, skeleton_attr, )