diff --git a/assets/common/abilities/custom/minotaur/cleave.ron b/assets/common/abilities/custom/minotaur/cleave.ron index 486ffed3fb..f08f594881 100644 --- a/assets/common/abilities/custom/minotaur/cleave.ron +++ b/assets/common/abilities/custom/minotaur/cleave.ron @@ -11,7 +11,7 @@ ChargedMelee( max_angle: 45.0, speed: 1.0, charge_duration: 2.0, - swing_duration: 0.2, + swing_duration: 0.1, hit_timing: 0.8, recover_duration: 0.5, ) diff --git a/assets/common/abilities/custom/minotaur/cripplingstrike.ron b/assets/common/abilities/custom/minotaur/cripplingstrike.ron index 8376a1f147..f363a35a06 100644 --- a/assets/common/abilities/custom/minotaur/cripplingstrike.ron +++ b/assets/common/abilities/custom/minotaur/cripplingstrike.ron @@ -1,7 +1,7 @@ BasicMelee( energy_cost: 0, buildup_duration: 0.3, - swing_duration: 0.2, + swing_duration: 0.1, recover_duration: 0.6, base_damage: 250.0, base_poise_damage: 60.0, diff --git a/assets/common/abilities/custom/minotaur/frenzy.ron b/assets/common/abilities/custom/minotaur/frenzy.ron index 4a014d42bb..5d905a28ac 100644 --- a/assets/common/abilities/custom/minotaur/frenzy.ron +++ b/assets/common/abilities/custom/minotaur/frenzy.ron @@ -1,6 +1,6 @@ SelfBuff( - buildup_duration: 0.5, - cast_duration: 0.25, + buildup_duration: 0.25, + cast_duration: 0.8, recover_duration: 0.25, buff_kind: Frenzied, buff_strength: 0.5, diff --git a/assets/voxygen/voxel/biped_weapon_manifest.ron b/assets/voxygen/voxel/biped_weapon_manifest.ron index ae60874a09..57dfec123d 100644 --- a/assets/voxygen/voxel/biped_weapon_manifest.ron +++ b/assets/voxygen/voxel/biped_weapon_manifest.ron @@ -1043,7 +1043,7 @@ color: None ), "common.items.npc_weapons.axe.minotaur_axe": ( - vox_spec: ("weapon.axe.2haxe_minotaur", (-2.5, -9.0, -6.0)), + vox_spec: ("weapon.axe.2haxe_minotaur", (-2.5, -9.0, -8.0)), color: None ), "common.items.npc_weapons.hammer.yeti_hammer": ( diff --git a/assets/voxygen/voxel/weapon/axe/2haxe_minotaur.vox b/assets/voxygen/voxel/weapon/axe/2haxe_minotaur.vox index f8c4cd5649..452452357f 100644 --- a/assets/voxygen/voxel/weapon/axe/2haxe_minotaur.vox +++ b/assets/voxygen/voxel/weapon/axe/2haxe_minotaur.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e9b3f271457750c4e6d86fd23554322c15439b9583e23322b6143ef1cee86cf -size 3652 +oid sha256:5ecbd8d48af72ec42fb7f8d265cb4ffe0f0732b1fe9b5eafe0ff1d1a19018ab5 +size 3484 diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 96b2f9d3fa..9e0525b3e0 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -644,10 +644,7 @@ impl CharacterAbility { 0 } }, - Boost { .. } - | ComboMelee { .. } - | Blink { .. } - | BasicSummon { .. } => 0, + Boost { .. } | ComboMelee { .. } | Blink { .. } | BasicSummon { .. } => 0, } } diff --git a/voxygen/anim/src/biped_large/alpha.rs b/voxygen/anim/src/biped_large/alpha.rs index 27d6f70049..c5ac772d68 100644 --- a/voxygen/anim/src/biped_large/alpha.rs +++ b/voxygen/anim/src/biped_large/alpha.rs @@ -63,7 +63,8 @@ impl Animation for AlphaAnimation { let pullback = 1.0 - move3; let move1 = move1base * pullback; let move2 = move2base * pullback; - + next.second.position = Vec3::new(0.0, 0.0, 0.0); + next.second.orientation = Quaternion::rotation_x(0.0); next.shoulder_l.position = Vec3::new( -s_a.shoulder.0, s_a.shoulder.1, @@ -79,7 +80,6 @@ impl Animation for AlphaAnimation { ); next.shoulder_r.orientation = Quaternion::rotation_x(move1 * 0.8 + 0.6 * speednorm + (footrotl * -0.2) * speednorm); - next.torso.orientation = Quaternion::rotation_z(0.0); next.main.position = Vec3::new(0.0, 0.0, 0.0); next.main.orientation = Quaternion::rotation_x(0.0); @@ -231,6 +231,38 @@ impl Animation for AlphaAnimation { * Quaternion::rotation_z(move1 * -0.5 + move2 * 0.6); next.head.orientation = Quaternion::rotation_x(move1 * 0.3); }, + "Minotaur" => { + next.control_l.position = Vec3::new(0.0, 4.0, 5.0); + next.control_r.position = Vec3::new(0.0, 4.0, 5.0); + next.weapon_l.position = Vec3::new( + -12.0 + move1 * -9.0 + move2 * 16.0, + -6.0 + move2 * 8.0, + -18.0 + move1 * 8.0 + move2 * -4.0, + ); + next.weapon_r.position = Vec3::new( + 12.0 + move1 * 9.0 + move2 * -16.0, + -6.0 + move2 * 8.0, + -18.0 + move1 * 8.0 + move2 * -8.0, + ); + + next.weapon_l.orientation = Quaternion::rotation_x(-1.67) + * Quaternion::rotation_y(move1 * -0.3 + move2 * 1.0) + * Quaternion::rotation_z(move1 * 0.8 + move2 * -1.8); + next.weapon_r.orientation = Quaternion::rotation_x(-1.67) + * Quaternion::rotation_y(move1 * 0.3 + move2 * -0.6) + * Quaternion::rotation_z(move1 * -0.8 + move2 * 1.8); + + next.control_l.orientation = Quaternion::rotation_x(1.57 + move2 * 1.0); + next.control_r.orientation = Quaternion::rotation_x(1.57 + move2 * 1.0); + + next.shoulder_l.orientation = Quaternion::rotation_x(-0.3) + * Quaternion::rotation_y(move1 * 0.7 + move2 * -0.7); + + next.shoulder_r.orientation = Quaternion::rotation_x(-0.3) + * Quaternion::rotation_y(move1 * -0.7 + move2 * 0.7); + next.head.orientation = + Quaternion::rotation_x(move1 * -0.6 + move2 * 0.4) + }, _ => {}, } } diff --git a/voxygen/anim/src/biped_large/chargemelee.rs b/voxygen/anim/src/biped_large/chargemelee.rs new file mode 100644 index 0000000000..0a0862de8a --- /dev/null +++ b/voxygen/anim/src/biped_large/chargemelee.rs @@ -0,0 +1,159 @@ +use super::{ + super::{vek::*, Animation}, + BipedLargeSkeleton, SkeletonAttr, +}; +use common::{ + comp::item::tool::{AbilitySpec, ToolKind}, + states::utils::StageSection, +}; +use std::f32::consts::PI; + +pub struct ChargeMeleeAnimation; + +impl Animation for ChargeMeleeAnimation { + #[allow(clippy::type_complexity)] + type Dependency<'a> = ( + (Option, Option<&'a AbilitySpec>), + (Option, Option<&'a AbilitySpec>), + Vec3, + f32, + Option, + f32, + ); + type Skeleton = BipedLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"biped_large_chargemelee\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_large_chargemelee")] + #[allow(clippy::approx_constant)] // TODO: Pending review in #587 + fn update_skeleton_inner<'a>( + skeleton: &Self::Skeleton, + ( + (active_tool_kind, active_tool_spec), + _second_tool, + velocity, + _global_time, + stage_section, + acc_vel, + ): Self::Dependency<'a>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let mut next = (*skeleton).clone(); + let speed = Vec2::::from(velocity).magnitude(); + + let lab: f32 = 0.65 * s_a.tempo; + let speednorm = (speed / 12.0).powf(0.4); + let foothoril = (acc_vel * lab + PI * 1.45).sin() * speednorm; + let foothorir = (acc_vel * lab + PI * (0.45)).sin() * speednorm; + let footrotl = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 1.4).sin()).powi(2))).sqrt()) + * ((acc_vel * lab + PI * 1.4).sin()); + + let footrotr = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 0.4).sin()).powi(2))).sqrt()) + * ((acc_vel * lab + PI * 0.4).sin()); + let (move1base, move2base, movement3, tension) = match stage_section { + Some(StageSection::Charge) => ( + (anim_time.powf(0.25)).min(1.0), + 0.0, + 0.0, + (anim_time * 100.0).sin(), + ), + Some(StageSection::Swing) => (1.0, anim_time.powf(0.25), 0.0, 0.0), + Some(StageSection::Recover) => (1.0, 1.0, anim_time.powi(4), 0.0), + _ => (0.0, 0.0, 0.0, 0.0), + }; + + let pullback = 1.0 - movement3; + let move1 = move1base * pullback; + let move2 = move2base * pullback; + next.second.position = Vec3::new(0.0, 0.0, 0.0); + next.second.orientation = Quaternion::rotation_x(0.0); + next.shoulder_l.position = Vec3::new( + -s_a.shoulder.0, + s_a.shoulder.1, + s_a.shoulder.2 - foothorir * 1.0, + ); + next.shoulder_l.orientation = + Quaternion::rotation_x(move1 * 0.8 + 0.6 * speednorm + (footrotr * -0.2) * speednorm); + + next.shoulder_r.position = Vec3::new( + s_a.shoulder.0, + s_a.shoulder.1, + s_a.shoulder.2 - foothoril * 1.0, + ); + next.shoulder_r.orientation = + Quaternion::rotation_x(move1 * 0.8 + 0.6 * speednorm + (footrotl * -0.2) * speednorm); + next.torso.orientation = Quaternion::rotation_z(0.0); + + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_x(0.0); + + next.hand_l.position = Vec3::new(0.0, 0.0, s_a.grip.0); + next.hand_r.position = Vec3::new(0.0, 0.0, s_a.grip.0); + + next.hand_l.orientation = Quaternion::rotation_x(0.0); + next.hand_r.orientation = Quaternion::rotation_x(0.0); + + #[allow(clippy::single_match)] + match active_tool_kind { + Some(ToolKind::Natural) => { + if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { + match spec.as_str() { + "Minotaur" => { + next.upper_torso.orientation = + Quaternion::rotation_x(move1 * 0.3 + move2 * -0.9); + next.lower_torso.orientation = + Quaternion::rotation_x(move1 * -0.3 + move2 * 0.9); + next.head.orientation = + Quaternion::rotation_x(move1 * -0.5 + move2 * 0.5); + + next.control_l.position = Vec3::new(0.0, 4.0, 5.0); + next.control_r.position = Vec3::new(0.0, 4.0, 5.0); + next.weapon_l.position = Vec3::new( + -12.0 + move2 * 5.0, + -6.0 + move1 * 22.0 + move2 * 8.0, + -18.0 + move1 * 16.0 + move2 * -19.0, + ); + next.weapon_r.position = Vec3::new( + 12.0 + move2 * -5.0, + -6.0 + move1 * 22.0 + move2 * 8.0, + -18.0 + move1 * 14.0 + move2 * -19.0, + ); + next.torso.position = Vec3::new(0.0, move2 * 1.5, 0.0); + + next.weapon_l.orientation = + Quaternion::rotation_x( + -1.67 + move1 * 2.8 + tension * 0.03 + move2 * -2.3, + ) * Quaternion::rotation_y(move1 * 0.3 + move2 * 0.5); + next.weapon_r.orientation = Quaternion::rotation_x( + -1.67 + move1 * 1.6 + tension * -0.03 + move2 * -0.7, + ) * Quaternion::rotation_y( + move1 * -0.3 + move2 * -0.5, + ) * Quaternion::rotation_z(0.0); + + next.control_l.orientation = + Quaternion::rotation_x(1.57 + move1 * 0.2 + move2 * 0.1); + next.control_r.orientation = + Quaternion::rotation_x(1.57 + move1 * 0.4 + move2 * -0.4); + + next.control.orientation = + Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0); + next.shoulder_l.orientation = + Quaternion::rotation_x(-0.3 + move1 * 1.0); + + next.shoulder_r.orientation = + Quaternion::rotation_x(-0.3 + move1 * 1.0); + }, + _ => {}, + } + } + }, + _ => {}, + } + + next + } +} diff --git a/voxygen/anim/src/biped_large/dash.rs b/voxygen/anim/src/biped_large/dash.rs index 8257b9d075..f969de6df9 100644 --- a/voxygen/anim/src/biped_large/dash.rs +++ b/voxygen/anim/src/biped_large/dash.rs @@ -2,15 +2,19 @@ use super::{ super::{vek::*, Animation}, BipedLargeSkeleton, SkeletonAttr, }; -use common::{comp::item::ToolKind, states::utils::StageSection}; +use common::{ + comp::item::tool::{AbilitySpec, ToolKind}, + states::utils::StageSection, +}; use std::f32::consts::PI; pub struct DashAnimation; impl Animation for DashAnimation { + #[allow(clippy::type_complexity)] type Dependency<'a> = ( - Option, - Option, + (Option, Option<&'a AbilitySpec>), + (Option, Option<&'a AbilitySpec>), Vec3, f32, Option, @@ -25,7 +29,14 @@ impl Animation for DashAnimation { #[allow(clippy::single_match)] // TODO: Pending review in #587 fn update_skeleton_inner<'a>( skeleton: &Self::Skeleton, - (active_tool_kind, _second_tool_kind, velocity, _global_time, stage_section, acc_vel): Self::Dependency<'a>, + ( + (active_tool_kind, active_tool_spec), + _second_tool, + velocity, + _global_time, + stage_section, + acc_vel, + ): Self::Dependency<'a>, anim_time: f32, rate: &mut f32, s_a: &SkeletonAttr, @@ -49,7 +60,8 @@ impl Animation for DashAnimation { next.hand_l.position = Vec3::new(0.0, 0.0, s_a.grip.0); next.hand_r.position = Vec3::new(0.0, 0.0, s_a.grip.0); - + next.second.position = Vec3::new(0.0, 0.0, 0.0); + next.second.orientation = Quaternion::rotation_x(0.0); next.hand_l.orientation = Quaternion::rotation_x(0.0); next.hand_r.orientation = Quaternion::rotation_x(0.0); let (move1base, move2base, move3base, move4) = match stage_section { @@ -136,6 +148,51 @@ impl Animation for DashAnimation { * Quaternion::rotation_y(-1.8 + move1 * -0.2 + move3 * -0.2) * Quaternion::rotation_z(move1 * -0.8 + move3 * -0.1); }, + Some(ToolKind::Natural) => { + if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { + match spec.as_str() { + "Minotaur" => { + next.head.orientation = + Quaternion::rotation_x(move1 * 0.4 + move3 * 0.5) + * Quaternion::rotation_z(move1 * -0.3 + move3 * -0.3); + next.upper_torso.orientation = + Quaternion::rotation_x(move1 * -0.4 + move3 * 0.9) + * Quaternion::rotation_z(move1 * 0.6 + move3 * -1.5); + next.lower_torso.orientation = + Quaternion::rotation_y(move1 * -0.2 + move3 * -0.1) + * Quaternion::rotation_x( + move1 * 0.4 + move3 * -0.7 + footrotr * 0.1, + ) + * Quaternion::rotation_z(move1 * -0.6 + move3 * 1.6); + next.control_l.position = Vec3::new(0.0, 4.0, 5.0); + next.control_r.position = Vec3::new(0.0, 4.0, 5.0); + next.weapon_l.position = Vec3::new(-12.0 + move1 * -3.0, -6.0, -18.0); + next.weapon_r.position = Vec3::new( + 12.0 + move1 * -3.0, + -6.0 + move1 * 2.0, + -18.0 + move1 * 2.0, + ); + + next.weapon_l.orientation = Quaternion::rotation_x(-1.67 + move1 * 0.4) + * Quaternion::rotation_y(move1 * 0.4 + move2 * 0.2) + * Quaternion::rotation_z(move3 * -0.5); + next.weapon_r.orientation = Quaternion::rotation_x(-1.67 + move1 * 0.3) + * Quaternion::rotation_y(move1 * 0.6 + move2 * -0.6) + * Quaternion::rotation_z(move3 * -0.5); + + next.control_l.orientation = Quaternion::rotation_x(1.57); + next.control_r.orientation = Quaternion::rotation_x(1.57); + + next.control.orientation = + Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0); + next.shoulder_l.orientation = Quaternion::rotation_x(-0.3); + + next.shoulder_r.orientation = Quaternion::rotation_x(-0.3); + }, + _ => {}, + } + } + }, _ => {}, } diff --git a/voxygen/anim/src/biped_large/idle.rs b/voxygen/anim/src/biped_large/idle.rs index 62bbf6c87b..92ca199c0c 100644 --- a/voxygen/anim/src/biped_large/idle.rs +++ b/voxygen/anim/src/biped_large/idle.rs @@ -101,8 +101,11 @@ impl Animation for IdleAnimation { next.main.orientation = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); }, Some(ToolKind::Hammer) | Some(ToolKind::Axe) => { - next.main.position = Vec3::new(-10.0, -8.0, 12.0); + next.main.position = Vec3::new(-6.0, -8.0, 8.0); next.main.orientation = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + next.second.position = Vec3::new(6.0, -8.0, 8.0); + next.second.orientation = + Quaternion::rotation_y(-2.5) * Quaternion::rotation_z(1.57); }, _ => { next.main.position = Vec3::new(-2.0, -5.0, -6.0); diff --git a/voxygen/anim/src/biped_large/jump.rs b/voxygen/anim/src/biped_large/jump.rs index e9586d068c..7724daea85 100644 --- a/voxygen/anim/src/biped_large/jump.rs +++ b/voxygen/anim/src/biped_large/jump.rs @@ -28,6 +28,7 @@ impl Animation for JumpAnimation { let torso = (anim_time * lab + 1.5 * PI).sin(); let wave_slow = (anim_time * 0.8).sin(); + next.hold.scale = Vec3::one() * 0.0; next.head.scale = Vec3::one() * 1.02; @@ -57,7 +58,7 @@ impl Animation for JumpAnimation { next.second.position = Vec3::new(0.0, 0.0, 0.0); next.second.orientation = Quaternion::rotation_x(PI) * Quaternion::rotation_y(0.0) * Quaternion::rotation_z(0.0); - next.second.scale = Vec3::one() * 0.0; + next.second.scale = Vec3::one() * 1.0; match active_tool_kind { Some(ToolKind::Bow) => { diff --git a/voxygen/anim/src/biped_large/mod.rs b/voxygen/anim/src/biped_large/mod.rs index 85155ca677..1db51f23b6 100644 --- a/voxygen/anim/src/biped_large/mod.rs +++ b/voxygen/anim/src/biped_large/mod.rs @@ -3,12 +3,14 @@ pub mod beam; pub mod beta; pub mod blink; pub mod charge; +pub mod chargemelee; pub mod dash; pub mod equip; pub mod idle; pub mod jump; pub mod leapmelee; pub mod run; +pub mod selfbuff; pub mod shockwave; pub mod shoot; pub mod spin; @@ -20,11 +22,11 @@ pub mod wield; // Reexports pub use self::{ alpha::AlphaAnimation, beam::BeamAnimation, beta::BetaAnimation, blink::BlinkAnimation, - charge::ChargeAnimation, dash::DashAnimation, equip::EquipAnimation, idle::IdleAnimation, - jump::JumpAnimation, leapmelee::LeapAnimation, run::RunAnimation, - shockwave::ShockwaveAnimation, shoot::ShootAnimation, spin::SpinAnimation, - spinmelee::SpinMeleeAnimation, stunned::StunnedAnimation, summon::SummonAnimation, - wield::WieldAnimation, + charge::ChargeAnimation, chargemelee::ChargeMeleeAnimation, dash::DashAnimation, + equip::EquipAnimation, idle::IdleAnimation, jump::JumpAnimation, leapmelee::LeapAnimation, + run::RunAnimation, selfbuff::SelfBuffAnimation, shockwave::ShockwaveAnimation, + shoot::ShootAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation, + stunned::StunnedAnimation, summon::SummonAnimation, wield::WieldAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Skeleton}; @@ -54,6 +56,8 @@ skeleton_impls!(struct BipedLargeSkeleton { control, control_l, control_r, + weapon_l, + weapon_r, leg_control_l, leg_control_r, arm_control_l, @@ -78,8 +82,11 @@ impl Skeleton for BipedLargeSkeleton { let torso_mat = base_mat * Mat4::::from(self.torso); let upper_torso_mat = torso_mat * upper_torso; + let control_mat = Mat4::::from(self.control); let control_l_mat = Mat4::::from(self.control_l); let control_r_mat = Mat4::::from(self.control_r); + let weapon_l_mat = control_mat * Mat4::::from(self.weapon_l); + let weapon_r_mat = control_mat * Mat4::::from(self.weapon_r); let lower_torso_mat = upper_torso_mat * Mat4::::from(self.lower_torso); let leg_l = Mat4::::from(self.leg_l); @@ -92,8 +99,6 @@ impl Skeleton for BipedLargeSkeleton { let arm_control_r = upper_torso_mat * Mat4::::from(self.arm_control_r); let head_mat = upper_torso_mat * Mat4::::from(self.head); - let control_mat = Mat4::::from(self.control); - let hand_l_mat = Mat4::::from(self.hand_l); *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ @@ -102,12 +107,16 @@ impl Skeleton for BipedLargeSkeleton { make_bone(upper_torso_mat), make_bone(lower_torso_mat), make_bone(lower_torso_mat * Mat4::::from(self.tail)), - make_bone(upper_torso_mat * control_mat * Mat4::::from(self.main)), - make_bone(upper_torso_mat * control_mat * Mat4::::from(self.second)), + make_bone(upper_torso_mat * weapon_l_mat * Mat4::::from(self.main)), + make_bone(upper_torso_mat * weapon_r_mat * Mat4::::from(self.second)), make_bone(arm_control_l * Mat4::::from(self.shoulder_l)), make_bone(arm_control_r * Mat4::::from(self.shoulder_r)), - make_bone(arm_control_l * control_mat * control_l_mat * Mat4::::from(self.hand_l)), - make_bone(arm_control_r * control_mat * control_r_mat * Mat4::::from(self.hand_r)), + make_bone( + arm_control_l * weapon_l_mat * control_l_mat * Mat4::::from(self.hand_l), + ), + make_bone( + arm_control_r * weapon_r_mat * control_r_mat * Mat4::::from(self.hand_r), + ), make_bone(leg_control_l * leg_l), make_bone(leg_control_r * leg_r), make_bone(leg_control_l * Mat4::::from(self.foot_l)), diff --git a/voxygen/anim/src/biped_large/run.rs b/voxygen/anim/src/biped_large/run.rs index 2b8a6d67d5..b39791fd20 100644 --- a/voxygen/anim/src/biped_large/run.rs +++ b/voxygen/anim/src/biped_large/run.rs @@ -271,12 +271,12 @@ impl Animation for RunAnimation { s_a.upper_torso.1 + shortalt * -1.5 * speednorm, ); next.upper_torso.orientation = - Quaternion::rotation_z(short * 0.18 * speednorm + tilt * -1.0) + Quaternion::rotation_z(short * 0.07 * speednorm + tilt * -1.0) * Quaternion::rotation_y(tilt); next.lower_torso.position = Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1); next.lower_torso.orientation = - Quaternion::rotation_z(short * 0.15 * speednorm + tilt * 0.5) + Quaternion::rotation_z(short * 0.05 * speednorm + tilt * 0.5) * Quaternion::rotation_y(tilt * -0.5) * Quaternion::rotation_x(0.14 * speednorm); @@ -287,7 +287,7 @@ impl Animation for RunAnimation { next.tail.orientation = Quaternion::rotation_x(shortalt * 0.3 * speednorm); next.second.position = Vec3::new(0.0, 0.0, 0.0); - next.second.orientation = Quaternion::rotation_x(PI) + next.second.orientation = Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0) * Quaternion::rotation_z(0.0); @@ -308,9 +308,12 @@ impl Animation for RunAnimation { Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); }, Some(ToolKind::Hammer) | Some(ToolKind::Axe) => { - next.main.position = Vec3::new(-10.0, -8.0, 12.0); + next.main.position = Vec3::new(-6.0, -8.0, 8.0); next.main.orientation = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + next.second.position = Vec3::new(6.0, -8.0, 8.0); + next.second.orientation = + Quaternion::rotation_y(-2.5) * Quaternion::rotation_z(1.57); }, _ => { next.main.position = Vec3::new(-2.0, -5.0, -6.0); diff --git a/voxygen/anim/src/biped_large/selfbuff.rs b/voxygen/anim/src/biped_large/selfbuff.rs new file mode 100644 index 0000000000..5b3be3bfe2 --- /dev/null +++ b/voxygen/anim/src/biped_large/selfbuff.rs @@ -0,0 +1,163 @@ +use super::{ + super::{vek::*, Animation}, + BipedLargeSkeleton, SkeletonAttr, +}; +use common::{ + comp::item::tool::{AbilitySpec, ToolKind}, + states::utils::StageSection, +}; +use std::f32::consts::PI; + +pub struct SelfBuffAnimation; + +impl Animation for SelfBuffAnimation { + #[allow(clippy::type_complexity)] + type Dependency<'a> = ( + (Option, Option<&'a AbilitySpec>), + (Option, Option<&'a AbilitySpec>), + Vec3, + f32, + Option, + f32, + ); + type Skeleton = BipedLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"biped_large_selfbuff\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_large_selfbuff")] + #[allow(clippy::approx_constant)] // TODO: Pending review in #587 + fn update_skeleton_inner<'a>( + skeleton: &Self::Skeleton, + ( + (active_tool_kind, active_tool_spec), + _second_tool, + velocity, + _global_time, + stage_section, + acc_vel, + ): Self::Dependency<'a>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let mut next = (*skeleton).clone(); + let speed = Vec2::::from(velocity).magnitude(); + + let lab: f32 = 0.65 * s_a.tempo; + let speednorm = (speed / 12.0).powf(0.4); + let foothoril = (acc_vel * lab + PI * 1.45).sin() * speednorm; + let foothorir = (acc_vel * lab + PI * (0.45)).sin() * speednorm; + let footrotl = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 1.4).sin()).powi(2))).sqrt()) + * ((acc_vel * lab + PI * 1.4).sin()); + + let footrotr = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 0.4).sin()).powi(2))).sqrt()) + * ((acc_vel * lab + PI * 0.4).sin()); + let (move1base, movement3, tensionbase, tension2base) = match stage_section { + Some(StageSection::Buildup) => ( + (anim_time.powf(0.25)).min(1.0), + 0.0, + (anim_time * 10.0).sin(), + 0.0, + ), + Some(StageSection::Cast) => { + (1.0, 0.0, (anim_time * 30.0).sin(), (anim_time * 12.0).sin()) + }, + Some(StageSection::Recover) => (1.0, anim_time.powi(4), 1.0, 1.0), + _ => (0.0, 0.0, 0.0, 0.0), + }; + + let pullback = 1.0 - movement3; + let move1 = move1base * pullback; + let tension = tensionbase * pullback; + let tension2 = tension2base * pullback; + + next.second.position = Vec3::new(0.0, 0.0, 0.0); + next.second.orientation = Quaternion::rotation_x(0.0); + next.shoulder_l.position = Vec3::new( + -s_a.shoulder.0, + s_a.shoulder.1, + s_a.shoulder.2 - foothorir * 1.0, + ); + next.shoulder_l.orientation = + Quaternion::rotation_x(move1 * 0.8 + 0.6 * speednorm + (footrotr * -0.2) * speednorm); + + next.shoulder_r.position = Vec3::new( + s_a.shoulder.0, + s_a.shoulder.1, + s_a.shoulder.2 - foothoril * 1.0, + ); + next.shoulder_r.orientation = + Quaternion::rotation_x(move1 * 0.8 + 0.6 * speednorm + (footrotl * -0.2) * speednorm); + next.torso.orientation = Quaternion::rotation_z(0.0); + + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_x(0.0); + + next.hand_l.position = Vec3::new(0.0, 0.0, s_a.grip.0); + next.hand_r.position = Vec3::new(0.0, 0.0, s_a.grip.0); + + next.hand_l.orientation = Quaternion::rotation_x(0.0); + next.hand_r.orientation = Quaternion::rotation_x(0.0); + + #[allow(clippy::single_match)] + match active_tool_kind { + Some(ToolKind::Natural) => { + if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { + match spec.as_str() { + "Minotaur" => { + next.upper_torso.orientation = + Quaternion::rotation_x(move1 * -0.1 + tension2 * 0.05); + next.lower_torso.orientation = + Quaternion::rotation_x(move1 * 0.1 + tension2 * -0.05); + + next.head.orientation = + Quaternion::rotation_x(move1 * 0.8 + tension2 * -0.1) + * Quaternion::rotation_y(tension2 * -0.1); + + next.control_l.position = Vec3::new(0.0, 4.0, 5.0); + next.control_r.position = Vec3::new(0.0, 4.0, 5.0); + next.weapon_l.position = Vec3::new( + -12.0 + move1 * -15.0, + -6.0 + move1 * 13.0, + -18.0 + move1 * 16.0 + tension2 * 3.0, + ); + next.weapon_r.position = Vec3::new( + 12.0 + move1 * 1.0, + -6.0 + move1 * 7.0 + tension * 0.3, + -18.0 + move1 * -2.0, + ); + + next.weapon_l.orientation = Quaternion::rotation_x(-1.67 + move1 * 1.9) + * Quaternion::rotation_y(move1 * 0.25 + tension2 * 0.06) + * Quaternion::rotation_z(move1 * 1.3); + next.weapon_r.orientation = Quaternion::rotation_x(-1.67 + move1 * 0.8) + * Quaternion::rotation_y(move1 * -0.85 + tension * 0.12) + * Quaternion::rotation_z(move1 * 0.7); + + next.control_l.orientation = Quaternion::rotation_x(1.57 + move1 * 0.1) + * Quaternion::rotation_y(0.0); + next.control_r.orientation = Quaternion::rotation_x(1.57 + move1 * 0.1) + * Quaternion::rotation_y(0.0); + + next.control.orientation = + Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0); + next.shoulder_l.orientation = + Quaternion::rotation_x(-0.3 + move1 * 2.2 + tension2 * 0.17) + * Quaternion::rotation_y(move1 * 0.95); + + next.shoulder_r.orientation = + Quaternion::rotation_x(-0.3 + move1 * 0.1) + * Quaternion::rotation_y(move1 * -0.35); + }, + _ => {}, + } + } + }, + _ => {}, + } + + next + } +} diff --git a/voxygen/anim/src/biped_large/stunned.rs b/voxygen/anim/src/biped_large/stunned.rs index cfd429d812..f8f0ff1e53 100644 --- a/voxygen/anim/src/biped_large/stunned.rs +++ b/voxygen/anim/src/biped_large/stunned.rs @@ -65,7 +65,8 @@ impl Animation for StunnedAnimation { let short = (acc_vel * lab).sin() * speednorm; let shortalt = (anim_time * lab * 16.0 + PI / 2.0).sin(); - + next.second.position = Vec3::new(0.0, 0.0, 0.0); + next.second.orientation = Quaternion::rotation_x(0.0); if s_a.beast { next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); } else { @@ -391,6 +392,24 @@ impl Animation for StunnedAnimation { next.torso.orientation = Quaternion::rotation_x(-0.25); } }, + "Minotaur" => { + next.control_l.position = Vec3::new(0.0, 4.0, 5.0); + next.control_r.position = Vec3::new(0.0, 4.0, 5.0); + next.weapon_l.position = Vec3::new(-12.0, -6.0, -18.0); + next.weapon_r.position = Vec3::new(12.0, -6.0, -18.0); + + next.weapon_l.orientation = Quaternion::rotation_x(-1.57 - 0.1); + next.weapon_r.orientation = Quaternion::rotation_x(-1.57 - 0.1); + + next.control_l.orientation = Quaternion::rotation_x(1.57); + next.control_r.orientation = Quaternion::rotation_x(1.57); + + next.control.orientation = + Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0); + next.shoulder_l.orientation = Quaternion::rotation_x(-0.3); + + next.shoulder_r.orientation = Quaternion::rotation_x(-0.3); + }, _ => {}, } } diff --git a/voxygen/anim/src/biped_large/wield.rs b/voxygen/anim/src/biped_large/wield.rs index f37bf0dc30..6a280feb08 100644 --- a/voxygen/anim/src/biped_large/wield.rs +++ b/voxygen/anim/src/biped_large/wield.rs @@ -91,6 +91,8 @@ impl Animation for WieldAnimation { let short = (acc_vel * lab).sin() * speednorm; let shortalt = (anim_time * lab * 16.0 + PI / 2.0).sin(); + next.second.position = Vec3::new(0.0, 0.0, 0.0); + next.second.orientation = Quaternion::rotation_x(0.0); if s_a.beast { next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); @@ -169,12 +171,12 @@ impl Animation for WieldAnimation { 5.0 + s_a.grip.0 / 1.2, -4.0 + -s_a.grip.0 / 2.0 + short * -1.5, ); + next.second.scale = Vec3::one() * 0.0; next.control_l.orientation = Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.2); - next.control_r.orientation = Quaternion::rotation_x(PI / 2.2) - * Quaternion::rotation_y(0.2) - * Quaternion::rotation_z(0.0); + next.control_r.orientation = + Quaternion::rotation_x(PI / 2.2) * Quaternion::rotation_y(0.2); next.control.orientation = Quaternion::rotation_x(-0.2 + short * 0.2) * Quaternion::rotation_y(-0.1); @@ -430,6 +432,24 @@ impl Animation for WieldAnimation { next.torso.orientation = Quaternion::rotation_x(-0.25); } }, + "Minotaur" => { + next.control_l.position = Vec3::new(0.0, 4.0, 5.0); + next.control_r.position = Vec3::new(0.0, 4.0, 5.0); + next.weapon_l.position = Vec3::new(-12.0, -6.0, -18.0); + next.weapon_r.position = Vec3::new(12.0, -6.0, -18.0); + + next.weapon_l.orientation = Quaternion::rotation_x(-1.57 - 0.1); + next.weapon_r.orientation = Quaternion::rotation_x(-1.57 - 0.1); + + next.control_l.orientation = Quaternion::rotation_x(1.57); + next.control_r.orientation = Quaternion::rotation_x(1.57); + + next.control.orientation = + Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0); + next.shoulder_l.orientation = Quaternion::rotation_x(-0.3); + + next.shoulder_r.orientation = Quaternion::rotation_x(-0.3); + }, _ => {}, } } diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs index 1a0dde31f7..754ffd8eec 100644 --- a/voxygen/src/scene/figure/load.rs +++ b/voxygen/src/scene/figure/load.rs @@ -3495,7 +3495,6 @@ struct SidedBLCentralVoxSpec { torso_upper: BipedLargeCentralSubSpec, torso_lower: BipedLargeCentralSubSpec, tail: BipedLargeCentralSubSpec, - second: BipedLargeCentralSubSpec, } #[derive(Deserialize)] struct BipedLargeCentralSubSpec { @@ -3523,13 +3522,16 @@ struct BipedLargeLateralSubSpec { lateral: VoxSimple, } #[derive(Deserialize)] -struct BipedLargeWeaponSpec(HashMap); +struct BipedLargeMainSpec(HashMap); +#[derive(Deserialize)] +struct BipedLargeSecondSpec(HashMap); make_vox_spec!( biped_large::Body, struct BipedLargeSpec { central: BipedLargeCentralSpec = "voxygen.voxel.biped_large_central_manifest", lateral: BipedLargeLateralSpec = "voxygen.voxel.biped_large_lateral_manifest", - weapon: BipedLargeWeaponSpec = "voxygen.voxel.biped_weapon_manifest", + main: BipedLargeMainSpec = "voxygen.voxel.biped_weapon_manifest", + second: BipedLargeSecondSpec = "voxygen.voxel.biped_weapon_manifest", }, |FigureKey { body, extra }, spec| { const DEFAULT_LOADOUT: super::cache::CharacterCacheKey = super::cache::CharacterCacheKey { @@ -3567,15 +3569,17 @@ make_vox_spec!( body.body_type, )), tool.and_then(|tool| tool.active.as_ref()).map(|tool| { - spec.weapon.read().0.mesh_main( + spec.main.read().0.mesh_main( + &tool.name, + false, + ) + }), + tool.and_then(|tool| tool.active.as_ref()).map(|tool| { + spec.second.read().0.mesh_second( &tool.name, false, ) }), - Some(spec.central.read().0.mesh_second( - body.species, - body.body_type, - )), Some(spec.lateral.read().0.mesh_shoulder_l( body.species, body.body_type, @@ -3693,22 +3697,6 @@ impl BipedLargeCentralSpec { (central, Vec3::from(spec.tail.offset)) } - - fn mesh_second(&self, species: BLSpecies, body_type: BLBodyType) -> BoneMeshes { - let spec = match self.0.get(&(species, body_type)) { - Some(spec) => spec, - None => { - error!( - "No second weapon specification exists for the combination of {:?} and {:?}", - species, body_type - ); - return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5)); - }, - }; - let central = graceful_load_segment(&spec.second.central.0); - - (central, Vec3::from(spec.second.offset)) - } } impl BipedLargeLateralSpec { fn mesh_shoulder_l(&self, species: BLSpecies, body_type: BLBodyType) -> BoneMeshes { @@ -3839,7 +3827,7 @@ impl BipedLargeLateralSpec { (lateral, Vec3::from(spec.foot_r.offset)) } } -impl BipedLargeWeaponSpec { +impl BipedLargeMainSpec { fn mesh_main(&self, item_definition_id: &str, flipped: bool) -> BoneMeshes { let spec = match self.0.get(item_definition_id) { Some(spec) => spec, @@ -3868,6 +3856,35 @@ impl BipedLargeWeaponSpec { (tool_kind_segment, offset) } } +impl BipedLargeSecondSpec { + fn mesh_second(&self, item_definition_id: &str, flipped: bool) -> BoneMeshes { + let spec = match self.0.get(item_definition_id) { + Some(spec) => spec, + None => { + error!(?item_definition_id, "No tool/weapon specification exists"); + return load_mesh("not_found", Vec3::new(-1.5, -1.5, -7.0)); + }, + }; + + let tool_kind_segment = if flipped { + graceful_load_segment_flipped(&spec.vox_spec.0, true) + } else { + graceful_load_segment(&spec.vox_spec.0) + }; + + let offset = Vec3::new( + if flipped { + 0.0 - spec.vox_spec.1[0] - (tool_kind_segment.sz.x as f32) + } else { + spec.vox_spec.1[0] + }, + spec.vox_spec.1[1], + spec.vox_spec.1[2], + ); + + (tool_kind_segment, offset) + } +} //// #[derive(Deserialize)] struct GolemCentralSpec(HashMap<(GSpecies, GBodyType), SidedGCentralVoxSpec>); diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index c502b07ddf..f0411c9d72 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -3713,7 +3713,84 @@ impl FigureMgr { skeleton_attr, ) }, - CharacterState::BasicMelee(_) => { + CharacterState::ChargedMelee(s) => { + let stage_time = s.timer.as_secs_f32(); + + let stage_progress = match s.stage_section { + StageSection::Charge => { + stage_time / s.static_data.charge_duration.as_secs_f32() + }, + StageSection::Swing => { + 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::biped_large::ChargeMeleeAnimation::update_skeleton( + &target_base, + ( + (active_tool_kind, active_tool_spec), + (second_tool_kind, second_tool_spec), + rel_vel, + time, + Some(s.stage_section), + state.acc_vel, + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, + CharacterState::SelfBuff(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::Cast => { + stage_time / s.static_data.cast_duration.as_secs_f32() + }, + StageSection::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f32() + }, + _ => 0.0, + }; + + anim::biped_large::SelfBuffAnimation::update_skeleton( + &target_base, + ( + (active_tool_kind, active_tool_spec), + (second_tool_kind, second_tool_spec), + rel_vel, + time, + Some(s.stage_section), + state.acc_vel, + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, + CharacterState::BasicMelee(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::Swing => { + 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::biped_large::AlphaAnimation::update_skeleton( &target_base, ( @@ -3721,10 +3798,10 @@ impl FigureMgr { (second_tool_kind, second_tool_spec), rel_vel, time, - None, + Some(s.stage_section), state.acc_vel, ), - state.state_time, + stage_progress, &mut state_animation_rate, skeleton_attr, ) @@ -3875,8 +3952,8 @@ impl FigureMgr { anim::biped_large::DashAnimation::update_skeleton( &target_base, ( - active_tool_kind, - second_tool_kind, + (active_tool_kind, active_tool_spec), + (second_tool_kind, second_tool_spec), rel_vel, time, Some(s.stage_section),