mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'james/hammer-axe-bow-skillz' into 'master'
Add 3rd skill for hammer, bow, and axe Closes #766, #765, and #764 See merge request veloren/veloren!1399
This commit is contained in:
commit
4a90f7c088
@ -21,6 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Theropod body
|
||||
- Several new animals
|
||||
- Item quality indicators
|
||||
- Added a jump/burst attack for the bow to the skillbar
|
||||
- Gave the axe a third attack
|
||||
- A new secondary charged melee attack for the hammer
|
||||
|
||||
### Changed
|
||||
|
||||
@ -46,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Reworked healing sceptre
|
||||
- Split out the sections of the server settings that can be edited and saved by the server.
|
||||
- Revamped structure of where settings, logs, and game saves are stored so that almost everything is in one place.
|
||||
- Moved hammer leap attack to skillbar
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -73,7 +73,6 @@
|
||||
),
|
||||
GliderClose: (
|
||||
files: [
|
||||
// Event Missing or not implemented?
|
||||
"voxygen.audio.sfx.glider_close",
|
||||
],
|
||||
threshold: 0.5,
|
||||
@ -112,12 +111,18 @@
|
||||
],
|
||||
threshold: 0.7,
|
||||
),
|
||||
Attack(DashMelee, Sword): (
|
||||
Attack(DashMelee(Swing), Sword): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.sword_dash",
|
||||
],
|
||||
threshold: 0.8,
|
||||
),
|
||||
Attack(SpinMelee(Swing), Sword): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.swing_sword",
|
||||
],
|
||||
threshold: 0.7,
|
||||
),
|
||||
Inventory(CollectedTool(Sword)): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.inventory.pickup_sword",
|
||||
@ -146,9 +151,15 @@
|
||||
],
|
||||
threshold: 0.7,
|
||||
),
|
||||
Attack(LeapMelee, Hammer): (
|
||||
Attack(ChargedMelee(Swing), Hammer): (
|
||||
files: [
|
||||
//
|
||||
"voxygen.audio.sfx.abilities.swing",
|
||||
],
|
||||
threshold: 0.7,
|
||||
),
|
||||
Attack(LeapMelee(Swing), Hammer): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.swing",
|
||||
],
|
||||
threshold: 0.8,
|
||||
),
|
||||
@ -180,7 +191,13 @@
|
||||
],
|
||||
threshold: 0.7,
|
||||
),
|
||||
Attack(SpinMelee, Axe): (
|
||||
Attack(SpinMelee(Swing), Axe): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.swing",
|
||||
],
|
||||
threshold: 0.8,
|
||||
),
|
||||
Attack(LeapMelee(Swing), Axe): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.swing",
|
||||
],
|
||||
@ -276,7 +293,7 @@
|
||||
],
|
||||
threshold: 0.8,
|
||||
),
|
||||
Attack(DashMelee, Dagger): (
|
||||
Attack(DashMelee(Swing), Dagger): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.sword_dash",
|
||||
],
|
||||
|
BIN
assets/voxygen/element/icons/2hhammer_m1.png
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/2hhammer_m1.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/icons/skill_axe_leap_slash.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/icons/skill_axe_leap_slash.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/icons/skill_bow_jump_burst.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/icons/skill_bow_jump_burst.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/icons/skill_hammergolf.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/icons/skill_hammergolf.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/icons/skill_hammerleap.png
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/skill_hammerleap.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/icons/sword_whirlwind.png
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/sword_whirlwind.png
(Stored with Git LFS)
Binary file not shown.
@ -18,14 +18,16 @@ pub enum CharacterAbilityType {
|
||||
BasicMelee,
|
||||
BasicRanged,
|
||||
Boost,
|
||||
ChargedMelee(StageSection),
|
||||
ChargedRanged,
|
||||
DashMelee,
|
||||
DashMelee(StageSection),
|
||||
BasicBlock,
|
||||
ComboMelee(StageSection, u32),
|
||||
LeapMelee,
|
||||
SpinMelee,
|
||||
LeapMelee(StageSection),
|
||||
SpinMelee(StageSection),
|
||||
GroundShockwave,
|
||||
BasicBeam,
|
||||
RepeaterRanged,
|
||||
}
|
||||
|
||||
impl From<&CharacterState> for CharacterAbilityType {
|
||||
@ -34,14 +36,16 @@ impl From<&CharacterState> for CharacterAbilityType {
|
||||
CharacterState::BasicMelee(_) => Self::BasicMelee,
|
||||
CharacterState::BasicRanged(_) => Self::BasicRanged,
|
||||
CharacterState::Boost(_) => Self::Boost,
|
||||
CharacterState::DashMelee(_) => Self::DashMelee,
|
||||
CharacterState::DashMelee(data) => Self::DashMelee(data.stage_section),
|
||||
CharacterState::BasicBlock => Self::BasicBlock,
|
||||
CharacterState::LeapMelee(_) => Self::LeapMelee,
|
||||
CharacterState::LeapMelee(data) => Self::LeapMelee(data.stage_section),
|
||||
CharacterState::ComboMelee(data) => Self::ComboMelee(data.stage_section, data.stage),
|
||||
CharacterState::SpinMelee(_) => Self::SpinMelee,
|
||||
CharacterState::SpinMelee(data) => Self::SpinMelee(data.stage_section),
|
||||
CharacterState::ChargedMelee(data) => Self::ChargedMelee(data.stage_section),
|
||||
CharacterState::ChargedRanged(_) => Self::ChargedRanged,
|
||||
CharacterState::GroundShockwave(_) => Self::ChargedRanged,
|
||||
CharacterState::BasicBeam(_) => Self::BasicBeam,
|
||||
CharacterState::RepeaterRanged(_) => Self::RepeaterRanged,
|
||||
_ => Self::BasicMelee,
|
||||
}
|
||||
}
|
||||
@ -69,6 +73,20 @@ pub enum CharacterAbility {
|
||||
projectile_gravity: Option<Gravity>,
|
||||
projectile_speed: f32,
|
||||
},
|
||||
RepeaterRanged {
|
||||
energy_cost: u32,
|
||||
movement_duration: Duration,
|
||||
buildup_duration: Duration,
|
||||
shoot_duration: Duration,
|
||||
recover_duration: Duration,
|
||||
leap: Option<f32>,
|
||||
projectile: Projectile,
|
||||
projectile_body: Body,
|
||||
projectile_light: Option<LightEmitter>,
|
||||
projectile_gravity: Option<Gravity>,
|
||||
projectile_speed: f32,
|
||||
reps_remaining: u32,
|
||||
},
|
||||
Boost {
|
||||
duration: Duration,
|
||||
only_up: bool,
|
||||
@ -103,10 +121,16 @@ pub enum CharacterAbility {
|
||||
},
|
||||
LeapMelee {
|
||||
energy_cost: u32,
|
||||
movement_duration: Duration,
|
||||
buildup_duration: Duration,
|
||||
movement_duration: Duration,
|
||||
swing_duration: Duration,
|
||||
recover_duration: Duration,
|
||||
base_damage: u32,
|
||||
range: f32,
|
||||
max_angle: f32,
|
||||
knockback: f32,
|
||||
forward_leap_strength: f32,
|
||||
vertical_leap_strength: f32,
|
||||
},
|
||||
SpinMelee {
|
||||
buildup_duration: Duration,
|
||||
@ -122,6 +146,19 @@ pub enum CharacterAbility {
|
||||
forward_speed: f32,
|
||||
num_spins: u32,
|
||||
},
|
||||
ChargedMelee {
|
||||
energy_cost: u32,
|
||||
energy_drain: u32,
|
||||
initial_damage: u32,
|
||||
max_damage: u32,
|
||||
initial_knockback: f32,
|
||||
max_knockback: f32,
|
||||
range: f32,
|
||||
max_angle: f32,
|
||||
charge_duration: Duration,
|
||||
swing_duration: Duration,
|
||||
recover_duration: Duration,
|
||||
},
|
||||
ChargedRanged {
|
||||
energy_cost: u32,
|
||||
energy_drain: u32,
|
||||
@ -203,6 +240,14 @@ impl CharacterAbility {
|
||||
.energy
|
||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||
.is_ok(),
|
||||
CharacterAbility::ChargedMelee { energy_cost, .. } => update
|
||||
.energy
|
||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||
.is_ok(),
|
||||
CharacterAbility::RepeaterRanged { energy_cost, .. } => update
|
||||
.energy
|
||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||
.is_ok(),
|
||||
CharacterAbility::GroundShockwave { energy_cost, .. } => update
|
||||
.energy
|
||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||
@ -420,17 +465,32 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
}),
|
||||
CharacterAbility::LeapMelee {
|
||||
energy_cost: _,
|
||||
movement_duration,
|
||||
buildup_duration,
|
||||
movement_duration,
|
||||
swing_duration,
|
||||
recover_duration,
|
||||
base_damage,
|
||||
knockback,
|
||||
range,
|
||||
max_angle,
|
||||
forward_leap_strength,
|
||||
vertical_leap_strength,
|
||||
} => CharacterState::LeapMelee(leap_melee::Data {
|
||||
initialize: true,
|
||||
static_data: leap_melee::StaticData {
|
||||
buildup_duration: *buildup_duration,
|
||||
movement_duration: *movement_duration,
|
||||
swing_duration: *swing_duration,
|
||||
recover_duration: *recover_duration,
|
||||
base_damage: *base_damage,
|
||||
knockback: *knockback,
|
||||
range: *range,
|
||||
max_angle: *max_angle,
|
||||
forward_leap_strength: *forward_leap_strength,
|
||||
vertical_leap_strength: *vertical_leap_strength,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
exhausted: false,
|
||||
movement_duration: *movement_duration,
|
||||
buildup_duration: *buildup_duration,
|
||||
recover_duration: *recover_duration,
|
||||
base_damage: *base_damage,
|
||||
}),
|
||||
CharacterAbility::SpinMelee {
|
||||
buildup_duration,
|
||||
@ -465,6 +525,37 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
stage_section: StageSection::Buildup,
|
||||
exhausted: false,
|
||||
}),
|
||||
CharacterAbility::ChargedMelee {
|
||||
energy_cost,
|
||||
energy_drain,
|
||||
initial_damage,
|
||||
max_damage,
|
||||
initial_knockback,
|
||||
max_knockback,
|
||||
charge_duration,
|
||||
swing_duration,
|
||||
recover_duration,
|
||||
range,
|
||||
max_angle,
|
||||
} => CharacterState::ChargedMelee(charged_melee::Data {
|
||||
static_data: charged_melee::StaticData {
|
||||
energy_cost: *energy_cost,
|
||||
energy_drain: *energy_drain,
|
||||
initial_damage: *initial_damage,
|
||||
max_damage: *max_damage,
|
||||
initial_knockback: *initial_knockback,
|
||||
max_knockback: *max_knockback,
|
||||
range: *range,
|
||||
max_angle: *max_angle,
|
||||
charge_duration: *charge_duration,
|
||||
swing_duration: *swing_duration,
|
||||
recover_duration: *recover_duration,
|
||||
},
|
||||
stage_section: StageSection::Charge,
|
||||
timer: Duration::default(),
|
||||
exhausted: false,
|
||||
charge_amount: 0.0,
|
||||
}),
|
||||
CharacterAbility::ChargedRanged {
|
||||
energy_cost: _,
|
||||
energy_drain,
|
||||
@ -497,6 +588,36 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
initial_projectile_speed: *initial_projectile_speed,
|
||||
max_projectile_speed: *max_projectile_speed,
|
||||
}),
|
||||
CharacterAbility::RepeaterRanged {
|
||||
energy_cost: _,
|
||||
movement_duration,
|
||||
buildup_duration,
|
||||
shoot_duration,
|
||||
recover_duration,
|
||||
leap,
|
||||
projectile,
|
||||
projectile_body,
|
||||
projectile_light,
|
||||
projectile_gravity,
|
||||
projectile_speed,
|
||||
reps_remaining,
|
||||
} => CharacterState::RepeaterRanged(repeater_ranged::Data {
|
||||
static_data: repeater_ranged::StaticData {
|
||||
movement_duration: *movement_duration,
|
||||
buildup_duration: *buildup_duration,
|
||||
shoot_duration: *shoot_duration,
|
||||
recover_duration: *recover_duration,
|
||||
leap: *leap,
|
||||
projectile: projectile.clone(),
|
||||
projectile_body: *projectile_body,
|
||||
projectile_light: *projectile_light,
|
||||
projectile_gravity: *projectile_gravity,
|
||||
projectile_speed: *projectile_speed,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Movement,
|
||||
reps_remaining: *reps_remaining,
|
||||
}),
|
||||
CharacterAbility::GroundShockwave {
|
||||
energy_cost: _,
|
||||
buildup_duration,
|
||||
|
@ -69,6 +69,10 @@ pub enum CharacterState {
|
||||
SpinMelee(spin_melee::Data),
|
||||
/// A charged ranged attack (e.g. bow)
|
||||
ChargedRanged(charged_ranged::Data),
|
||||
/// A charged melee attack
|
||||
ChargedMelee(charged_melee::Data),
|
||||
/// A repeating ranged attack
|
||||
RepeaterRanged(repeater_ranged::Data),
|
||||
/// A ground shockwave attack
|
||||
GroundShockwave(ground_shockwave::Data),
|
||||
/// A continuous attack that affects all creatures in a cone originating
|
||||
@ -87,7 +91,9 @@ impl CharacterState {
|
||||
| CharacterState::BasicBlock
|
||||
| CharacterState::LeapMelee(_)
|
||||
| CharacterState::SpinMelee(_)
|
||||
| CharacterState::ChargedMelee(_)
|
||||
| CharacterState::ChargedRanged(_)
|
||||
| CharacterState::RepeaterRanged(_)
|
||||
| CharacterState::GroundShockwave(_)
|
||||
| CharacterState::BasicBeam(_)
|
||||
)
|
||||
@ -101,7 +107,9 @@ impl CharacterState {
|
||||
| CharacterState::ComboMelee(_)
|
||||
| CharacterState::LeapMelee(_)
|
||||
| CharacterState::SpinMelee(_)
|
||||
| CharacterState::ChargedMelee(_)
|
||||
| CharacterState::ChargedRanged(_)
|
||||
| CharacterState::RepeaterRanged(_)
|
||||
| CharacterState::GroundShockwave(_)
|
||||
| CharacterState::BasicBeam(_)
|
||||
)
|
||||
@ -115,7 +123,9 @@ impl CharacterState {
|
||||
| CharacterState::ComboMelee(_)
|
||||
| CharacterState::BasicBlock
|
||||
| CharacterState::LeapMelee(_)
|
||||
| CharacterState::ChargedMelee(_)
|
||||
| CharacterState::ChargedRanged(_)
|
||||
| CharacterState::RepeaterRanged(_)
|
||||
| CharacterState::GroundShockwave(_)
|
||||
| CharacterState::BasicBeam(_)
|
||||
)
|
||||
|
@ -226,6 +226,19 @@ impl Tool {
|
||||
forward_speed: 0.0,
|
||||
num_spins: 1,
|
||||
},
|
||||
LeapMelee {
|
||||
energy_cost: 450,
|
||||
buildup_duration: Duration::from_millis(200),
|
||||
movement_duration: Duration::from_millis(200),
|
||||
swing_duration: Duration::from_millis(200),
|
||||
recover_duration: Duration::from_millis(200),
|
||||
base_damage: (240.0 * self.base_power()) as u32,
|
||||
knockback: 12.0,
|
||||
range: 4.5,
|
||||
max_angle: 30.0,
|
||||
forward_leap_strength: 28.0,
|
||||
vertical_leap_strength: 8.0,
|
||||
},
|
||||
],
|
||||
Hammer(_) => vec![
|
||||
BasicMelee {
|
||||
@ -237,12 +250,31 @@ impl Tool {
|
||||
range: 3.5,
|
||||
max_angle: 20.0,
|
||||
},
|
||||
LeapMelee {
|
||||
energy_cost: 800,
|
||||
movement_duration: Duration::from_millis(500),
|
||||
buildup_duration: Duration::from_millis(1000),
|
||||
ChargedMelee {
|
||||
energy_cost: 1,
|
||||
energy_drain: 300,
|
||||
initial_damage: (10.0 * self.base_power()) as u32,
|
||||
max_damage: (170.0 * self.base_power()) as u32,
|
||||
initial_knockback: 10.0,
|
||||
max_knockback: 60.0,
|
||||
range: 3.5,
|
||||
max_angle: 30.0,
|
||||
charge_duration: Duration::from_millis(1200),
|
||||
swing_duration: Duration::from_millis(400),
|
||||
recover_duration: Duration::from_millis(100),
|
||||
},
|
||||
LeapMelee {
|
||||
energy_cost: 700,
|
||||
buildup_duration: Duration::from_millis(100),
|
||||
movement_duration: Duration::from_millis(800),
|
||||
swing_duration: Duration::from_millis(150),
|
||||
recover_duration: Duration::from_millis(200),
|
||||
base_damage: (240.0 * self.base_power()) as u32,
|
||||
knockback: 25.0,
|
||||
range: 4.5,
|
||||
max_angle: 360.0,
|
||||
forward_leap_strength: 28.0,
|
||||
vertical_leap_strength: 8.0,
|
||||
},
|
||||
],
|
||||
Farming(_) => vec![BasicMelee {
|
||||
@ -293,6 +325,31 @@ impl Tool {
|
||||
initial_projectile_speed: 100.0,
|
||||
max_projectile_speed: 500.0,
|
||||
},
|
||||
RepeaterRanged {
|
||||
energy_cost: 450,
|
||||
movement_duration: Duration::from_millis(300),
|
||||
buildup_duration: Duration::from_millis(200),
|
||||
shoot_duration: Duration::from_millis(200),
|
||||
recover_duration: Duration::from_millis(800),
|
||||
leap: Some(10.0),
|
||||
projectile: Projectile {
|
||||
hit_solid: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage((-40.0 * self.base_power()) as i32),
|
||||
projectile::Effect::Knockback(10.0),
|
||||
projectile::Effect::RewardEnergy(50),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(15),
|
||||
owner: None,
|
||||
ignore_group: true,
|
||||
},
|
||||
projectile_body: Body::Object(object::Body::Arrow),
|
||||
projectile_light: None,
|
||||
projectile_gravity: Some(Gravity(0.2)),
|
||||
projectile_speed: 100.0,
|
||||
reps_remaining: 5,
|
||||
},
|
||||
],
|
||||
Dagger(_) => vec![BasicMelee {
|
||||
energy_cost: 0,
|
||||
|
200
common/src/states/charged_melee.rs
Normal file
200
common/src/states/charged_melee.rs
Normal file
@ -0,0 +1,200 @@
|
||||
use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::{StageSection, *},
|
||||
sys::character_behavior::*,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
/// Separated out to condense update portions of character state
|
||||
pub struct StaticData {
|
||||
/// How much energy is drained per second when charging
|
||||
pub energy_drain: u32,
|
||||
/// Energy cost per attack
|
||||
pub energy_cost: u32,
|
||||
/// How much damage is dealt with no charge
|
||||
pub initial_damage: u32,
|
||||
/// How much damage is dealt with max charge
|
||||
pub max_damage: u32,
|
||||
/// How much knockback there is with no charge
|
||||
pub initial_knockback: f32,
|
||||
/// How much knockback there is at max charge
|
||||
pub max_knockback: f32,
|
||||
/// Max range
|
||||
pub range: f32,
|
||||
/// Max angle (45.0 will give you a 90.0 angle window)
|
||||
pub max_angle: f32,
|
||||
/// How long it takes to charge the weapon to max damage and knockback
|
||||
pub charge_duration: Duration,
|
||||
/// How long the weapon is swinging for
|
||||
pub swing_duration: Duration,
|
||||
/// How long the state has until exiting
|
||||
pub recover_duration: Duration,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
/// Struct containing data that does not change over the course of the
|
||||
/// character state
|
||||
pub static_data: StaticData,
|
||||
/// Checks what section a stage is in
|
||||
pub stage_section: StageSection,
|
||||
/// Timer for each stage
|
||||
pub timer: Duration,
|
||||
/// Whether the attack fired already
|
||||
pub exhausted: bool,
|
||||
/// How much the attack charged by
|
||||
pub charge_amount: f32,
|
||||
}
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
handle_move(data, &mut update, 0.7);
|
||||
handle_jump(data, &mut update);
|
||||
|
||||
match self.stage_section {
|
||||
StageSection::Charge => {
|
||||
if data.inputs.secondary.is_pressed()
|
||||
&& update.energy.current() >= self.static_data.energy_cost
|
||||
&& self.timer < self.static_data.charge_duration
|
||||
{
|
||||
let charge = (self.timer.as_secs_f32()
|
||||
/ self.static_data.charge_duration.as_secs_f32())
|
||||
.min(1.0);
|
||||
|
||||
// Charge the attack
|
||||
update.character = CharacterState::ChargedMelee(Data {
|
||||
static_data: self.static_data,
|
||||
stage_section: self.stage_section,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
exhausted: self.exhausted,
|
||||
charge_amount: charge,
|
||||
});
|
||||
|
||||
// Consumes energy if there's enough left and RMB is held down
|
||||
update.energy.change_by(
|
||||
-(self.static_data.energy_drain as f32 * data.dt.0) as i32,
|
||||
EnergySource::Ability,
|
||||
);
|
||||
} else if data.inputs.secondary.is_pressed()
|
||||
&& update.energy.current() >= self.static_data.energy_cost
|
||||
{
|
||||
// Maintains charge
|
||||
update.character = CharacterState::ChargedMelee(Data {
|
||||
static_data: self.static_data,
|
||||
stage_section: self.stage_section,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
exhausted: self.exhausted,
|
||||
charge_amount: self.charge_amount,
|
||||
});
|
||||
|
||||
// Consumes energy if there's enough left and RMB is held down
|
||||
update.energy.change_by(
|
||||
-(self.static_data.energy_drain as f32 * data.dt.0 / 5.0) as i32,
|
||||
EnergySource::Ability,
|
||||
);
|
||||
} else {
|
||||
// Transitions to swing
|
||||
update.character = CharacterState::ChargedMelee(Data {
|
||||
static_data: self.static_data,
|
||||
stage_section: StageSection::Swing,
|
||||
timer: Duration::default(),
|
||||
exhausted: self.exhausted,
|
||||
charge_amount: self.charge_amount,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Swing => {
|
||||
if !self.exhausted {
|
||||
let damage = self.static_data.initial_damage
|
||||
+ ((self.static_data.max_damage - self.static_data.initial_damage) as f32
|
||||
* self.charge_amount) as u32;
|
||||
let knockback = self.static_data.initial_knockback
|
||||
+ (self.static_data.max_knockback - self.static_data.initial_knockback)
|
||||
* self.charge_amount;
|
||||
|
||||
// Hit attempt
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: damage as u32,
|
||||
base_heal: 0,
|
||||
range: self.static_data.range,
|
||||
max_angle: self.static_data.max_angle.to_radians(),
|
||||
applied: false,
|
||||
hit_count: 0,
|
||||
knockback,
|
||||
});
|
||||
|
||||
// Starts swinging
|
||||
update.character = CharacterState::ChargedMelee(Data {
|
||||
static_data: self.static_data,
|
||||
stage_section: self.stage_section,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
exhausted: true,
|
||||
charge_amount: self.charge_amount,
|
||||
});
|
||||
} else if self.timer < self.static_data.swing_duration {
|
||||
// Swings
|
||||
update.character = CharacterState::ChargedMelee(Data {
|
||||
static_data: self.static_data,
|
||||
stage_section: self.stage_section,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
exhausted: self.exhausted,
|
||||
charge_amount: self.charge_amount,
|
||||
});
|
||||
} else {
|
||||
// Transitions to recover
|
||||
update.character = CharacterState::ChargedMelee(Data {
|
||||
static_data: self.static_data,
|
||||
stage_section: StageSection::Recover,
|
||||
timer: Duration::default(),
|
||||
exhausted: self.exhausted,
|
||||
charge_amount: self.charge_amount,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Recover => {
|
||||
if self.timer < self.static_data.recover_duration {
|
||||
// Recovers
|
||||
update.character = CharacterState::ChargedMelee(Data {
|
||||
static_data: self.static_data,
|
||||
stage_section: self.stage_section,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
exhausted: self.exhausted,
|
||||
charge_amount: self.charge_amount,
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
update.character = CharacterState::Wielding;
|
||||
// Make sure attack component is removed
|
||||
data.updater.remove::<Attacking>(data.entity);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// If it somehow ends up in an incorrect stage section
|
||||
update.character = CharacterState::Wielding;
|
||||
// Make sure attack component is removed
|
||||
data.updater.remove::<Attacking>(data.entity);
|
||||
},
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
}
|
@ -1,114 +1,197 @@
|
||||
use crate::{
|
||||
comp::{Attacking, CharacterState, StateUpdate},
|
||||
states::utils::*,
|
||||
states::utils::{StageSection, *},
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use vek::Vec3;
|
||||
|
||||
const LEAP_SPEED: f32 = 24.0;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct Data {
|
||||
/// Separated out to condense update portions of character state
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct StaticData {
|
||||
/// How long the state is moving
|
||||
pub movement_duration: Duration,
|
||||
/// How long until state should deal damage
|
||||
pub buildup_duration: Duration,
|
||||
/// How long the weapon swings
|
||||
pub swing_duration: Duration,
|
||||
/// How long the state has until exiting
|
||||
pub recover_duration: Duration,
|
||||
/// Base damage
|
||||
pub base_damage: u32,
|
||||
/// Knockback
|
||||
pub knockback: f32,
|
||||
/// Max range
|
||||
pub range: f32,
|
||||
/// Max angle (45.0 will give you a 90.0 angle window)
|
||||
pub max_angle: f32,
|
||||
/// Affects how far forward the player leaps
|
||||
pub forward_leap_strength: f32,
|
||||
/// Affects how high the player leaps
|
||||
pub vertical_leap_strength: f32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
/// Struct containing data that does not change over the course of the
|
||||
/// character state
|
||||
pub static_data: StaticData,
|
||||
/// Timer for each stage
|
||||
pub timer: Duration,
|
||||
/// What section the character stage is in
|
||||
pub stage_section: StageSection,
|
||||
/// 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();
|
||||
}
|
||||
}
|
||||
handle_move(data, &mut update, 0.3);
|
||||
handle_jump(data, &mut update);
|
||||
|
||||
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
|
||||
* (1.0 - data.inputs.look_dir.z.abs());
|
||||
match self.stage_section {
|
||||
StageSection::Buildup => {
|
||||
if self.timer < self.static_data.buildup_duration {
|
||||
// Buildup
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
} else {
|
||||
// Transitions to leap portion of state
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Movement,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Movement => {
|
||||
// Jumping
|
||||
update.vel.0 = Vec3::new(
|
||||
data.inputs.look_dir.x,
|
||||
data.inputs.look_dir.y,
|
||||
self.static_data.vertical_leap_strength,
|
||||
) * 2.0
|
||||
* (1.0
|
||||
- self.timer.as_secs_f32()
|
||||
/ self.static_data.movement_duration.as_secs_f32())
|
||||
+ (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()
|
||||
* self.static_data.forward_leap_strength
|
||||
* (1.0 - data.inputs.look_dir.z.abs());
|
||||
|
||||
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_damage: self.base_damage,
|
||||
base_heal: 0,
|
||||
range: 4.5,
|
||||
max_angle: 360_f32.to_radians(),
|
||||
applied: false,
|
||||
hit_count: 0,
|
||||
knockback: 25.0,
|
||||
});
|
||||
if self.timer < self.static_data.movement_duration {
|
||||
// Movement duration
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
} else {
|
||||
// Transitions to swing portion of state
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Swing,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Swing => {
|
||||
if self.timer < self.static_data.swing_duration {
|
||||
// Swings weapons
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
} else {
|
||||
// Transitions to recover portion
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Recover,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Recover => {
|
||||
if !data.physics.on_ground {
|
||||
// Falls
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
} else if !self.exhausted {
|
||||
// Hit attempt
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: self.static_data.base_damage,
|
||||
base_heal: 0,
|
||||
range: self.static_data.range,
|
||||
max_angle: self.static_data.max_angle.to_radians(),
|
||||
applied: false,
|
||||
hit_count: 0,
|
||||
knockback: self.static_data.knockback,
|
||||
});
|
||||
|
||||
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);
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
exhausted: true,
|
||||
});
|
||||
} else if self.timer < self.static_data.recover_duration {
|
||||
// Recovers
|
||||
update.character = CharacterState::LeapMelee(Data {
|
||||
static_data: self.static_data,
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
exhausted: self.exhausted,
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
update.character = CharacterState::Wielding;
|
||||
// Make sure attack component is removed
|
||||
data.updater.remove::<Attacking>(data.entity);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// If it somehow ends up in an incorrect stage section
|
||||
update.character = CharacterState::Wielding;
|
||||
// Make sure attack component is removed
|
||||
data.updater.remove::<Attacking>(data.entity);
|
||||
},
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -3,6 +3,7 @@ pub mod basic_block;
|
||||
pub mod basic_melee;
|
||||
pub mod basic_ranged;
|
||||
pub mod boost;
|
||||
pub mod charged_melee;
|
||||
pub mod charged_ranged;
|
||||
pub mod climb;
|
||||
pub mod combo_melee;
|
||||
@ -14,6 +15,7 @@ pub mod glide_wield;
|
||||
pub mod ground_shockwave;
|
||||
pub mod idle;
|
||||
pub mod leap_melee;
|
||||
pub mod repeater_ranged;
|
||||
pub mod roll;
|
||||
pub mod sit;
|
||||
pub mod sneak;
|
||||
|
207
common/src/states/repeater_ranged.rs
Normal file
207
common/src/states/repeater_ranged.rs
Normal file
@ -0,0 +1,207 @@
|
||||
use crate::{
|
||||
comp::{Body, CharacterState, Gravity, LightEmitter, Projectile, StateUpdate},
|
||||
event::ServerEvent,
|
||||
states::utils::{StageSection, *},
|
||||
sys::character_behavior::*,
|
||||
util::dir::*,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use vek::Vec3;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
/// Separated out to condense update portions of character state
|
||||
pub struct StaticData {
|
||||
/// How long the state is in movement
|
||||
pub movement_duration: Duration,
|
||||
/// How long we've readied the weapon
|
||||
pub buildup_duration: Duration,
|
||||
/// How long the state is shooting
|
||||
pub shoot_duration: Duration,
|
||||
/// How long the state has until exiting
|
||||
pub recover_duration: Duration,
|
||||
/// Whether there should be a jump and how strong the leap is
|
||||
pub leap: Option<f32>,
|
||||
/// Projectile options
|
||||
pub projectile: Projectile,
|
||||
pub projectile_body: Body,
|
||||
pub projectile_light: Option<LightEmitter>,
|
||||
pub projectile_gravity: Option<Gravity>,
|
||||
pub projectile_speed: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
/// Struct containing data that does not change over the course of the
|
||||
/// character state
|
||||
pub static_data: StaticData,
|
||||
/// Timer for each stage
|
||||
pub timer: Duration,
|
||||
/// What section the character stage is in
|
||||
pub stage_section: StageSection,
|
||||
/// How many repetitions remaining
|
||||
pub reps_remaining: u32,
|
||||
}
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
handle_move(data, &mut update, 1.0);
|
||||
handle_jump(data, &mut update);
|
||||
|
||||
match self.stage_section {
|
||||
StageSection::Movement => {
|
||||
// Jumping
|
||||
if let Some(leap_strength) = self.static_data.leap {
|
||||
update.vel.0 = Vec3::new(
|
||||
data.vel.0.x,
|
||||
data.vel.0.y,
|
||||
leap_strength
|
||||
* (1.0
|
||||
- self.timer.as_secs_f32()
|
||||
/ self.static_data.movement_duration.as_secs_f32()),
|
||||
);
|
||||
}
|
||||
if self.timer < self.static_data.movement_duration {
|
||||
// Do movement
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
reps_remaining: self.reps_remaining,
|
||||
});
|
||||
} else {
|
||||
// Transition to buildup
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
reps_remaining: self.reps_remaining,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Buildup => {
|
||||
// Aim gliding
|
||||
if self.static_data.leap.is_some() {
|
||||
update.vel.0 = Vec3::new(data.vel.0.x, data.vel.0.y, 0.0);
|
||||
}
|
||||
if self.timer < self.static_data.buildup_duration {
|
||||
// Buildup to attack
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
reps_remaining: self.reps_remaining,
|
||||
});
|
||||
} else {
|
||||
// Transition to shoot
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Shoot,
|
||||
reps_remaining: self.reps_remaining,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Shoot => {
|
||||
// Aim gliding
|
||||
if self.static_data.leap.is_some() {
|
||||
update.vel.0 = Vec3::new(data.vel.0.x, data.vel.0.y, 0.0);
|
||||
}
|
||||
if self.reps_remaining > 0 {
|
||||
// Fire
|
||||
let mut projectile = self.static_data.projectile.clone();
|
||||
projectile.owner = Some(*data.uid);
|
||||
update.server_events.push_front(ServerEvent::Shoot {
|
||||
entity: data.entity,
|
||||
// Provides slight variation to projectile direction
|
||||
dir: Dir::from_unnormalized(Vec3::new(
|
||||
data.inputs.look_dir[0]
|
||||
+ (if self.reps_remaining % 2 == 0 {
|
||||
self.reps_remaining as f32 / 400.0
|
||||
} else {
|
||||
-1.0 * self.reps_remaining as f32 / 400.0
|
||||
}),
|
||||
data.inputs.look_dir[1]
|
||||
+ (if self.reps_remaining % 2 == 0 {
|
||||
-1.0 * self.reps_remaining as f32 / 400.0
|
||||
} else {
|
||||
self.reps_remaining as f32 / 400.0
|
||||
}),
|
||||
data.inputs.look_dir[2],
|
||||
))
|
||||
.unwrap_or(data.inputs.look_dir),
|
||||
body: self.static_data.projectile_body,
|
||||
projectile,
|
||||
light: self.static_data.projectile_light,
|
||||
gravity: self.static_data.projectile_gravity,
|
||||
speed: self.static_data.projectile_speed,
|
||||
});
|
||||
|
||||
// Shoot projectiles
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
reps_remaining: self.reps_remaining - 1,
|
||||
});
|
||||
} else if self.timer < self.static_data.shoot_duration {
|
||||
// Finish shooting
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
reps_remaining: self.reps_remaining,
|
||||
});
|
||||
} else {
|
||||
// Transition to recover
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Recover,
|
||||
reps_remaining: self.reps_remaining,
|
||||
});
|
||||
}
|
||||
},
|
||||
StageSection::Recover => {
|
||||
if self.static_data.leap.is_some() && data.physics.on_ground {
|
||||
// Done
|
||||
update.character = CharacterState::Wielding;
|
||||
} else if self.timer < self.static_data.recover_duration {
|
||||
// Recover from attack
|
||||
update.character = CharacterState::RepeaterRanged(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: self
|
||||
.timer
|
||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||
.unwrap_or_default(),
|
||||
stage_section: self.stage_section,
|
||||
reps_remaining: self.reps_remaining,
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
update.character = CharacterState::Wielding;
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// If it somehow ends up in an incorrect stage section
|
||||
update.character = CharacterState::Wielding;
|
||||
},
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
}
|
@ -107,7 +107,7 @@ pub fn forward_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32,
|
||||
|
||||
pub fn handle_orientation(data: &JoinData, update: &mut StateUpdate, rate: f32) {
|
||||
// Set direction based on move direction
|
||||
let ori_dir = if update.character.is_attack() | update.character.is_block() {
|
||||
let ori_dir = if update.character.is_block() || update.character.is_attack() {
|
||||
data.inputs.look_dir.xy()
|
||||
} else if !data.inputs.move_dir.is_approx_zero() {
|
||||
data.inputs.move_dir
|
||||
@ -365,4 +365,6 @@ pub enum StageSection {
|
||||
Recover,
|
||||
Charge,
|
||||
Cast,
|
||||
Shoot,
|
||||
Movement,
|
||||
}
|
||||
|
@ -261,7 +261,9 @@ impl<'a> System<'a> for Sys {
|
||||
CharacterState::DashMelee(data) => data.handle_event(&j, action),
|
||||
CharacterState::LeapMelee(data) => data.handle_event(&j, action),
|
||||
CharacterState::SpinMelee(data) => data.handle_event(&j, action),
|
||||
CharacterState::ChargedMelee(data) => data.handle_event(&j, action),
|
||||
CharacterState::ChargedRanged(data) => data.handle_event(&j, action),
|
||||
CharacterState::RepeaterRanged(data) => data.handle_event(&j, action),
|
||||
CharacterState::GroundShockwave(data) => data.handle_event(&j, action),
|
||||
CharacterState::BasicBeam(data) => data.handle_event(&j, action),
|
||||
};
|
||||
@ -291,7 +293,9 @@ impl<'a> System<'a> for Sys {
|
||||
CharacterState::DashMelee(data) => data.behavior(&j),
|
||||
CharacterState::LeapMelee(data) => data.behavior(&j),
|
||||
CharacterState::SpinMelee(data) => data.behavior(&j),
|
||||
CharacterState::ChargedMelee(data) => data.behavior(&j),
|
||||
CharacterState::ChargedRanged(data) => data.behavior(&j),
|
||||
CharacterState::RepeaterRanged(data) => data.behavior(&j),
|
||||
CharacterState::GroundShockwave(data) => data.behavior(&j),
|
||||
CharacterState::BasicBeam(data) => data.behavior(&j),
|
||||
};
|
||||
|
@ -112,7 +112,9 @@ impl<'a> System<'a> for Sys {
|
||||
| CharacterState::SpinMelee { .. }
|
||||
| CharacterState::ComboMelee { .. }
|
||||
| CharacterState::BasicRanged { .. }
|
||||
| CharacterState::ChargedMelee { .. }
|
||||
| CharacterState::ChargedRanged { .. }
|
||||
| CharacterState::RepeaterRanged { .. }
|
||||
| CharacterState::GroundShockwave { .. }
|
||||
| CharacterState::BasicBeam { .. } => {
|
||||
if energy.get_unchecked().regen_rate != 0.0 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
mod color;
|
||||
mod dir;
|
||||
pub mod dir;
|
||||
mod option;
|
||||
pub mod userdata_dir;
|
||||
|
||||
|
@ -8,7 +8,7 @@ version = "0.7.0"
|
||||
name = "voxygen_anim"
|
||||
# Uncomment to use animation hot reloading
|
||||
# Note: this breaks `cargo test`
|
||||
crate-type = ["lib", "cdylib"]
|
||||
# crate-type = ["lib", "cdylib"]
|
||||
|
||||
[features]
|
||||
be-dyn-lib = []
|
||||
|
@ -147,6 +147,22 @@ impl Animation for ChargeAnimation {
|
||||
* Quaternion::rotation_z(stop * -0.6);
|
||||
next.control.scale = Vec3::one();
|
||||
},
|
||||
Some(ToolKind::Hammer(_)) => {
|
||||
next.l_hand.position = Vec3::new(-8.0, -2.0 + stop * -1.0, 13.0);
|
||||
next.l_hand.orientation = Quaternion::rotation_x(2.1)
|
||||
* Quaternion::rotation_y(0.7)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.05;
|
||||
next.r_hand.position = Vec3::new(-11.0, 2.0, 6.0);
|
||||
next.r_hand.orientation = Quaternion::rotation_x(1.8)
|
||||
* Quaternion::rotation_y(2.3)
|
||||
* Quaternion::rotation_z(0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.05;
|
||||
next.main.position = Vec3::new(-12.0, 1.0, 4.0);
|
||||
next.main.orientation = Quaternion::rotation_x(0.3)
|
||||
* Quaternion::rotation_y(0.3)
|
||||
* Quaternion::rotation_z(0.6);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
|
195
voxygen/src/anim/src/character/chargeswing.rs
Normal file
195
voxygen/src/anim/src/character/chargeswing.rs
Normal file
@ -0,0 +1,195 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
CharacterSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::{Hands, ToolKind},
|
||||
states::utils::StageSection,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
pub struct ChargeswingAnimation;
|
||||
|
||||
impl Animation for ChargeswingAnimation {
|
||||
type Dependency = (
|
||||
Option<ToolKind>,
|
||||
Option<ToolKind>,
|
||||
Vec3<f32>,
|
||||
f64,
|
||||
Option<StageSection>,
|
||||
);
|
||||
type Skeleton = CharacterSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"character_chargeswing\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "character_chargeswing")]
|
||||
#[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, stage_section): Self::Dependency,
|
||||
anim_time: f64,
|
||||
rate: &mut f32,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
*rate = 1.0;
|
||||
let mut next = (*skeleton).clone();
|
||||
let speed = Vec2::<f32>::from(velocity).magnitude();
|
||||
|
||||
let lab = 1.0;
|
||||
|
||||
let short = (((5.0)
|
||||
/ (1.5 + 3.5 * ((anim_time as f32 * lab as f32 * 8.0).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * lab as f32 * 8.0).sin());
|
||||
// end spin stuff
|
||||
|
||||
let movement = anim_time as f32 * 1.0;
|
||||
let fire = (anim_time as f32 * 18.0 * lab as f32).sin();
|
||||
|
||||
let foothoril = (anim_time as f32 * 8.0 * lab as f32 + PI * 1.45).sin();
|
||||
let foothorir = (anim_time as f32 * 8.0 * lab as f32 + PI * (0.45)).sin();
|
||||
|
||||
let footvertl = (anim_time as f32 * 8.0 * lab as f32).sin();
|
||||
let footvertr = (anim_time as f32 * 8.0 * lab as f32 + PI).sin();
|
||||
let footrotl = (((1.0)
|
||||
/ (0.5
|
||||
+ (0.5)
|
||||
* ((anim_time as f32 * 8.0 * lab as f32 + PI * 1.4).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * 8.0 * lab as f32 + PI * 1.4).sin());
|
||||
|
||||
let footrotr = (((1.0)
|
||||
/ (0.5
|
||||
+ (0.5)
|
||||
* ((anim_time as f32 * 8.0 * lab as f32 + PI * 0.4).sin()).powf(2.0 as f32)))
|
||||
.sqrt())
|
||||
* ((anim_time as f32 * 8.0 * lab as f32 + PI * 0.4).sin());
|
||||
if let Some(ToolKind::Hammer(_)) = active_tool_kind {
|
||||
next.l_hand.position = Vec3::new(-12.0, 0.0, 0.0);
|
||||
next.l_hand.orientation = Quaternion::rotation_x(-0.0) * Quaternion::rotation_y(0.0);
|
||||
next.l_hand.scale = Vec3::one() * 1.08;
|
||||
next.r_hand.position = Vec3::new(2.0, 0.0, 0.0);
|
||||
next.r_hand.orientation = Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
|
||||
next.r_hand.scale = Vec3::one() * 1.06;
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.main.orientation = Quaternion::rotation_y(-1.57) * Quaternion::rotation_z(1.57);
|
||||
|
||||
next.control.position = Vec3::new(6.0, 7.0, 1.0);
|
||||
next.control.orientation = Quaternion::rotation_x(0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.control.scale = Vec3::one();
|
||||
if let Some(stage_section) = stage_section {
|
||||
match stage_section {
|
||||
StageSection::Charge => {
|
||||
next.control.position = Vec3::new(
|
||||
6.0 + (movement * -4.0).max(-8.0),
|
||||
7.0 + (movement * 2.0).min(2.0),
|
||||
1.0,
|
||||
);
|
||||
next.control.orientation = Quaternion::rotation_x(0.3)
|
||||
* Quaternion::rotation_y(
|
||||
0.0 + (movement * 0.7).min(0.7)
|
||||
+ fire * 0.1 * (anim_time as f32).min(2.0),
|
||||
)
|
||||
* Quaternion::rotation_z(0.0 + (movement * 0.2).min(0.5));
|
||||
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1);
|
||||
next.chest.orientation =
|
||||
Quaternion::rotation_z((movement * 2.0).min(PI / 2.0));
|
||||
next.belt.orientation =
|
||||
Quaternion::rotation_z((short * 0.08 + movement * -1.0).max(-PI / 5.0));
|
||||
next.shorts.orientation =
|
||||
Quaternion::rotation_z((short * 0.15 + movement * -1.0).max(-PI / 4.0));
|
||||
|
||||
next.head.position = Vec3::new(
|
||||
0.0,
|
||||
skeleton_attr.head.0 - 2.0 + (movement * 2.0).min(2.0),
|
||||
skeleton_attr.head.1,
|
||||
);
|
||||
|
||||
next.head.orientation =
|
||||
Quaternion::rotation_z((movement * -1.8).max(PI / -2.0));
|
||||
next.belt.orientation = Quaternion::rotation_z(short * 0.05);
|
||||
|
||||
next.shorts.orientation = Quaternion::rotation_z(short * 0.15);
|
||||
if speed > 0.5 {
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + foothoril * -2.5 - 3.5,
|
||||
skeleton_attr.foot.2 + ((footvertl * -1.2).max(-1.0)),
|
||||
);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + foothorir * -2.5 + 6.0,
|
||||
skeleton_attr.foot.2 + ((footvertr * -1.2).max(-1.0)),
|
||||
);
|
||||
|
||||
next.l_foot.orientation =
|
||||
Quaternion::rotation_x(-0.4 + footrotl * -0.2)
|
||||
* Quaternion::rotation_z((movement * 0.5).min(0.5));
|
||||
next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.orientation =
|
||||
Quaternion::rotation_x(-0.4 + footrotr * -0.2)
|
||||
* Quaternion::rotation_z((movement * 0.5).min(0.5));
|
||||
} else {
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 - 5.0,
|
||||
skeleton_attr.foot.2,
|
||||
);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + 7.0,
|
||||
skeleton_attr.foot.2,
|
||||
);
|
||||
|
||||
next.l_foot.orientation =
|
||||
Quaternion::rotation_x(-0.2) * Quaternion::rotation_z(0.5);
|
||||
|
||||
next.r_foot.orientation =
|
||||
Quaternion::rotation_x(0.2) * Quaternion::rotation_z(0.5);
|
||||
};
|
||||
},
|
||||
|
||||
StageSection::Swing => {
|
||||
next.chest.orientation = Quaternion::rotation_z(-0.5);
|
||||
next.control.position = Vec3::new(6.0, 7.0, 1.0 + 3.0);
|
||||
next.control.orientation = Quaternion::rotation_x(PI / 2.0)
|
||||
* Quaternion::rotation_y(-1.6)
|
||||
* Quaternion::rotation_z(0.3 - movement * 2.5);
|
||||
next.head.orientation = Quaternion::rotation_z(0.8);
|
||||
next.l_hand.position = Vec3::new(-3.0, 0.0, 0.0);
|
||||
},
|
||||
StageSection::Recover => {
|
||||
next.chest.orientation = Quaternion::rotation_z(-0.5 + movement * 0.5);
|
||||
next.control.position = Vec3::new(6.0, 7.0, 1.0 + 3.0 + movement * -3.0);
|
||||
next.control.orientation = Quaternion::rotation_x(PI / 2.0)
|
||||
* Quaternion::rotation_y(-1.6 + movement * 1.6)
|
||||
* Quaternion::rotation_z(-2.2 + movement * 2.2);
|
||||
next.head.orientation = Quaternion::rotation_z(0.8 + movement * -0.8);
|
||||
next.l_hand.position = Vec3::new(-3.0 + movement * -9.0, 0.0, 0.0);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next.second.scale = match (
|
||||
active_tool_kind.map(|tk| tk.hands()),
|
||||
second_tool_kind.map(|tk| tk.hands()),
|
||||
) {
|
||||
(Some(Hands::OneHand), Some(Hands::OneHand)) => Vec3::one(),
|
||||
(_, _) => Vec3::zero(),
|
||||
};
|
||||
|
||||
//next.torso.position = Vec3::new(0.0, 0.0, 0.0) * skeleton_attr.scaler;
|
||||
//next.torso.orientation = Quaternion::rotation_z(0.0);
|
||||
//next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
next
|
||||
}
|
||||
}
|
@ -1,12 +1,22 @@
|
||||
use super::{super::Animation, CharacterSkeleton, SkeletonAttr};
|
||||
use common::comp::item::{Hands, ToolKind};
|
||||
/* use std::f32::consts::PI; */
|
||||
use super::super::vek::*;
|
||||
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
CharacterSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::{Hands, ToolKind},
|
||||
states::utils::StageSection,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
pub struct LeapAnimation;
|
||||
|
||||
impl Animation for LeapAnimation {
|
||||
type Dependency = (Option<ToolKind>, Option<ToolKind>, Vec3<f32>, f64);
|
||||
type Dependency = (
|
||||
Option<ToolKind>,
|
||||
Option<ToolKind>,
|
||||
Vec3<f32>,
|
||||
f64,
|
||||
Option<StageSection>,
|
||||
);
|
||||
type Skeleton = CharacterSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -16,7 +26,7 @@ impl Animation for LeapAnimation {
|
||||
#[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,
|
||||
(active_tool_kind, second_tool_kind, _velocity, _global_time, stage_section): Self::Dependency,
|
||||
anim_time: f64,
|
||||
rate: &mut f32,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
@ -24,86 +34,306 @@ impl Animation for LeapAnimation {
|
||||
*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());
|
||||
let movement = (anim_time as f32 * 1.0).min(1.0);
|
||||
|
||||
if let Some(ToolKind::Hammer(_)) = active_tool_kind {
|
||||
next.l_hand.position = Vec3::new(-12.0, 0.0, 0.0);
|
||||
next.l_hand.orientation = Quaternion::rotation_x(-0.0) * Quaternion::rotation_y(0.0);
|
||||
next.l_hand.orientation = Quaternion::rotation_x(PI) * Quaternion::rotation_y(0.0);
|
||||
next.l_hand.scale = Vec3::one() * 1.08;
|
||||
next.r_hand.position = Vec3::new(3.0, 0.0, 0.0);
|
||||
next.r_hand.orientation = Quaternion::rotation_x(0.0) * Quaternion::rotation_y(0.0);
|
||||
next.r_hand.position = Vec3::new(2.0, 0.0, 0.0);
|
||||
next.r_hand.orientation = Quaternion::rotation_x(PI) * Quaternion::rotation_y(0.0);
|
||||
next.r_hand.scale = Vec3::one() * 1.06;
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.main.orientation = Quaternion::rotation_x(0.0)
|
||||
* Quaternion::rotation_y(-1.57)
|
||||
* Quaternion::rotation_z(1.57);
|
||||
next.main.orientation = Quaternion::rotation_y(-1.57) * Quaternion::rotation_z(1.57);
|
||||
|
||||
next.head.position = Vec3::new(
|
||||
0.0,
|
||||
-2.0 + skeleton_attr.head.0 + slower * -1.0,
|
||||
skeleton_attr.head.1,
|
||||
);
|
||||
next.head.orientation = 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.position = Vec3::new(0.0, 0.0, 7.0);
|
||||
next.chest.orientation = 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.position = Vec3::new(0.0, 0.0, -2.0 + slower * -0.7);
|
||||
next.belt.orientation = 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.position = Vec3::new(0.0, 0.0, -5.0 + slower * -0.7);
|
||||
next.shorts.orientation = 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.orientation =
|
||||
Quaternion::rotation_x(slower * -0.7 + 0.4) * Quaternion::rotation_y(slower * 0.4);
|
||||
next.hold.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
slower * 3.0 + slowersmooth * -6.0 - 2.0,
|
||||
skeleton_attr.foot.2,
|
||||
);
|
||||
next.l_foot.orientation =
|
||||
Quaternion::rotation_x(slower * -0.2 + slowersmooth * -0.3 - 0.2);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
slower * 2.0 + slowersmooth * -4.0 - 1.0,
|
||||
-2.0 + skeleton_attr.foot.2,
|
||||
);
|
||||
next.r_foot.orientation =
|
||||
Quaternion::rotation_x(slower * -0.4 + slowersmooth * -0.6 - 1.0);
|
||||
|
||||
next.control.scale = Vec3::one();
|
||||
next.control.position = Vec3::new(-7.0, 7.0, 1.0);
|
||||
next.control.orientation = Quaternion::rotation_x(-0.7 + slower * 1.5)
|
||||
next.control.position = Vec3::new(6.0, 7.0, 1.0);
|
||||
next.control.orientation = Quaternion::rotation_x(0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(1.4 + slowersmooth * -0.4 + slower * 0.2);
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.control.scale = Vec3::one();
|
||||
|
||||
next.head.position = Vec3::new(0.0, -2.0 + skeleton_attr.head.0, skeleton_attr.head.1);
|
||||
|
||||
if let Some(stage_section) = stage_section {
|
||||
match stage_section {
|
||||
StageSection::Buildup => {
|
||||
next.control.position = Vec3::new(6.0, 7.0, 1.0);
|
||||
next.control.orientation = Quaternion::rotation_x(0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(movement * 0.5);
|
||||
next.chest.orientation = Quaternion::rotation_x(movement * 0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(movement * 0.5);
|
||||
|
||||
next.head.orientation = Quaternion::rotation_x(0.0)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(movement * -0.4);
|
||||
},
|
||||
|
||||
StageSection::Movement => {
|
||||
next.control.position = Vec3::new(
|
||||
6.0 + movement * -10.0,
|
||||
7.0 + movement * 5.0,
|
||||
1.0 + movement * 5.0,
|
||||
);
|
||||
next.control.orientation = Quaternion::rotation_x(0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.5 + movement * 0.5);
|
||||
next.chest.orientation = Quaternion::rotation_x(0.3 + movement * 0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.5 + movement * 0.2);
|
||||
next.head.orientation = Quaternion::rotation_x(0.0)
|
||||
* Quaternion::rotation_y(movement * -0.1)
|
||||
* Quaternion::rotation_z(-0.4 + movement * -0.2);
|
||||
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 - 5.0,
|
||||
skeleton_attr.foot.2,
|
||||
);
|
||||
next.l_foot.orientation = Quaternion::rotation_x(-0.8);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + 8.0,
|
||||
skeleton_attr.foot.2 + 5.0,
|
||||
);
|
||||
next.r_foot.orientation = Quaternion::rotation_x(0.9);
|
||||
},
|
||||
StageSection::Swing => {
|
||||
next.control.position =
|
||||
Vec3::new(-4.0, 12.0 + movement * 5.0, 6.0 + movement * -7.0);
|
||||
next.control.orientation = Quaternion::rotation_x(0.3 + movement * -3.0)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(1.0 + movement * 0.5);
|
||||
next.chest.orientation = Quaternion::rotation_x(0.6 + movement * -0.9)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.7 + movement * -0.7);
|
||||
next.head.orientation = Quaternion::rotation_x(movement * 0.2)
|
||||
* Quaternion::rotation_y(-0.1)
|
||||
* Quaternion::rotation_z(-0.6 + movement * 0.6);
|
||||
|
||||
next.l_hand.position = Vec3::new(-12.0 + movement * 10.0, 0.0, 0.0);
|
||||
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + 8.0,
|
||||
skeleton_attr.foot.2 - 5.0,
|
||||
);
|
||||
next.l_foot.orientation = Quaternion::rotation_x(0.9);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 - 5.0,
|
||||
skeleton_attr.foot.2,
|
||||
);
|
||||
next.r_foot.orientation = Quaternion::rotation_x(-0.8);
|
||||
},
|
||||
StageSection::Recover => {
|
||||
next.control.position = Vec3::new(-4.0, 17.0, -1.0);
|
||||
next.control.orientation = Quaternion::rotation_x(-2.7)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(1.5);
|
||||
next.chest.orientation = Quaternion::rotation_x(-0.3 + movement * 0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.head.orientation = Quaternion::rotation_x(0.2)
|
||||
* Quaternion::rotation_y(-0.1)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
|
||||
next.l_hand.position = Vec3::new(-2.0, 0.0, 0.0);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
} else if let Some(ToolKind::Axe(_)) = active_tool_kind {
|
||||
next.l_hand.position = Vec3::new(-0.5, 0.0, 4.0);
|
||||
next.l_hand.orientation = Quaternion::rotation_x(PI / 2.0)
|
||||
* Quaternion::rotation_z(0.0)
|
||||
* Quaternion::rotation_y(0.0);
|
||||
next.l_hand.scale = Vec3::one() * 1.08;
|
||||
next.r_hand.position = Vec3::new(0.5, 0.0, -2.5);
|
||||
next.r_hand.orientation = Quaternion::rotation_x(PI / 2.0)
|
||||
* Quaternion::rotation_z(0.0)
|
||||
* Quaternion::rotation_y(0.0);
|
||||
next.r_hand.scale = Vec3::one() * 1.06;
|
||||
next.main.position = Vec3::new(-0.0, -2.0, -1.0);
|
||||
next.main.orientation = Quaternion::rotation_x(0.0)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
|
||||
next.control.position = Vec3::new(-3.0, 11.0, 3.0);
|
||||
next.control.orientation = Quaternion::rotation_x(1.8)
|
||||
* Quaternion::rotation_y(-0.5)
|
||||
* Quaternion::rotation_z(PI - 0.2);
|
||||
next.control.scale = Vec3::one();
|
||||
|
||||
next.head.position = Vec3::new(0.0, -2.0 + skeleton_attr.head.0, skeleton_attr.head.1);
|
||||
|
||||
if let Some(stage_section) = stage_section {
|
||||
match stage_section {
|
||||
StageSection::Buildup => {
|
||||
next.control.position = Vec3::new(
|
||||
-3.0 + movement * 3.0,
|
||||
11.0 + movement * 1.0,
|
||||
3.0 + movement * 12.0,
|
||||
);
|
||||
next.control.orientation = Quaternion::rotation_x(1.8 + movement * -1.0)
|
||||
* Quaternion::rotation_y(-0.5 + movement * 0.5)
|
||||
* Quaternion::rotation_z(PI + 0.2 - movement * 0.2);
|
||||
next.chest.orientation = Quaternion::rotation_x(movement * -0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(movement * 0.5);
|
||||
|
||||
next.head.orientation = Quaternion::rotation_x(0.0 + movement * -0.4);
|
||||
|
||||
next.l_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1,
|
||||
skeleton_attr.foot.2 - 8.0,
|
||||
);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1,
|
||||
skeleton_attr.foot.2 - 8.0,
|
||||
);
|
||||
|
||||
next.l_foot.orientation = Quaternion::rotation_x(movement * 0.9);
|
||||
|
||||
next.r_foot.orientation = Quaternion::rotation_x(movement * 0.9);
|
||||
|
||||
next.belt.orientation = Quaternion::rotation_x(movement * 0.22);
|
||||
next.shorts.orientation = Quaternion::rotation_x(movement * 0.3);
|
||||
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1 - 8.0);
|
||||
next.torso.position =
|
||||
Vec3::new(0.0, 0.0, 0.0 + 8.0) * skeleton_attr.scaler / 11.0;
|
||||
},
|
||||
|
||||
StageSection::Movement => {
|
||||
next.control.position = Vec3::new(
|
||||
0.0, 12.0, //11
|
||||
15.0,
|
||||
);
|
||||
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1 - 8.0);
|
||||
next.torso.position = Vec3::new(0.0, 0.0, 0.0 + 8.0) * skeleton_attr.scaler;
|
||||
next.control.orientation = Quaternion::rotation_x(0.8 + movement * -0.5)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(PI);
|
||||
next.torso.orientation = Quaternion::rotation_x(-0.3 + movement * 6.0)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.head.orientation = Quaternion::rotation_x(-0.4 + movement * 0.4);
|
||||
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + movement * 4.0,
|
||||
skeleton_attr.foot.2 - 8.0 + movement * 3.0,
|
||||
);
|
||||
next.l_foot.orientation = Quaternion::rotation_x(0.9);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + movement * 4.0,
|
||||
skeleton_attr.foot.2 - 8.0 + movement * 3.0,
|
||||
);
|
||||
next.r_foot.orientation = Quaternion::rotation_x(0.9);
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1 - 8.0);
|
||||
next.torso.position =
|
||||
Vec3::new(0.0, 0.0, 0.0 + 8.0) * skeleton_attr.scaler / 11.0;
|
||||
next.torso.orientation = Quaternion::rotation_x(movement * -1.8 * PI);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
|
||||
next.belt.orientation = Quaternion::rotation_x(0.22 + movement * 0.1);
|
||||
next.shorts.orientation = Quaternion::rotation_x(0.3 + movement * 0.1);
|
||||
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1 - 8.0);
|
||||
next.torso.position =
|
||||
Vec3::new(0.0, 0.0, 0.0 + 8.0) * skeleton_attr.scaler / 11.0;
|
||||
},
|
||||
StageSection::Swing => {
|
||||
next.control.position =
|
||||
Vec3::new(0.0, 12.0 + movement * 3.0, 15.0 + movement * -15.0);
|
||||
next.control.orientation = Quaternion::rotation_x(0.3 + movement * -1.0)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(PI);
|
||||
|
||||
next.head.orientation = Quaternion::rotation_x(movement * 0.2);
|
||||
|
||||
next.l_hand.position = Vec3::new(-0.5, 0.0, 4.0);
|
||||
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + 4.0 + movement * -8.0,
|
||||
skeleton_attr.foot.2 - 5.0 + movement * -3.0,
|
||||
);
|
||||
next.l_foot.orientation = Quaternion::rotation_x(0.9 - movement * 1.8);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 + 4.0 + movement * -8.0,
|
||||
skeleton_attr.foot.2 - 5.0 + movement * -3.0,
|
||||
);
|
||||
next.r_foot.orientation = Quaternion::rotation_x(0.9 - movement * 1.8);
|
||||
|
||||
next.torso.orientation =
|
||||
Quaternion::rotation_x(-1.9 * PI - movement * 0.2 * PI);
|
||||
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1 - 8.0);
|
||||
next.torso.position =
|
||||
Vec3::new(0.0, 0.0, 0.0 + 8.0) * skeleton_attr.scaler / 11.0;
|
||||
},
|
||||
StageSection::Recover => {
|
||||
next.control.position = Vec3::new(0.0, 15.0, 0.0);
|
||||
next.control.orientation = Quaternion::rotation_x(-0.7)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(PI);
|
||||
|
||||
next.head.orientation = Quaternion::rotation_x(0.2);
|
||||
|
||||
next.l_hand.position = Vec3::new(-0.5, 0.0, 4.0);
|
||||
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1 - 8.0);
|
||||
next.torso.position =
|
||||
Vec3::new(0.0, 0.0, 0.0 + 8.0) * skeleton_attr.scaler / 11.0;
|
||||
next.torso.orientation =
|
||||
Quaternion::rotation_x(-6.7 + movement * -0.1 * PI);
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 - 4.0,
|
||||
skeleton_attr.foot.2 - 8.0,
|
||||
);
|
||||
next.l_foot.orientation = Quaternion::rotation_x(-0.9);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0,
|
||||
skeleton_attr.foot.1 - 4.0,
|
||||
skeleton_attr.foot.2 - 8.0,
|
||||
);
|
||||
next.r_foot.orientation = Quaternion::rotation_x(-0.9);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
next.lantern.position = Vec3::new(
|
||||
skeleton_attr.lantern.0,
|
||||
skeleton_attr.lantern.1,
|
||||
skeleton_attr.lantern.2,
|
||||
);
|
||||
next.glider.position = 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.lantern.position = Vec3::new(
|
||||
// skeleton_attr.lantern.0,
|
||||
// skeleton_attr.lantern.1,
|
||||
// skeleton_attr.lantern.2,
|
||||
//);
|
||||
//next.glider.position = 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.hands()),
|
||||
@ -113,9 +343,9 @@ impl Animation for LeapAnimation {
|
||||
(_, _) => Vec3::zero(),
|
||||
};
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 0.0, 0.0) * skeleton_attr.scaler;
|
||||
next.torso.orientation = Quaternion::rotation_z(0.0);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
//next.torso.position = Vec3::new(0.0, 0.0, 0.0) * skeleton_attr.scaler;
|
||||
//next.torso.orientation = Quaternion::rotation_z(0.0);
|
||||
//next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
next
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ pub mod beta;
|
||||
pub mod block;
|
||||
pub mod blockidle;
|
||||
pub mod charge;
|
||||
pub mod chargeswing;
|
||||
pub mod climb;
|
||||
pub mod dance;
|
||||
pub mod dash;
|
||||
@ -12,6 +13,7 @@ pub mod gliding;
|
||||
pub mod idle;
|
||||
pub mod jump;
|
||||
pub mod leapmelee;
|
||||
pub mod repeater;
|
||||
pub mod roll;
|
||||
pub mod run;
|
||||
pub mod shoot;
|
||||
@ -27,13 +29,14 @@ pub mod wield;
|
||||
// Reexports
|
||||
pub use self::{
|
||||
alpha::AlphaAnimation, beta::BetaAnimation, block::BlockAnimation,
|
||||
blockidle::BlockIdleAnimation, charge::ChargeAnimation, climb::ClimbAnimation,
|
||||
dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation,
|
||||
blockidle::BlockIdleAnimation, charge::ChargeAnimation, chargeswing::ChargeswingAnimation,
|
||||
climb::ClimbAnimation, dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation,
|
||||
glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation,
|
||||
jump::JumpAnimation, leapmelee::LeapAnimation, roll::RollAnimation, run::RunAnimation,
|
||||
shoot::ShootAnimation, sit::SitAnimation, sneak::SneakAnimation, spin::SpinAnimation,
|
||||
spinmelee::SpinMeleeAnimation, stand::StandAnimation, swim::SwimAnimation,
|
||||
swimwield::SwimWieldAnimation, wield::WieldAnimation,
|
||||
jump::JumpAnimation, leapmelee::LeapAnimation, repeater::RepeaterAnimation,
|
||||
roll::RollAnimation, run::RunAnimation, shoot::ShootAnimation, sit::SitAnimation,
|
||||
sneak::SneakAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation,
|
||||
stand::StandAnimation, swim::SwimAnimation, swimwield::SwimWieldAnimation,
|
||||
wield::WieldAnimation,
|
||||
};
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
|
198
voxygen/src/anim/src/character/repeater.rs
Normal file
198
voxygen/src/anim/src/character/repeater.rs
Normal file
@ -0,0 +1,198 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
CharacterSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::{Hands, ToolKind},
|
||||
states::utils::StageSection,
|
||||
};
|
||||
pub struct RepeaterAnimation;
|
||||
|
||||
impl Animation for RepeaterAnimation {
|
||||
type Dependency = (
|
||||
Option<ToolKind>,
|
||||
Option<ToolKind>,
|
||||
Vec3<f32>,
|
||||
f64,
|
||||
Option<StageSection>,
|
||||
);
|
||||
type Skeleton = CharacterSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"character_repeater\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "character_repeater")]
|
||||
#[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, stage_section): 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;
|
||||
|
||||
// end spin stuff
|
||||
|
||||
let movement = (anim_time as f32 * 1.0).min(1.0);
|
||||
let fire = (anim_time as f32 * 18.0 * lab as f32).sin();
|
||||
|
||||
if let Some(ToolKind::Bow(_)) = active_tool_kind {
|
||||
next.l_hand.position = Vec3::new(2.0, 1.5, 0.0);
|
||||
next.l_hand.orientation = Quaternion::rotation_x(1.20)
|
||||
* Quaternion::rotation_y(-0.6)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.05;
|
||||
next.r_hand.position = Vec3::new(5.9, 4.5, -5.0);
|
||||
next.r_hand.orientation = Quaternion::rotation_x(1.20)
|
||||
* Quaternion::rotation_y(-0.6)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.05;
|
||||
next.main.position = Vec3::new(3.0, 2.0, -13.0);
|
||||
next.main.orientation = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.3)
|
||||
* Quaternion::rotation_z(-0.6);
|
||||
|
||||
next.hold.position = Vec3::new(1.2, -1.0, -5.2);
|
||||
next.hold.orientation = Quaternion::rotation_x(-1.7)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.1);
|
||||
next.hold.scale = Vec3::one() * 1.0;
|
||||
|
||||
next.control.position = Vec3::new(-7.0, 6.0, 6.0);
|
||||
next.control.orientation = Quaternion::rotation_x(0.0) * Quaternion::rotation_z(0.0);
|
||||
next.control.scale = Vec3::one();
|
||||
if let Some(stage_section) = stage_section {
|
||||
match stage_section {
|
||||
StageSection::Movement => {
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0 + movement * -0.75 - 0.75,
|
||||
skeleton_attr.foot.1 + movement * 4.0 + 4.0,
|
||||
skeleton_attr.foot.2 + movement * 2.5 + 2.5,
|
||||
);
|
||||
next.l_foot.orientation = Quaternion::rotation_x(movement * 0.6 + 0.6)
|
||||
* Quaternion::rotation_z(movement * 0.3 + 0.3);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0 + movement * 0.75 + 0.75,
|
||||
skeleton_attr.foot.1 + movement * 4.0 + 4.0,
|
||||
skeleton_attr.foot.2 + movement * 2.5 + 2.5,
|
||||
);
|
||||
next.r_foot.orientation = Quaternion::rotation_x(movement * 0.6 + 0.6)
|
||||
* Quaternion::rotation_z(movement * -0.3 - 0.3);
|
||||
next.shorts.position = Vec3::new(
|
||||
0.0,
|
||||
skeleton_attr.shorts.0 + movement * 4.0,
|
||||
skeleton_attr.shorts.1 + movement * 1.0,
|
||||
);
|
||||
next.shorts.orientation = Quaternion::rotation_x(movement * 0.6);
|
||||
next.belt.position = Vec3::new(
|
||||
0.0,
|
||||
skeleton_attr.belt.0 + movement * 2.0,
|
||||
skeleton_attr.belt.1,
|
||||
);
|
||||
next.belt.orientation = Quaternion::rotation_x(movement * 0.2);
|
||||
next.control.position = Vec3::new(
|
||||
-7.0 + movement * 5.0,
|
||||
6.0 + movement * 3.0,
|
||||
6.0 + movement * 1.0,
|
||||
);
|
||||
next.control.orientation = Quaternion::rotation_x(movement * 0.4)
|
||||
* Quaternion::rotation_y(movement * 0.8);
|
||||
next.head.orientation = Quaternion::rotation_y(movement * 0.15);
|
||||
next.torso.orientation = Quaternion::rotation_x(movement * 0.1)
|
||||
},
|
||||
|
||||
StageSection::Buildup => {
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0 - 1.5,
|
||||
skeleton_attr.foot.1 + 8.0,
|
||||
skeleton_attr.foot.2 + 5.0,
|
||||
);
|
||||
next.l_foot.orientation = Quaternion::rotation_x(1.2 + movement * -0.2)
|
||||
* Quaternion::rotation_z(0.6);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0 + 1.5,
|
||||
skeleton_attr.foot.1 + 8.0,
|
||||
skeleton_attr.foot.2 + 5.0,
|
||||
);
|
||||
next.r_foot.orientation = Quaternion::rotation_x(1.2 + movement * -0.2)
|
||||
* Quaternion::rotation_z(-0.6);
|
||||
next.shorts.position = Vec3::new(
|
||||
0.0,
|
||||
skeleton_attr.shorts.0 + 4.0,
|
||||
skeleton_attr.shorts.1 + 1.0,
|
||||
);
|
||||
next.shorts.orientation = Quaternion::rotation_x(0.6);
|
||||
next.belt.position =
|
||||
Vec3::new(0.0, skeleton_attr.belt.0 + 2.0, skeleton_attr.belt.1);
|
||||
next.belt.orientation = Quaternion::rotation_x(0.2);
|
||||
next.control.position = Vec3::new(-2.0, 9.0, 7.0);
|
||||
next.control.orientation =
|
||||
Quaternion::rotation_x(0.4) * Quaternion::rotation_y(0.8);
|
||||
next.head.orientation = Quaternion::rotation_y(0.15 + movement * 0.05);
|
||||
next.torso.orientation = Quaternion::rotation_x(0.1 + movement * 0.1);
|
||||
},
|
||||
|
||||
StageSection::Shoot => {
|
||||
next.l_foot.position = Vec3::new(
|
||||
-skeleton_attr.foot.0 - 1.5,
|
||||
skeleton_attr.foot.1 + 8.0,
|
||||
skeleton_attr.foot.2 + 5.0,
|
||||
);
|
||||
next.l_foot.orientation =
|
||||
Quaternion::rotation_x(1.0) * Quaternion::rotation_z(0.6);
|
||||
|
||||
next.r_foot.position = Vec3::new(
|
||||
skeleton_attr.foot.0 + 1.5,
|
||||
skeleton_attr.foot.1 + 8.0,
|
||||
skeleton_attr.foot.2 + 5.0,
|
||||
);
|
||||
next.r_foot.orientation =
|
||||
Quaternion::rotation_x(1.0) * Quaternion::rotation_z(-0.6);
|
||||
next.shorts.position = Vec3::new(
|
||||
0.0,
|
||||
skeleton_attr.shorts.0 + 4.0,
|
||||
skeleton_attr.shorts.1 + 1.0,
|
||||
);
|
||||
next.shorts.orientation = Quaternion::rotation_x(0.6);
|
||||
next.belt.position =
|
||||
Vec3::new(0.0, skeleton_attr.belt.0 + 2.0, skeleton_attr.belt.1);
|
||||
next.belt.orientation = Quaternion::rotation_x(0.2);
|
||||
next.control.position = Vec3::new(-2.0, 9.0, 7.0);
|
||||
next.control.orientation =
|
||||
Quaternion::rotation_x(0.4) * Quaternion::rotation_y(0.8);
|
||||
next.head.orientation = Quaternion::rotation_y(0.2);
|
||||
next.torso.orientation = Quaternion::rotation_x(0.2 + movement * 0.15);
|
||||
|
||||
next.l_hand.position =
|
||||
Vec3::new(2.0 + fire * -6.0 - 3.0, 1.5 + fire * -6.0 - 3.0, 0.0);
|
||||
next.l_hand.orientation = Quaternion::rotation_x(1.20)
|
||||
* Quaternion::rotation_y(-0.6)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.hold.scale = Vec3::one() * 0.0;
|
||||
},
|
||||
StageSection::Recover => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next.second.scale = match (
|
||||
active_tool_kind.map(|tk| tk.hands()),
|
||||
second_tool_kind.map(|tk| tk.hands()),
|
||||
) {
|
||||
(Some(Hands::OneHand), Some(Hands::OneHand)) => Vec3::one(),
|
||||
(_, _) => Vec3::zero(),
|
||||
};
|
||||
|
||||
//next.torso.position = Vec3::new(0.0, 0.0, 0.0) * skeleton_attr.scaler;
|
||||
//next.torso.orientation = Quaternion::rotation_z(0.0);
|
||||
//next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
next
|
||||
}
|
||||
}
|
@ -81,6 +81,9 @@ impl State {
|
||||
ToolKind::Staff(_) => true,
|
||||
ToolKind::Debug(kind) => kind == "Boost",
|
||||
ToolKind::Sword(_) => true,
|
||||
ToolKind::Hammer(_) => true,
|
||||
ToolKind::Axe(_) => true,
|
||||
ToolKind::Bow(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
|
@ -140,7 +140,7 @@ image_ids! {
|
||||
flyingrod_m1: "voxygen.element.icons.debug_wand_m1",
|
||||
flyingrod_m2: "voxygen.element.icons.debug_wand_m2",
|
||||
sword_pierce: "voxygen.element.icons.skill_sword_pierce",
|
||||
hammerleap: "voxygen.element.icons.skill_hammerleap",
|
||||
hammergolf: "voxygen.element.icons.skill_hammergolf",
|
||||
axespin: "voxygen.element.icons.skill_axespin",
|
||||
|
||||
// Skillbar
|
||||
@ -277,6 +277,9 @@ image_ids! {
|
||||
heal_0: "voxygen.element.icons.heal_0",
|
||||
sword_whirlwind: "voxygen.element.icons.sword_whirlwind",
|
||||
heal_bomb: "voxygen.element.icons.heal_bomb",
|
||||
hammerleap: "voxygen.element.icons.skill_hammerleap",
|
||||
skill_axe_leap_slash: "voxygen.element.icons.skill_axe_leap_slash",
|
||||
skill_bow_jump_burst: "voxygen.element.icons.skill_bow_jump_burst",
|
||||
|
||||
// Buttons
|
||||
button: "voxygen.element.buttons.button",
|
||||
|
@ -696,7 +696,7 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
Some(ToolKind::Sword(_)) => self.imgs.twohsword_m2,
|
||||
Some(ToolKind::Dagger(_)) => self.imgs.onehdagger_m2,
|
||||
Some(ToolKind::Shield(_)) => self.imgs.onehshield_m2,
|
||||
Some(ToolKind::Hammer(_)) => self.imgs.hammerleap,
|
||||
Some(ToolKind::Hammer(_)) => self.imgs.hammergolf,
|
||||
Some(ToolKind::Axe(_)) => self.imgs.axespin,
|
||||
Some(ToolKind::Bow(_)) => self.imgs.bow_m2,
|
||||
Some(ToolKind::Sceptre(_)) => self.imgs.heal_bomb,
|
||||
@ -724,6 +724,13 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
Color::Rgba(0.3, 0.3, 0.3, 0.8)
|
||||
}
|
||||
},
|
||||
Some(ToolKind::Axe(_)) => {
|
||||
if self.energy.current() as f64 >= 100.0 {
|
||||
Color::Rgba(1.0, 1.0, 1.0, 1.0)
|
||||
} else {
|
||||
Color::Rgba(0.3, 0.3, 0.3, 0.8)
|
||||
}
|
||||
},
|
||||
_ => Color::Rgba(1.0, 1.0, 1.0, 1.0),
|
||||
})
|
||||
.set(state.ids.m2_content, ui);
|
||||
@ -785,6 +792,14 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.map(|i| i.item.kind())
|
||||
.and_then(|kind| match kind {
|
||||
ItemKind::Tool(Tool { kind, .. }) => match kind {
|
||||
ToolKind::Hammer(_) => Some((
|
||||
"Smash of Doom",
|
||||
"\nAn AOE attack with knockback. \nLeaps to position of \
|
||||
cursor.",
|
||||
)),
|
||||
ToolKind::Axe(_) => {
|
||||
Some(("Spin Leap", "\nA slashing running spin leap."))
|
||||
},
|
||||
ToolKind::Staff(_) => Some((
|
||||
"Firebomb",
|
||||
"\nWhirls a big fireball into the air. \nExplodes the ground \
|
||||
@ -794,6 +809,10 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
"Whirlwind",
|
||||
"\nMove forward while spinning with \n your sword.",
|
||||
)),
|
||||
ToolKind::Bow(_) => Some((
|
||||
"Burst",
|
||||
"\nLaunches a burst of arrows at the top \nof a running leap.",
|
||||
)),
|
||||
ToolKind::Debug(kind) => match kind.as_ref() {
|
||||
"Boost" => Some((
|
||||
"Possessing Arrow",
|
||||
|
@ -85,6 +85,9 @@ pub enum HotbarImage {
|
||||
Fireball,
|
||||
SnakeArrow,
|
||||
SwordWhirlwind,
|
||||
HammerLeap,
|
||||
AxeLeapSlash,
|
||||
BowJumpBurst,
|
||||
}
|
||||
|
||||
type HotbarSource<'a> = (&'a hotbar::State, &'a Inventory, &'a Loadout, &'a Energy);
|
||||
@ -110,6 +113,9 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
match kind {
|
||||
ItemKind::Tool(Tool { kind, .. }) => match kind {
|
||||
ToolKind::Staff(_) => Some(HotbarImage::Fireball),
|
||||
ToolKind::Hammer(_) => Some(HotbarImage::HammerLeap),
|
||||
ToolKind::Axe(_) => Some(HotbarImage::AxeLeapSlash),
|
||||
ToolKind::Bow(_) => Some(HotbarImage::BowJumpBurst),
|
||||
ToolKind::Debug(kind) => match kind.as_ref() {
|
||||
"Boost" => Some(HotbarImage::SnakeArrow),
|
||||
_ => None,
|
||||
@ -119,11 +125,27 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
.map(|image_key| {
|
||||
(
|
||||
.map(|image_key| match image_key {
|
||||
HotbarImage::Fireball => (
|
||||
image_key,
|
||||
(energy.current() < 500).then_some(Color::Rgba(0.3, 0.3, 0.3, 0.8)),
|
||||
)
|
||||
(energy.current() < 450).then_some(Color::Rgba(0.3, 0.3, 0.3, 0.8)),
|
||||
),
|
||||
HotbarImage::HammerLeap => (
|
||||
image_key,
|
||||
(energy.current() < 700).then_some(Color::Rgba(0.3, 0.3, 0.3, 0.8)),
|
||||
),
|
||||
HotbarImage::AxeLeapSlash => (
|
||||
image_key,
|
||||
(energy.current() < 450).then_some(Color::Rgba(0.3, 0.3, 0.3, 0.8)),
|
||||
),
|
||||
HotbarImage::BowJumpBurst => (
|
||||
image_key,
|
||||
(energy.current() < 450).then_some(Color::Rgba(0.3, 0.3, 0.3, 0.8)),
|
||||
),
|
||||
_ => (
|
||||
image_key,
|
||||
(energy.current() < 1000).then_some(Color::Rgba(1.0, 1.0, 1.0, 1.0)),
|
||||
),
|
||||
})
|
||||
}),
|
||||
})
|
||||
@ -146,6 +168,9 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
HotbarImage::SnakeArrow => imgs.snake_arrow_0,
|
||||
HotbarImage::Fireball => imgs.fire_spell_1,
|
||||
HotbarImage::SwordWhirlwind => imgs.sword_whirlwind,
|
||||
HotbarImage::HammerLeap => imgs.hammerleap,
|
||||
HotbarImage::AxeLeapSlash => imgs.skill_axe_leap_slash,
|
||||
HotbarImage::BowJumpBurst => imgs.skill_bow_jump_burst,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -848,6 +848,36 @@ impl FigureMgr {
|
||||
)
|
||||
}
|
||||
},
|
||||
CharacterState::ChargedMelee(s) => {
|
||||
let stage_time = s.timer.as_secs_f64();
|
||||
|
||||
let stage_progress = match s.stage_section {
|
||||
StageSection::Charge => {
|
||||
stage_time / s.static_data.charge_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Swing => {
|
||||
stage_time / s.static_data.swing_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Recover => {
|
||||
stage_time / s.static_data.recover_duration.as_secs_f64()
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
|
||||
anim::character::ChargeswingAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
active_tool_kind,
|
||||
second_tool_kind,
|
||||
vel.0,
|
||||
time,
|
||||
Some(s.stage_section),
|
||||
),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::ChargedRanged(data) => {
|
||||
if data.exhausted {
|
||||
anim::character::ShootAnimation::update_skeleton(
|
||||
@ -874,6 +904,39 @@ impl FigureMgr {
|
||||
)
|
||||
}
|
||||
},
|
||||
CharacterState::RepeaterRanged(s) => {
|
||||
let stage_time = s.timer.as_secs_f64();
|
||||
|
||||
let stage_progress = match s.stage_section {
|
||||
StageSection::Buildup => {
|
||||
stage_time / s.static_data.buildup_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Movement => {
|
||||
stage_time / s.static_data.movement_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Shoot => {
|
||||
stage_time / s.static_data.shoot_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Recover => {
|
||||
stage_time / s.static_data.recover_duration.as_secs_f64()
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
|
||||
anim::character::RepeaterAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
active_tool_kind,
|
||||
second_tool_kind,
|
||||
vel.0,
|
||||
time,
|
||||
Some(s.stage_section),
|
||||
),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::Sneak { .. } => {
|
||||
anim::character::SneakAnimation::update_skeleton(
|
||||
&CharacterSkeleton::default(),
|
||||
@ -928,11 +991,42 @@ impl FigureMgr {
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::LeapMelee(_) => {
|
||||
CharacterState::LeapMelee(s) => {
|
||||
let stage_progress = match active_tool_kind {
|
||||
Some(ToolKind::Axe(_) | ToolKind::Hammer(_)) => {
|
||||
let stage_time = s.timer.as_secs_f64();
|
||||
match s.stage_section {
|
||||
StageSection::Buildup => {
|
||||
stage_time
|
||||
/ s.static_data.buildup_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Movement => {
|
||||
stage_time
|
||||
/ s.static_data.movement_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Swing => {
|
||||
stage_time / s.static_data.swing_duration.as_secs_f64()
|
||||
},
|
||||
StageSection::Recover => {
|
||||
stage_time
|
||||
/ s.static_data.recover_duration.as_secs_f64()
|
||||
},
|
||||
_ => 0.0,
|
||||
}
|
||||
},
|
||||
_ => state.state_time,
|
||||
};
|
||||
|
||||
anim::character::LeapAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(active_tool_kind, second_tool_kind, vel.0, time),
|
||||
state.state_time,
|
||||
(
|
||||
active_tool_kind,
|
||||
second_tool_kind,
|
||||
vel.0,
|
||||
time,
|
||||
Some(s.stage_section),
|
||||
),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user