veloren/common/src/states/glide_wield.rs

109 lines
3.6 KiB
Rust
Raw Normal View History

use super::utils::*;
use crate::{
comp::{slot::EquipSlot, CharacterState, InventoryAction, Ori, StateUpdate},
2021-04-27 14:41:48 +00:00
states::{
behavior::{CharacterBehavior, JoinData},
glide,
},
};
2021-08-01 11:20:46 +00:00
use serde::{Deserialize, Serialize};
2021-08-01 11:20:46 +00:00
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data {
pub ori: Ori,
span_length: f32,
chord_length: f32,
2021-08-01 11:20:46 +00:00
}
impl From<&JoinData<'_>> for Data {
fn from(data: &JoinData) -> Self {
let scale = data.body.dimensions().z.sqrt();
Self {
// Aspect ratio is what really matters for lift/drag ratio
// and the aerodynamics model works for ARs up to 25.
// The inflated dimensions are hopefully only a temporary
// bandaid for the poor glide ratio experienced under 2.5G.
// A span/chord ratio of 4.5 gives an AR of ~5.73.
span_length: scale * 4.5,
chord_length: scale,
ori: *data.ori,
}
}
2021-08-01 11:20:46 +00:00
}
impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
2021-04-27 03:17:04 +00:00
handle_orientation(data, &mut update, 1.0);
handle_move(data, &mut update, 1.0);
handle_jump(data, &mut update, 1.0);
2020-07-21 01:37:13 +00:00
handle_dodge_input(data, &mut update);
handle_wield(data, &mut update);
// If still in this state, do the things
if matches!(update.character, CharacterState::GlideWield(_)) {
// If not on the ground while wielding glider enter gliding state
update.character = if data.physics.on_ground.is_none() {
CharacterState::Glide(glide::Data::new(
self.span_length,
self.chord_length,
self.ori,
))
// make sure we have a glider and we're not (too deep) in water
} else if data
.inventory
.and_then(|inv| inv.equipped(EquipSlot::Glider))
.is_some()
&& data.physics.in_liquid().map_or(true, |depth| depth < 0.5)
{
2021-08-01 11:20:46 +00:00
CharacterState::GlideWield(Self {
// Glider tilt follows look dir
ori: self.ori.slerped_towards(
data.ori.slerped_towards(
Ori::from(data.inputs.look_dir).pitched_up(0.6),
(1.0 + data.inputs.look_dir.dot(*data.ori.look_dir()).max(0.0)) / 3.0,
),
5.0 * data.dt.0,
),
..*self
2021-08-01 11:20:46 +00:00
})
} else {
CharacterState::Idle
2021-08-01 11:20:46 +00:00
};
}
update
}
2021-07-20 07:43:52 +00:00
fn manipulate_loadout(&self, data: &JoinData, inv_action: InventoryAction) -> StateUpdate {
let mut update = StateUpdate::from(data);
2021-07-20 07:43:52 +00:00
handle_manipulate_loadout(data, &mut update, inv_action);
update
}
2021-07-20 07:43:52 +00:00
fn unwield(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
2021-07-20 07:43:52 +00:00
update.character = CharacterState::Idle;
update
}
2021-07-20 07:43:52 +00:00
fn sit(&self, data: &JoinData) -> StateUpdate {
2020-08-02 05:09:11 +00:00
let mut update = StateUpdate::from(data);
2021-07-20 07:43:52 +00:00
attempt_sit(data, &mut update);
2020-08-02 05:09:11 +00:00
update
}
2021-07-20 07:43:52 +00:00
fn dance(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
2021-07-20 07:43:52 +00:00
attempt_dance(data, &mut update);
update
}
2021-07-20 07:43:52 +00:00
fn sneak(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
2021-07-20 07:43:52 +00:00
attempt_sneak(data, &mut update);
update
}
}