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