From fe47a14ba5f57aab840d38245c6ee91b0001fea1 Mon Sep 17 00:00:00 2001 From: Samuel Keiffer Date: Wed, 8 Jul 2020 19:58:41 +0000 Subject: [PATCH] Spin attack for axe --- CHANGELOG.md | 1 + assets/voxygen/element/icons/2haxe_m1.png | 4 +- .../voxygen/element/icons/skill_axespin.png | 3 + assets/voxygen/voxel/weapon/axe/rusty_2h.vox | 4 +- common/src/comp/ability.rs | 32 ++++ common/src/comp/character_state.rs | 8 +- common/src/comp/inventory/item/tool.rs | 10 +- common/src/states/mod.rs | 1 + common/src/states/spin_melee.rs | 146 +++++++++++++++ common/src/sys/character_behavior.rs | 2 + common/src/sys/stats.rs | 1 + voxygen/src/anim/src/character/mod.rs | 5 +- voxygen/src/anim/src/character/spinmelee.rs | 170 ++++++++++++++++++ voxygen/src/anim/src/character/wield.rs | 62 +++++-- voxygen/src/hud/img_ids.rs | 1 + voxygen/src/hud/skillbar.rs | 2 +- voxygen/src/scene/figure/mod.rs | 9 + 17 files changed, 428 insertions(+), 33 deletions(-) create mode 100644 assets/voxygen/element/icons/skill_axespin.png create mode 100644 common/src/states/spin_melee.rs create mode 100644 voxygen/src/anim/src/character/spinmelee.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d4ddc625..c81a1137d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Better pathfinding - Bombs - Training dummy items +- Added spin attack for axe ### Changed diff --git a/assets/voxygen/element/icons/2haxe_m1.png b/assets/voxygen/element/icons/2haxe_m1.png index 5b26cd998a..42871690f2 100644 --- a/assets/voxygen/element/icons/2haxe_m1.png +++ b/assets/voxygen/element/icons/2haxe_m1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bddd94d15a337c957883c58d8c0cc437f59c1adab9cadd083d3bbaeedc4540be -size 947 +oid sha256:9804ff754021eaec1c916001cb04dd690cd489b864b9e0b29e5f1a1606023545 +size 517 diff --git a/assets/voxygen/element/icons/skill_axespin.png b/assets/voxygen/element/icons/skill_axespin.png new file mode 100644 index 0000000000..f6d46e2212 --- /dev/null +++ b/assets/voxygen/element/icons/skill_axespin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a86ceb4f26f3e2d1ce1e346c02ef424033e5e955152226998d55a812efa571d0 +size 479 diff --git a/assets/voxygen/voxel/weapon/axe/rusty_2h.vox b/assets/voxygen/voxel/weapon/axe/rusty_2h.vox index 6c88590b64..de6bed8668 100644 --- a/assets/voxygen/voxel/weapon/axe/rusty_2h.vox +++ b/assets/voxygen/voxel/weapon/axe/rusty_2h.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:32f582124883285583904f940e6ee84c79972fc20202c4c12f57cc718758c9ff -size 1752 +oid sha256:41c7d03d3f941210ad3f8e278477ddf154233cf00c03267220d0623028bf55e9 +size 2088 diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index cb5bba0419..b09b7bfaf8 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -20,6 +20,7 @@ pub enum CharacterAbilityType { BasicBlock, TripleStrike(Stage), LeapMelee, + SpinMelee, } impl From<&CharacterState> for CharacterAbilityType { @@ -32,6 +33,7 @@ impl From<&CharacterState> for CharacterAbilityType { CharacterState::BasicBlock => Self::BasicBlock, CharacterState::LeapMelee(_) => Self::LeapMelee, CharacterState::TripleStrike(data) => Self::TripleStrike(data.stage), + CharacterState::SpinMelee(_) => Self::SpinMelee, _ => Self::BasicMelee, } } @@ -80,6 +82,12 @@ pub enum CharacterAbility { recover_duration: Duration, base_damage: u32, }, + SpinMelee { + energy_cost: u32, + buildup_duration: Duration, + recover_duration: Duration, + base_damage: u32, + }, } impl CharacterAbility { @@ -117,6 +125,10 @@ impl CharacterAbility { .energy .try_change_by(-(*energy_cost as i32), EnergySource::Ability) .is_ok(), + CharacterAbility::SpinMelee { energy_cost, .. } => update + .energy + .try_change_by(-(*energy_cost as i32), EnergySource::Ability) + .is_ok(), _ => true, } } @@ -239,6 +251,26 @@ impl From<&CharacterAbility> for CharacterState { recover_duration: *recover_duration, base_damage: *base_damage, }), + CharacterAbility::SpinMelee { + energy_cost, + buildup_duration, + recover_duration, + base_damage, + } => CharacterState::SpinMelee(spin_melee::Data { + exhausted: false, + energy_cost: *energy_cost, + buildup_duration: *buildup_duration, + buildup_duration_default: *buildup_duration, + recover_duration: *recover_duration, + recover_duration_default: *recover_duration, + base_damage: *base_damage, + // This isn't needed for it's continuous implementation, but is left in should this + // skill be moved to the skillbar + hits_remaining: 1, + hits_remaining_default: 1, /* Should be the same value as hits_remaining, also + * this value can be removed if ability moved to + * skillbar */ + }), } } } diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 3b6c5ba2e0..ee132711fd 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -64,6 +64,8 @@ pub enum CharacterState { TripleStrike(triple_strike::Data), /// A leap followed by a small aoe ground attack LeapMelee(leap_melee::Data), + /// Spin around, dealing damage to enemies surrounding you + SpinMelee(spin_melee::Data), } impl CharacterState { @@ -75,7 +77,8 @@ impl CharacterState { | CharacterState::DashMelee(_) | CharacterState::TripleStrike(_) | CharacterState::BasicBlock - | CharacterState::LeapMelee(_) => true, + | CharacterState::LeapMelee(_) + | CharacterState::SpinMelee(_) => true, _ => false, } } @@ -86,7 +89,8 @@ impl CharacterState { | CharacterState::BasicRanged(_) | CharacterState::DashMelee(_) | CharacterState::TripleStrike(_) - | CharacterState::LeapMelee(_) => true, + | CharacterState::LeapMelee(_) + | CharacterState::SpinMelee(_) => true, _ => false, } } diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index 19b741eed8..abeb4a04c9 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -221,13 +221,11 @@ impl Tool { base_damage: 7, needs_timing: true, }, - BasicMelee { + SpinMelee { energy_cost: 100, - buildup_duration: Duration::from_millis(700), - recover_duration: Duration::from_millis(100), - base_healthchange: -12, - range: 3.5, - max_angle: 30.0, + buildup_duration: Duration::from_millis(125), + recover_duration: Duration::from_millis(125), + base_damage: 5, }, ], Hammer(_) => vec![ diff --git a/common/src/states/mod.rs b/common/src/states/mod.rs index aaf7f0bdc1..35676a2d17 100644 --- a/common/src/states/mod.rs +++ b/common/src/states/mod.rs @@ -12,6 +12,7 @@ pub mod idle; pub mod leap_melee; pub mod roll; pub mod sit; +pub mod spin_melee; pub mod triple_strike; pub mod utils; pub mod wielding; diff --git a/common/src/states/spin_melee.rs b/common/src/states/spin_melee.rs new file mode 100644 index 0000000000..55d00c14db --- /dev/null +++ b/common/src/states/spin_melee.rs @@ -0,0 +1,146 @@ +use crate::{ + comp::{Attacking, CharacterState, EnergySource, StateUpdate}, + sys::character_behavior::*, +}; +use serde::{Deserialize, Serialize}; +use std::time::Duration; +use vek::Vec3; + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] +pub struct Data { + /// How long until the state attacks + pub buildup_duration: Duration, + /// Allows for buildup_duration to be reset to default value + pub buildup_duration_default: Duration, + /// How long until state ends + pub recover_duration: Duration, + /// Allows for recover_duration to be reset to default value + pub recover_duration_default: Duration, + /// Base damage + pub base_damage: u32, + /// Whether the attack can deal more damage + pub exhausted: bool, + /// How many hits it can do before ending + pub hits_remaining: u32, + /// Allows for hits_remaining to be reset to default value + pub hits_remaining_default: u32, + /// Energy cost per attack + pub energy_cost: u32, +} + +const MOVE_SPEED: f32 = 5.0; + +impl CharacterBehavior for Data { + fn behavior(&self, data: &JoinData) -> StateUpdate { + let mut update = StateUpdate::from(data); + + if self.buildup_duration != Duration::default() { + // Allows for moving + update.vel.0 = + Vec3::new(data.inputs.move_dir.x, data.inputs.move_dir.y, 0.0) * MOVE_SPEED; + + update.character = CharacterState::SpinMelee(Data { + buildup_duration: self + .buildup_duration + .checked_sub(Duration::from_secs_f32(data.dt.0)) + .unwrap_or_default(), + buildup_duration_default: self.buildup_duration_default, + recover_duration: self.recover_duration, + recover_duration_default: self.recover_duration_default, + base_damage: self.base_damage, + exhausted: self.exhausted, + hits_remaining: self.hits_remaining, + hits_remaining_default: self.hits_remaining_default, + energy_cost: self.energy_cost, + }); + } else if !self.exhausted { + //Hit attempt + data.updater.insert(data.entity, Attacking { + base_healthchange: -(self.base_damage as i32), + range: 3.5, + max_angle: 360_f32.to_radians(), + applied: false, + hit_count: 0, + knockback: 0.0, + }); + + update.character = CharacterState::SpinMelee(Data { + buildup_duration: self.buildup_duration, + buildup_duration_default: self.buildup_duration_default, + recover_duration: self.recover_duration, + recover_duration_default: self.recover_duration_default, + base_damage: self.base_damage, + exhausted: true, + hits_remaining: self.hits_remaining - 1, + hits_remaining_default: self.hits_remaining_default, + energy_cost: self.energy_cost, + }); + } else if self.recover_duration != Duration::default() { + // Allows for moving + update.vel.0 = + Vec3::new(data.inputs.move_dir.x, data.inputs.move_dir.y, 0.0) * MOVE_SPEED; + + update.character = CharacterState::SpinMelee(Data { + buildup_duration: self.buildup_duration, + buildup_duration_default: self.buildup_duration_default, + recover_duration: self + .recover_duration + .checked_sub(Duration::from_secs_f32(data.dt.0)) + .unwrap_or_default(), + recover_duration_default: self.recover_duration_default, + base_damage: self.base_damage, + exhausted: self.exhausted, + hits_remaining: self.hits_remaining, + hits_remaining_default: self.hits_remaining_default, + energy_cost: self.energy_cost, + }); + } else if self.hits_remaining != 0 { + // Allows for one ability usage to have multiple hits + // This isn't needed for it's continuous implementation, but is left in should + // this skill be moved to the skillbar + update.character = CharacterState::SpinMelee(Data { + buildup_duration: self.buildup_duration_default, + buildup_duration_default: self.buildup_duration_default, + recover_duration: self.recover_duration_default, + recover_duration_default: self.recover_duration_default, + base_damage: self.base_damage, + exhausted: false, + hits_remaining: self.hits_remaining, + hits_remaining_default: self.hits_remaining_default, + energy_cost: self.energy_cost, + }); + } else if update.energy.current() >= self.energy_cost && data.inputs.secondary.is_pressed() + { + update.character = CharacterState::SpinMelee(Data { + buildup_duration: self.buildup_duration_default, + buildup_duration_default: self.buildup_duration_default, + recover_duration: self.recover_duration_default, + recover_duration_default: self.recover_duration_default, + base_damage: self.base_damage, + exhausted: false, + hits_remaining: self.hits_remaining_default, + hits_remaining_default: self.hits_remaining_default, + energy_cost: self.energy_cost, + }); + // Consumes energy if there's enough left and RMB is held down + update + .energy + .change_by(-(self.energy_cost as i32), EnergySource::Ability); + } else { + // Done + update.character = CharacterState::Wielding; + // Make sure attack component is removed + data.updater.remove::(data.entity); + } + + // Grant energy on successful hit + if let Some(attack) = data.attacking { + if attack.applied && attack.hit_count > 0 { + data.updater.remove::(data.entity); + update.energy.change_by(10, EnergySource::HitEnemy); + } + } + + update + } +} diff --git a/common/src/sys/character_behavior.rs b/common/src/sys/character_behavior.rs index 586dc239ba..496a3f2207 100644 --- a/common/src/sys/character_behavior.rs +++ b/common/src/sys/character_behavior.rs @@ -244,6 +244,7 @@ impl<'a> System<'a> for Sys { CharacterState::Boost(data) => data.handle_event(&j, action), CharacterState::DashMelee(data) => data.handle_event(&j, action), CharacterState::LeapMelee(data) => data.handle_event(&j, action), + CharacterState::SpinMelee(data) => data.handle_event(&j, action), }; local_emitter.append(&mut state_update.local_events); server_emitter.append(&mut state_update.server_events); @@ -269,6 +270,7 @@ impl<'a> System<'a> for Sys { CharacterState::Boost(data) => data.behavior(&j), CharacterState::DashMelee(data) => data.behavior(&j), CharacterState::LeapMelee(data) => data.behavior(&j), + CharacterState::SpinMelee(data) => data.behavior(&j), }; local_emitter.append(&mut state_update.local_events); diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs index 2335c64fce..8f7d57b100 100644 --- a/common/src/sys/stats.rs +++ b/common/src/sys/stats.rs @@ -103,6 +103,7 @@ impl<'a> System<'a> for Sys { CharacterState::BasicMelee { .. } | CharacterState::DashMelee { .. } | CharacterState::LeapMelee { .. } + | CharacterState::SpinMelee { .. } | CharacterState::TripleStrike { .. } | CharacterState::BasicRanged { .. } => { if energy.get_unchecked().regen_rate != 0.0 { diff --git a/voxygen/src/anim/src/character/mod.rs b/voxygen/src/anim/src/character/mod.rs index 6416638929..f3440fa3ed 100644 --- a/voxygen/src/anim/src/character/mod.rs +++ b/voxygen/src/anim/src/character/mod.rs @@ -17,6 +17,7 @@ pub mod run; pub mod shoot; pub mod sit; pub mod spin; +pub mod spinmelee; pub mod stand; pub mod swim; pub mod wield; @@ -28,8 +29,8 @@ pub use self::{ dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation, glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation, jump::JumpAnimation, leapmelee::LeapAnimation, roll::RollAnimation, run::RunAnimation, - shoot::ShootAnimation, sit::SitAnimation, spin::SpinAnimation, stand::StandAnimation, - swim::SwimAnimation, wield::WieldAnimation, + shoot::ShootAnimation, sit::SitAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation, + stand::StandAnimation, swim::SwimAnimation, wield::WieldAnimation, }; use super::{Bone, FigureBoneData, Skeleton}; diff --git a/voxygen/src/anim/src/character/spinmelee.rs b/voxygen/src/anim/src/character/spinmelee.rs new file mode 100644 index 0000000000..26b4f43269 --- /dev/null +++ b/voxygen/src/anim/src/character/spinmelee.rs @@ -0,0 +1,170 @@ +use super::{super::Animation, CharacterSkeleton, SkeletonAttr}; +use common::comp::item::{Hands, ToolKind}; +use std::f32::consts::PI; +use vek::*; + +pub struct SpinMeleeAnimation; + +impl Animation for SpinMeleeAnimation { + type Dependency = (Option, Option, Vec3, f64); + type Skeleton = CharacterSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"character_spinmelee\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "character_spinmelee")] + #[allow(clippy::approx_constant)] // TODO: Pending review in #587 + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + (active_tool_kind, second_tool_kind, velocity, _global_time): Self::Dependency, + anim_time: f64, + rate: &mut f32, + skeleton_attr: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let lab = 1.0; + let speed = Vec2::::from(velocity).magnitude(); + let mut next = (*skeleton).clone(); + //torso movement + let xshift = if velocity.z.abs() < 0.1 { + ((anim_time as f32 - 1.1) * lab as f32 * 3.0).sin() + } else { + 0.0 + }; + let yshift = if velocity.z.abs() < 0.1 { + ((anim_time as f32 - 1.1) * lab as f32 * 3.0 + PI / 2.0).sin() + } else { + 0.0 + }; + + let spin = if anim_time < 1.1 && velocity.z.abs() < 0.1 { + 0.5 * ((anim_time as f32).powf(2.0)) + } else { + lab as f32 * anim_time as f32 * 0.9 + }; + + //feet + let slowersmooth = (anim_time as f32 * lab as f32 * 4.0).sin(); + let quick = (anim_time as f32 * lab as f32 * 8.0).sin(); + + if let Some(ToolKind::Axe(_)) = active_tool_kind { + next.l_hand.offset = Vec3::new(-0.5, 0.0, 4.0); + next.l_hand.ori = Quaternion::rotation_x(PI / 2.0) + * Quaternion::rotation_z(0.0) + * Quaternion::rotation_y(PI); + next.l_hand.scale = Vec3::one() * 1.08; + next.r_hand.offset = Vec3::new(0.5, 0.0, -2.5); + next.r_hand.ori = Quaternion::rotation_x(PI / 2.0) + * Quaternion::rotation_z(0.0) + * Quaternion::rotation_y(0.0); + next.r_hand.scale = Vec3::one() * 1.06; + next.main.offset = Vec3::new(-0.0, -2.0, -1.0); + next.main.ori = Quaternion::rotation_x(0.0) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); + + next.control.offset = Vec3::new(0.0, 16.0, 3.0); + next.control.ori = Quaternion::rotation_x(-1.4) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(1.4); + next.control.scale = Vec3::one(); + + next.head.offset = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1); + next.head.ori = Quaternion::rotation_z(0.0) + * Quaternion::rotation_x(-0.15) + * Quaternion::rotation_y(0.08); + next.chest.offset = Vec3::new( + 0.0, + skeleton_attr.chest.0 - 3.0, + skeleton_attr.chest.1 - 2.0, + ); + next.chest.ori = Quaternion::rotation_z(0.0) + * Quaternion::rotation_x(-0.1) + * Quaternion::rotation_y(0.3); + next.chest.scale = Vec3::one(); + + next.belt.offset = Vec3::new(0.0, 1.0, -1.0); + next.belt.ori = Quaternion::rotation_z(0.0) + * Quaternion::rotation_x(0.4) + * Quaternion::rotation_y(0.0); + next.belt.scale = Vec3::one() * 0.98; + next.shorts.offset = Vec3::new(0.0, 3.0, -2.5); + next.shorts.ori = Quaternion::rotation_z(0.0) + * Quaternion::rotation_x(0.7) + * Quaternion::rotation_y(0.0); + next.shorts.scale = Vec3::one(); + next.torso.offset = Vec3::new( + -xshift * (anim_time as f32).min(0.6), + -yshift * (anim_time as f32).min(0.6), + 0.0, + ) * skeleton_attr.scaler; + next.torso.ori = Quaternion::rotation_z(spin * -16.0) + * Quaternion::rotation_x(0.0) + * Quaternion::rotation_y(0.0); + next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler; + } + if velocity.z.abs() > 0.1 { + next.l_foot.offset = Vec3::new(-skeleton_attr.foot.0, 8.0, skeleton_attr.foot.2 + 2.0); + next.l_foot.ori = Quaternion::rotation_x(1.0) * Quaternion::rotation_z(0.0); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new(skeleton_attr.foot.0, 8.0, skeleton_attr.foot.2 + 2.0); + next.r_foot.ori = Quaternion::rotation_x(1.0); + next.r_foot.scale = Vec3::one(); + } else if speed < 0.5 { + next.l_foot.offset = Vec3::new( + -skeleton_attr.foot.0, + 2.0 + quick * -6.0, + skeleton_attr.foot.2, + ); + next.l_foot.ori = + Quaternion::rotation_x(0.5 + slowersmooth * 0.2) * Quaternion::rotation_z(0.0); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new(skeleton_attr.foot.0, 4.0, skeleton_attr.foot.2); + next.r_foot.ori = + Quaternion::rotation_x(0.5 - slowersmooth * 0.2) * Quaternion::rotation_y(-0.4); + next.r_foot.scale = Vec3::one(); + } else { + next.l_foot.offset = Vec3::new( + -skeleton_attr.foot.0, + 2.0 + quick * -6.0, + skeleton_attr.foot.2, + ); + next.l_foot.ori = + Quaternion::rotation_x(0.5 + slowersmooth * 0.2) * Quaternion::rotation_z(0.0); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new( + skeleton_attr.foot.0, + 2.0 + quick * 6.0, + skeleton_attr.foot.2, + ); + next.r_foot.ori = + Quaternion::rotation_x(0.5 - slowersmooth * 0.2) * Quaternion::rotation_z(0.0); + next.r_foot.scale = Vec3::one(); + }; + next.lantern.offset = Vec3::new( + skeleton_attr.lantern.0, + skeleton_attr.lantern.1, + skeleton_attr.lantern.2, + ); + next.lantern.ori = Quaternion::rotation_z(0.0) + * Quaternion::rotation_x(0.7) + * Quaternion::rotation_y(-0.8); + next.glider.offset = Vec3::new(0.0, 0.0, 10.0); + next.glider.scale = Vec3::one() * 0.0; + next.l_control.scale = Vec3::one(); + next.r_control.scale = Vec3::one(); + + next.second.scale = match ( + active_tool_kind.map(|tk| tk.into_hands()), + second_tool_kind.map(|tk| tk.into_hands()), + ) { + (Some(Hands::OneHand), Some(Hands::OneHand)) => Vec3::one(), + (_, _) => Vec3::zero(), + }; + + next + } +} diff --git a/voxygen/src/anim/src/character/wield.rs b/voxygen/src/anim/src/character/wield.rs index eb11f819aa..299146b5f4 100644 --- a/voxygen/src/anim/src/character/wield.rs +++ b/voxygen/src/anim/src/character/wield.rs @@ -131,7 +131,7 @@ impl Animation for WieldAnimation { let hand_scale = 1.12; next.control.offset = Vec3::new(0.0, 0.0, 0.0); - // next.control.ori = Quaternion::rotation_x(u_slow * 0.15 + 1.0) + //next.control.ori = Quaternion::rotation_x(slow * 1.0); // * Quaternion::rotation_y(0.0) // * Quaternion::rotation_z(u_slowalt * 0.08); // next.control.scale = Vec3::one(); @@ -172,26 +172,52 @@ impl Animation for WieldAnimation { // next.r_control.scale = Vec3::one(); }, Some(ToolKind::Axe(_)) => { - next.l_hand.offset = Vec3::new(-4.0, 3.0, 6.0); - next.l_hand.ori = Quaternion::rotation_x(-0.3) - * Quaternion::rotation_z(3.14 - 0.3) - * Quaternion::rotation_y(-0.8); + if velocity < 0.5 { + next.head.offset = Vec3::new( + 0.0, + -3.5 + skeleton_attr.head.0, + skeleton_attr.head.1 + u_slow * 0.1, + ); + next.head.ori = Quaternion::rotation_z(head_look.x) + * Quaternion::rotation_x(0.35 + head_look.y.abs()); + next.head.scale = Vec3::one() * skeleton_attr.head_scale; + next.chest.ori = Quaternion::rotation_x(-0.35) + * Quaternion::rotation_y(u_slowalt * 0.04) + * Quaternion::rotation_z(0.15); + next.belt.offset = + Vec3::new(0.0, 1.0 + skeleton_attr.belt.0, skeleton_attr.belt.1); + next.belt.ori = Quaternion::rotation_x(0.15) + * Quaternion::rotation_y(u_slowalt * 0.03) + * Quaternion::rotation_z(0.15); + next.shorts.offset = + Vec3::new(0.0, 1.0 + skeleton_attr.shorts.0, skeleton_attr.shorts.1); + next.shorts.ori = Quaternion::rotation_x(0.15) * Quaternion::rotation_z(0.25); + next.control.ori = Quaternion::rotation_x(1.8) + * Quaternion::rotation_y(-0.5) + * Quaternion::rotation_z(PI - 0.2); + next.control.scale = Vec3::one(); + } else { + next.control.ori = Quaternion::rotation_x(2.1) + * Quaternion::rotation_y(-0.4) + * Quaternion::rotation_z(PI - 0.2); + next.control.scale = Vec3::one(); + } + next.l_hand.offset = Vec3::new(-0.5, 0.0, 4.0); + next.l_hand.ori = Quaternion::rotation_x(PI / 2.0) + * Quaternion::rotation_z(0.0) + * Quaternion::rotation_y(0.0); next.l_hand.scale = Vec3::one() * 1.08; - next.r_hand.offset = Vec3::new(-2.5, 9.0, 4.0); - next.r_hand.ori = Quaternion::rotation_x(-0.3) - * Quaternion::rotation_z(3.14 - 0.3) - * Quaternion::rotation_y(-0.8); + next.r_hand.offset = Vec3::new(0.5, 0.0, -2.5); + next.r_hand.ori = Quaternion::rotation_x(PI / 2.0) + * Quaternion::rotation_z(0.0) + * Quaternion::rotation_y(0.0); next.r_hand.scale = Vec3::one() * 1.06; - next.main.offset = Vec3::new(-6.0, 10.0, -1.0); - next.main.ori = Quaternion::rotation_x(1.27) - * Quaternion::rotation_y(-0.3) - * Quaternion::rotation_z(-0.8); + next.main.offset = Vec3::new(-0.0, -2.0, -1.0); + next.main.ori = Quaternion::rotation_x(0.0) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); - next.control.offset = Vec3::new(0.0, 0.0, 0.0); - next.control.ori = Quaternion::rotation_x(u_slowalt * 0.1 + 0.2) - * Quaternion::rotation_y(-0.3) - * Quaternion::rotation_z(u_slow * 0.1 + 0.0); - next.control.scale = Vec3::one(); + next.control.offset = Vec3::new(-3.0, 11.0, 3.0); }, Some(ToolKind::Hammer(_)) => { next.l_hand.offset = Vec3::new(-12.0, 0.0, 0.0); diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 9357985bb7..50fff76512 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -117,6 +117,7 @@ image_ids! { flyingrod_m2: "voxygen.element.icons.debug_wand_m2", charge: "voxygen.element.icons.skill_charge_3", hammerleap: "voxygen.element.icons.skill_hammerleap", + axespin: "voxygen.element.icons.skill_axespin", // Skillbar level_up: "voxygen.element.misc_bg.level_up", diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs index b8d21f71d8..54a3a9e032 100644 --- a/voxygen/src/hud/skillbar.rs +++ b/voxygen/src/hud/skillbar.rs @@ -708,7 +708,7 @@ impl<'a> Widget for Skillbar<'a> { Some(ToolKind::Dagger(_)) => self.imgs.onehdagger_m2, Some(ToolKind::Shield(_)) => self.imgs.onehshield_m2, Some(ToolKind::Hammer(_)) => self.imgs.hammerleap, - Some(ToolKind::Axe(_)) => self.imgs.nothing, + Some(ToolKind::Axe(_)) => self.imgs.axespin, Some(ToolKind::Bow(_)) => self.imgs.bow_m2, Some(ToolKind::Staff(StaffKind::Sceptre)) => self.imgs.heal_0, Some(ToolKind::Staff(_)) => self.imgs.staff_m2, diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index e1b182bdc6..32db9276ba 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -708,6 +708,15 @@ impl FigureMgr { skeleton_attr, ) }, + CharacterState::SpinMelee(_) => { + anim::character::SpinMeleeAnimation::update_skeleton( + &target_base, + (active_tool_kind, second_tool_kind, vel.0, time), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, CharacterState::TripleStrike(s) => match s.stage { triple_strike::Stage::First => { anim::character::AlphaAnimation::update_skeleton(