diff --git a/assets/common/abilities/sword/reaching_flurry.ron b/assets/common/abilities/sword/reaching_flurry.ron index 6bf4e61399..3a9c9bc48b 100644 --- a/assets/common/abilities/sword/reaching_flurry.ron +++ b/assets/common/abilities/sword/reaching_flurry.ron @@ -1,6 +1,6 @@ RapidMelee( buildup_duration: 0.3, - swing_duration: 0.2, + swing_duration: 0.1, recover_duration: 0.5, melee_constructor: ( kind: Slash( diff --git a/voxygen/anim/src/character/combomelee.rs b/voxygen/anim/src/character/combomelee.rs index 7e6c955a24..576fe66cd2 100644 --- a/voxygen/anim/src/character/combomelee.rs +++ b/voxygen/anim/src/character/combomelee.rs @@ -86,22 +86,15 @@ impl Animation for ComboAnimation { * Quaternion::rotation_z(move2alt * -1.5); }, 1 => { - next.chest - .orientation - .rotate_z(move1 * -0.2 + move2alt * 1.4); - next.head - .orientation - .rotate_z(move1 * 0.1 + move2alt * -0.4); - next.belt - .orientation - .rotate_z(move1 * 0.1 + move2alt * -0.4); - next.shorts - .orientation - .rotate_z(move1 * 0.2 + move2alt * -0.8); - next.control.position += Vec3::new(move2 * -25.0, 0.0, move2 * 10.0); - next.control.orientation.rotate_x(move2alt * 0.4); - next.control.orientation.rotate_y(move2 * -0.6); - next.control.orientation.rotate_z(move2alt * 3.0); + next.control.orientation.rotate_x(move1 * 3.2); + next.control.orientation.rotate_z(move1 * 1.0); + + next.chest.orientation.rotate_z(move2 * 1.4); + next.head.orientation.rotate_z(move2 * -0.6); + next.shorts.orientation.rotate_z(move2 * -0.8); + next.belt.orientation.rotate_z(move2 * -0.3); + next.control.orientation.rotate_z(move2 * 1.5); + next.control.position += Vec3::new(move2 * -27.0, 0.0, move2 * 5.0); }, _ => {}, } diff --git a/voxygen/anim/src/character/mod.rs b/voxygen/anim/src/character/mod.rs index bf702dd781..be145c6639 100644 --- a/voxygen/anim/src/character/mod.rs +++ b/voxygen/anim/src/character/mod.rs @@ -19,6 +19,7 @@ pub mod jump; pub mod leapmelee; pub mod mount; pub mod music; +pub mod rapidmelee; pub mod repeater; pub mod ripostemelee; pub mod roll; @@ -49,14 +50,14 @@ pub use self::{ dash::DashAnimation, divemelee::DiveMeleeAnimation, equip::EquipAnimation, finishermelee::FinisherMeleeAnimation, glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation, jump::JumpAnimation, leapmelee::LeapAnimation, - mount::MountAnimation, music::MusicAnimation, repeater::RepeaterAnimation, - ripostemelee::RiposteMeleeAnimation, roll::RollAnimation, run::RunAnimation, - selfbuff::SelfBuffAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation, - sit::SitAnimation, sneak::SneakAnimation, sneakequip::SneakEquipAnimation, - sneakwield::SneakWieldAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation, - staggered::StaggeredAnimation, stand::StandAnimation, stunned::StunnedAnimation, - swim::SwimAnimation, swimwield::SwimWieldAnimation, talk::TalkAnimation, - wallrun::WallrunAnimation, wield::WieldAnimation, + mount::MountAnimation, music::MusicAnimation, rapidmelee::RapidMeleeAnimation, + repeater::RepeaterAnimation, ripostemelee::RiposteMeleeAnimation, roll::RollAnimation, + run::RunAnimation, selfbuff::SelfBuffAnimation, shockwave::ShockwaveAnimation, + shoot::ShootAnimation, sit::SitAnimation, sneak::SneakAnimation, + sneakequip::SneakEquipAnimation, sneakwield::SneakWieldAnimation, spin::SpinAnimation, + spinmelee::SpinMeleeAnimation, staggered::StaggeredAnimation, stand::StandAnimation, + stunned::StunnedAnimation, swim::SwimAnimation, swimwield::SwimWieldAnimation, + talk::TalkAnimation, wallrun::WallrunAnimation, wield::WieldAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton, TrailSource}; use common::comp; diff --git a/voxygen/anim/src/character/rapidmelee.rs b/voxygen/anim/src/character/rapidmelee.rs new file mode 100644 index 0000000000..3d26dcc47a --- /dev/null +++ b/voxygen/anim/src/character/rapidmelee.rs @@ -0,0 +1,80 @@ +use super::{ + super::{vek::*, Animation}, + CharacterSkeleton, SkeletonAttr, +}; +use common::states::utils::StageSection; +use core::f32::consts::PI; +use std::ops::{Mul, Sub}; + +pub struct RapidMeleeAnimation; +impl Animation for RapidMeleeAnimation { + type Dependency<'a> = (Option<&'a str>, Option, (u32, u32)); + type Skeleton = CharacterSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"character_rapid_melee\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "character_rapid_melee")] + fn update_skeleton_inner<'a>( + skeleton: &Self::Skeleton, + (ability_id, stage_section, (current_strike, max_strikes)): Self::Dependency<'a>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let mut next = (*skeleton).clone(); + + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_z(0.0); + + match ability_id { + Some("common.abilities.sword.reaching_flurry") => { + let (move1, move2, move3, move2alt) = match stage_section { + Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0, 0.0), + Some(StageSection::Action) => ( + 1.0, + anim_time.min(0.5).mul(2.0).powi(2) - anim_time.max(0.5).sub(0.5).mul(2.0), + 0.0, + anim_time.powi(2), + ), + Some(StageSection::Recover) => (1.0, 1.0, anim_time.powi(4), 1.0), + _ => (0.0, 0.0, 0.0, 0.0), + }; + + let move2_slow = move2.powi(4); + + next.hand_l.position = Vec3::new(s_a.shl.0, s_a.shl.1, s_a.shl.2); + next.hand_l.orientation = + Quaternion::rotation_x(s_a.shl.3) * Quaternion::rotation_y(s_a.shl.4); + next.hand_r.position = + Vec3::new(-s_a.sc.0 + 6.0 + move1 * -12.0, -4.0 + move1 * 3.0, -2.0); + next.hand_r.orientation = Quaternion::rotation_x(0.9 + move1 * 0.5); + next.control.position = Vec3::new(s_a.sc.0, s_a.sc.1, s_a.sc.2); + next.control.orientation = Quaternion::rotation_x(s_a.sc.3); + + next.chest.orientation = Quaternion::rotation_z(move1 * 0.7); + next.head.orientation = Quaternion::rotation_z(move1 * -0.4); + next.shorts.orientation = Quaternion::rotation_z(move1 * -0.5); + next.belt.orientation = Quaternion::rotation_z(move1 * -0.2); + next.control.orientation.rotate_x(move1 * -1.1); + next.control.orientation.rotate_z(move1 * -0.7); + next.control.position += Vec3::new(move1 * 1.0, move1 * -1.0, move1 * 4.0); + + next.chest.orientation.rotate_z(move2 * -1.2); + next.head.orientation.rotate_z(move2 * 0.6); + next.belt.orientation.rotate_z(move2 * 0.3); + next.shorts.orientation.rotate_z(move2 * 0.7); + next.control.orientation.rotate_z(move2 * 1.2); + next.control.position += Vec3::new(0.0, move2 * 12.0, 0.0); + + if current_strike == max_strikes { + next.control.position += Vec3::new(move2alt * -6.0, move2alt * -6.0, 0.0); + } + }, + _ => {}, + } + + next + } +} diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 256582792a..399197c975 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -1572,6 +1572,33 @@ impl FigureMgr { skeleton_attr, ) }, + CharacterState::RapidMelee(s) => { + let stage_time = s.timer.as_secs_f32(); + let stage_progress = match s.stage_section { + StageSection::Buildup => { + stage_time / s.static_data.buildup_duration.as_secs_f32() + }, + StageSection::Action => { + stage_time / s.static_data.swing_duration.as_secs_f32() + }, + StageSection::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f32() + }, + _ => 0.0, + }; + + anim::character::RapidMeleeAnimation::update_skeleton( + &target_base, + ( + ability_id, + Some(s.stage_section), + (s.current_strike, s.static_data.max_strikes), + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, CharacterState::Stunned(s) => { let stage_time = s.timer.as_secs_f32(); let wield_status = s.was_wielded;