mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'refactor-controller-movement-states' into 'master'
Refactor controller movement states See merge request veloren/veloren!672
This commit is contained in:
commit
ea6374b1e4
@ -8,28 +8,20 @@ pub enum MovementState {
|
||||
Sit,
|
||||
Run,
|
||||
Jump,
|
||||
Fall,
|
||||
Glide,
|
||||
Roll { time_left: Duration },
|
||||
Swim,
|
||||
Climb,
|
||||
}
|
||||
|
||||
impl MovementState {
|
||||
pub fn is_roll(&self) -> bool {
|
||||
if let Self::Roll { .. } = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub enum ActionState {
|
||||
Idle,
|
||||
Wield { time_left: Duration },
|
||||
Attack { time_left: Duration, applied: bool },
|
||||
Block { time_left: Duration },
|
||||
Block { time_active: Duration },
|
||||
Roll { time_left: Duration },
|
||||
Charge { time_left: Duration },
|
||||
//Carry,
|
||||
}
|
||||
|
||||
@ -42,6 +34,16 @@ impl ActionState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_action_finished(&self) -> bool {
|
||||
match self {
|
||||
Self::Wield { time_left }
|
||||
| Self::Attack { time_left, .. }
|
||||
| Self::Roll { time_left }
|
||||
| Self::Charge { time_left } => *time_left == Duration::default(),
|
||||
Self::Idle | Self::Block { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_attack(&self) -> bool {
|
||||
if let Self::Attack { .. } = self {
|
||||
true
|
||||
@ -57,6 +59,22 @@ impl ActionState {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_roll(&self) -> bool {
|
||||
if let Self::Roll { .. } = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_charge(&self) -> bool {
|
||||
if let Self::Charge { .. } = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
|
@ -1,12 +1,11 @@
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
use sphynx::Uid;
|
||||
use std::ops::Add;
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
/// Default duration for how long before an input is considered 'held'.
|
||||
pub const DEFAULT_HOLD_DURATION: Duration = Duration::from_millis(250);
|
||||
/// Default duration before an input is considered 'held'.
|
||||
pub const DEFAULT_HOLD_DURATION: Duration = Duration::from_millis(200);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ControlEvent {
|
||||
@ -27,39 +26,62 @@ pub enum InputState {
|
||||
/// and how long it has been in that state
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Input {
|
||||
// Should not be pub because duration should
|
||||
// always be reset when state is updated
|
||||
/// Should not be pub because duration should
|
||||
/// always be reset when state is updated
|
||||
state: InputState,
|
||||
// Should only be updated by npc agents
|
||||
// through appropriate fn
|
||||
/// Should only be updated by npc agents
|
||||
/// through appropriate fn
|
||||
duration: Duration,
|
||||
/// Turned off first tick after switching states
|
||||
just_changed: bool,
|
||||
/// Set when `set_state` is called. Needed so
|
||||
/// tick after change doesn't immediately unset `just_changed`
|
||||
dirty: bool,
|
||||
}
|
||||
|
||||
impl Input {
|
||||
fn tick(&mut self, dt: Duration) {
|
||||
// Increase how long input has been in current state
|
||||
self.duration = self.duration.checked_add(dt).unwrap_or_default();
|
||||
if self.dirty {
|
||||
// Unset dirty first tick after changing into current state
|
||||
self.dirty = false;
|
||||
} else {
|
||||
// Otherwise, just changed is always false
|
||||
self.just_changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether input is in `InputState::Pressed` state
|
||||
pub fn is_pressed(&self) -> bool {
|
||||
self.state == InputState::Pressed
|
||||
}
|
||||
|
||||
/// Whether it's the first frame this input has been in
|
||||
/// its current state
|
||||
pub fn is_just_pressed(&self) -> bool {
|
||||
(self.just_changed && self.is_pressed())
|
||||
}
|
||||
|
||||
/// Whether input has been in current state longer than
|
||||
/// `DEFAULT_HOLD_DURATION`
|
||||
pub fn is_held_down(&self) -> bool {
|
||||
(self.is_pressed() && self.duration >= DEFAULT_HOLD_DURATION)
|
||||
}
|
||||
|
||||
/// Sets the `input::state` and resets `input::duration`
|
||||
///
|
||||
///
|
||||
/// `new_state` == `true` -> `InputState::Pressed`
|
||||
///
|
||||
/// `new_state` == `false` -> `InputState::Unpressed`
|
||||
/// Handles logic of updating state of Input
|
||||
pub fn set_state(&mut self, new_state: bool) {
|
||||
// Only update if state switches
|
||||
match (new_state, self.is_pressed()) {
|
||||
(true, false) => {
|
||||
match (self.is_pressed(), new_state) {
|
||||
(false, true) => {
|
||||
self.just_changed = true;
|
||||
self.dirty = true;
|
||||
self.state = InputState::Pressed;
|
||||
self.duration = Duration::default();
|
||||
}
|
||||
(false, true) => {
|
||||
(true, false) => {
|
||||
self.just_changed = true;
|
||||
self.dirty = true;
|
||||
self.state = InputState::Unpressed;
|
||||
self.duration = Duration::default();
|
||||
}
|
||||
@ -67,9 +89,9 @@ impl Input {
|
||||
};
|
||||
}
|
||||
|
||||
/// Sets `input::duration`
|
||||
/// Increases `input::duration` by `dur`
|
||||
pub fn inc_dur(&mut self, dur: Duration) {
|
||||
self.duration = self.duration + dur;
|
||||
self.duration = self.duration.checked_add(dur).unwrap_or_default();
|
||||
}
|
||||
|
||||
/// Returns `input::duration`
|
||||
@ -83,23 +105,16 @@ impl Default for Input {
|
||||
Self {
|
||||
state: InputState::Unpressed,
|
||||
duration: Duration::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Duration> for Input {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, dur: Duration) -> Self {
|
||||
Self {
|
||||
state: self.state,
|
||||
duration: self.duration.checked_add(dur).unwrap_or_default(),
|
||||
just_changed: false,
|
||||
dirty: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ControllerInputs {
|
||||
// When adding new inputs:
|
||||
// 1. Add to tick() update
|
||||
pub primary: Input,
|
||||
pub secondary: Input,
|
||||
pub sit: Input,
|
||||
@ -111,6 +126,7 @@ pub struct ControllerInputs {
|
||||
pub wall_leap: Input,
|
||||
pub respawn: Input,
|
||||
pub toggle_wield: Input,
|
||||
pub charge: Input,
|
||||
pub move_dir: Vec2<f32>,
|
||||
pub look_dir: Vec3<f32>,
|
||||
}
|
||||
@ -125,17 +141,33 @@ pub struct Controller {
|
||||
impl ControllerInputs {
|
||||
/// Updates all inputs, accounting for delta time
|
||||
pub fn tick(&mut self, dt: Duration) {
|
||||
self.primary = self.primary + dt;
|
||||
self.secondary = self.secondary + dt;
|
||||
self.sit = self.sit + dt;
|
||||
self.jump = self.jump + dt;
|
||||
self.roll = self.roll + dt;
|
||||
self.glide = self.glide + dt;
|
||||
self.climb = self.climb + dt;
|
||||
self.climb_down = self.climb_down + dt;
|
||||
self.wall_leap = self.wall_leap + dt;
|
||||
self.respawn = self.respawn + dt;
|
||||
self.toggle_wield = self.toggle_wield + dt;
|
||||
self.primary.tick(dt);
|
||||
self.secondary.tick(dt);
|
||||
self.sit.tick(dt);
|
||||
self.jump.tick(dt);
|
||||
self.roll.tick(dt);
|
||||
self.glide.tick(dt);
|
||||
self.climb.tick(dt);
|
||||
self.climb_down.tick(dt);
|
||||
self.wall_leap.tick(dt);
|
||||
self.respawn.tick(dt);
|
||||
self.toggle_wield.tick(dt);
|
||||
self.charge.tick(dt);
|
||||
}
|
||||
/// Updates `inputs.move_dir`.
|
||||
pub fn update_move_dir(&mut self) {
|
||||
self.move_dir = if self.move_dir.magnitude_squared() > 1.0 {
|
||||
// Cap move_dir to 1
|
||||
self.move_dir.normalized()
|
||||
} else {
|
||||
self.move_dir
|
||||
};
|
||||
}
|
||||
/// Updates `inputs.look_dir`
|
||||
pub fn update_look_dir(&mut self) {
|
||||
self.look_dir
|
||||
.try_normalized()
|
||||
.unwrap_or(self.move_dir.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,19 +8,63 @@ use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Tool {
|
||||
Dagger,
|
||||
Shield,
|
||||
Sword,
|
||||
Axe,
|
||||
Hammer,
|
||||
Bow,
|
||||
Dagger,
|
||||
Staff,
|
||||
Shield,
|
||||
Debug(Debug),
|
||||
}
|
||||
|
||||
// TODO: Allow override in item ron?
|
||||
impl Tool {
|
||||
pub fn wield_duration(&self) -> Duration {
|
||||
match self {
|
||||
Tool::Sword => Duration::from_millis(800),
|
||||
Tool::Axe => Duration::from_millis(1000),
|
||||
Tool::Hammer => Duration::from_millis(1000),
|
||||
Tool::Bow => Duration::from_millis(800),
|
||||
Tool::Dagger => Duration::from_millis(300),
|
||||
Tool::Staff => Duration::from_millis(800),
|
||||
Tool::Shield => Duration::from_millis(1000),
|
||||
Tool::Debug(_) => Duration::from_millis(0),
|
||||
}
|
||||
}
|
||||
pub fn attack_buildup_duration(&self) -> Duration {
|
||||
match self {
|
||||
Tool::Sword => Duration::from_millis(100),
|
||||
Tool::Axe => Duration::from_millis(700),
|
||||
Tool::Hammer => Duration::from_millis(700),
|
||||
Tool::Bow => Duration::from_millis(0),
|
||||
Tool::Dagger => Duration::from_millis(100),
|
||||
Tool::Staff => Duration::from_millis(400),
|
||||
Tool::Shield => Duration::from_millis(100),
|
||||
Tool::Debug(_) => Duration::from_millis(0),
|
||||
}
|
||||
}
|
||||
pub fn attack_recover_duration(&self) -> Duration {
|
||||
match self {
|
||||
Tool::Sword => Duration::from_millis(500),
|
||||
Tool::Axe => Duration::from_millis(100),
|
||||
Tool::Hammer => Duration::from_millis(100),
|
||||
Tool::Bow => Duration::from_millis(800),
|
||||
Tool::Dagger => Duration::from_millis(400),
|
||||
Tool::Staff => Duration::from_millis(300),
|
||||
Tool::Shield => Duration::from_millis(1000),
|
||||
Tool::Debug(_) => Duration::from_millis(0),
|
||||
}
|
||||
}
|
||||
pub fn attack_duration(&self) -> Duration {
|
||||
self.attack_buildup_duration() + self.attack_recover_duration()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Debug {
|
||||
Boost,
|
||||
@ -43,6 +87,7 @@ pub enum Armor {
|
||||
Necklace,
|
||||
}
|
||||
|
||||
//TODO: Do we even need this?
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Consumable {
|
||||
Apple,
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::comp::{
|
||||
Agent, CharacterState, Controller, MountState, MovementState::Glide, Pos, Stats,
|
||||
Agent, CharacterState, Controller, ControllerInputs, MountState, MovementState::Glide, Pos,
|
||||
Stats,
|
||||
};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use specs::{Entities, Join, ReadStorage, System, WriteStorage};
|
||||
@ -47,7 +48,7 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
controller.reset();
|
||||
|
||||
let mut inputs = &mut controller.inputs;
|
||||
let mut inputs = ControllerInputs::default();
|
||||
|
||||
match agent {
|
||||
Agent::Wanderer(bearing) => {
|
||||
@ -92,7 +93,7 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
Agent::Enemy { bearing, target } => {
|
||||
const SIGHT_DIST: f32 = 30.0;
|
||||
const MIN_ATTACK_DIST: f32 = 3.5;
|
||||
const MIN_ATTACK_DIST: f32 = 3.25;
|
||||
let mut choose_new = false;
|
||||
|
||||
if let Some((Some(target_pos), Some(target_stats), Some(target_character))) =
|
||||
@ -109,7 +110,10 @@ impl<'a> System<'a> for Sys {
|
||||
let dist = Vec2::<f32>::from(target_pos.0 - pos.0).magnitude();
|
||||
if target_stats.is_dead {
|
||||
choose_new = true;
|
||||
} else if dist < MIN_ATTACK_DIST && dist > 0.001 {
|
||||
} else if dist < MIN_ATTACK_DIST
|
||||
&& dist > 0.001
|
||||
&& rand::random::<f32>() < 0.3
|
||||
{
|
||||
// Fight (and slowly move closer)
|
||||
inputs.move_dir =
|
||||
Vec2::<f32>::from(target_pos.0 - pos.0).normalized() * 0.01;
|
||||
@ -161,6 +165,8 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
controller.inputs = inputs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
ActionState::*, CharacterState, Controller, HealthChange, HealthSource, ItemKind, Ori, Pos,
|
||||
Stats,
|
||||
ActionState::*, CharacterState, Controller, HealthChange, HealthSource, Item, ItemKind,
|
||||
Ori, Pos, Stats,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
state::{DeltaTime, Uid},
|
||||
@ -10,12 +10,6 @@ use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
pub const WIELD_DURATION: Duration = Duration::from_millis(300);
|
||||
pub const ATTACK_DURATION: Duration = Duration::from_millis(500);
|
||||
|
||||
// Delay before hit
|
||||
const PREPARE_DURATION: Duration = Duration::from_millis(100);
|
||||
|
||||
const BLOCK_EFFICIENCY: f32 = 0.9;
|
||||
|
||||
const ATTACK_RANGE: f32 = 4.0;
|
||||
@ -66,13 +60,23 @@ impl<'a> System<'a> for Sys {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let recover_duration = if let Some(Item {
|
||||
kind: ItemKind::Tool { kind, .. },
|
||||
..
|
||||
}) = stat.equipment.main
|
||||
{
|
||||
kind.attack_recover_duration()
|
||||
} else {
|
||||
Duration::from_secs(1)
|
||||
};
|
||||
|
||||
let (deal_damage, should_end) = if let Some(Attack { time_left, applied }) =
|
||||
&mut character_states.get_mut(entity).map(|c| &mut c.action)
|
||||
{
|
||||
*time_left = time_left
|
||||
.checked_sub(Duration::from_secs_f32(dt.0))
|
||||
.unwrap_or_default();
|
||||
if !*applied && ATTACK_DURATION - *time_left > PREPARE_DURATION {
|
||||
if !*applied && recover_duration > *time_left {
|
||||
*applied = true;
|
||||
(true, false)
|
||||
} else if *time_left == Duration::default() {
|
||||
@ -107,7 +111,7 @@ impl<'a> System<'a> for Sys {
|
||||
&& !stat_b.is_dead
|
||||
&& pos.0.distance_squared(pos_b.0) < ATTACK_RANGE.powi(2)
|
||||
// TODO: Use size instead of 1.0
|
||||
&& ori2.angle_between(pos_b2 - pos2) < (1.0 / pos2.distance(pos_b2)).atan()
|
||||
&& ori2.angle_between(pos_b2 - pos2) < (2.0 / pos2.distance(pos_b2)).atan()
|
||||
{
|
||||
// Weapon gives base damage
|
||||
let mut dmg = if let Some(ItemKind::Tool { power, .. }) =
|
||||
|
@ -1,388 +1,641 @@
|
||||
use super::{
|
||||
combat::{ATTACK_DURATION, WIELD_DURATION},
|
||||
movement::ROLL_DURATION,
|
||||
};
|
||||
use super::movement::ROLL_DURATION;
|
||||
use crate::{
|
||||
comp::{
|
||||
self, item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller,
|
||||
HealthChange, HealthSource, ItemKind, MovementState::*, PhysicsState, Projectile, Stats,
|
||||
Vel,
|
||||
self, item, projectile, ActionState, ActionState::*, Body, CharacterState, ControlEvent,
|
||||
Controller, ControllerInputs, HealthChange, HealthSource, ItemKind, Mounting,
|
||||
MovementState, MovementState::*, PhysicsState, Projectile, Stats, Vel,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
event::{Emitter, EventBus, LocalEvent, ServerEvent},
|
||||
state::DeltaTime,
|
||||
};
|
||||
use specs::{
|
||||
saveload::{Marker, MarkerAllocator},
|
||||
Entities, Join, Read, ReadStorage, System, WriteStorage,
|
||||
Entities, Entity, Join, Read, ReadStorage, System, WriteStorage,
|
||||
};
|
||||
use sphynx::{Uid, UidAllocator};
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
/// This system is responsible for validating controller inputs
|
||||
/// # Controller System
|
||||
/// #### Responsible for validating controller inputs and setting new Character States
|
||||
/// ----
|
||||
///
|
||||
/// **Writes:**
|
||||
/// `CharacterState`, `ControllerInputs`
|
||||
///
|
||||
/// **Reads:**
|
||||
/// `Stats`, `Vel`, `PhysicsState`, `Uid`, `Mounting`
|
||||
///
|
||||
/// _TODO: Join ActionStates and MovementStates into one and have a handle() trait / fn?_
|
||||
/// _TODO: Move weapon action to trait fn?_
|
||||
pub struct Sys;
|
||||
|
||||
impl Sys {
|
||||
/// Assumes `input.primary` has been pressed
|
||||
/// handles primary actions. ie. equipping, mainhand weapon attacks.
|
||||
///
|
||||
/// Returns the `ActionState` that occurred
|
||||
fn handle_primary(
|
||||
inputs: &mut ControllerInputs,
|
||||
character: &mut CharacterState,
|
||||
stats: &Stats,
|
||||
entity: Entity,
|
||||
uid: &Uid,
|
||||
server_emitter: &mut Emitter<'_, ServerEvent>,
|
||||
local_emitter: &mut Emitter<'_, LocalEvent>,
|
||||
) -> ActionState {
|
||||
match stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
// Character is wielding something
|
||||
Some(ItemKind::Tool { kind, power, .. }) => {
|
||||
let attack_duration = kind.attack_duration();
|
||||
let wield_duration = kind.wield_duration();
|
||||
|
||||
// Since primary input was pressed, set
|
||||
// action to new Wield, in case of
|
||||
// instant primary actions
|
||||
if character.action == Idle {
|
||||
character.action = Wield {
|
||||
time_left: wield_duration,
|
||||
};
|
||||
}
|
||||
|
||||
match kind {
|
||||
item::Tool::Bow if character.action.is_action_finished() => {
|
||||
// Immediately end the wield
|
||||
server_emitter.emit(ServerEvent::Shoot {
|
||||
entity,
|
||||
dir: inputs.look_dir,
|
||||
body: comp::Body::Object(comp::object::Body::Arrow),
|
||||
light: None,
|
||||
gravity: Some(comp::Gravity(0.3)),
|
||||
projectile: Projectile {
|
||||
owner: *uid,
|
||||
hit_ground: vec![projectile::Effect::Stick],
|
||||
hit_wall: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(HealthChange {
|
||||
amount: -(*power as i32),
|
||||
cause: HealthSource::Attack { by: *uid },
|
||||
}),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(30),
|
||||
},
|
||||
});
|
||||
character.action
|
||||
}
|
||||
item::Tool::Debug(item::Debug::Boost) => {
|
||||
local_emitter.emit(LocalEvent::Boost {
|
||||
entity,
|
||||
vel: inputs.look_dir * 7.0,
|
||||
});
|
||||
character.action
|
||||
}
|
||||
|
||||
item::Tool::Debug(item::Debug::Possess)
|
||||
if character.action.is_action_finished() =>
|
||||
{
|
||||
server_emitter.emit(ServerEvent::Shoot {
|
||||
entity,
|
||||
gravity: Some(comp::Gravity(0.1)),
|
||||
dir: inputs.look_dir,
|
||||
body: comp::Body::Object(comp::object::Body::ArrowSnake),
|
||||
light: Some(comp::LightEmitter {
|
||||
col: (0.0, 1.0, 0.3).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
projectile: Projectile {
|
||||
owner: *uid,
|
||||
hit_ground: vec![projectile::Effect::Stick],
|
||||
hit_wall: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Stick,
|
||||
projectile::Effect::Possess,
|
||||
],
|
||||
time_left: Duration::from_secs(10),
|
||||
},
|
||||
});
|
||||
|
||||
character.action
|
||||
}
|
||||
// All other weapons
|
||||
_ if character.action.is_action_finished() => Attack {
|
||||
time_left: attack_duration,
|
||||
applied: false,
|
||||
},
|
||||
_ => {
|
||||
// Return the new Wield action
|
||||
character.action
|
||||
}
|
||||
}
|
||||
}
|
||||
// Without a weapon
|
||||
None => {
|
||||
// Attack
|
||||
if !character.action.is_attack() {
|
||||
Attack {
|
||||
time_left: Duration::from_millis(100),
|
||||
applied: false,
|
||||
}
|
||||
} else {
|
||||
character.action
|
||||
}
|
||||
}
|
||||
_ => character.action,
|
||||
}
|
||||
}
|
||||
|
||||
/// Assumes `input.seconday` has been pressed
|
||||
/// handles seconday actions. ie. blocking, althand weapons
|
||||
///
|
||||
/// Returns the `ActionState` that occurred
|
||||
fn handle_secondary(
|
||||
inputs: &mut ControllerInputs,
|
||||
character: &mut CharacterState,
|
||||
stats: &Stats,
|
||||
entity: Entity,
|
||||
uid: &Uid,
|
||||
server_emitter: &mut Emitter<'_, ServerEvent>,
|
||||
local_emitter: &mut Emitter<'_, LocalEvent>,
|
||||
) -> ActionState {
|
||||
match stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
// Character is wielding something
|
||||
Some(ItemKind::Tool { kind, power, .. }) => {
|
||||
let attack_duration = kind.attack_duration();
|
||||
let wield_duration = kind.wield_duration();
|
||||
|
||||
// Since primary input was pressed, set
|
||||
// action to new Wield, in case of
|
||||
// instant primary actions
|
||||
if character.action == Idle {
|
||||
character.action = Wield {
|
||||
time_left: wield_duration,
|
||||
};
|
||||
}
|
||||
|
||||
match kind {
|
||||
// Magical Bolt
|
||||
item::Tool::Staff
|
||||
if character.movement == Stand && character.action.is_action_finished() =>
|
||||
{
|
||||
server_emitter.emit(ServerEvent::Shoot {
|
||||
entity,
|
||||
dir: inputs.look_dir,
|
||||
body: comp::Body::Object(comp::object::Body::BoltFire),
|
||||
gravity: Some(comp::Gravity(0.0)),
|
||||
light: Some(comp::LightEmitter {
|
||||
col: (0.72, 0.11, 0.11).into(),
|
||||
strength: 10.0,
|
||||
offset: Vec3::new(0.0, -5.0, 2.0),
|
||||
}),
|
||||
projectile: Projectile {
|
||||
owner: *uid,
|
||||
hit_ground: vec![projectile::Effect::Vanish],
|
||||
hit_wall: vec![projectile::Effect::Vanish],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(HealthChange {
|
||||
amount: -(*power as i32),
|
||||
cause: HealthSource::Attack { by: *uid },
|
||||
}),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(5),
|
||||
},
|
||||
});
|
||||
// TODO: Don't play melee animation
|
||||
Attack {
|
||||
time_left: attack_duration,
|
||||
applied: true, // We don't want to do a melee attack
|
||||
}
|
||||
}
|
||||
|
||||
// Go upward
|
||||
item::Tool::Debug(item::Debug::Boost) => {
|
||||
local_emitter.emit(LocalEvent::Boost {
|
||||
entity,
|
||||
vel: Vec3::new(0.0, 0.0, 7.0),
|
||||
});
|
||||
|
||||
character.action
|
||||
}
|
||||
|
||||
// All other weapons block
|
||||
_ if character.action.is_action_finished() => Block {
|
||||
time_active: Duration::from_secs(0),
|
||||
},
|
||||
|
||||
_ => character.action,
|
||||
}
|
||||
}
|
||||
|
||||
_ => character.action,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Read<'a, UidAllocator>,
|
||||
Entities<'a>,
|
||||
Read<'a, UidAllocator>,
|
||||
Read<'a, EventBus<ServerEvent>>,
|
||||
Read<'a, EventBus<LocalEvent>>,
|
||||
Read<'a, DeltaTime>,
|
||||
WriteStorage<'a, Controller>,
|
||||
WriteStorage<'a, CharacterState>,
|
||||
ReadStorage<'a, Stats>,
|
||||
ReadStorage<'a, Body>,
|
||||
ReadStorage<'a, Vel>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
ReadStorage<'a, Uid>,
|
||||
WriteStorage<'a, CharacterState>,
|
||||
ReadStorage<'a, Mounting>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(
|
||||
uid_allocator,
|
||||
entities,
|
||||
uid_allocator,
|
||||
server_bus,
|
||||
local_bus,
|
||||
dt,
|
||||
mut controllers,
|
||||
mut character_states,
|
||||
stats,
|
||||
bodies,
|
||||
velocities,
|
||||
physics_states,
|
||||
uids,
|
||||
mut character_states,
|
||||
mountings,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
let mut server_emitter = server_bus.emitter();
|
||||
let mut local_emitter = local_bus.emitter();
|
||||
|
||||
for (entity, uid, controller, stats, body, vel, physics, mut character) in (
|
||||
for (entity, uid, controller, mut character, stats, body, vel, physics, mount) in (
|
||||
&entities,
|
||||
&uids,
|
||||
&mut controllers,
|
||||
&mut character_states,
|
||||
&stats,
|
||||
&bodies,
|
||||
&velocities,
|
||||
&physics_states,
|
||||
&mut character_states,
|
||||
mountings.maybe(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let mut inputs = &mut controller.inputs;
|
||||
let inputs = &mut controller.inputs;
|
||||
|
||||
// ---------------------------------------
|
||||
// Common actions for multiple states as closure fn's for convenience
|
||||
// Returns a Wield action, or Idle if nothing to wield
|
||||
let try_wield = |stats: &Stats| -> ActionState {
|
||||
// Get weapon to wield
|
||||
if let Some(ItemKind::Tool { kind, .. }) =
|
||||
stats.equipment.main.as_ref().map(|i| &i.kind)
|
||||
{
|
||||
let wield_duration = kind.wield_duration();
|
||||
Wield {
|
||||
time_left: wield_duration,
|
||||
}
|
||||
} else {
|
||||
Idle
|
||||
}
|
||||
};
|
||||
|
||||
let get_state_from_move_dir = |move_dir: &Vec2<f32>| -> MovementState {
|
||||
if move_dir.magnitude_squared() > 0.0 {
|
||||
Run
|
||||
} else {
|
||||
Stand
|
||||
}
|
||||
};
|
||||
|
||||
// End common actions
|
||||
// ---------------------------------------
|
||||
|
||||
// Being dead overrides all other states
|
||||
if stats.is_dead {
|
||||
// Respawn
|
||||
if inputs.respawn.is_pressed() {
|
||||
// Only options: click respawn
|
||||
// prevent instant-respawns (i.e. player was holding attack)
|
||||
// by disallowing while input is held down
|
||||
if inputs.respawn.is_pressed() && !inputs.respawn.is_held_down() {
|
||||
server_emitter.emit(ServerEvent::Respawn(entity));
|
||||
}
|
||||
// Or do nothing
|
||||
continue;
|
||||
}
|
||||
// If mounted, character state is controlled by mount
|
||||
if mount.is_some() {
|
||||
character.movement = Sit;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Move
|
||||
inputs.move_dir = if inputs.move_dir.magnitude_squared() > 1.0 {
|
||||
inputs.move_dir.normalized()
|
||||
} else {
|
||||
inputs.move_dir
|
||||
match (character.action, character.movement) {
|
||||
// Jumping, one frame state that calls jump server event
|
||||
(_, Jump) => {
|
||||
inputs.update_look_dir();
|
||||
inputs.update_move_dir();
|
||||
character.movement = get_state_from_move_dir(&inputs.move_dir);
|
||||
|
||||
character.movement = Fall;
|
||||
local_emitter.emit(LocalEvent::Jump(entity));
|
||||
}
|
||||
// Charging + Any Movement, prioritizes finishing charge
|
||||
// over movement states
|
||||
(Charge { time_left }, _) => {
|
||||
println!("{:?}", character);
|
||||
inputs.update_move_dir();
|
||||
if time_left == Duration::default() || vel.0.magnitude_squared() < 10.0 {
|
||||
character.action = try_wield(stats);
|
||||
} else {
|
||||
character.action = Charge {
|
||||
time_left: time_left
|
||||
.checked_sub(Duration::from_secs_f32(dt.0))
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
}
|
||||
if let Some(uid_b) = physics.touch_entity {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: uid_b,
|
||||
change: HealthChange {
|
||||
amount: -20,
|
||||
cause: HealthSource::Attack { by: *uid },
|
||||
},
|
||||
});
|
||||
|
||||
character.action = try_wield(stats);
|
||||
}
|
||||
}
|
||||
// Rolling + Any Movement, prioritizes finishing charge
|
||||
// over movement states
|
||||
(Roll { time_left }, _) => {
|
||||
if time_left == Duration::default() {
|
||||
character.action = try_wield(stats);
|
||||
} else {
|
||||
character.action = Roll {
|
||||
time_left: time_left
|
||||
.checked_sub(Duration::from_secs_f32(dt.0))
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// Any Action + Falling
|
||||
(action_state, Fall) => {
|
||||
inputs.update_move_dir();
|
||||
inputs.update_look_dir();
|
||||
character.movement = get_state_from_move_dir(&inputs.move_dir);
|
||||
// Reset to Falling while not standing on ground,
|
||||
// otherwise keep the state given above
|
||||
if !physics.on_ground {
|
||||
if physics.in_fluid {
|
||||
character.movement = Swim;
|
||||
} else {
|
||||
character.movement = Fall;
|
||||
}
|
||||
}
|
||||
if inputs.glide.is_pressed() && !inputs.glide.is_held_down() {
|
||||
character.movement = Glide;
|
||||
continue;
|
||||
}
|
||||
|
||||
match action_state {
|
||||
// Unwield if buttons pressed
|
||||
Wield { .. } | Attack { .. } => {
|
||||
if inputs.toggle_wield.is_just_pressed() {
|
||||
character.action = Idle;
|
||||
}
|
||||
}
|
||||
// Try to wield if any of buttons pressed
|
||||
Idle => {
|
||||
if inputs.primary.is_pressed() || inputs.secondary.is_pressed() {
|
||||
character.action = try_wield(stats);
|
||||
}
|
||||
}
|
||||
// Cancel blocks
|
||||
Block { .. } => {
|
||||
character.action = try_wield(stats);
|
||||
}
|
||||
// Don't change action
|
||||
Charge { .. } | Roll { .. } => {}
|
||||
}
|
||||
}
|
||||
// Any Action + Swimming
|
||||
(_action_state, Swim) => {
|
||||
inputs.update_move_dir();
|
||||
inputs.update_look_dir();
|
||||
character.movement = get_state_from_move_dir(&inputs.move_dir);
|
||||
|
||||
if !physics.on_ground && physics.in_fluid {
|
||||
character.movement = Swim;
|
||||
}
|
||||
if inputs.primary.is_pressed() {
|
||||
character.action = Self::handle_primary(
|
||||
inputs,
|
||||
character,
|
||||
stats,
|
||||
entity,
|
||||
uid,
|
||||
&mut server_emitter,
|
||||
&mut local_emitter,
|
||||
);
|
||||
} else if inputs.secondary.is_pressed() {
|
||||
character.action = Self::handle_secondary(
|
||||
inputs,
|
||||
character,
|
||||
stats,
|
||||
entity,
|
||||
uid,
|
||||
&mut server_emitter,
|
||||
&mut local_emitter,
|
||||
);
|
||||
}
|
||||
}
|
||||
// Blocking, restricted look_dir compared to other states
|
||||
(Block { .. }, Stand) | (Block { .. }, Run) => {
|
||||
inputs.update_move_dir();
|
||||
character.movement = get_state_from_move_dir(&inputs.move_dir);
|
||||
|
||||
if !inputs.secondary.is_pressed() {
|
||||
character.action = try_wield(stats);
|
||||
} else {
|
||||
character.action = Self::handle_secondary(
|
||||
inputs,
|
||||
character,
|
||||
stats,
|
||||
entity,
|
||||
uid,
|
||||
&mut server_emitter,
|
||||
&mut local_emitter,
|
||||
);
|
||||
}
|
||||
|
||||
if !physics.on_ground && physics.in_fluid {
|
||||
character.movement = Swim;
|
||||
}
|
||||
}
|
||||
// Standing and Running states, typical states :shrug:
|
||||
(action_state, Run) | (action_state, Stand) => {
|
||||
inputs.update_move_dir();
|
||||
inputs.update_look_dir();
|
||||
character.movement = get_state_from_move_dir(&inputs.move_dir);
|
||||
// Try to sit
|
||||
if inputs.sit.is_pressed() && physics.on_ground && body.is_humanoid() {
|
||||
character.movement = Sit;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to climb
|
||||
if let (true, Some(_wall_dir)) = (
|
||||
inputs.climb.is_pressed() | inputs.climb_down.is_pressed()
|
||||
&& body.is_humanoid(),
|
||||
physics.on_wall,
|
||||
) {
|
||||
character.movement = Climb;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to swim
|
||||
if !physics.on_ground && physics.in_fluid {
|
||||
character.movement = Swim;
|
||||
continue;
|
||||
}
|
||||
|
||||
// While on ground ...
|
||||
if physics.on_ground {
|
||||
// Try to jump
|
||||
if inputs.jump.is_pressed() && !inputs.jump.is_held_down() {
|
||||
character.movement = Jump;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to charge
|
||||
if inputs.charge.is_pressed() && !inputs.charge.is_held_down() {
|
||||
character.action = Charge {
|
||||
time_left: Duration::from_millis(250),
|
||||
};
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to roll
|
||||
if character.movement == Run
|
||||
&& inputs.roll.is_pressed()
|
||||
&& body.is_humanoid()
|
||||
{
|
||||
character.action = Roll {
|
||||
time_left: ROLL_DURATION,
|
||||
};
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// While not on ground ...
|
||||
else {
|
||||
// Try to glide
|
||||
if physics.on_wall == None
|
||||
&& inputs.glide.is_pressed()
|
||||
&& !inputs.glide.is_held_down()
|
||||
&& body.is_humanoid()
|
||||
{
|
||||
character.movement = Glide;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Tool Actions
|
||||
if inputs.toggle_wield.is_just_pressed() {
|
||||
match action_state {
|
||||
Wield { .. } | Attack { .. } => {
|
||||
// Prevent instantaneous reequipping by checking
|
||||
// for done wielding
|
||||
if character.action.is_action_finished() {
|
||||
character.action = Idle;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Idle => {
|
||||
character.action = try_wield(stats);
|
||||
}
|
||||
Charge { .. } | Roll { .. } | Block { .. } => {}
|
||||
}
|
||||
}
|
||||
if inputs.primary.is_pressed() {
|
||||
character.action = Self::handle_primary(
|
||||
inputs,
|
||||
character,
|
||||
stats,
|
||||
entity,
|
||||
uid,
|
||||
&mut server_emitter,
|
||||
&mut local_emitter,
|
||||
);
|
||||
} else if inputs.secondary.is_pressed() {
|
||||
character.action = Self::handle_secondary(
|
||||
inputs,
|
||||
character,
|
||||
stats,
|
||||
entity,
|
||||
uid,
|
||||
&mut server_emitter,
|
||||
&mut local_emitter,
|
||||
);
|
||||
}
|
||||
}
|
||||
// Sitting
|
||||
(Idle, Sit) => {
|
||||
inputs.update_move_dir();
|
||||
character.movement = get_state_from_move_dir(&inputs.move_dir);
|
||||
|
||||
// character.movement will be Stand after updating when
|
||||
// no movement has occurred
|
||||
if character.movement == Stand {
|
||||
character.movement = Sit;
|
||||
}
|
||||
if inputs.jump.is_pressed() && !inputs.jump.is_held_down() {
|
||||
character.movement = Jump;
|
||||
continue;
|
||||
}
|
||||
if !physics.on_ground {
|
||||
character.movement = Fall;
|
||||
}
|
||||
}
|
||||
// Any Action + Gliding, shouldnt care about action,
|
||||
// because should be Idle
|
||||
(_, Glide) => {
|
||||
character.action = Idle;
|
||||
|
||||
inputs.update_look_dir();
|
||||
inputs.update_move_dir();
|
||||
|
||||
if !inputs.glide.is_pressed() {
|
||||
character.movement = Fall;
|
||||
} else if let Some(_wall_dir) = physics.on_wall {
|
||||
character.movement = Fall;
|
||||
}
|
||||
|
||||
if physics.on_ground {
|
||||
character.movement = Stand
|
||||
}
|
||||
}
|
||||
// Any Action + Climbing, shouldnt care about action,
|
||||
// because should be Idle
|
||||
(_, Climb) => {
|
||||
if let None = physics.on_wall {
|
||||
if physics.on_ground {
|
||||
character.movement = Stand;
|
||||
} else if inputs.jump.is_pressed() && !inputs.jump.is_held_down() {
|
||||
character.movement = Jump;
|
||||
} else {
|
||||
character.movement = Fall;
|
||||
}
|
||||
}
|
||||
}
|
||||
// In case of adding new states
|
||||
(_, _) => {
|
||||
println!("UNKNOWN STATE");
|
||||
character.action = Idle;
|
||||
character.movement = Fall;
|
||||
}
|
||||
};
|
||||
|
||||
if character.movement == Stand && inputs.move_dir.magnitude_squared() > 0.0 {
|
||||
character.movement = Run;
|
||||
} else if character.movement == Run && inputs.move_dir.magnitude_squared() == 0.0 {
|
||||
character.movement = Stand;
|
||||
}
|
||||
|
||||
// Look
|
||||
inputs.look_dir = inputs
|
||||
.look_dir
|
||||
.try_normalized()
|
||||
.unwrap_or(inputs.move_dir.into());
|
||||
|
||||
// Glide
|
||||
// TODO: Check for glide ability/item
|
||||
if inputs.glide.is_pressed()
|
||||
&& !physics.on_ground
|
||||
&& (character.action == Idle || character.action.is_wield())
|
||||
&& character.movement == Jump
|
||||
&& body.is_humanoid()
|
||||
{
|
||||
character.movement = Glide;
|
||||
} else if !inputs.glide.is_pressed() && character.movement == Glide {
|
||||
// character.movement = Jump;
|
||||
}
|
||||
|
||||
// Sit
|
||||
if inputs.sit.is_pressed()
|
||||
&& physics.on_ground
|
||||
&& character.action == Idle
|
||||
&& character.movement != Sit
|
||||
&& body.is_humanoid()
|
||||
{
|
||||
character.movement = Sit;
|
||||
} else if character.movement == Sit
|
||||
&& (inputs.move_dir.magnitude_squared() > 0.0 || !physics.on_ground)
|
||||
{
|
||||
character.movement = Run;
|
||||
}
|
||||
|
||||
// Wield
|
||||
if inputs.primary.is_pressed()
|
||||
&& character.action == Idle
|
||||
&& (character.movement == Stand || character.movement == Run)
|
||||
{
|
||||
character.action = Wield {
|
||||
time_left: WIELD_DURATION,
|
||||
};
|
||||
}
|
||||
|
||||
match stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Bow,
|
||||
power,
|
||||
..
|
||||
}) => {
|
||||
if inputs.primary.is_pressed()
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
|| character.movement == Jump)
|
||||
{
|
||||
if let Wield { time_left } = character.action {
|
||||
if time_left == Duration::default() {
|
||||
// Immediately end the wield
|
||||
character.action = Idle;
|
||||
server_emitter.emit(ServerEvent::Shoot {
|
||||
entity,
|
||||
dir: inputs.look_dir,
|
||||
body: comp::Body::Object(comp::object::Body::Arrow),
|
||||
light: None,
|
||||
gravity: Some(comp::Gravity(0.3)),
|
||||
projectile: Projectile {
|
||||
owner: *uid,
|
||||
hit_ground: vec![projectile::Effect::Stick],
|
||||
hit_wall: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(HealthChange {
|
||||
amount: -(*power as i32),
|
||||
cause: HealthSource::Attack { by: *uid },
|
||||
}),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(30),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Staff,
|
||||
power,
|
||||
..
|
||||
}) => {
|
||||
// Melee Attack
|
||||
if inputs.primary.is_pressed()
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
|| character.movement == Jump)
|
||||
{
|
||||
if let Wield { time_left } = character.action {
|
||||
if time_left == Duration::default() {
|
||||
character.action = Attack {
|
||||
time_left: ATTACK_DURATION,
|
||||
applied: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
// Magical Bolt
|
||||
if inputs.secondary.is_pressed()
|
||||
&& (
|
||||
character.movement == Stand
|
||||
//|| character.movement == Run
|
||||
//|| character.movement == Jump
|
||||
)
|
||||
{
|
||||
if let Wield { time_left } = character.action {
|
||||
if time_left == Duration::default() {
|
||||
character.action = Attack {
|
||||
time_left: ATTACK_DURATION,
|
||||
applied: false,
|
||||
};
|
||||
server_emitter.emit(ServerEvent::Shoot {
|
||||
entity,
|
||||
dir: inputs.look_dir,
|
||||
body: comp::Body::Object(comp::object::Body::BoltFire),
|
||||
gravity: Some(comp::Gravity(0.0)),
|
||||
light: Some(comp::LightEmitter {
|
||||
col: (0.72, 0.11, 0.11).into(),
|
||||
strength: 10.0,
|
||||
offset: Vec3::new(0.0, -5.0, 2.0),
|
||||
}),
|
||||
projectile: Projectile {
|
||||
owner: *uid,
|
||||
hit_ground: vec![projectile::Effect::Vanish],
|
||||
hit_wall: vec![projectile::Effect::Vanish],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(HealthChange {
|
||||
amount: -(*power as i32),
|
||||
cause: HealthSource::Attack { by: *uid },
|
||||
}),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(5),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Debug(item::Debug::Boost),
|
||||
..
|
||||
}) => {
|
||||
if inputs.primary.is_pressed() {
|
||||
local_emitter.emit(LocalEvent::Boost {
|
||||
entity,
|
||||
vel: inputs.look_dir * 7.0,
|
||||
});
|
||||
}
|
||||
if inputs.secondary.is_pressed() {
|
||||
// Go upward
|
||||
local_emitter.emit(LocalEvent::Boost {
|
||||
entity,
|
||||
vel: Vec3::new(0.0, 0.0, 7.0),
|
||||
});
|
||||
}
|
||||
}
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Debug(item::Debug::Possess),
|
||||
..
|
||||
}) => {
|
||||
if inputs.primary.is_pressed()
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
|| character.movement == Jump)
|
||||
{
|
||||
if let Wield { time_left } = character.action {
|
||||
if time_left == Duration::default() {
|
||||
// Immediately end the wield
|
||||
character.action = Idle;
|
||||
server_emitter.emit(ServerEvent::Shoot {
|
||||
entity,
|
||||
gravity: Some(comp::Gravity(0.1)),
|
||||
dir: inputs.look_dir,
|
||||
body: comp::Body::Object(comp::object::Body::ArrowSnake),
|
||||
light: Some(comp::LightEmitter {
|
||||
col: (0.0, 1.0, 0.3).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
projectile: Projectile {
|
||||
owner: *uid,
|
||||
hit_ground: vec![projectile::Effect::Stick],
|
||||
hit_wall: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Stick,
|
||||
projectile::Effect::Possess,
|
||||
],
|
||||
time_left: Duration::from_secs(10),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// Block
|
||||
if inputs.secondary.is_pressed()
|
||||
&& (character.movement == Stand || character.movement == Run)
|
||||
&& character.action.is_wield()
|
||||
{
|
||||
character.action = Block {
|
||||
time_left: Duration::from_secs(5),
|
||||
};
|
||||
} else if !inputs.secondary.is_pressed() && character.action.is_block() {
|
||||
character.action = Wield {
|
||||
time_left: Duration::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
// All other tools
|
||||
Some(ItemKind::Tool { .. }) => {
|
||||
// Attack
|
||||
if inputs.primary.is_pressed()
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
|| character.movement == Jump)
|
||||
{
|
||||
if let Wield { time_left } = character.action {
|
||||
if time_left == Duration::default() {
|
||||
character.action = Attack {
|
||||
time_left: ATTACK_DURATION,
|
||||
applied: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block
|
||||
if inputs.secondary.is_pressed()
|
||||
&& (character.movement == Stand || character.movement == Run)
|
||||
&& character.action.is_wield()
|
||||
{
|
||||
character.action = Block {
|
||||
time_left: Duration::from_secs(5),
|
||||
};
|
||||
} else if !inputs.secondary.is_pressed() && character.action.is_block() {
|
||||
character.action = Wield {
|
||||
time_left: Duration::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Attack
|
||||
if inputs.primary.is_pressed()
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
|| character.movement == Jump)
|
||||
&& !character.action.is_attack()
|
||||
{
|
||||
character.action = Attack {
|
||||
time_left: ATTACK_DURATION,
|
||||
applied: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Roll
|
||||
if inputs.roll.is_pressed()
|
||||
&& (character.action == Idle || character.action.is_wield())
|
||||
&& character.movement == Run
|
||||
&& physics.on_ground
|
||||
{
|
||||
character.movement = Roll {
|
||||
time_left: ROLL_DURATION,
|
||||
};
|
||||
}
|
||||
|
||||
// Jump
|
||||
if (inputs.jump.is_pressed() && !inputs.jump.is_held_down())
|
||||
&& physics.on_ground
|
||||
&& vel.0.z <= 0.0
|
||||
&& !character.movement.is_roll()
|
||||
|| (inputs.jump.is_pressed() && character.movement == Swim)
|
||||
{
|
||||
local_emitter.emit(LocalEvent::Jump(entity));
|
||||
}
|
||||
|
||||
// Wall leap
|
||||
if inputs.wall_leap.is_pressed() {
|
||||
if let (Some(_wall_dir), Climb) = (physics.on_wall, character.movement) {
|
||||
//local_emitter.emit(LocalEvent::WallLeap { entity, wall_dir });
|
||||
}
|
||||
}
|
||||
|
||||
if let (true, Wield { .. }) = (inputs.toggle_wield.is_pressed(), character.action) {
|
||||
character.action = Idle;
|
||||
}
|
||||
|
||||
// Process controller events
|
||||
// Process other controller events
|
||||
for event in controller.events.drain(..) {
|
||||
match event {
|
||||
ControlEvent::Mount(mountee_uid) => {
|
||||
|
@ -1,17 +1,18 @@
|
||||
use super::phys::GRAVITY;
|
||||
use crate::{
|
||||
comp::{
|
||||
ActionState::*, CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState,
|
||||
Pos, Stats, Vel,
|
||||
CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState, Pos, Stats, Vel,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::DeltaTime,
|
||||
terrain::TerrainGrid,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
use sphynx::Uid;
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
pub const ROLL_DURATION: Duration = Duration::from_millis(600);
|
||||
pub const ROLL_DURATION: Duration = Duration::from_millis(250);
|
||||
|
||||
const HUMANOID_ACCEL: f32 = 50.0;
|
||||
const HUMANOID_SPEED: f32 = 120.0;
|
||||
@ -20,7 +21,8 @@ const HUMANOID_AIR_SPEED: f32 = 100.0;
|
||||
const HUMANOID_WATER_ACCEL: f32 = 70.0;
|
||||
const HUMANOID_WATER_SPEED: f32 = 120.0;
|
||||
const HUMANOID_CLIMB_ACCEL: f32 = 5.0;
|
||||
const ROLL_SPEED: f32 = 13.0;
|
||||
const ROLL_SPEED: f32 = 17.0;
|
||||
const CHARGE_SPEED: f32 = 20.0;
|
||||
const GLIDE_ACCEL: f32 = 15.0;
|
||||
const GLIDE_SPEED: f32 = 45.0;
|
||||
const BLOCK_ACCEL: f32 = 30.0;
|
||||
@ -31,20 +33,31 @@ const CLIMB_SPEED: f32 = 5.0;
|
||||
|
||||
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
|
||||
|
||||
/// This system applies forces and calculates new positions and velocities.
|
||||
/// # Movement System
|
||||
/// #### Applies forces, calculates new positions and velocities,7
|
||||
/// #### based on Controller(Inputs) and CharacterState.
|
||||
/// ----
|
||||
///
|
||||
/// **Writes:**
|
||||
/// Pos, Vel, Ori
|
||||
///
|
||||
/// **Reads:**
|
||||
/// Uid, Stats, Controller, PhysicsState, CharacterState, Mounting
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
ReadExpect<'a, TerrainGrid>,
|
||||
Read<'a, EventBus<ServerEvent>>,
|
||||
Read<'a, DeltaTime>,
|
||||
ReadStorage<'a, Stats>,
|
||||
ReadStorage<'a, Controller>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
WriteStorage<'a, CharacterState>,
|
||||
WriteStorage<'a, Pos>,
|
||||
WriteStorage<'a, Vel>,
|
||||
WriteStorage<'a, Ori>,
|
||||
ReadStorage<'a, Uid>,
|
||||
ReadStorage<'a, Stats>,
|
||||
ReadStorage<'a, Controller>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
ReadStorage<'a, CharacterState>,
|
||||
ReadStorage<'a, Mounting>,
|
||||
);
|
||||
|
||||
@ -53,37 +66,41 @@ impl<'a> System<'a> for Sys {
|
||||
(
|
||||
entities,
|
||||
_terrain,
|
||||
_server_bus,
|
||||
dt,
|
||||
stats,
|
||||
controllers,
|
||||
physics_states,
|
||||
mut character_states,
|
||||
mut positions,
|
||||
mut velocities,
|
||||
mut orientations,
|
||||
uids,
|
||||
stats,
|
||||
controllers,
|
||||
physics_states,
|
||||
character_states,
|
||||
mountings,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
// Apply movement inputs
|
||||
for (
|
||||
_entity,
|
||||
stats,
|
||||
controller,
|
||||
physics,
|
||||
mut character,
|
||||
mut _pos,
|
||||
mut vel,
|
||||
mut ori,
|
||||
mounting,
|
||||
_uid,
|
||||
stats,
|
||||
controller,
|
||||
physics,
|
||||
character,
|
||||
mount,
|
||||
) in (
|
||||
&entities,
|
||||
&stats,
|
||||
&controllers,
|
||||
&physics_states,
|
||||
&mut character_states,
|
||||
&mut positions,
|
||||
&mut velocities,
|
||||
&mut orientations,
|
||||
&uids,
|
||||
&stats,
|
||||
&controllers,
|
||||
&physics_states,
|
||||
&character_states,
|
||||
mountings.maybe(),
|
||||
)
|
||||
.join()
|
||||
@ -92,22 +109,27 @@ impl<'a> System<'a> for Sys {
|
||||
continue;
|
||||
}
|
||||
|
||||
if mounting.is_some() {
|
||||
character.movement = Sit;
|
||||
if mount.is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let inputs = &controller.inputs;
|
||||
|
||||
if character.movement.is_roll() {
|
||||
if character.action.is_roll() {
|
||||
vel.0 = Vec3::new(0.0, 0.0, vel.0.z)
|
||||
+ (vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||
+ 1.5 * inputs.move_dir.try_normalized().unwrap_or_default())
|
||||
.try_normalized()
|
||||
.unwrap_or_default()
|
||||
* ROLL_SPEED;
|
||||
}
|
||||
if character.action.is_block() || character.action.is_attack() {
|
||||
} else if character.action.is_charge() {
|
||||
vel.0 = Vec3::new(0.0, 0.0, vel.0.z)
|
||||
+ (vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||
+ 1.5 * inputs.move_dir.try_normalized().unwrap_or_default())
|
||||
.try_normalized()
|
||||
.unwrap_or_default()
|
||||
* CHARGE_SPEED;
|
||||
} else if character.action.is_block() {
|
||||
vel.0 += Vec2::broadcast(dt.0)
|
||||
* inputs.move_dir
|
||||
* match physics.on_ground {
|
||||
@ -143,10 +165,9 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
|
||||
// Set direction based on move direction when on the ground
|
||||
let ori_dir = if character.action.is_wield()
|
||||
|| character.action.is_attack()
|
||||
|| character.action.is_block()
|
||||
{
|
||||
let ori_dir = if
|
||||
//character.action.is_wield() ||
|
||||
character.action.is_attack() || character.action.is_block() {
|
||||
Vec2::from(inputs.look_dir).normalized()
|
||||
} else if let (Climb, Some(wall_dir)) = (character.movement, physics.on_wall) {
|
||||
if Vec2::<f32>::from(wall_dir).magnitude_squared() > 0.001 {
|
||||
@ -174,7 +195,6 @@ impl<'a> System<'a> for Sys {
|
||||
&& Vec2::<f32>::from(vel.0).magnitude_squared() < GLIDE_SPEED.powf(2.0)
|
||||
&& vel.0.z < 0.0
|
||||
{
|
||||
character.action = Idle;
|
||||
let lift = GLIDE_ANTIGRAV + vel.0.z.abs().powf(2.0) * 0.15;
|
||||
vel.0.z += dt.0
|
||||
* lift
|
||||
@ -183,18 +203,6 @@ impl<'a> System<'a> for Sys {
|
||||
.max(0.2);
|
||||
}
|
||||
|
||||
// Roll
|
||||
if let Roll { time_left } = &mut character.movement {
|
||||
character.action = Idle;
|
||||
if *time_left == Duration::default() || vel.0.magnitude_squared() < 10.0 {
|
||||
character.movement = Run;
|
||||
} else {
|
||||
*time_left = time_left
|
||||
.checked_sub(Duration::from_secs_f32(dt.0))
|
||||
.unwrap_or_default();
|
||||
}
|
||||
}
|
||||
|
||||
// Climb
|
||||
if let (true, Some(_wall_dir)) = (
|
||||
(inputs.climb.is_pressed() | inputs.climb_down.is_pressed())
|
||||
@ -213,34 +221,10 @@ impl<'a> System<'a> for Sys {
|
||||
30.0 * dt.0 / (1.0 - vel.0.z.min(0.0) * 5.0),
|
||||
);
|
||||
}
|
||||
|
||||
character.movement = Climb;
|
||||
character.action = Idle;
|
||||
} else if let Climb = character.movement {
|
||||
character.movement = Jump;
|
||||
}
|
||||
|
||||
if physics.on_ground
|
||||
&& (character.movement == Jump
|
||||
|| character.movement == Climb
|
||||
|| character.movement == Glide
|
||||
|| character.movement == Swim)
|
||||
{
|
||||
character.movement = Stand;
|
||||
}
|
||||
|
||||
if !physics.on_ground
|
||||
&& (character.movement == Stand
|
||||
|| character.movement.is_roll()
|
||||
|| character.movement == Run)
|
||||
{
|
||||
character.movement = Jump;
|
||||
}
|
||||
|
||||
if !physics.on_ground && physics.in_fluid {
|
||||
character.movement = Swim;
|
||||
} else if let Swim = character.movement {
|
||||
character.movement = Stand;
|
||||
if character.movement == Swim && inputs.jump.is_pressed() {
|
||||
vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(HUMANOID_WATER_SPEED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -353,6 +353,8 @@ impl<'a> System<'a> for Sys {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
physics.touch_entity = None;
|
||||
|
||||
let scale = scale.map(|s| s.0).unwrap_or(1.0);
|
||||
let mass = mass.map(|m| m.0).unwrap_or(scale);
|
||||
|
||||
|
@ -87,15 +87,15 @@ impl Animation for AttackAnimation {
|
||||
//next.r_foot.ori = Quaternion::rotation_x(wave_stop_quick * 1.2);
|
||||
//next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-8.0 + wave_quicken_slow * 10.0 + skeleton_attr.weapon_x,
|
||||
8.0 + wave_quicken_double * 3.0,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_z(-0.8)
|
||||
next.main.ori = Quaternion::rotation_z(-0.8)
|
||||
* Quaternion::rotation_x(0.0 + wave_quicken * -0.8)
|
||||
* Quaternion::rotation_y(0.0 + wave_quicken * -0.4);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
@ -105,9 +105,13 @@ impl Animation for AttackAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_z(wave_stop_quick * -0.2)
|
||||
|
@ -72,15 +72,15 @@ impl Animation for BlockAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Axe) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -97,15 +97,15 @@ impl Animation for BlockAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Hammer) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 3.5, 6.5);
|
||||
@ -118,15 +118,15 @@ impl Animation for BlockAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
5.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(-0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Staff) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -143,15 +143,15 @@ impl Animation for BlockAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Shield) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -168,15 +168,15 @@ impl Animation for BlockAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Bow) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -193,15 +193,15 @@ impl Animation for BlockAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Dagger) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -214,15 +214,15 @@ impl Animation for BlockAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Debug(_)) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 3.5, 6.5);
|
||||
@ -235,15 +235,15 @@ impl Animation for BlockAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
5.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(-0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -263,9 +263,13 @@ impl Animation for BlockAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
|
@ -71,15 +71,15 @@ impl Animation for BlockIdleAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Axe) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -96,15 +96,15 @@ impl Animation for BlockIdleAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Hammer) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 3.5 + wave_ultra_slow * 2.0, 6.5);
|
||||
@ -117,15 +117,15 @@ impl Animation for BlockIdleAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + wave_ultra_slow * 2.0 + skeleton_attr.weapon_y,
|
||||
5.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(-0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Staff) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -142,15 +142,15 @@ impl Animation for BlockIdleAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Shield) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -167,15 +167,15 @@ impl Animation for BlockIdleAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Bow) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -192,15 +192,15 @@ impl Animation for BlockIdleAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Dagger) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -213,15 +213,15 @@ impl Animation for BlockIdleAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Debug(_)) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 3.5 + wave_ultra_slow * 2.0, 6.5);
|
||||
@ -234,15 +234,15 @@ impl Animation for BlockIdleAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + wave_ultra_slow * 2.0 + skeleton_attr.weapon_y,
|
||||
5.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(-0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -262,9 +262,13 @@ impl Animation for BlockIdleAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
|
111
voxygen/src/anim/character/charge.rs
Normal file
111
voxygen/src/anim/character/charge.rs
Normal file
@ -0,0 +1,111 @@
|
||||
use super::{
|
||||
super::{Animation, SkeletonAttr},
|
||||
CharacterSkeleton,
|
||||
};
|
||||
use common::comp::item::Tool;
|
||||
use std::f32::consts::PI;
|
||||
use vek::*;
|
||||
|
||||
pub struct Input {
|
||||
pub attack: bool,
|
||||
}
|
||||
pub struct ChargeAnimation;
|
||||
|
||||
impl Animation for ChargeAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = (Option<Tool>, f64);
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &Self::Skeleton,
|
||||
(_active_tool_kind, _global_time): Self::Dependency,
|
||||
anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let wave_stop_quick = (anim_time as f32 * 8.0).min(PI / 2.0).sin();
|
||||
let constant = 8.0;
|
||||
|
||||
let wave_cos = (((5.0)
|
||||
/ (1.1 + 3.9 * ((anim_time as f32 * constant as f32 * 2.4).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * constant as f32 * 1.5).sin());
|
||||
let wave_cos_dub = (((5.0)
|
||||
/ (1.1 + 3.9 * ((anim_time as f32 * constant as f32 * 4.8).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * constant as f32 * 1.5).sin());
|
||||
next.head.offset = Vec3::new(
|
||||
0.0 + skeleton_attr.neck_right,
|
||||
5.0 + skeleton_attr.neck_forward,
|
||||
skeleton_attr.neck_height + 19.0 + wave_cos * 2.0,
|
||||
);
|
||||
next.head.ori =
|
||||
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
|
||||
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
|
||||
|
||||
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_cos * 2.0);
|
||||
next.chest.ori = Quaternion::rotation_x(-0.7) * Quaternion::rotation_z(-0.9);
|
||||
next.chest.scale = Vec3::one();
|
||||
|
||||
next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_cos * 2.0);
|
||||
next.belt.ori = Quaternion::rotation_x(-0.6) * Quaternion::rotation_z(-0.9);
|
||||
next.belt.scale = Vec3::one();
|
||||
|
||||
next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_cos * 2.0);
|
||||
next.shorts.ori = Quaternion::rotation_x(-0.5) * Quaternion::rotation_z(-0.9);
|
||||
next.shorts.scale = Vec3::one();
|
||||
|
||||
next.l_hand.offset = Vec3::new(-8.0, -7.5, 5.0);
|
||||
next.l_hand.ori = Quaternion::rotation_z(0.5)
|
||||
* Quaternion::rotation_x(wave_stop_quick * -1.5 + 0.5 + 1.57)
|
||||
* Quaternion::rotation_y(-0.6);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
|
||||
next.r_hand.offset = Vec3::new(-8.0, -8.0, 3.0);
|
||||
next.r_hand.ori = Quaternion::rotation_z(0.5)
|
||||
* Quaternion::rotation_x(wave_stop_quick * -1.5 + 0.5 + 1.57)
|
||||
* Quaternion::rotation_y(-0.6);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
|
||||
next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7);
|
||||
next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 0.8);
|
||||
next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7);
|
||||
next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 0.8);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.main.offset = Vec3::new(
|
||||
-8.0 + skeleton_attr.weapon_x,
|
||||
0.0 + skeleton_attr.weapon_y,
|
||||
5.0,
|
||||
);
|
||||
next.main.ori = Quaternion::rotation_z(-0.0)
|
||||
* Quaternion::rotation_x(wave_stop_quick * -1.5 + 0.7)
|
||||
* Quaternion::rotation_y(-0.5);
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.l_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7);
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, 0.0, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori =
|
||||
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
next
|
||||
}
|
||||
}
|
@ -57,7 +57,7 @@ impl Animation for CidleAnimation {
|
||||
|
||||
next.belt.offset = Vec3::new(0.0 + wave_slow_cos * 0.5, 0.0, 5.0 + wave_ultra_slow * 0.5);
|
||||
next.belt.ori = Quaternion::rotation_y(wave_ultra_slow_cos * 0.03);
|
||||
next.belt.scale = Vec3::one();
|
||||
next.belt.scale = Vec3::one() * 1.02;
|
||||
|
||||
next.shorts.offset = Vec3::new(0.0 + wave_slow_cos * 0.5, 0.0, 2.0 + wave_ultra_slow * 0.5);
|
||||
next.shorts.ori = Quaternion::rotation_x(0.0);
|
||||
@ -68,52 +68,54 @@ impl Animation for CidleAnimation {
|
||||
Some(Tool::Sword) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.5 + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
-2.0 + wave_ultra_slow_cos * 0.5,
|
||||
1.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.l_hand.ori = Quaternion::rotation_x(1.27);
|
||||
next.l_hand.scale = Vec3::one() * 1.0;
|
||||
next.r_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.0 + wave_ultra_slow_cos * 0.5,
|
||||
-2.0 + wave_ultra_slow * 1.0,
|
||||
-2.5 + wave_ultra_slow_cos * 0.5,
|
||||
-1.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.ori = Quaternion::rotation_x(1.27);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
5.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
1.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Axe) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.5 + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
-6.5 + wave_ultra_slow_cos * 1.0,
|
||||
-0.5 + wave_ultra_slow_cos * 0.5,
|
||||
6.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.ori = Quaternion::rotation_x(0.13) * Quaternion::rotation_z(-0.25);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.0 + wave_ultra_slow_cos * 0.5,
|
||||
-2.0 + wave_ultra_slow * 1.0,
|
||||
-3.0 + wave_ultra_slow_cos * 1.0,
|
||||
6.5 + wave_ultra_slow_cos * 0.5,
|
||||
6.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.ori = Quaternion::rotation_x(0.13)
|
||||
* Quaternion::rotation_z(2.98)
|
||||
* Quaternion::rotation_y(-0.50);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
next.main.offset = Vec3::new(
|
||||
-5.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
8.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
-0.5 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(1.27)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
next.main.ori = Quaternion::rotation_x(1.70)
|
||||
* Quaternion::rotation_y(-0.25)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Hammer) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 4.0, 3.0);
|
||||
@ -126,15 +128,15 @@ impl Animation for CidleAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
-2.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.27)
|
||||
* Quaternion::rotation_z(wave_ultra_slow * 0.2);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Staff) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -151,15 +153,15 @@ impl Animation for CidleAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Shield) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -176,15 +178,15 @@ impl Animation for CidleAnimation {
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Bow) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -205,15 +207,15 @@ impl Animation for CidleAnimation {
|
||||
* Quaternion::rotation_y(-1.7)
|
||||
* Quaternion::rotation_z(0.85);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
9.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
10.0 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
-3.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(0.0)
|
||||
next.main.ori = Quaternion::rotation_x(0.0)
|
||||
* Quaternion::rotation_y(-1.7)
|
||||
* Quaternion::rotation_z(0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Dagger) => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
@ -226,15 +228,15 @@ impl Animation for CidleAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Debug(_)) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 4.0, 3.0);
|
||||
@ -247,15 +249,15 @@ impl Animation for CidleAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
-2.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.27)
|
||||
* Quaternion::rotation_z(wave_ultra_slow * 0.2);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -275,9 +277,13 @@ impl Animation for CidleAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
|
@ -78,14 +78,14 @@ impl Animation for ClimbAnimation {
|
||||
next.r_foot.ori = Quaternion::rotation_x(0.2 + wave_testc * 0.5);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori =
|
||||
next.main.ori =
|
||||
Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(wave_cos * 0.15);
|
||||
@ -95,9 +95,13 @@ impl Animation for ClimbAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.15);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2 + wave * -0.08, 0.4) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
|
||||
|
@ -108,13 +108,13 @@ impl Animation for GlidingAnimation {
|
||||
);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
@ -124,10 +124,14 @@ impl Animation for GlidingAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, -13.0 + wave_very_slow * 0.10, 6.0);
|
||||
next.draw.ori =
|
||||
next.glider.offset = Vec3::new(0.0, -13.0 + wave_very_slow * 0.10, 6.0);
|
||||
next.glider.ori =
|
||||
Quaternion::rotation_x(1.0) * Quaternion::rotation_y(wave_very_slow_cos * 0.04);
|
||||
next.draw.scale = Vec3::one();
|
||||
next.glider.scale = Vec3::one();
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, 6.0, 15.0) / 11.0 * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(-0.05 * speed.max(12.0) + wave_very_slow * 0.10)
|
||||
|
@ -83,13 +83,13 @@ impl Animation for IdleAnimation {
|
||||
next.r_foot.ori = Quaternion::identity();
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.weapon.scale = Vec3::one() + wave_ultra_slow_abs * -0.05;
|
||||
next.main.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.main.scale = Vec3::one() + wave_ultra_slow_abs * -0.05;
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 5.0);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
@ -99,9 +99,13 @@ impl Animation for IdleAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = (Vec3::one() + wave_ultra_slow_abs * -0.05) * 1.15;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
|
@ -71,13 +71,13 @@ impl Animation for JumpAnimation {
|
||||
next.r_foot.ori = Quaternion::rotation_x(wave_stop * 1.2 + wave_slow * 0.2);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(wave_stop_alt * 0.3);
|
||||
@ -87,9 +87,13 @@ impl Animation for JumpAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(-wave_stop_alt * 0.3);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, 0.0, 0.0) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(-0.2);
|
||||
|
@ -1,6 +1,7 @@
|
||||
pub mod attack;
|
||||
pub mod block;
|
||||
pub mod blockidle;
|
||||
pub mod charge;
|
||||
pub mod cidle;
|
||||
pub mod climb;
|
||||
pub mod gliding;
|
||||
@ -17,6 +18,7 @@ pub mod wield;
|
||||
pub use self::attack::AttackAnimation;
|
||||
pub use self::block::BlockAnimation;
|
||||
pub use self::blockidle::BlockIdleAnimation;
|
||||
pub use self::charge::ChargeAnimation;
|
||||
pub use self::cidle::CidleAnimation;
|
||||
pub use self::climb::ClimbAnimation;
|
||||
pub use self::gliding::GlidingAnimation;
|
||||
@ -42,10 +44,11 @@ pub struct CharacterSkeleton {
|
||||
r_hand: Bone,
|
||||
l_foot: Bone,
|
||||
r_foot: Bone,
|
||||
weapon: Bone,
|
||||
main: Bone,
|
||||
l_shoulder: Bone,
|
||||
r_shoulder: Bone,
|
||||
draw: Bone,
|
||||
glider: Bone,
|
||||
lantern: Bone,
|
||||
torso: Bone,
|
||||
}
|
||||
|
||||
@ -60,10 +63,11 @@ impl CharacterSkeleton {
|
||||
r_hand: Bone::default(),
|
||||
l_foot: Bone::default(),
|
||||
r_foot: Bone::default(),
|
||||
weapon: Bone::default(),
|
||||
main: Bone::default(),
|
||||
l_shoulder: Bone::default(),
|
||||
r_shoulder: Bone::default(),
|
||||
draw: Bone::default(),
|
||||
glider: Bone::default(),
|
||||
lantern: Bone::default(),
|
||||
torso: Bone::default(),
|
||||
}
|
||||
}
|
||||
@ -74,7 +78,8 @@ impl Skeleton for CharacterSkeleton {
|
||||
let chest_mat = self.chest.compute_base_matrix();
|
||||
let torso_mat = self.torso.compute_base_matrix();
|
||||
let l_hand_mat = self.l_hand.compute_base_matrix();
|
||||
let weapon_mat = self.weapon.compute_base_matrix();
|
||||
let main_mat = self.main.compute_base_matrix();
|
||||
|
||||
let head_mat = self.head.compute_base_matrix();
|
||||
[
|
||||
FigureBoneData::new(torso_mat * head_mat),
|
||||
@ -85,14 +90,14 @@ impl Skeleton for CharacterSkeleton {
|
||||
FigureBoneData::new(torso_mat * chest_mat * self.r_hand.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat * self.l_foot.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat * self.r_foot.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat * chest_mat * weapon_mat),
|
||||
FigureBoneData::new(torso_mat * chest_mat * main_mat),
|
||||
FigureBoneData::new(torso_mat * chest_mat * self.l_shoulder.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat * chest_mat * self.r_shoulder.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat * self.draw.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat * self.glider.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat * chest_mat * self.lantern.compute_base_matrix()),
|
||||
FigureBoneData::new(torso_mat),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
FigureBoneData::default(),
|
||||
]
|
||||
}
|
||||
|
||||
@ -105,10 +110,11 @@ impl Skeleton for CharacterSkeleton {
|
||||
self.r_hand.interpolate(&target.r_hand, dt);
|
||||
self.l_foot.interpolate(&target.l_foot, dt);
|
||||
self.r_foot.interpolate(&target.r_foot, dt);
|
||||
self.weapon.interpolate(&target.weapon, dt);
|
||||
self.main.interpolate(&target.main, dt);
|
||||
self.l_shoulder.interpolate(&target.l_shoulder, dt);
|
||||
self.r_shoulder.interpolate(&target.r_shoulder, dt);
|
||||
self.draw.interpolate(&target.draw, dt);
|
||||
self.glider.interpolate(&target.glider, dt);
|
||||
self.lantern.interpolate(&target.lantern, dt);
|
||||
self.torso.interpolate(&target.torso, dt);
|
||||
}
|
||||
}
|
||||
|
@ -74,15 +74,15 @@ impl Animation for RollAnimation {
|
||||
next.r_foot.ori = Quaternion::rotation_x(wave * -0.4);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_y(2.5)
|
||||
next.main.ori = Quaternion::rotation_y(2.5)
|
||||
* Quaternion::rotation_z(1.57)
|
||||
* Quaternion::rotation_x(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
@ -92,9 +92,13 @@ impl Animation for RollAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset =
|
||||
Vec3::new(0.0, 11.0, 0.1 + wave_dub * 16.0) / 11.0 * skeleton_attr.scaler;
|
||||
|
@ -1,147 +0,0 @@
|
||||
use super::{
|
||||
super::{Animation, SkeletonAttr},
|
||||
CharacterSkeleton,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
use std::ops::Mul;
|
||||
use vek::*;
|
||||
|
||||
pub struct SneakAnimation;
|
||||
|
||||
impl Animation for SneakAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f64);
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &Self::Skeleton,
|
||||
(velocity, orientation, last_ori, global_time): Self::Dependency,
|
||||
anim_time: f64,
|
||||
rate: &mut f32,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let speed = Vec2::<f32>::from(velocity).magnitude();
|
||||
*rate = speed;
|
||||
|
||||
let constant = 1.0;
|
||||
let wave = (((5.0)
|
||||
/ (1.1 + 3.9 * ((anim_time as f32 * constant as f32 * 1.2).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * constant as f32 * 1.2).sin());
|
||||
let wave_cos = (((5.0)
|
||||
/ (1.1 + 3.9 * ((anim_time as f32 * constant as f32 * 2.4).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * constant as f32 * 1.5).sin());
|
||||
let wave_cos_dub = (((5.0)
|
||||
/ (1.1 + 3.9 * ((anim_time as f32 * constant as f32 * 4.8).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * constant as f32 * 1.5).sin());
|
||||
|
||||
let wave_diff = (anim_time as f32 * 0.6).sin();
|
||||
let wave_stop = (anim_time as f32 * 2.6).min(PI / 2.0).sin();
|
||||
let head_look = Vec2::new(
|
||||
((global_time + anim_time) as f32 / 4.0)
|
||||
.floor()
|
||||
.mul(7331.0)
|
||||
.sin()
|
||||
* 0.2,
|
||||
((global_time + anim_time) as f32 / 4.0)
|
||||
.floor()
|
||||
.mul(1337.0)
|
||||
.sin()
|
||||
* 0.1,
|
||||
);
|
||||
|
||||
let ori = Vec2::from(orientation);
|
||||
let last_ori = Vec2::from(last_ori);
|
||||
|
||||
let tilt = if Vec2::new(ori, last_ori)
|
||||
.map(|o| Vec2::<f32>::from(o).magnitude_squared())
|
||||
.map(|m| m > 0.001 && m.is_finite())
|
||||
.reduce_and()
|
||||
&& ori.angle_between(last_ori).is_finite()
|
||||
{
|
||||
ori.angle_between(last_ori).min(0.5)
|
||||
* last_ori.determine_side(Vec2::zero(), ori).signum()
|
||||
} else {
|
||||
0.0
|
||||
} * 1.3;
|
||||
|
||||
next.head.offset = Vec3::new(
|
||||
0.0,
|
||||
-3.0 + skeleton_attr.neck_forward,
|
||||
skeleton_attr.neck_height + 20.0 + wave_cos * 1.3,
|
||||
);
|
||||
next.head.ori = Quaternion::rotation_z(head_look.x + wave * 0.1)
|
||||
* Quaternion::rotation_x(head_look.y + 0.35);
|
||||
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
|
||||
|
||||
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_cos * 1.1);
|
||||
next.chest.ori = Quaternion::rotation_z(wave * 0.2);
|
||||
next.chest.scale = Vec3::one();
|
||||
|
||||
next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_cos * 1.1);
|
||||
next.belt.ori = Quaternion::rotation_z(wave * 0.35);
|
||||
next.belt.scale = Vec3::one();
|
||||
|
||||
next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_cos * 1.1);
|
||||
next.shorts.ori = Quaternion::rotation_z(wave * 0.6);
|
||||
next.shorts.scale = Vec3::one();
|
||||
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_stop * -1.0,
|
||||
-0.25 + wave_cos * 2.0,
|
||||
5.0 - wave * 1.5,
|
||||
);
|
||||
next.l_hand.ori =
|
||||
Quaternion::rotation_x(0.8 + wave_cos * 1.2) * Quaternion::rotation_y(wave_stop * 0.1);
|
||||
next.l_hand.scale = Vec3::one();
|
||||
|
||||
next.r_hand.offset = Vec3::new(
|
||||
6.0 + wave_stop * 1.0,
|
||||
-0.25 - wave_cos * 2.0,
|
||||
5.0 + wave * 1.5,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(0.8 + wave_cos * -1.2)
|
||||
* Quaternion::rotation_y(wave_stop * -0.1);
|
||||
next.r_hand.scale = Vec3::one();
|
||||
|
||||
next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7);
|
||||
next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.2);
|
||||
next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7);
|
||||
next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.2);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori =
|
||||
Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(wave_cos * 0.15);
|
||||
next.l_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7);
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.15);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, 0.3 + wave * -0.08, 0.4) * skeleton_attr.scaler;
|
||||
next.torso.ori =
|
||||
Quaternion::rotation_x(wave_stop * speed * -0.06 + wave_diff * speed * -0.005)
|
||||
* Quaternion::rotation_y(tilt);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -116,14 +116,14 @@ impl Animation for RunAnimation {
|
||||
next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.2);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori =
|
||||
next.main.ori =
|
||||
Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(wave_cos * 0.15);
|
||||
@ -133,9 +133,13 @@ impl Animation for RunAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.15);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_y(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, 0.3 + wave * -0.08, 0.4) * skeleton_attr.scaler;
|
||||
next.torso.ori =
|
||||
|
@ -98,13 +98,13 @@ impl Animation for SitAnimation {
|
||||
);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.weapon.scale = Vec3::one() + wave_slow_abs * -0.05;
|
||||
next.main.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.main.scale = Vec3::one() + wave_slow_abs * -0.05;
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
@ -114,9 +114,13 @@ impl Animation for SitAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = (Vec3::one() + wave_slow_abs * -0.05) * 1.15;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, wave_stop * -0.16) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
|
@ -111,14 +111,14 @@ impl Animation for SneakAnimation {
|
||||
next.r_foot.ori = Quaternion::rotation_x(-0.8 - wavecos * 0.15);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori =
|
||||
next.main.ori =
|
||||
Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(wavecos * 0.05);
|
||||
@ -128,9 +128,13 @@ impl Animation for SneakAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.05);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_y(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, 0.3 + wave * -0.08, 0.4) * skeleton_attr.scaler;
|
||||
next.torso.ori =
|
||||
|
@ -82,13 +82,13 @@ impl Animation for StandAnimation {
|
||||
next.r_foot.ori = Quaternion::identity();
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.weapon.scale = Vec3::one() + wave_ultra_slow_abs * -0.05;
|
||||
next.main.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.main.scale = Vec3::one() + wave_ultra_slow_abs * -0.05;
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 5.0);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
@ -98,9 +98,13 @@ impl Animation for StandAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = (Vec3::one() + wave_ultra_slow_abs * -0.05) * 1.15;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_x(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.1, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
|
@ -99,14 +99,14 @@ impl Animation for SwimAnimation {
|
||||
next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.5);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori =
|
||||
next.main.ori =
|
||||
Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(wave_cos * 0.15);
|
||||
@ -116,9 +116,13 @@ impl Animation for SwimAnimation {
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.15);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
next.glider.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.glider.ori = Quaternion::rotation_y(0.0);
|
||||
next.glider.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.lantern.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.lantern.ori = Quaternion::rotation_y(0.0);
|
||||
next.lantern.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2 + wave * -0.08, 0.4) * skeleton_attr.scaler;
|
||||
next.torso.ori =
|
||||
|
@ -3,6 +3,8 @@ use super::{
|
||||
CharacterSkeleton,
|
||||
};
|
||||
use common::comp::item::Tool;
|
||||
use std::f32::consts::PI;
|
||||
|
||||
use vek::*;
|
||||
|
||||
pub struct WieldAnimation;
|
||||
@ -13,50 +15,55 @@ impl Animation for WieldAnimation {
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &Self::Skeleton,
|
||||
(active_tool_kind, _velocity, _global_time): Self::Dependency,
|
||||
(active_tool_kind, velocity, _global_time): Self::Dependency,
|
||||
anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
rate: &mut f32,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let wave = (anim_time as f32 * 12.0).sin();
|
||||
let speed = Vec2::<f32>::from(velocity).magnitude();
|
||||
*rate = speed;
|
||||
|
||||
let wave = (anim_time as f32 * 1.0).sin();
|
||||
let wave_stop = (anim_time as f32 * 2.6).min(PI / 2.0).sin();
|
||||
match active_tool_kind {
|
||||
//TODO: Inventory
|
||||
Some(Tool::Sword) => {
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.75, 0.25);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.offset = Vec3::new(-6.0, -2.0, 1.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(1.27);
|
||||
next.l_hand.scale = Vec3::one() * 1.00;
|
||||
next.r_hand.offset = Vec3::new(-6.0, -2.5, -1.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(1.27);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.0 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
5.5 + skeleton_attr.weapon_y,
|
||||
1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Axe) => {
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.offset = Vec3::new(-6.5, -0.5, 6.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(0.13) * Quaternion::rotation_z(-0.25);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.offset = Vec3::new(-3.0, 6.5, 6.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(0.13)
|
||||
* Quaternion::rotation_z(2.98)
|
||||
* Quaternion::rotation_y(-0.50);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
next.main.offset = Vec3::new(
|
||||
-5.0 + skeleton_attr.weapon_x,
|
||||
8.5 + skeleton_attr.weapon_y,
|
||||
-0.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
next.main.ori = Quaternion::rotation_x(1.70)
|
||||
* Quaternion::rotation_y(-0.25)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Hammer) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 4.0, 3.0);
|
||||
@ -69,15 +76,15 @@ impl Animation for WieldAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
-2.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.27)
|
||||
* Quaternion::rotation_z(wave * -0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Staff) => {
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
||||
@ -86,15 +93,15 @@ impl Animation for WieldAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Shield) => {
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
||||
@ -103,15 +110,15 @@ impl Animation for WieldAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Bow) => {
|
||||
next.l_hand.offset = Vec3::new(-4.0, 5.0, 0.0);
|
||||
@ -124,15 +131,15 @@ impl Animation for WieldAnimation {
|
||||
* Quaternion::rotation_y(-1.7)
|
||||
* Quaternion::rotation_z(0.85);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
9.0 + skeleton_attr.weapon_x,
|
||||
10.0 + skeleton_attr.weapon_y,
|
||||
-3.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(0.0)
|
||||
next.main.ori = Quaternion::rotation_x(0.0)
|
||||
* Quaternion::rotation_y(-1.7)
|
||||
* Quaternion::rotation_z(0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Dagger) => {
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
||||
@ -141,15 +148,15 @@ impl Animation for WieldAnimation {
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
Some(Tool::Debug(_)) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 4.0, 3.0);
|
||||
@ -162,19 +169,21 @@ impl Animation for WieldAnimation {
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
next.main.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
-2.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
next.main.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.27)
|
||||
* Quaternion::rotation_z(wave * -0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
next.main.scale = Vec3::one();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, 0.3 + wave * -0.08, 0.4) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(wave_stop * -0.2);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
next
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ impl SfxEventMapper {
|
||||
}
|
||||
}
|
||||
|
||||
/// Voxygen has an existing list of character states via `MovementState::*` and `ActivityState::*`
|
||||
/// Voxygen has an existing list of character states via `MovementState::*` and `ActionState::*`
|
||||
/// however that list does not provide enough resolution to target specific entity events, such
|
||||
/// as opening or closing the glider. These methods translate those entity states with some additional
|
||||
/// data into more specific `SfxEvent`'s which we attach sounds to
|
||||
@ -164,7 +164,7 @@ impl SfxEventMapper {
|
||||
vel,
|
||||
stats,
|
||||
) {
|
||||
(MovementState::Roll { .. }, ..) => SfxEvent::Roll,
|
||||
(_, ActionState::Roll { .. }, ..) => SfxEvent::Roll,
|
||||
(MovementState::Climb, ..) => SfxEvent::Climb,
|
||||
(MovementState::Swim, ..) => SfxEvent::Swim,
|
||||
(MovementState::Run, ..) => SfxEvent::Run,
|
||||
@ -317,10 +317,10 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
movement: MovementState::Roll {
|
||||
action: ActionState::Roll {
|
||||
time_left: Duration::new(1, 0),
|
||||
},
|
||||
action: ActionState::Idle,
|
||||
movement: MovementState::Run,
|
||||
},
|
||||
SfxEvent::Run,
|
||||
Vec3::zero(),
|
||||
|
@ -132,7 +132,7 @@ impl FigureModelCache {
|
||||
},
|
||||
if camera_mode == CameraMode::FirstPerson
|
||||
&& character_state
|
||||
.map(|cs| cs.movement.is_roll())
|
||||
.map(|cs| cs.action.is_roll())
|
||||
.unwrap_or_default()
|
||||
{
|
||||
None
|
||||
@ -140,7 +140,7 @@ impl FigureModelCache {
|
||||
Some(humanoid_armor_hand_spec.mesh_left_hand(&body))
|
||||
},
|
||||
if character_state
|
||||
.map(|cs| cs.movement.is_roll())
|
||||
.map(|cs| cs.action.is_roll())
|
||||
.unwrap_or_default()
|
||||
{
|
||||
None
|
||||
@ -184,8 +184,8 @@ impl FigureModelCache {
|
||||
),
|
||||
CameraMode::FirstPerson => None,
|
||||
},
|
||||
Some(mesh_draw()),
|
||||
None,
|
||||
Some(mesh_glider()),
|
||||
Some(mesh_lantern()),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
|
@ -532,7 +532,10 @@ pub fn mesh_main(item: Option<&Item>) -> Mesh<FigurePipeline> {
|
||||
}
|
||||
|
||||
// TODO: Inventory
|
||||
pub fn mesh_draw() -> Mesh<FigurePipeline> {
|
||||
pub fn mesh_glider() -> Mesh<FigurePipeline> {
|
||||
load_mesh("object.glider", Vec3::new(-26.0, -26.0, -5.0))
|
||||
}
|
||||
pub fn mesh_lantern() -> Mesh<FigurePipeline> {
|
||||
load_mesh("object.glider", Vec3::new(-26.0, -26.0, -5.0))
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ impl FigureMgr {
|
||||
}
|
||||
|
||||
let target_base = match &character.movement {
|
||||
Stand => anim::character::StandAnimation::update_skeleton(
|
||||
Fall | Stand => anim::character::StandAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
(active_tool_kind, time),
|
||||
state.movement_time,
|
||||
@ -218,13 +218,6 @@ impl FigureMgr {
|
||||
&mut movement_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
Roll { .. } => anim::character::RollAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
(active_tool_kind, time),
|
||||
state.movement_time,
|
||||
&mut movement_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
Glide => anim::character::GlidingAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
(active_tool_kind, vel.0, ori.0, state.last_ori, time),
|
||||
@ -254,7 +247,6 @@ impl FigureMgr {
|
||||
skeleton_attr,
|
||||
),
|
||||
};
|
||||
|
||||
let target_bones = match (&character.movement, &character.action) {
|
||||
(Stand, Wield { .. }) => anim::character::CidleAnimation::update_skeleton(
|
||||
&target_base,
|
||||
@ -286,6 +278,13 @@ impl FigureMgr {
|
||||
&mut action_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
(_, Roll { .. }) => anim::character::RollAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(active_tool_kind, time),
|
||||
state.action_time,
|
||||
&mut action_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
(_, Block { .. }) => anim::character::BlockAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(active_tool_kind, time),
|
||||
@ -293,10 +292,17 @@ impl FigureMgr {
|
||||
&mut action_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
(_, Charge { .. }) => anim::character::ChargeAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(active_tool_kind, time),
|
||||
state.action_time,
|
||||
&mut action_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
_ => target_base,
|
||||
};
|
||||
state.skeleton.interpolate(&target_bones, dt);
|
||||
|
||||
state.skeleton.interpolate(&target_bones, dt);
|
||||
state.update(
|
||||
renderer,
|
||||
pos.0,
|
||||
|
@ -160,7 +160,7 @@ impl Scene {
|
||||
.ecs()
|
||||
.read_storage::<comp::CharacterState>()
|
||||
.get(client.entity())
|
||||
.map_or(false, |cs| cs.movement.is_roll());
|
||||
.map_or(false, |cs| cs.action.is_roll());
|
||||
|
||||
let player_scale = match client
|
||||
.state()
|
||||
|
@ -201,7 +201,11 @@ impl PlayState for SessionState {
|
||||
.state()
|
||||
.read_storage::<comp::CharacterState>()
|
||||
.get(client.entity())
|
||||
.map(|cs| cs.action.is_wield())
|
||||
.map(|cs| {
|
||||
cs.action.is_wield()
|
||||
|| cs.action.is_block()
|
||||
|| cs.action.is_attack()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
{
|
||||
self.inputs.secondary.set_state(state);
|
||||
@ -323,6 +327,9 @@ impl PlayState for SessionState {
|
||||
Event::InputUpdate(GameInput::ToggleWield, state) => {
|
||||
self.inputs.toggle_wield.set_state(state)
|
||||
}
|
||||
Event::InputUpdate(GameInput::Charge, state) => {
|
||||
self.inputs.charge.set_state(state);
|
||||
}
|
||||
|
||||
// Pass all other events to the scene
|
||||
event => {
|
||||
|
@ -48,6 +48,7 @@ pub struct ControlSettings {
|
||||
pub respawn: KeyMouse,
|
||||
pub interact: KeyMouse,
|
||||
pub toggle_wield: KeyMouse,
|
||||
pub charge: KeyMouse,
|
||||
}
|
||||
|
||||
impl Default for ControlSettings {
|
||||
@ -87,6 +88,7 @@ impl Default for ControlSettings {
|
||||
respawn: KeyMouse::Mouse(MouseButton::Left),
|
||||
interact: KeyMouse::Key(VirtualKeyCode::E),
|
||||
toggle_wield: KeyMouse::Key(VirtualKeyCode::T),
|
||||
charge: KeyMouse::Key(VirtualKeyCode::V),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ pub enum GameInput {
|
||||
Respawn,
|
||||
Interact,
|
||||
ToggleWield,
|
||||
Charge,
|
||||
}
|
||||
|
||||
/// Represents an incoming event from the window.
|
||||
@ -225,6 +226,9 @@ impl Window {
|
||||
map.entry(settings.controls.toggle_wield)
|
||||
.or_default()
|
||||
.push(GameInput::ToggleWield);
|
||||
map.entry(settings.controls.charge)
|
||||
.or_default()
|
||||
.push(GameInput::Charge);
|
||||
|
||||
let keypress_map = HashMap::new();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user