Add 3rd skill for hammer, bow, and axe minus skillbar UI stuff

This commit is contained in:
jiminycrick 2020-09-20 21:16:52 -07:00
parent 5bcfb6bd0a
commit 951acfca21
12 changed files with 698 additions and 21 deletions

View File

@ -18,6 +18,7 @@ pub enum CharacterAbilityType {
BasicMelee,
BasicRanged,
Boost,
ChargedMelee,
ChargedRanged,
DashMelee,
BasicBlock,
@ -26,6 +27,7 @@ pub enum CharacterAbilityType {
SpinMelee,
GroundShockwave,
BasicBeam,
RepeaterRanged,
}
impl From<&CharacterState> for CharacterAbilityType {
@ -39,9 +41,11 @@ impl From<&CharacterState> for CharacterAbilityType {
CharacterState::LeapMelee(_) => Self::LeapMelee,
CharacterState::ComboMelee(data) => Self::ComboMelee(data.stage_section, data.stage),
CharacterState::SpinMelee(_) => Self::SpinMelee,
CharacterState::ChargedMelee(_) => Self::ChargedMelee,
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 {
movement_duration: Duration,
energy_cost: u32,
holdable: bool,
prepare_duration: Duration,
recover_duration: Duration,
projectile: Projectile,
projectile_body: Body,
projectile_light: Option<LightEmitter>,
projectile_gravity: Option<Gravity>,
projectile_speed: f32,
repetitions: u32,
current_rep: u32,
},
Boost {
duration: Duration,
only_up: bool,
@ -107,6 +125,10 @@ pub enum CharacterAbility {
buildup_duration: Duration,
recover_duration: Duration,
base_damage: u32,
range: f32,
max_angle: f32,
leap_speed: f32,
leap_vert_speed: f32,
},
SpinMelee {
buildup_duration: Duration,
@ -122,6 +144,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,
prepare_duration: Duration,
charge_duration: Duration,
recover_duration: Duration,
range: f32,
max_angle: f32,
},
ChargedRanged {
energy_cost: u32,
energy_drain: u32,
@ -203,6 +238,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)
@ -424,6 +467,10 @@ impl From<&CharacterAbility> for CharacterState {
buildup_duration,
recover_duration,
base_damage,
range,
max_angle,
leap_speed,
leap_vert_speed,
} => CharacterState::LeapMelee(leap_melee::Data {
initialize: true,
exhausted: false,
@ -431,6 +478,10 @@ impl From<&CharacterAbility> for CharacterState {
buildup_duration: *buildup_duration,
recover_duration: *recover_duration,
base_damage: *base_damage,
range: *range,
max_angle: *max_angle,
leap_speed: *leap_speed,
leap_vert_speed: *leap_vert_speed,
}),
CharacterAbility::SpinMelee {
buildup_duration,
@ -465,6 +516,32 @@ 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,
prepare_duration,
charge_duration,
recover_duration,
range,
max_angle,
} => CharacterState::ChargedMelee(charged_melee::Data {
exhausted: false,
energy_drain: *energy_drain,
initial_damage: *initial_damage,
max_damage: *max_damage,
initial_knockback: *initial_knockback,
max_knockback: *max_knockback,
prepare_duration: *prepare_duration,
charge_duration: *charge_duration,
charge_timer: Duration::default(),
recover_duration: *recover_duration,
range: *range,
max_angle: *max_angle,
}),
CharacterAbility::ChargedRanged {
energy_cost: _,
energy_drain,
@ -497,6 +574,35 @@ impl From<&CharacterAbility> for CharacterState {
initial_projectile_speed: *initial_projectile_speed,
max_projectile_speed: *max_projectile_speed,
}),
CharacterAbility::RepeaterRanged {
energy_cost: _,
movement_duration,
holdable,
prepare_duration,
recover_duration,
projectile,
projectile_body,
projectile_light,
projectile_gravity,
projectile_speed,
repetitions,
current_rep,
} => CharacterState::RepeaterRanged(repeater_ranged::Data {
exhausted: false,
prepare_timer: Duration::default(),
holdable: *holdable,
movement_duration: *movement_duration,
prepare_duration: *prepare_duration,
recover_duration: *recover_duration,
projectile: projectile.clone(),
projectile_body: *projectile_body,
projectile_light: *projectile_light,
projectile_gravity: *projectile_gravity,
projectile_speed: *projectile_speed,
repetitions: *repetitions,
current_rep: *current_rep,
initialize: true,
}),
CharacterAbility::GroundShockwave {
energy_cost: _,
buildup_duration,

View File

@ -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(_)
)

View File

@ -226,6 +226,17 @@ impl Tool {
forward_speed: 0.0,
num_spins: 1,
},
LeapMelee {
energy_cost: 300,
movement_duration: Duration::from_millis(200),
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(600),
base_damage: (170.0 * self.base_power()) as u32,
range: 3.5,
max_angle: 50.0,
leap_speed: 20.0,
leap_vert_speed: 16.0,
},
],
Hammer(_) => vec![
BasicMelee {
@ -237,12 +248,29 @@ impl Tool {
range: 3.5,
max_angle: 20.0,
},
ChargedMelee {
energy_cost: 0,
energy_drain: 300,
initial_damage: (20.0 * self.base_power()) as u32,
max_damage: (170.0 * self.base_power()) as u32,
initial_knockback: 12.0,
max_knockback: 60.0,
prepare_duration: Duration::from_millis(200),
charge_duration: Duration::from_millis(1200),
recover_duration: Duration::from_millis(500),
range: 3.5,
max_angle: 30.0,
},
LeapMelee {
energy_cost: 800,
energy_cost: 700,
movement_duration: Duration::from_millis(500),
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(100),
base_damage: (240.0 * self.base_power()) as u32,
range: 4.5,
max_angle: 360.0,
leap_speed: 24.0,
leap_vert_speed: 8.0,
},
],
Farming(_) => vec![BasicMelee {
@ -293,6 +321,31 @@ impl Tool {
initial_projectile_speed: 100.0,
max_projectile_speed: 500.0,
},
RepeaterRanged {
energy_cost: 400,
holdable: true,
movement_duration: Duration::from_millis(200),
prepare_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(1000),
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,
repetitions: 4,
current_rep: 0,
},
],
Dagger(_) => vec![BasicMelee {
energy_cost: 0,

View File

@ -0,0 +1,171 @@
use crate::{
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
states::utils::*,
sys::character_behavior::*,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data {
/// Whether the attack fired already
pub exhausted: bool,
/// How much energy is drained per second when charging
pub energy_drain: 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,
/// How long the weapon needs to be prepared for
pub prepare_duration: Duration,
/// How long it takes to charge the weapon to max damage and knockback
pub charge_duration: Duration,
/// How long the state has been charging
pub charge_timer: Duration,
/// How long the state has until exiting
pub recover_duration: Duration,
/// Max range
pub range: f32,
/// Max angle (45.0 will give you a 90.0 angle window)
pub max_angle: f32,
}
impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
handle_move(data, &mut update, 0.3);
handle_jump(data, &mut update);
if self.prepare_duration != Duration::default() {
// Prepare (draw the bow)
update.character = CharacterState::ChargedMelee(Data {
exhausted: self.exhausted,
energy_drain: self.energy_drain,
initial_damage: self.initial_damage,
max_damage: self.max_damage,
initial_knockback: self.initial_knockback,
max_knockback: self.max_knockback,
prepare_duration: self
.prepare_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
charge_duration: self.charge_duration,
charge_timer: self.charge_timer,
recover_duration: self.recover_duration,
range: self.range,
max_angle: self.max_angle,
});
} else if data.inputs.secondary.is_pressed()
&& self.charge_timer < self.charge_duration
&& update.energy.current() > 0
{
// Charge the attack
update.character = CharacterState::ChargedMelee(Data {
exhausted: self.exhausted,
energy_drain: self.energy_drain,
initial_damage: self.initial_damage,
max_damage: self.max_damage,
initial_knockback: self.initial_knockback,
max_knockback: self.max_knockback,
prepare_duration: self.prepare_duration,
charge_timer: self
.charge_timer
.checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
charge_duration: self.charge_duration,
recover_duration: self.recover_duration,
range: self.range,
max_angle: self.max_angle,
});
// Consumes energy if there's enough left and RMB is held down
update.energy.change_by(
-(self.energy_drain as f32 * data.dt.0) as i32,
EnergySource::Ability,
);
} else if data.inputs.secondary.is_pressed() {
// Charge the attack
update.character = CharacterState::ChargedMelee(Data {
exhausted: self.exhausted,
energy_drain: self.energy_drain,
initial_damage: self.initial_damage,
max_damage: self.max_damage,
initial_knockback: self.initial_knockback,
max_knockback: self.max_knockback,
prepare_duration: self.prepare_duration,
charge_timer: self.charge_timer,
charge_duration: self.charge_duration,
recover_duration: self.recover_duration,
range: self.range,
max_angle: self.max_angle,
});
// Consumes energy if there's enough left and RMB is held down
update.energy.change_by(
-(self.energy_drain as f32 * data.dt.0 / 5.0) as i32,
EnergySource::Ability,
);
} else if !self.exhausted {
let charge_amount =
(self.charge_timer.as_secs_f32() / self.charge_duration.as_secs_f32()).min(1.0);
let damage = self.initial_damage as f32 + (charge_amount * (self.max_damage - self.initial_damage) as f32);
// Hit attempt
data.updater.insert(data.entity, Attacking {
base_damage: damage as u32,
base_heal: 0,
range: self.range,
max_angle: self.max_angle.to_radians(),
applied: false,
hit_count: 0,
knockback: self.initial_knockback
+ charge_amount * (self.max_knockback - self.initial_knockback),
});
update.character = CharacterState::ChargedMelee(Data {
exhausted: true,
energy_drain: self.energy_drain,
initial_damage: self.initial_damage,
max_damage: self.max_damage,
initial_knockback: self.initial_knockback,
max_knockback: self.max_knockback,
prepare_duration: self.prepare_duration,
charge_timer: self.charge_timer,
charge_duration: self.charge_duration,
recover_duration: self.recover_duration,
range: self.range,
max_angle: self.max_angle,
});
} else if self.recover_duration != Duration::default() {
// Recovery
update.character = CharacterState::ChargedMelee(Data {
exhausted: self.exhausted,
energy_drain: self.energy_drain,
initial_damage: self.initial_damage,
max_damage: self.max_damage,
initial_knockback: self.initial_knockback,
max_knockback: self.max_knockback,
prepare_duration: self.prepare_duration,
charge_timer: self.charge_timer,
charge_duration: self.charge_duration,
recover_duration: self
.recover_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
range: self.range,
max_angle: self.max_angle,
});
} else {
// Done
update.character = CharacterState::Wielding;
// Make sure attack component is removed
data.updater.remove::<Attacking>(data.entity);
}
update
}
}

View File

@ -7,9 +7,8 @@ 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)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
//#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub struct Data {
/// How long the state is moving
pub movement_duration: Duration,
@ -21,6 +20,14 @@ pub struct Data {
pub base_damage: u32,
/// Whether the attack can deal more damage
pub exhausted: bool,
/// Max range
pub range: f32,
/// Max angle (45.0 will give you a 90.0 angle window)
pub max_angle: f32,
/// Leap speed
pub leap_speed: f32,
/// Leap vertical speed?
pub leap_vert_speed: f32,
pub initialize: bool,
}
@ -37,13 +44,17 @@ impl CharacterBehavior for Data {
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(data.inputs.look_dir.x, data.inputs.look_dir.y, 8.0)
update.vel.0 = Vec3::new(
data.inputs.look_dir.x,
data.inputs.look_dir.y,
self.leap_vert_speed,
) * ((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
* self.leap_speed
* (1.0 - data.inputs.look_dir.z.abs());
update.character = CharacterState::LeapMelee(Data {
@ -55,6 +66,10 @@ impl CharacterBehavior for Data {
recover_duration: self.recover_duration,
base_damage: self.base_damage,
exhausted: false,
range: self.range,
max_angle: self.max_angle,
leap_speed: self.leap_speed,
leap_vert_speed: self.leap_vert_speed,
initialize: false,
});
} else if self.buildup_duration != Duration::default() && !data.physics.on_ground {
@ -68,6 +83,10 @@ impl CharacterBehavior for Data {
recover_duration: self.recover_duration,
base_damage: self.base_damage,
exhausted: false,
range: self.range,
max_angle: self.max_angle,
leap_speed: self.leap_speed,
leap_vert_speed: self.leap_vert_speed,
initialize: false,
});
} else if !self.exhausted {
@ -75,8 +94,9 @@ impl CharacterBehavior for Data {
data.updater.insert(data.entity, Attacking {
base_damage: self.base_damage,
base_heal: 0,
range: 4.5,
max_angle: 360_f32.to_radians(),
range: self.range,
//range: 4.5,
max_angle: self.max_angle.to_radians(),
applied: false,
hit_count: 0,
knockback: 25.0,
@ -88,6 +108,10 @@ impl CharacterBehavior for Data {
recover_duration: self.recover_duration,
base_damage: self.base_damage,
exhausted: true,
range: self.range,
max_angle: self.max_angle,
leap_speed: self.leap_speed,
leap_vert_speed: self.leap_vert_speed,
initialize: false,
});
} else if self.recover_duration != Duration::default() {
@ -102,6 +126,10 @@ impl CharacterBehavior for Data {
.unwrap_or_default(),
base_damage: self.base_damage,
exhausted: true,
range: self.range,
max_angle: self.max_angle,
leap_speed: self.leap_speed,
leap_vert_speed: self.leap_vert_speed,
initialize: false,
});
} else {

View File

@ -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;

View File

@ -0,0 +1,153 @@
use crate::{
comp::{Body, CharacterState, Gravity, LightEmitter, Projectile, StateUpdate},
event::ServerEvent,
states::utils::*,
sys::character_behavior::*,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use vek::Vec3;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data {
/// How long the state is moving
pub movement_duration: Duration,
/// Can you hold the ability beyond the prepare duration
pub holdable: bool,
/// How long we have to prepare the weapon
pub prepare_duration: Duration,
/// How long we prepared the weapon already
pub prepare_timer: Duration,
/// How long the state has until exiting
pub recover_duration: Duration,
pub projectile: Projectile,
pub projectile_body: Body,
pub projectile_light: Option<LightEmitter>,
pub projectile_gravity: Option<Gravity>,
pub projectile_speed: f32,
/// Whether the attack fired already
pub exhausted: bool,
/// How many times to repeat
pub repetitions: u32,
/// Current repetition
pub current_rep: u32,
pub initialize: bool,
}
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);
if !self.exhausted
&& if self.holdable {
data.inputs.holding_ability_key() || self.prepare_timer < self.prepare_duration
} else {
self.prepare_timer < self.prepare_duration
}
{
// Prepare (draw the bow)
update.character = CharacterState::RepeaterRanged(Data {
movement_duration: self.movement_duration,
prepare_timer: self.prepare_timer + Duration::from_secs_f32(data.dt.0),
holdable: self.holdable,
prepare_duration: self.prepare_duration,
recover_duration: self.recover_duration,
projectile: self.projectile.clone(),
projectile_body: self.projectile_body,
projectile_light: self.projectile_light,
projectile_gravity: self.projectile_gravity,
projectile_speed: self.projectile_speed,
exhausted: false,
repetitions: self.repetitions,
current_rep: self.current_rep,
initialize: false,
});
} else if self.movement_duration != Duration::default() {
// Jumping
update.vel.0 = Vec3::new(data.vel.0[0], data.vel.0[1], 10.0);
update.character = CharacterState::RepeaterRanged(Data {
movement_duration: self
.movement_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
prepare_timer: self.prepare_timer,
holdable: self.holdable,
prepare_duration: self.prepare_duration,
recover_duration: self.recover_duration,
projectile: self.projectile.clone(),
projectile_body: self.projectile_body,
projectile_light: self.projectile_light,
projectile_gravity: self.projectile_gravity,
projectile_speed: self.projectile_speed,
exhausted: false,
repetitions: self.repetitions,
current_rep: self.current_rep,
initialize: false,
});
} else if !self.exhausted && self.current_rep < self.repetitions {
let mut projectile = self.projectile.clone();
projectile.owner = Some(*data.uid);
update.server_events.push_front(ServerEvent::Shoot {
entity: data.entity,
dir: data.inputs.look_dir,
body: self.projectile_body,
projectile,
light: self.projectile_light,
gravity: self.projectile_gravity,
speed: self.projectile_speed,
});
update.character = CharacterState::RepeaterRanged(Data {
movement_duration: self.movement_duration,
prepare_timer: self.prepare_timer,
holdable: self.holdable,
prepare_duration: self.prepare_duration,
//recover_duration: self.recover_duration,
recover_duration: self
.recover_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
projectile: self.projectile.clone(),
projectile_body: self.projectile_body,
projectile_light: self.projectile_light,
projectile_gravity: self.projectile_gravity,
projectile_speed: self.projectile_speed,
exhausted: false,
repetitions: self.repetitions,
current_rep: self.current_rep + 1,
initialize: false,
});
} else if self.recover_duration != Duration::default() {
// Recovery
update.character = CharacterState::RepeaterRanged(Data {
movement_duration: Duration::default(),
prepare_timer: self.prepare_timer,
holdable: self.holdable,
prepare_duration: self.prepare_duration,
recover_duration: self
.recover_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
projectile: self.projectile.clone(),
projectile_body: self.projectile_body,
projectile_light: self.projectile_light,
projectile_gravity: self.projectile_gravity,
projectile_speed: self.projectile_speed,
exhausted: true,
repetitions: self.repetitions,
current_rep: 0,
initialize: false,
});
return update;
} else {
// Done
update.character = CharacterState::Wielding;
}
update
}
}

View File

@ -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),
};

View File

@ -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 {

View File

@ -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);
},
_ => {},
}

View File

@ -2,6 +2,7 @@ use super::{super::Animation, CharacterSkeleton, SkeletonAttr};
use common::comp::item::{Hands, ToolKind};
/* use std::f32::consts::PI; */
use super::super::vek::*;
use std::f32::consts::PI;
pub struct LeapAnimation;
@ -31,6 +32,19 @@ impl Animation for LeapAnimation {
.sqrt())
* ((anim_time as f32 * lab as f32 * 4.0).sin());
// Spin stuff here
let foot = (((5.0)
/ (1.1 + 3.9 * ((anim_time as f32 * lab as f32 * 10.32).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 * 10.32).sin());
let decel = (anim_time as f32 * 16.0 * lab as f32).min(PI / 2.0).sin();
let spin = (anim_time as f32 * 2.8 * lab as f32).sin();
let spinhalf = (anim_time as f32 * 1.4 * lab as f32).sin();
// end spin stuff
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);
@ -94,16 +108,119 @@ impl Animation for LeapAnimation {
* Quaternion::rotation_y(0.0)
* Quaternion::rotation_z(1.4 + slowersmooth * -0.4 + slower * 0.2);
next.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.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;
} else if let Some(ToolKind::Axe(_)) = active_tool_kind {
//INTENTION: SWORD
next.l_hand.position = Vec3::new(-0.75, -1.0, -2.5);
next.l_hand.orientation = Quaternion::rotation_x(1.27);
next.l_hand.scale = Vec3::one() * 1.04;
next.r_hand.position = Vec3::new(0.75, -1.5, -5.5);
next.r_hand.orientation = Quaternion::rotation_x(1.27);
next.r_hand.scale = Vec3::one() * 1.05;
//next.main.position = Vec3::new(0.0, 0.0, 10.0);
next.main.position = Vec3::new(0.0, 0.0, -5.0);
next.main.orientation = Quaternion::rotation_x(1.6)
* Quaternion::rotation_y(0.0)
* Quaternion::rotation_z(-0.4);
next.main.scale = Vec3::one();
next.control.position = Vec3::new(-4.5 + spinhalf * 4.0, 11.0, 8.0);
next.control.orientation = Quaternion::rotation_x(0.6 + spinhalf * -3.3)
* Quaternion::rotation_y(0.2 + spin * -2.0)
* Quaternion::rotation_z(1.4 + spin * 0.1);
next.control.scale = Vec3::one();
next.head.position = Vec3::new(
0.0,
-2.0 + skeleton_attr.head.0 + spin * -0.8,
skeleton_attr.head.1,
);
next.head.orientation = Quaternion::rotation_z(spin * -0.25)
* Quaternion::rotation_x(0.0 + spin * -0.1)
* Quaternion::rotation_y(spin * -0.2);
next.chest.position = Vec3::new(0.0, skeleton_attr.chest.0, skeleton_attr.chest.1);
next.chest.orientation = Quaternion::rotation_z(spin * 0.1)
* Quaternion::rotation_x(0.0 + spin * 0.1)
* Quaternion::rotation_y(decel * -0.2);
next.chest.scale = Vec3::one();
next.belt.position = Vec3::new(0.0, 0.0, -2.0);
next.belt.orientation = next.chest.orientation * -0.1;
next.belt.scale = Vec3::one();
next.shorts.position = Vec3::new(0.0, 0.0, -5.0);
next.belt.orientation = next.chest.orientation * -0.08;
next.shorts.scale = Vec3::one();
next.torso.position = Vec3::new(0.0, 0.0, 0.1) * skeleton_attr.scaler;
next.torso.orientation = Quaternion::rotation_z((spin * 7.0).max(0.3))
* Quaternion::rotation_x(0.0)
* Quaternion::rotation_y(0.3);
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
// Stuff after the branch in the spin animation file
next.l_foot.position =
Vec3::new(-skeleton_attr.foot.0, foot * 1.0, skeleton_attr.foot.2);
next.l_foot.orientation = Quaternion::rotation_x(foot * -1.2);
next.l_foot.scale = Vec3::one();
next.r_foot.position =
Vec3::new(skeleton_attr.foot.0, foot * -1.0, skeleton_attr.foot.2);
next.r_foot.orientation = Quaternion::rotation_x(foot * 1.2);
next.r_foot.scale = Vec3::one();
next.l_shoulder.position = Vec3::new(-5.0, 0.0, 4.7);
next.l_shoulder.orientation = Quaternion::rotation_x(0.0);
next.l_shoulder.scale = Vec3::one() * 1.1;
next.r_shoulder.position = Vec3::new(5.0, 0.0, 4.7);
next.r_shoulder.orientation = Quaternion::rotation_x(0.0);
next.r_shoulder.scale = Vec3::one() * 1.1;
next.glider.position = Vec3::new(0.0, 5.0, 0.0);
next.glider.orientation = Quaternion::rotation_y(0.0);
next.glider.scale = Vec3::one() * 0.0;
next.lantern.position = Vec3::new(
skeleton_attr.lantern.0,
skeleton_attr.lantern.1,
skeleton_attr.lantern.2,
);
next.lantern.orientation =
Quaternion::rotation_x(spin * -0.7 + 0.4) * Quaternion::rotation_y(spin * 0.4);
next.lantern.scale = Vec3::one() * 0.65;
next.hold.scale = Vec3::one() * 0.0;
next.l_control.position = Vec3::new(0.0, 0.0, 0.0);
next.l_control.orientation = Quaternion::rotation_x(0.0);
next.l_control.scale = Vec3::one();
next.r_control.position = Vec3::new(0.0, 0.0, 0.0);
next.r_control.orientation = Quaternion::rotation_x(0.0);
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.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 +230,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
}
}

View File

@ -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 \