From d5565c4a41ea86b95f83037037067ee6f2bd3950 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 12 Oct 2023 12:34:08 +0100 Subject: [PATCH] Added strafe-like rolling --- common/src/comp/ability.rs | 1 + common/src/states/roll.rs | 3 +++ common/src/states/utils.rs | 8 ++++++++ voxygen/anim/src/character/roll.rs | 25 ++++++++++++++++++++++--- voxygen/src/scene/figure/mod.rs | 1 + 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 19ffd92768..aea3d75b57 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -2404,6 +2404,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { timer: Duration::default(), stage_section: StageSection::Buildup, was_wielded: false, // false by default. utils might set it to true + prev_aimed_dir: None, is_sneaking: false, was_combo: None, }), diff --git a/common/src/states/roll.rs b/common/src/states/roll.rs index 3e2d0ee5e5..24a7af4c5a 100644 --- a/common/src/states/roll.rs +++ b/common/src/states/roll.rs @@ -9,6 +9,7 @@ use crate::{ behavior::{CharacterBehavior, JoinData}, utils::*, }, + util::Dir, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -41,6 +42,8 @@ pub struct Data { pub stage_section: StageSection, /// Had weapon pub was_wielded: bool, + /// What direction were we previously aiming in? + pub prev_aimed_dir: Option, /// Is sneaking, true if previous state was also considered sneaking pub is_sneaking: bool, /// Was in state with combo diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index b5a29af7f4..247c15198e 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -1246,6 +1246,9 @@ fn handle_ability( roll.is_sneaking = true; } } + if data.character.is_aimed() { + roll.prev_aimed_dir = Some(data.controller.inputs.look_dir); + } } return true; } @@ -1553,6 +1556,11 @@ pub fn end_ability(data: &JoinData<'_>, update: &mut StateUpdate) { time_entered: *data.time, }); } + if let CharacterState::Roll(roll) = data.character { + if let Some(dir) = roll.prev_aimed_dir { + update.ori = dir.into(); + } + } } pub fn end_melee_ability(data: &JoinData<'_>, update: &mut StateUpdate) { diff --git a/voxygen/anim/src/character/roll.rs b/voxygen/anim/src/character/roll.rs index aeae182ef7..19543c636b 100644 --- a/voxygen/anim/src/character/roll.rs +++ b/voxygen/anim/src/character/roll.rs @@ -5,6 +5,7 @@ use super::{ use common::{ comp::item::{Hands, ToolKind}, states::utils::StageSection, + util::Dir, }; use std::f32::consts::PI; @@ -19,6 +20,7 @@ type RollAnimationDependency = ( Vec3, f32, Option, + Option, ); impl Animation for RollAnimation { @@ -41,6 +43,7 @@ impl Animation for RollAnimation { last_ori, _global_time, stage_section, + prev_aimed_dir, ): Self::Dependency<'_>, anim_time: f32, rate: &mut f32, @@ -257,9 +260,25 @@ impl Animation for RollAnimation { next.foot_r.orientation = Quaternion::rotation_x(0.9 * movement1); next.torso.position = Vec3::new(0.0, 0.0, 7.0 * movement1); - next.torso.orientation = - Quaternion::rotation_x(-0.3 + movement1 * -0.4 + movement2 * -2.0 * PI) - * Quaternion::rotation_z(tilt * -10.0); + let roll_spin = Quaternion::rotation_x(-0.3 + movement1 * -0.4 + movement2 * -2.0 * PI); + next.torso.orientation = if let Some(prev_aimed_dir) = prev_aimed_dir { + // This is *slightly* hacky. Because rolling is not strafed movement, we + // actually correct for the entity orientation to make sure that our + // rolling motion is correct with respect to our original orientation + let move_dir = Quaternion::::from_vec4( + Dir::new(orientation.into_array().into()) + .rotation() + .into_vec4() + .into_array() + .into(), + ); + let aim_dir = Quaternion::::from_vec4( + prev_aimed_dir.rotation().into_vec4().into_array().into(), + ); + roll_spin * move_dir.inverse() * aim_dir + } else { + roll_spin * Quaternion::rotation_z(tilt * -10.0) + }; next } diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 93e19e1d62..9506d2cac5 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -1263,6 +1263,7 @@ impl FigureMgr { state.last_ori * anim::vek::Vec3::::unit_y(), time, Some(s.stage_section), + s.prev_aimed_dir, ), stage_progress, &mut state_animation_rate,