mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implement aerodynamic GlideWield
This commit is contained in:
parent
df666cef40
commit
9e20b090c4
@ -1252,7 +1252,7 @@ impl Client {
|
||||
.map(|cs| {
|
||||
matches!(
|
||||
cs,
|
||||
comp::CharacterState::GlideWield | comp::CharacterState::Glide(_)
|
||||
comp::CharacterState::GlideWield(_) | comp::CharacterState::Glide(_)
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -53,7 +53,7 @@ pub enum CharacterState {
|
||||
Talk,
|
||||
Sneak,
|
||||
Glide(glide::Data),
|
||||
GlideWield,
|
||||
GlideWield(glide_wield::Data),
|
||||
/// A stunned state
|
||||
Stunned(stunned::Data),
|
||||
/// A basic blocking state
|
||||
@ -180,7 +180,7 @@ impl CharacterState {
|
||||
| CharacterState::Equipping(_)
|
||||
| CharacterState::Dance
|
||||
| CharacterState::Glide(_)
|
||||
| CharacterState::GlideWield
|
||||
| CharacterState::GlideWield(_)
|
||||
| CharacterState::Talk
|
||||
| CharacterState::Roll(_),
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::utils::handle_climb;
|
||||
use super::{glide_wield, utils::handle_climb};
|
||||
use crate::{
|
||||
comp::{inventory::slot::EquipSlot, CharacterState, ControllerInputs, Ori, StateUpdate, Vel},
|
||||
glider::Glider,
|
||||
@ -108,7 +108,7 @@ impl CharacterBehavior for Data {
|
||||
if data.physics.on_ground
|
||||
&& (data.vel.0 - data.physics.ground_vel).magnitude_squared() < 2_f32.powi(2)
|
||||
{
|
||||
update.character = CharacterState::GlideWield;
|
||||
update.character = CharacterState::GlideWield(glide_wield::Data(self.glider));
|
||||
update.ori = update.ori.to_horizontal();
|
||||
} else if data.physics.in_liquid().is_some()
|
||||
|| data.inventory.equipped(EquipSlot::Glider).is_none()
|
||||
@ -149,9 +149,6 @@ impl CharacterBehavior for Data {
|
||||
{
|
||||
let glider_up = glider.ori.up();
|
||||
let d = glider_up.dot(*char_up);
|
||||
let cap = |max_ang: f32| -> Option<f32> {
|
||||
(d - max_ang.cos()).is_sign_positive().then_some(max_ang)
|
||||
};
|
||||
|
||||
if let Some(roll_input) = self.roll_input(data.inputs) {
|
||||
if (d - max_roll.cos()).is_sign_positive()
|
||||
|
@ -1,14 +1,26 @@
|
||||
use super::utils::*;
|
||||
use crate::{
|
||||
comp::{slot::EquipSlot, CharacterState, InventoryAction, StateUpdate},
|
||||
comp::{slot::EquipSlot, Body, CharacterState, InventoryAction, Ori, StateUpdate},
|
||||
glider::Glider,
|
||||
states::{
|
||||
behavior::{CharacterBehavior, JoinData},
|
||||
glide,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub struct Data;
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Data(pub Glider);
|
||||
|
||||
impl Data {
|
||||
pub fn new(body: &Body, ori: &Ori) -> Self {
|
||||
Self(Glider::new(
|
||||
body.dimensions().z * 3.0,
|
||||
body.dimensions().z / 3.0,
|
||||
*ori,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||
@ -20,25 +32,26 @@ impl CharacterBehavior for Data {
|
||||
handle_dodge_input(data, &mut update);
|
||||
handle_wield(data, &mut update);
|
||||
|
||||
let mut glider = self.0;
|
||||
glider.ori = glider.ori.slerped_towards(
|
||||
Ori::from(data.inputs.look_dir).pitched_up(inline_tweak::tweak!(0.35)),
|
||||
inline_tweak::tweak!(10.0) * data.dt.0,
|
||||
);
|
||||
|
||||
// If not on the ground while wielding glider enter gliding state
|
||||
if !data.physics.on_ground {
|
||||
let glider = Glider::new(
|
||||
data.body.dimensions().z * 3.0,
|
||||
data.body.dimensions().z / 3.0,
|
||||
*data.ori,
|
||||
);
|
||||
update.character = CharacterState::Glide(glide::Data::new(glider, data.ori));
|
||||
}
|
||||
if data
|
||||
update.character = if !data.physics.on_ground {
|
||||
CharacterState::Glide(glide::Data::new(glider, data.ori))
|
||||
} else if data
|
||||
.physics
|
||||
.in_liquid()
|
||||
.map(|depth| depth > 0.5)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
update.character = CharacterState::Idle;
|
||||
}
|
||||
if data.inventory.equipped(EquipSlot::Glider).is_none() {
|
||||
update.character = CharacterState::Idle
|
||||
CharacterState::Idle
|
||||
} else if data.inventory.equipped(EquipSlot::Glider).is_none() {
|
||||
CharacterState::Idle
|
||||
} else {
|
||||
CharacterState::GlideWield(Self(glider))
|
||||
};
|
||||
|
||||
update
|
||||
|
@ -570,7 +570,7 @@ pub fn attempt_glide_wield(data: &JoinData, update: &mut StateUpdate) {
|
||||
.unwrap_or(false)
|
||||
&& data.body.is_humanoid()
|
||||
{
|
||||
update.character = CharacterState::GlideWield;
|
||||
update.character = CharacterState::GlideWield(glide_wield::Data::new(data.body, data.ori));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,8 +297,8 @@ impl<'a> System<'a> for Sys {
|
||||
CharacterState::Talk => states::talk::Data.handle_event(&j, action),
|
||||
CharacterState::Climb(data) => data.handle_event(&j, action),
|
||||
CharacterState::Glide(data) => data.handle_event(&j, action),
|
||||
CharacterState::GlideWield => {
|
||||
states::glide_wield::Data.handle_event(&j, action)
|
||||
CharacterState::GlideWield(data) => {
|
||||
data.handle_event(&j, action)
|
||||
},
|
||||
CharacterState::Stunned(data) => data.handle_event(&j, action),
|
||||
CharacterState::Sit => {
|
||||
@ -360,7 +360,7 @@ impl<'a> System<'a> for Sys {
|
||||
CharacterState::Talk => states::talk::Data.behavior(&j),
|
||||
CharacterState::Climb(data) => data.behavior(&j),
|
||||
CharacterState::Glide(data) => data.behavior(&j),
|
||||
CharacterState::GlideWield => states::glide_wield::Data.behavior(&j),
|
||||
CharacterState::GlideWield(data) => data.behavior(&j),
|
||||
CharacterState::Stunned(data) => data.behavior(&j),
|
||||
CharacterState::Sit => states::sit::Data::behavior(&states::sit::Data, &j),
|
||||
CharacterState::Dance => states::dance::Data::behavior(&states::dance::Data, &j),
|
||||
|
@ -49,7 +49,8 @@ fn integrate_glider_forces(
|
||||
rel_wind: &Vel,
|
||||
) -> Option<()> {
|
||||
let glider = match character_state {
|
||||
CharacterState::Glide(glider) => Some(glider.glider),
|
||||
CharacterState::Glide(data) => Some(data.glider),
|
||||
CharacterState::GlideWield(data) => Some(data.0),
|
||||
_ => None,
|
||||
}?;
|
||||
|
||||
|
@ -279,7 +279,7 @@ impl<'a> System<'a> for Sys {
|
||||
});
|
||||
let is_gliding = matches!(
|
||||
read_data.char_states.get(entity),
|
||||
Some(CharacterState::GlideWield) | Some(CharacterState::Glide(_))
|
||||
Some(CharacterState::GlideWield(_)) | Some(CharacterState::Glide(_))
|
||||
) && !physics_state.on_ground;
|
||||
|
||||
if let Some(pid) = agent.position_pid_controller.as_mut() {
|
||||
|
@ -5,8 +5,9 @@ use super::{
|
||||
|
||||
pub struct GlideWieldAnimation;
|
||||
|
||||
type GlideWieldAnimationDependency = (Quaternion<f32>, Quaternion<f32>);
|
||||
impl Animation for GlideWieldAnimation {
|
||||
type Dependency<'a> = ();
|
||||
type Dependency<'a> = GlideWieldAnimationDependency;
|
||||
type Skeleton = CharacterSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -16,21 +17,25 @@ impl Animation for GlideWieldAnimation {
|
||||
|
||||
fn update_skeleton_inner<'a>(
|
||||
skeleton: &Self::Skeleton,
|
||||
_: Self::Dependency<'a>,
|
||||
(orientation, glider_orientation): Self::Dependency<'a>,
|
||||
_anim_time: f32,
|
||||
rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
let glider_ori = orientation.inverse() * glider_orientation;
|
||||
let glider_pos = Vec3::new(0.0, -5.0, 13.0);
|
||||
*rate = 1.0;
|
||||
|
||||
next.hand_l.position = Vec3::new(-2.0 - s_a.hand.0, s_a.hand.1, s_a.hand.2 + 15.0);
|
||||
next.hand_l.position =
|
||||
glider_pos + glider_ori * Vec3::new(-s_a.hand.0 + -2.0, s_a.hand.1 + 8.0, s_a.hand.2);
|
||||
next.hand_l.orientation = Quaternion::rotation_x(3.35) * Quaternion::rotation_y(0.2);
|
||||
|
||||
next.hand_r.position = Vec3::new(2.0 + s_a.hand.0, s_a.hand.1, s_a.hand.2 + 15.0);
|
||||
next.hand_r.position =
|
||||
glider_pos + glider_ori * Vec3::new(s_a.hand.0 + 2.0, s_a.hand.1 + 8.0, s_a.hand.2);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(3.35) * Quaternion::rotation_y(-0.2);
|
||||
next.glider.scale = Vec3::one() * 1.0;
|
||||
next.glider.orientation = Quaternion::rotation_x(0.35);
|
||||
next.glider.orientation = glider_ori;
|
||||
|
||||
next.glider.position = Vec3::new(0.0, -5.0, 13.0);
|
||||
|
||||
|
@ -1522,10 +1522,10 @@ impl FigureMgr {
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::GlideWield { .. } => {
|
||||
CharacterState::GlideWield(data) => {
|
||||
anim::character::GlideWieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(),
|
||||
(ori, data.0.ori.into()),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
|
Loading…
Reference in New Issue
Block a user