Leap now actually works. In addition, leaping while next to an entity no longer interrupts the leap.

This commit is contained in:
Samuel Keiffer 2020-07-03 15:40:12 +00:00 committed by Justin Shipsey
parent 3473fd215b
commit 85d1d4b3ff
17 changed files with 374 additions and 60 deletions

View File

@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added command shortcuts for each of the above chat modes (`/g`, `/f`, `/r`, `/s`, and `/w`, respectively and `/t` for `/tell`) - Added command shortcuts for each of the above chat modes (`/g`, `/f`, `/r`, `/s`, and `/w`, respectively and `/t` for `/tell`)
- Ability to wield 2 × 1h weapons and shields (Note: 1h weapons & shields are not currently avaliable, see [!1095](https://gitlab.com/veloren/veloren/-/merge_requests/1095) for more info) - Ability to wield 2 × 1h weapons and shields (Note: 1h weapons & shields are not currently avaliable, see [!1095](https://gitlab.com/veloren/veloren/-/merge_requests/1095) for more info)
- Zoomable Map - Zoomable Map
- M2 attack for hammer
### Changed ### Changed

BIN
assets/voxygen/element/icons/skill_hammerleap.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -18,6 +18,7 @@ pub enum CharacterAbilityType {
DashMelee, DashMelee,
BasicBlock, BasicBlock,
TripleStrike(Stage), TripleStrike(Stage),
LeapMelee,
} }
impl From<&CharacterState> for CharacterAbilityType { impl From<&CharacterState> for CharacterAbilityType {
@ -28,6 +29,7 @@ impl From<&CharacterState> for CharacterAbilityType {
CharacterState::Boost(_) => Self::Boost, CharacterState::Boost(_) => Self::Boost,
CharacterState::DashMelee(_) => Self::DashMelee, CharacterState::DashMelee(_) => Self::DashMelee,
CharacterState::BasicBlock => Self::BasicBlock, CharacterState::BasicBlock => Self::BasicBlock,
CharacterState::LeapMelee(_) => Self::LeapMelee,
CharacterState::TripleStrike(data) => Self::TripleStrike(data.stage), CharacterState::TripleStrike(data) => Self::TripleStrike(data.stage),
_ => Self::BasicMelee, _ => Self::BasicMelee,
} }
@ -59,6 +61,7 @@ pub enum CharacterAbility {
only_up: bool, only_up: bool,
}, },
DashMelee { DashMelee {
energy_cost: u32,
buildup_duration: Duration, buildup_duration: Duration,
recover_duration: Duration, recover_duration: Duration,
base_damage: u32, base_damage: u32,
@ -69,6 +72,13 @@ pub enum CharacterAbility {
base_damage: u32, base_damage: u32,
needs_timing: bool, needs_timing: bool,
}, },
LeapMelee {
energy_cost: u32,
movement_duration: Duration,
buildup_duration: Duration,
recover_duration: Duration,
base_damage: u32,
},
} }
impl CharacterAbility { impl CharacterAbility {
@ -90,9 +100,9 @@ impl CharacterAbility {
.try_change_by(-220, EnergySource::Ability) .try_change_by(-220, EnergySource::Ability)
.is_ok() .is_ok()
}, },
CharacterAbility::DashMelee { .. } => update CharacterAbility::DashMelee { energy_cost, .. } => update
.energy .energy
.try_change_by(-700, EnergySource::Ability) .try_change_by(-(*energy_cost as i32), EnergySource::Ability)
.is_ok(), .is_ok(),
CharacterAbility::BasicMelee { energy_cost, .. } => update CharacterAbility::BasicMelee { energy_cost, .. } => update
.energy .energy
@ -102,6 +112,10 @@ impl CharacterAbility {
.energy .energy
.try_change_by(-(*energy_cost as i32), EnergySource::Ability) .try_change_by(-(*energy_cost as i32), EnergySource::Ability)
.is_ok(), .is_ok(),
CharacterAbility::LeapMelee { energy_cost, .. } => update
.energy
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
.is_ok(),
_ => true, _ => true,
} }
} }
@ -179,6 +193,7 @@ impl From<&CharacterAbility> for CharacterState {
only_up: *only_up, only_up: *only_up,
}), }),
CharacterAbility::DashMelee { CharacterAbility::DashMelee {
energy_cost: _,
buildup_duration, buildup_duration,
recover_duration, recover_duration,
base_damage, base_damage,
@ -209,6 +224,20 @@ impl From<&CharacterAbility> for CharacterState {
TransitionStyle::Hold(HoldingState::Holding) TransitionStyle::Hold(HoldingState::Holding)
}, },
}), }),
CharacterAbility::LeapMelee {
energy_cost: _,
movement_duration,
buildup_duration,
recover_duration,
base_damage,
} => CharacterState::LeapMelee(leap_melee::Data {
initialize: true,
exhausted: false,
movement_duration: *movement_duration,
buildup_duration: *buildup_duration,
recover_duration: *recover_duration,
base_damage: *base_damage,
}),
} }
} }
} }

View File

@ -61,6 +61,8 @@ pub enum CharacterState {
/// A three-stage attack where each attack pushes player forward /// A three-stage attack where each attack pushes player forward
/// and successive attacks increase in damage, while player holds button. /// and successive attacks increase in damage, while player holds button.
TripleStrike(triple_strike::Data), TripleStrike(triple_strike::Data),
/// A leap followed by a small aoe ground attack
LeapMelee(leap_melee::Data),
} }
impl CharacterState { impl CharacterState {
@ -71,7 +73,8 @@ impl CharacterState {
| CharacterState::BasicRanged(_) | CharacterState::BasicRanged(_)
| CharacterState::DashMelee(_) | CharacterState::DashMelee(_)
| CharacterState::TripleStrike(_) | CharacterState::TripleStrike(_)
| CharacterState::BasicBlock => true, | CharacterState::BasicBlock
| CharacterState::LeapMelee(_) => true,
_ => false, _ => false,
} }
} }
@ -81,7 +84,8 @@ impl CharacterState {
CharacterState::BasicMelee(_) CharacterState::BasicMelee(_)
| CharacterState::BasicRanged(_) | CharacterState::BasicRanged(_)
| CharacterState::DashMelee(_) | CharacterState::DashMelee(_)
| CharacterState::TripleStrike(_) => true, | CharacterState::TripleStrike(_)
| CharacterState::LeapMelee(_) => true,
_ => false, _ => false,
} }
} }
@ -92,7 +96,8 @@ impl CharacterState {
| CharacterState::BasicRanged(_) | CharacterState::BasicRanged(_)
| CharacterState::DashMelee(_) | CharacterState::DashMelee(_)
| CharacterState::TripleStrike(_) | CharacterState::TripleStrike(_)
| CharacterState::BasicBlock => true, | CharacterState::BasicBlock
| CharacterState::LeapMelee(_) => true,
_ => false, _ => false,
} }
} }

View File

@ -197,6 +197,7 @@ impl Tool {
needs_timing: false, needs_timing: false,
}, },
DashMelee { DashMelee {
energy_cost: 700,
buildup_duration: Duration::from_millis(500), buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500), recover_duration: Duration::from_millis(500),
base_damage: 20, base_damage: 20,
@ -208,6 +209,7 @@ impl Tool {
needs_timing: false, needs_timing: false,
}, },
DashMelee { DashMelee {
energy_cost: 700,
buildup_duration: Duration::from_millis(500), buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500), recover_duration: Duration::from_millis(500),
base_damage: 10, base_damage: 10,
@ -227,14 +229,23 @@ impl Tool {
max_angle: 30.0, max_angle: 30.0,
}, },
], ],
Hammer(_) => vec![BasicMelee { Hammer(_) => vec![
energy_cost: 0, BasicMelee {
buildup_duration: Duration::from_millis(700), energy_cost: 0,
recover_duration: Duration::from_millis(300), buildup_duration: Duration::from_millis(700),
base_healthchange: -10, recover_duration: Duration::from_millis(300),
range: 3.5, base_healthchange: -10,
max_angle: 60.0, range: 3.5,
}], max_angle: 60.0,
},
LeapMelee {
energy_cost: 800,
movement_duration: Duration::from_millis(500),
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(100),
base_damage: 20,
},
],
Farming(_) => vec![BasicMelee { Farming(_) => vec![BasicMelee {
energy_cost: 1, energy_cost: 1,
buildup_duration: Duration::from_millis(700), buildup_duration: Duration::from_millis(700),
@ -303,6 +314,7 @@ impl Tool {
max_angle: 60.0, max_angle: 60.0,
}, },
DashMelee { DashMelee {
energy_cost: 700,
buildup_duration: Duration::from_millis(500), buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500), recover_duration: Duration::from_millis(500),
base_damage: 20, base_damage: 20,

View File

@ -27,7 +27,7 @@ impl CharacterBehavior for Data {
if self.initialize { if self.initialize {
update.vel.0 = *data.inputs.look_dir * 20.0; update.vel.0 = *data.inputs.look_dir * 20.0;
if let Some(dir) = Vec3::from(data.vel.0.xy()).try_normalized() { if let Some(dir) = Vec3::from(data.inputs.look_dir.xy()).try_normalized() {
update.ori.0 = dir.into(); update.ori.0 = dir.into();
} }
} }

View File

@ -0,0 +1,121 @@
use crate::{
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
states::utils::*,
sys::character_behavior::*,
};
use std::time::Duration;
use vek::Vec3;
const LEAP_SPEED: f32 = 16.0;
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub struct Data {
/// How long the state is moving
pub movement_duration: Duration,
/// How long until state should deal damage
pub buildup_duration: Duration,
/// How long the state has until exiting
pub recover_duration: Duration,
/// Base damage
pub base_damage: u32,
/// Whether the attack can deal more damage
pub exhausted: bool,
pub initialize: bool,
}
impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
if self.initialize {
update.vel.0 = *data.inputs.look_dir * 20.0;
if let Some(dir) = Vec3::from(data.inputs.look_dir.xy()).try_normalized() {
update.ori.0 = dir.into();
}
}
if self.movement_duration != Duration::default() {
// Jumping
update.vel.0 = Vec3::new(data.inputs.look_dir.x, data.inputs.look_dir.y, 8.0)
* ((self.movement_duration.as_millis() as f32) / 250.0)
+ (update.vel.0 * Vec3::new(2.0, 2.0, 0.0)
+ 0.25 * data.inputs.move_dir.try_normalized().unwrap_or_default())
.try_normalized()
.unwrap_or_default()
* LEAP_SPEED;
update.character = CharacterState::LeapMelee(Data {
movement_duration: self
.movement_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
buildup_duration: self.buildup_duration,
recover_duration: self.recover_duration,
base_damage: self.base_damage,
exhausted: false,
initialize: false,
});
} else if self.buildup_duration != Duration::default() && !data.physics.on_ground {
// Falling
update.character = CharacterState::LeapMelee(Data {
movement_duration: Duration::default(),
buildup_duration: self
.buildup_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
recover_duration: self.recover_duration,
base_damage: self.base_damage,
exhausted: false,
initialize: false,
});
} else if !self.exhausted {
// Hit attempt
data.updater.insert(data.entity, Attacking {
base_healthchange: -(self.base_damage as i32),
range: 4.5,
max_angle: 360_f32.to_radians(),
applied: false,
hit_count: 0,
knockback: 25.0,
});
update.character = CharacterState::LeapMelee(Data {
movement_duration: self.movement_duration,
buildup_duration: Duration::default(),
recover_duration: self.recover_duration,
base_damage: self.base_damage,
exhausted: true,
initialize: false,
});
} else if self.recover_duration != Duration::default() {
// Recovery
handle_move(data, &mut update, 0.7);
update.character = CharacterState::LeapMelee(Data {
movement_duration: self.movement_duration,
buildup_duration: self.buildup_duration,
recover_duration: self
.recover_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
base_damage: self.base_damage,
exhausted: true,
initialize: false,
});
} else {
// Done
update.character = CharacterState::Wielding;
// Make sure attack component is removed
data.updater.remove::<Attacking>(data.entity);
}
// Grant energy on successful hit
if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 {
data.updater.remove::<Attacking>(data.entity);
update.energy.change_by(100, EnergySource::HitEnemy);
}
}
update
}
}

View File

@ -9,6 +9,7 @@ pub mod equipping;
pub mod glide; pub mod glide;
pub mod glide_wield; pub mod glide_wield;
pub mod idle; pub mod idle;
pub mod leap_melee;
pub mod roll; pub mod roll;
pub mod sit; pub mod sit;
pub mod triple_strike; pub mod triple_strike;

View File

@ -219,6 +219,7 @@ impl<'a> System<'a> for Sys {
CharacterState::BasicRanged(data) => data.handle_event(&j, action), CharacterState::BasicRanged(data) => data.handle_event(&j, action),
CharacterState::Boost(data) => data.handle_event(&j, action), CharacterState::Boost(data) => data.handle_event(&j, action),
CharacterState::DashMelee(data) => data.handle_event(&j, action), CharacterState::DashMelee(data) => data.handle_event(&j, action),
CharacterState::LeapMelee(data) => data.handle_event(&j, action),
}; };
local_emitter.append(&mut state_update.local_events); local_emitter.append(&mut state_update.local_events);
server_emitter.append(&mut state_update.server_events); server_emitter.append(&mut state_update.server_events);
@ -243,6 +244,7 @@ impl<'a> System<'a> for Sys {
CharacterState::BasicRanged(data) => data.behavior(&j), CharacterState::BasicRanged(data) => data.behavior(&j),
CharacterState::Boost(data) => data.behavior(&j), CharacterState::Boost(data) => data.behavior(&j),
CharacterState::DashMelee(data) => data.behavior(&j), CharacterState::DashMelee(data) => data.behavior(&j),
CharacterState::LeapMelee(data) => data.behavior(&j),
}; };
local_emitter.append(&mut state_update.local_events); local_emitter.append(&mut state_update.local_events);

View File

@ -105,6 +105,7 @@ impl<'a> System<'a> for Sys {
// Ability use does not regen and sets the rate back to zero. // Ability use does not regen and sets the rate back to zero.
CharacterState::BasicMelee { .. } CharacterState::BasicMelee { .. }
| CharacterState::DashMelee { .. } | CharacterState::DashMelee { .. }
| CharacterState::LeapMelee { .. }
| CharacterState::TripleStrike { .. } | CharacterState::TripleStrike { .. }
| CharacterState::BasicRanged { .. } => { | CharacterState::BasicRanged { .. } => {
if energy.get_unchecked().regen_rate != 0.0 { if energy.get_unchecked().regen_rate != 0.0 {

View File

@ -26,13 +26,13 @@ impl Animation for AlphaAnimation {
let lab = 1.0; let lab = 1.0;
let foot = (((5.0) let foot = (((1.0)
/ (0.2 / (0.2
+ 4.8 + 0.8
* ((anim_time as f32 * lab as f32 * 1.3 * velocity).sin()).powf(2.0 as f32))) * ((anim_time as f32 * lab as f32 * 2.0 * velocity).sin()).powf(2.0 as f32)))
.sqrt()) .sqrt())
* ((anim_time as f32 * lab as f32 * 1.3 * velocity).sin()); * ((anim_time as f32 * lab as f32 * 2.0 * velocity).sin());
let slowersmooth = (anim_time as f32 * lab as f32 * 4.0).sin();
let accel_med = 1.0 - (anim_time as f32 * 16.0 * lab as f32).cos(); let accel_med = 1.0 - (anim_time as f32 * 16.0 * lab as f32).cos();
let accel_slow = 1.0 - (anim_time as f32 * 12.0 * lab as f32).cos(); let accel_slow = 1.0 - (anim_time as f32 * 12.0 * lab as f32).cos();
let accel_fast = 1.0 - (anim_time as f32 * 24.0 * lab as f32).cos(); let accel_fast = 1.0 - (anim_time as f32 * 24.0 * lab as f32).cos();
@ -46,8 +46,8 @@ impl Animation for AlphaAnimation {
/ (0.4 + 4.6 * ((anim_time as f32 * lab as f32 * 18.0).sin()).powf(2.0 as f32))) / (0.4 + 4.6 * ((anim_time as f32 * lab as f32 * 18.0).sin()).powf(2.0 as f32)))
.sqrt()) .sqrt())
* ((anim_time as f32 * lab as f32 * 18.0).sin()); * ((anim_time as f32 * lab as f32 * 18.0).sin());
let slower = (((5.0) let slower = (((1.0)
/ (0.1 + 4.9 * ((anim_time as f32 * lab as f32 * 4.0).sin()).powf(2.0 as f32))) / (0.0001 + 0.999 * ((anim_time as f32 * lab as f32 * 4.0).sin()).powf(2.0 as f32)))
.sqrt()) .sqrt())
* ((anim_time as f32 * lab as f32 * 4.0).sin()); * ((anim_time as f32 * lab as f32 * 4.0).sin());
let slowax = (((5.0) let slowax = (((5.0)
@ -262,33 +262,39 @@ impl Animation for AlphaAnimation {
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler; next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
}, },
Some(ToolKind::Hammer(_)) => { Some(ToolKind::Hammer(_)) => {
next.l_hand.offset = Vec3::new(-7.0, 5.5, 3.5); next.l_hand.offset = Vec3::new(-12.0, 0.0, 0.0);
next.l_hand.ori = Quaternion::rotation_x(0.3) * Quaternion::rotation_y(0.32); next.l_hand.ori = Quaternion::rotation_x(-0.0) * Quaternion::rotation_y(0.0);
next.l_hand.scale = Vec3::one() * 1.05; next.l_hand.scale = Vec3::one() * 1.08;
next.r_hand.offset = Vec3::new(8.0, 7.75, 0.0); next.r_hand.offset = Vec3::new(3.0, 0.0, 0.0);
next.r_hand.ori = Quaternion::rotation_x(0.3) * Quaternion::rotation_y(0.22); next.r_hand.ori = Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
next.r_hand.scale = Vec3::one() * 1.05; next.r_hand.scale = Vec3::one() * 1.06;
next.main.offset = Vec3::new(6.0, 7.0, 0.0); next.main.offset = Vec3::new(0.0, 0.0, 0.0);
next.main.ori = Quaternion::rotation_x(0.3) next.main.ori = Quaternion::rotation_x(0.0)
* Quaternion::rotation_y(-1.35) * Quaternion::rotation_y(-1.57)
* Quaternion::rotation_z(1.57); * Quaternion::rotation_z(1.57);
next.head.offset = next.head.offset =
Vec3::new(0.0, -2.0 + skeleton_attr.head.0, skeleton_attr.head.1); Vec3::new(0.0, -2.0 + skeleton_attr.head.0, skeleton_attr.head.1);
next.head.ori = Quaternion::rotation_z(slower * 0.05) next.head.ori = Quaternion::rotation_z(slower * 0.03)
* Quaternion::rotation_x(0.0 + slower * 0.05) * Quaternion::rotation_x(slowersmooth * 0.1)
* Quaternion::rotation_y(slower * 0.05); * Quaternion::rotation_y(slower * 0.05 + slowersmooth * 0.06)
* Quaternion::rotation_z((slowersmooth * -0.4).max(0.0));
next.head.scale = Vec3::one() * skeleton_attr.head_scale; next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 7.0); next.chest.offset = Vec3::new(0.0, 0.0, 7.0);
next.chest.ori = Quaternion::rotation_z(slower * 0.2) next.chest.ori = Quaternion::rotation_z(slower * 0.18 + slowersmooth * 0.15)
* Quaternion::rotation_x(0.0 + slower * 0.2) * Quaternion::rotation_x(0.0 + slower * 0.18 + slowersmooth * 0.15)
* Quaternion::rotation_y(slower * 0.2); * Quaternion::rotation_y(slower * 0.18 + slowersmooth * 0.15);
next.belt.offset = Vec3::new(0.0, 0.0, -2.0); next.belt.offset = Vec3::new(0.0, 0.0, -2.0);
next.belt.ori = next.chest.ori * -0.2; next.belt.ori = Quaternion::rotation_z(slower * -0.1 + slowersmooth * -0.075)
* Quaternion::rotation_x(0.0 + slower * -0.1)
* Quaternion::rotation_y(slower * -0.1);
next.shorts.offset = Vec3::new(0.0, 0.0, -5.0); next.shorts.offset = Vec3::new(0.0, 0.0, -5.0);
next.shorts.ori = next.chest.ori * -0.15; next.shorts.ori = Quaternion::rotation_z(slower * -0.1 + slowersmooth * -0.075)
* Quaternion::rotation_x(0.0 + slower * -0.1)
* Quaternion::rotation_y(slower * -0.1);
next.lantern.ori = Quaternion::rotation_x(slower * -0.7 + 0.4) next.lantern.ori = Quaternion::rotation_x(slower * -0.7 + 0.4)
* Quaternion::rotation_y(slower * 0.4); * Quaternion::rotation_y(slower * 0.4);
@ -299,15 +305,15 @@ impl Animation for AlphaAnimation {
if velocity > 0.5 { if velocity > 0.5 {
next.l_foot.offset = next.l_foot.offset =
Vec3::new(-skeleton_attr.foot.0, foot * -2.0, skeleton_attr.foot.2); Vec3::new(-skeleton_attr.foot.0, foot * -6.0, skeleton_attr.foot.2);
next.l_foot.ori = Quaternion::rotation_x(foot * -0.4) next.l_foot.ori = Quaternion::rotation_x(foot * -0.4)
* Quaternion::rotation_z((slower * 0.6).max(0.0)); * Quaternion::rotation_z((slower * 0.3).max(0.0));
next.l_foot.scale = Vec3::one(); next.l_foot.scale = Vec3::one();
next.r_foot.offset = next.r_foot.offset =
Vec3::new(skeleton_attr.foot.0, foot * 2.0, skeleton_attr.foot.2); Vec3::new(skeleton_attr.foot.0, foot * 6.0, skeleton_attr.foot.2);
next.r_foot.ori = Quaternion::rotation_x(foot * 0.4) next.r_foot.ori = Quaternion::rotation_x(foot * 0.4)
* Quaternion::rotation_z((slower * 0.6).max(0.0)); * Quaternion::rotation_z((slower * 0.3).max(0.0));
next.r_foot.scale = Vec3::one(); next.r_foot.scale = Vec3::one();
next.torso.offset = Vec3::new(0.0, 0.0, 0.1) * skeleton_attr.scaler; 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.15); next.torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(-0.15);
@ -335,10 +341,15 @@ impl Animation for AlphaAnimation {
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler; next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
} }
next.control.offset = Vec3::new(-4.0, 3.0 + slower * 2.0, 5.0 + slower * 5.0); //next.control.offset = Vec3::new(-4.0, 3.0 + slower * 2.0, 5.0 + slower *
next.control.ori = Quaternion::rotation_x(-0.7 + slower * 1.8) // 5.0); next.control.ori = Quaternion::rotation_x()
* Quaternion::rotation_y(0.0) // * Quaternion::rotation_y(0.0)
* Quaternion::rotation_z(1.4); // * Quaternion::rotation_z(1.4);
next.control.scale = Vec3::one();
next.control.offset = Vec3::new(-8.0, 7.0, 1.0);
next.control.ori = Quaternion::rotation_x(-1.5 + slower * 1.5)
* Quaternion::rotation_y(slowersmooth * 0.35 - 0.3)
* Quaternion::rotation_z(1.4 + slowersmooth * 0.2);
next.control.scale = Vec3::one(); next.control.scale = Vec3::one();
next.torso.offset = Vec3::new(0.0, 0.0, 0.1) * skeleton_attr.scaler; next.torso.offset = Vec3::new(0.0, 0.0, 0.1) * skeleton_attr.scaler;

View File

@ -0,0 +1,118 @@
use super::{super::Animation, CharacterSkeleton, SkeletonAttr};
use common::comp::item::{Hands, ToolKind};
/* use std::f32::consts::PI; */
use vek::*;
pub struct LeapAnimation;
impl Animation for LeapAnimation {
type Dependency = (Option<ToolKind>, Option<ToolKind>, Vec3<f32>, f64);
type Skeleton = CharacterSkeleton;
#[cfg(feature = "use-dyn-lib")]
const UPDATE_FN: &'static [u8] = b"character_leapmelee\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "character_leapmelee")]
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
fn update_skeleton_inner(
skeleton: &Self::Skeleton,
(active_tool_kind, second_tool_kind, _velocity, _global_time): Self::Dependency,
anim_time: f64,
rate: &mut f32,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
*rate = 1.0;
let mut next = (*skeleton).clone();
let lab = 1.0;
let slowersmooth = (anim_time as f32 * lab as f32 * 4.0).sin();
let slower = (((1.0)
/ (0.0001 + 0.999 * ((anim_time as f32 * lab as f32 * 4.0).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 * 4.0).sin());
if let Some(ToolKind::Hammer(_)) = active_tool_kind {
next.l_hand.offset = Vec3::new(-12.0, 0.0, 0.0);
next.l_hand.ori = Quaternion::rotation_x(-0.0) * Quaternion::rotation_y(0.0);
next.l_hand.scale = Vec3::one() * 1.08;
next.r_hand.offset = Vec3::new(3.0, 0.0, 0.0);
next.r_hand.ori = Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
next.r_hand.scale = Vec3::one() * 1.06;
next.main.offset = Vec3::new(0.0, 0.0, 0.0);
next.main.ori = Quaternion::rotation_x(0.0)
* Quaternion::rotation_y(-1.57)
* Quaternion::rotation_z(1.57);
next.head.offset = Vec3::new(
0.0,
-2.0 + skeleton_attr.head.0 + slower * -1.0,
skeleton_attr.head.1,
);
next.head.ori = Quaternion::rotation_z(slower * 0.05)
* Quaternion::rotation_x((slowersmooth * -0.25 + slower * 0.55).max(-0.2))
* Quaternion::rotation_y(slower * 0.05);
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 7.0);
next.chest.ori = Quaternion::rotation_z(slower * 0.08 + slowersmooth * 0.15)
* Quaternion::rotation_x(-0.3 + slower * 0.45 + slowersmooth * 0.26)
* Quaternion::rotation_y(slower * 0.18 + slowersmooth * 0.15);
next.belt.offset = Vec3::new(0.0, 0.0, -2.0 + slower * -0.7);
next.belt.ori = Quaternion::rotation_z(slower * -0.16 + slowersmooth * -0.12)
* Quaternion::rotation_x(0.0 + slower * -0.06)
* Quaternion::rotation_y(slower * -0.05);
next.shorts.offset = Vec3::new(0.0, 0.0, -5.0 + slower * -0.7);
next.shorts.ori = Quaternion::rotation_z(slower * -0.08 + slowersmooth * -0.08)
* Quaternion::rotation_x(0.0 + slower * -0.08 + slowersmooth * -0.08)
* Quaternion::rotation_y(slower * -0.07);
next.lantern.ori =
Quaternion::rotation_x(slower * -0.7 + 0.4) * Quaternion::rotation_y(slower * 0.4);
next.l_foot.offset = Vec3::new(
-skeleton_attr.foot.0,
slower * 3.0 + slowersmooth * -6.0 - 2.0,
skeleton_attr.foot.2,
);
next.l_foot.ori = Quaternion::rotation_x(slower * -0.2 + slowersmooth * -0.3 - 0.2);
next.r_foot.offset = Vec3::new(
skeleton_attr.foot.0,
slower * 2.0 + slowersmooth * -4.0 - 1.0,
-2.0 + skeleton_attr.foot.2,
);
next.r_foot.ori = Quaternion::rotation_x(slower * -0.4 + slowersmooth * -0.6 - 1.0);
next.control.scale = Vec3::one();
next.control.offset = Vec3::new(-7.0, 7.0, 1.0);
next.control.ori = Quaternion::rotation_x(-0.7 + slower * 1.5)
* Quaternion::rotation_y(0.0)
* Quaternion::rotation_z(1.4 + slowersmooth * -0.4 + slower * 0.2);
next.control.scale = Vec3::one();
}
next.lantern.offset = Vec3::new(
skeleton_attr.lantern.0,
skeleton_attr.lantern.1,
skeleton_attr.lantern.2,
);
next.glider.offset = Vec3::new(0.0, 0.0, 10.0);
next.glider.scale = Vec3::one() * 0.0;
next.l_control.scale = Vec3::one();
next.r_control.scale = Vec3::one();
next.second.scale = match (
active_tool_kind.map(|tk| tk.into_hands()),
second_tool_kind.map(|tk| tk.into_hands()),
) {
(Some(Hands::OneHand), Some(Hands::OneHand)) => Vec3::one(),
(_, _) => Vec3::zero(),
};
next.torso.offset = Vec3::new(0.0, 0.0, 0.0) * skeleton_attr.scaler;
next.torso.ori = Quaternion::rotation_z(0.0);
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next
}
}

View File

@ -11,6 +11,7 @@ pub mod glidewield;
pub mod gliding; pub mod gliding;
pub mod idle; pub mod idle;
pub mod jump; pub mod jump;
pub mod leapmelee;
pub mod roll; pub mod roll;
pub mod run; pub mod run;
pub mod shoot; pub mod shoot;
@ -26,9 +27,9 @@ pub use self::{
blockidle::BlockIdleAnimation, charge::ChargeAnimation, climb::ClimbAnimation, blockidle::BlockIdleAnimation, charge::ChargeAnimation, climb::ClimbAnimation,
dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation, dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation,
glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation, glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation,
jump::JumpAnimation, roll::RollAnimation, run::RunAnimation, shoot::ShootAnimation, jump::JumpAnimation, leapmelee::LeapAnimation, roll::RollAnimation, run::RunAnimation,
sit::SitAnimation, spin::SpinAnimation, stand::StandAnimation, swim::SwimAnimation, shoot::ShootAnimation, sit::SitAnimation, spin::SpinAnimation, stand::StandAnimation,
wield::WieldAnimation, swim::SwimAnimation, wield::WieldAnimation,
}; };
use super::{Bone, FigureBoneData, Skeleton}; use super::{Bone, FigureBoneData, Skeleton};

View File

@ -194,19 +194,19 @@ impl Animation for WieldAnimation {
next.control.scale = Vec3::one(); next.control.scale = Vec3::one();
}, },
Some(ToolKind::Hammer(_)) => { Some(ToolKind::Hammer(_)) => {
next.l_hand.offset = Vec3::new(-7.0, 5.5, 3.5); next.l_hand.offset = Vec3::new(-12.0, 0.0, 0.0);
next.l_hand.ori = Quaternion::rotation_x(0.3) * Quaternion::rotation_y(0.32); next.l_hand.ori = Quaternion::rotation_x(-0.0) * Quaternion::rotation_y(0.0);
next.l_hand.scale = Vec3::one() * 1.08; next.l_hand.scale = Vec3::one() * 1.08;
next.r_hand.offset = Vec3::new(8.0, 7.75, 0.0); next.r_hand.offset = Vec3::new(2.0, 0.0, 0.0);
next.r_hand.ori = Quaternion::rotation_x(0.3) * Quaternion::rotation_y(0.22); next.r_hand.ori = Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
next.r_hand.scale = Vec3::one() * 1.06; next.r_hand.scale = Vec3::one() * 1.06;
next.main.offset = Vec3::new(6.0, 7.0, 0.0); next.main.offset = Vec3::new(0.0, 0.0, 0.0);
next.main.ori = Quaternion::rotation_x(0.3) next.main.ori = Quaternion::rotation_x(0.0)
* Quaternion::rotation_y(-1.35) * Quaternion::rotation_y(-1.57)
* Quaternion::rotation_z(1.57); * Quaternion::rotation_z(1.57);
next.control.offset = Vec3::new(0.0, 0.0, 0.0); next.control.offset = Vec3::new(6.0, 7.0, 1.0);
next.control.ori = Quaternion::rotation_x(u_slow * 0.15) next.control.ori = Quaternion::rotation_x(0.3 + u_slow * 0.15)
* Quaternion::rotation_y(0.0) * Quaternion::rotation_y(0.0)
* Quaternion::rotation_z(u_slowalt * 0.08); * Quaternion::rotation_z(u_slowalt * 0.08);
next.control.scale = Vec3::one(); next.control.scale = Vec3::one();

View File

@ -116,6 +116,7 @@ image_ids! {
flyingrod_m1: "voxygen.element.icons.debug_wand_m1", flyingrod_m1: "voxygen.element.icons.debug_wand_m1",
flyingrod_m2: "voxygen.element.icons.debug_wand_m2", flyingrod_m2: "voxygen.element.icons.debug_wand_m2",
charge: "voxygen.element.icons.skill_charge_3", charge: "voxygen.element.icons.skill_charge_3",
hammerleap: "voxygen.element.icons.skill_hammerleap",
// Skillbar // Skillbar
level_up: "voxygen.element.misc_bg.level_up", level_up: "voxygen.element.misc_bg.level_up",
@ -136,7 +137,6 @@ image_ids! {
skillbar_slot_l_act: "voxygen.element.skillbar.skillbar_slot_l_active", skillbar_slot_l_act: "voxygen.element.skillbar.skillbar_slot_l_active",
skillbar_slot_r_act: "voxygen.element.skillbar.skillbar_slot_r_active", skillbar_slot_r_act: "voxygen.element.skillbar.skillbar_slot_r_active",
// Other Icons/Art // Other Icons/Art
skull: "voxygen.element.icons.skull", skull: "voxygen.element.icons.skull",
skull_2: "voxygen.element.icons.skull_2", skull_2: "voxygen.element.icons.skull_2",

View File

@ -707,7 +707,7 @@ impl<'a> Widget for Skillbar<'a> {
Some(ToolKind::Sword(_)) => self.imgs.charge, Some(ToolKind::Sword(_)) => self.imgs.charge,
Some(ToolKind::Dagger(_)) => self.imgs.onehdagger_m2, Some(ToolKind::Dagger(_)) => self.imgs.onehdagger_m2,
Some(ToolKind::Shield(_)) => self.imgs.onehshield_m2, Some(ToolKind::Shield(_)) => self.imgs.onehshield_m2,
Some(ToolKind::Hammer(_)) => self.imgs.nothing, Some(ToolKind::Hammer(_)) => self.imgs.hammerleap,
Some(ToolKind::Axe(_)) => self.imgs.nothing, Some(ToolKind::Axe(_)) => self.imgs.nothing,
Some(ToolKind::Bow(_)) => self.imgs.bow_m2, Some(ToolKind::Bow(_)) => self.imgs.bow_m2,
Some(ToolKind::Staff(StaffKind::Sceptre)) => self.imgs.heal_0, Some(ToolKind::Staff(StaffKind::Sceptre)) => self.imgs.heal_0,

View File

@ -674,6 +674,15 @@ impl FigureMgr {
skeleton_attr, skeleton_attr,
) )
}, },
CharacterState::LeapMelee(_) => {
anim::character::LeapAnimation::update_skeleton(
&target_base,
(active_tool_kind, second_tool_kind, vel.0, time),
state.state_time,
&mut state_animation_rate,
skeleton_attr,
)
},
CharacterState::TripleStrike(s) => match s.stage { CharacterState::TripleStrike(s) => match s.stage {
triple_strike::Stage::First => { triple_strike::Stage::First => {
anim::character::AlphaAnimation::update_skeleton( anim::character::AlphaAnimation::update_skeleton(