Addressed first round of feedback on sword overhaul.

This commit is contained in:
Sam 2020-09-12 11:46:21 -05:00
parent c99e4c3c18
commit b06ab250cc
10 changed files with 170 additions and 135 deletions

View File

@ -6,7 +6,7 @@ ItemDef(
kind: Sword("Zweihander0"), kind: Sword("Zweihander0"),
stats: ( stats: (
equip_time_millis: 500, equip_time_millis: 500,
power: 0.2, power: 0.75,
), ),
) )
), ),

View File

@ -94,19 +94,19 @@
], ],
threshold: 0.5, threshold: 0.5,
), ),
Attack(ComboMelee(First), Sword): ( Attack(ComboMelee(1), Sword): (
files: [ files: [
"voxygen.audio.sfx.abilities.swing_sword", "voxygen.audio.sfx.abilities.swing_sword",
], ],
threshold: 0.7, threshold: 0.7,
), ),
Attack(ComboMelee(Second), Sword): ( Attack(ComboMelee(2), Sword): (
files: [ files: [
"voxygen.audio.sfx.abilities.separated_second_swing", "voxygen.audio.sfx.abilities.separated_second_swing",
], ],
threshold: 0.7, threshold: 0.7,
), ),
Attack(ComboMelee(Third), Sword): ( Attack(ComboMelee(3), Sword): (
files: [ files: [
"voxygen.audio.sfx.abilities.separated_third_swing", "voxygen.audio.sfx.abilities.separated_third_swing",
], ],
@ -174,19 +174,7 @@
], ],
threshold: 0.5, threshold: 0.5,
), ),
Attack(ComboMelee(First), Axe): ( Attack(BasicMelee, Axe): (
files: [
"voxygen.audio.sfx.abilities.swing",
],
threshold: 0.7,
),
Attack(ComboMelee(Second), Axe): (
files: [
"voxygen.audio.sfx.abilities.swing",
],
threshold: 0.7,
),
Attack(ComboMelee(Third), Axe): (
files: [ files: [
"voxygen.audio.sfx.abilities.swing", "voxygen.audio.sfx.abilities.swing",
], ],

View File

@ -20,7 +20,7 @@ pub enum CharacterAbilityType {
ChargedRanged, ChargedRanged,
DashMelee, DashMelee,
BasicBlock, BasicBlock,
ComboMelee, ComboMelee(u32),
LeapMelee, LeapMelee,
SpinMelee, SpinMelee,
GroundShockwave, GroundShockwave,
@ -35,7 +35,7 @@ impl From<&CharacterState> for CharacterAbilityType {
CharacterState::DashMelee(_) => Self::DashMelee, CharacterState::DashMelee(_) => Self::DashMelee,
CharacterState::BasicBlock => Self::BasicBlock, CharacterState::BasicBlock => Self::BasicBlock,
CharacterState::LeapMelee(_) => Self::LeapMelee, CharacterState::LeapMelee(_) => Self::LeapMelee,
CharacterState::ComboMelee(_) => Self::ComboMelee, CharacterState::ComboMelee(data) => Self::ComboMelee(data.stage),
CharacterState::SpinMelee(_) => Self::SpinMelee, CharacterState::SpinMelee(_) => Self::SpinMelee,
CharacterState::ChargedRanged(_) => Self::ChargedRanged, CharacterState::ChargedRanged(_) => Self::ChargedRanged,
CharacterState::GroundShockwave(_) => Self::ChargedRanged, CharacterState::GroundShockwave(_) => Self::ChargedRanged,
@ -85,6 +85,7 @@ pub enum CharacterAbility {
swing_duration: Duration, swing_duration: Duration,
recover_duration: Duration, recover_duration: Duration,
infinite_charge: bool, infinite_charge: bool,
is_interruptible: bool,
}, },
BasicBlock, BasicBlock,
Roll, Roll,
@ -95,6 +96,7 @@ pub enum CharacterAbility {
energy_increase: u32, energy_increase: u32,
speed_increase: f32, speed_increase: f32,
max_speed_increase: f32, max_speed_increase: f32,
is_interruptible: bool,
}, },
LeapMelee { LeapMelee {
energy_cost: u32, energy_cost: u32,
@ -334,6 +336,7 @@ impl From<&CharacterAbility> for CharacterState {
swing_duration, swing_duration,
recover_duration, recover_duration,
infinite_charge, infinite_charge,
is_interruptible,
} => CharacterState::DashMelee(dash_melee::Data { } => CharacterState::DashMelee(dash_melee::Data {
static_data: dash_melee::StaticData { static_data: dash_melee::StaticData {
base_damage: *base_damage, base_damage: *base_damage,
@ -349,6 +352,7 @@ impl From<&CharacterAbility> for CharacterState {
charge_duration: *charge_duration, charge_duration: *charge_duration,
swing_duration: *swing_duration, swing_duration: *swing_duration,
recover_duration: *recover_duration, recover_duration: *recover_duration,
is_interruptible: *is_interruptible,
}, },
end_charge: false, end_charge: false,
timer: Duration::default(), timer: Duration::default(),
@ -367,6 +371,7 @@ impl From<&CharacterAbility> for CharacterState {
energy_increase, energy_increase,
speed_increase, speed_increase,
max_speed_increase, max_speed_increase,
is_interruptible,
} => CharacterState::ComboMelee(combo_melee::Data { } => CharacterState::ComboMelee(combo_melee::Data {
stage: 1, stage: 1,
num_stages: stage_data.len() as u32, num_stages: stage_data.len() as u32,
@ -380,6 +385,7 @@ impl From<&CharacterAbility> for CharacterState {
next_stage: false, next_stage: false,
speed_increase: 1.0 - *speed_increase, speed_increase: 1.0 - *speed_increase,
max_speed_increase: *max_speed_increase - 1.0, max_speed_increase: *max_speed_increase - 1.0,
is_interruptible: *is_interruptible,
}), }),
CharacterAbility::LeapMelee { CharacterAbility::LeapMelee {
energy_cost: _, energy_cost: _,

View File

@ -124,7 +124,7 @@ impl Tool {
base_damage: (100.0 * self.base_power()) as u32, base_damage: (100.0 * self.base_power()) as u32,
max_damage: (120.0 * self.base_power()) as u32, max_damage: (120.0 * self.base_power()) as u32,
damage_increase: (10.0 * self.base_power()) as u32, damage_increase: (10.0 * self.base_power()) as u32,
knockback: 5.0, knockback: 8.0,
range: 4.0, range: 4.0,
angle: 30.0, angle: 30.0,
base_buildup_duration: Duration::from_millis(500), base_buildup_duration: Duration::from_millis(500),
@ -150,7 +150,7 @@ impl Tool {
base_damage: (130.0 * self.base_power()) as u32, base_damage: (130.0 * self.base_power()) as u32,
max_damage: (170.0 * self.base_power()) as u32, max_damage: (170.0 * self.base_power()) as u32,
damage_increase: (20.0 * self.base_power()) as u32, damage_increase: (20.0 * self.base_power()) as u32,
knockback: 7.5, knockback: 14.0,
range: 6.0, range: 6.0,
angle: 10.0, angle: 10.0,
base_buildup_duration: Duration::from_millis(500), base_buildup_duration: Duration::from_millis(500),
@ -164,11 +164,12 @@ impl Tool {
energy_increase: 20, energy_increase: 20,
speed_increase: 0.05, speed_increase: 0.05,
max_speed_increase: 1.8, max_speed_increase: 1.8,
is_interruptible: true,
}, },
DashMelee { DashMelee {
energy_cost: 200, energy_cost: 200,
base_damage: (60.0 * self.base_power()) as u32, base_damage: (120.0 * self.base_power()) as u32,
max_damage: (180.0 * self.base_power()) as u32, max_damage: (260.0 * self.base_power()) as u32,
base_knockback: 5.0, base_knockback: 5.0,
max_knockback: 10.0, max_knockback: 10.0,
range: 5.0, range: 5.0,
@ -178,8 +179,9 @@ impl Tool {
buildup_duration: Duration::from_millis(200), buildup_duration: Duration::from_millis(200),
charge_duration: Duration::from_millis(400), charge_duration: Duration::from_millis(400),
swing_duration: Duration::from_millis(100), swing_duration: Duration::from_millis(100),
recover_duration: Duration::from_millis(750), recover_duration: Duration::from_millis(500),
infinite_charge: true, infinite_charge: true,
is_interruptible: true,
}, },
], ],
Axe(_) => vec![ Axe(_) => vec![

View File

@ -43,7 +43,7 @@ pub struct Data {
pub num_stages: u32, pub num_stages: u32,
/// Number of consecutive strikes /// Number of consecutive strikes
pub combo: u32, pub combo: u32,
/// Data for first stage /// Data for each stage
pub stage_data: Vec<Stage>, pub stage_data: Vec<Stage>,
/// Initial energy gain per strike /// Initial energy gain per strike
pub initial_energy_gain: u32, pub initial_energy_gain: u32,
@ -57,10 +57,13 @@ pub struct Data {
pub stage_section: StageSection, pub stage_section: StageSection,
/// Whether the state should go onto the next stage /// Whether the state should go onto the next stage
pub next_stage: bool, pub next_stage: bool,
/// (100% - speed_increase) is percentage speed increases from current to max when combo increases /// (100% - speed_increase) is percentage speed increases from current to
/// max when combo increases
pub speed_increase: f32, pub speed_increase: f32,
/// (100% + max_speed_increase) is the max attack speed /// (100% + max_speed_increase) is the max attack speed
pub max_speed_increase: f32, pub max_speed_increase: f32,
/// Whether the state can be interrupted by other abilities
pub is_interruptible: bool,
} }
impl CharacterBehavior for Data { impl CharacterBehavior for Data {
@ -68,10 +71,22 @@ impl CharacterBehavior for Data {
let mut update = StateUpdate::from(data); let mut update = StateUpdate::from(data);
handle_orientation(data, &mut update, 1.0); handle_orientation(data, &mut update, 1.0);
handle_move(data, &mut update, 0.1); handle_move(data, &mut update, 0.3);
let stage_index = (self.stage - 1) as usize; let stage_index = (self.stage - 1) as usize;
// Allows for other states to interrupt this state
if self.is_interruptible && !data.inputs.primary.is_pressed() {
if data.inputs.roll.is_pressed() {
handle_dodge_input(data, &mut update);
return update;
}
if data.inputs.secondary.is_pressed() {
handle_ability2_input(data, &mut update);
return update;
}
}
if self.stage_section == StageSection::Buildup if self.stage_section == StageSection::Buildup
&& self.timer < self.stage_data[stage_index].base_buildup_duration && self.timer < self.stage_data[stage_index].base_buildup_duration
{ {
@ -86,12 +101,17 @@ impl CharacterBehavior for Data {
energy_increase: self.energy_increase, energy_increase: self.energy_increase,
timer: self timer: self
.timer .timer
.checked_add(Duration::from_secs_f32((1.0 + self.max_speed_increase * (1.0 - self.speed_increase.powi(self.combo as i32))) * data.dt.0)) .checked_add(Duration::from_secs_f32(
(1.0 + self.max_speed_increase
* (1.0 - self.speed_increase.powi(self.combo as i32)))
* data.dt.0,
))
.unwrap_or_default(), .unwrap_or_default(),
stage_section: self.stage_section, stage_section: self.stage_section,
next_stage: self.next_stage, next_stage: self.next_stage,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
} else if self.stage_section == StageSection::Buildup { } else if self.stage_section == StageSection::Buildup {
// Transitions to swing section of stage // Transitions to swing section of stage
@ -108,6 +128,7 @@ impl CharacterBehavior for Data {
next_stage: self.next_stage, next_stage: self.next_stage,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
// Hit attempt // Hit attempt
@ -130,7 +151,7 @@ impl CharacterBehavior for Data {
forward_move( forward_move(
data, data,
&mut update, &mut update,
0.1, 0.3,
self.stage_data[stage_index].forward_movement, self.stage_data[stage_index].forward_movement,
); );
@ -145,12 +166,17 @@ impl CharacterBehavior for Data {
energy_increase: self.energy_increase, energy_increase: self.energy_increase,
timer: self timer: self
.timer .timer
.checked_add(Duration::from_secs_f32((1.0 + self.max_speed_increase * (1.0 - self.speed_increase.powi(self.combo as i32))) * data.dt.0)) .checked_add(Duration::from_secs_f32(
(1.0 + self.max_speed_increase
* (1.0 - self.speed_increase.powi(self.combo as i32)))
* data.dt.0,
))
.unwrap_or_default(), .unwrap_or_default(),
stage_section: self.stage_section, stage_section: self.stage_section,
next_stage: self.next_stage, next_stage: self.next_stage,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
} else if self.stage_section == StageSection::Swing { } else if self.stage_section == StageSection::Swing {
// Transitions to recover section of stage // Transitions to recover section of stage
@ -167,6 +193,7 @@ impl CharacterBehavior for Data {
next_stage: self.next_stage, next_stage: self.next_stage,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
} else if self.stage_section == StageSection::Recover } else if self.stage_section == StageSection::Recover
&& self.timer < self.stage_data[stage_index].base_recover_duration && self.timer < self.stage_data[stage_index].base_recover_duration
@ -184,12 +211,17 @@ impl CharacterBehavior for Data {
energy_increase: self.energy_increase, energy_increase: self.energy_increase,
timer: self timer: self
.timer .timer
.checked_add(Duration::from_secs_f32((1.0 + self.max_speed_increase * (1.0 - self.speed_increase.powi(self.combo as i32))) * data.dt.0)) .checked_add(Duration::from_secs_f32(
(1.0 + self.max_speed_increase
* (1.0 - self.speed_increase.powi(self.combo as i32)))
* data.dt.0,
))
.unwrap_or_default(), .unwrap_or_default(),
stage_section: self.stage_section, stage_section: self.stage_section,
next_stage: true, next_stage: true,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
} else { } else {
update.character = CharacterState::ComboMelee(Data { update.character = CharacterState::ComboMelee(Data {
@ -202,12 +234,17 @@ impl CharacterBehavior for Data {
energy_increase: self.energy_increase, energy_increase: self.energy_increase,
timer: self timer: self
.timer .timer
.checked_add(Duration::from_secs_f32((1.0 + self.max_speed_increase * (1.0 - self.speed_increase.powi(self.combo as i32))) * data.dt.0)) .checked_add(Duration::from_secs_f32(
(1.0 + self.max_speed_increase
* (1.0 - self.speed_increase.powi(self.combo as i32)))
* data.dt.0,
))
.unwrap_or_default(), .unwrap_or_default(),
stage_section: self.stage_section, stage_section: self.stage_section,
next_stage: self.next_stage, next_stage: self.next_stage,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
} }
} else if self.next_stage { } else if self.next_stage {
@ -225,6 +262,7 @@ impl CharacterBehavior for Data {
next_stage: false, next_stage: false,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
} else { } else {
// Done // Done
@ -253,6 +291,7 @@ impl CharacterBehavior for Data {
next_stage: self.next_stage, next_stage: self.next_stage,
speed_increase: self.speed_increase, speed_increase: self.speed_increase,
max_speed_increase: self.max_speed_increase, max_speed_increase: self.max_speed_increase,
is_interruptible: self.is_interruptible,
}); });
data.updater.remove::<Attacking>(data.entity); data.updater.remove::<Attacking>(data.entity);
update.energy.change_by(energy, EnergySource::HitEnemy); update.energy.change_by(energy, EnergySource::HitEnemy);

View File

@ -5,6 +5,7 @@ use crate::{
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::Duration; use std::time::Duration;
use vek::Vec3;
/// Separated out to condense update portions of character state /// Separated out to condense update portions of character state
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -35,11 +36,14 @@ pub struct StaticData {
pub swing_duration: Duration, pub swing_duration: Duration,
/// How long the state has until exiting /// How long the state has until exiting
pub recover_duration: Duration, pub recover_duration: Duration,
/// Whether the state can be interrupted by other abilities
pub is_interruptible: bool,
} }
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data { pub struct Data {
/// Struct containing data that does not change over the course of the character state /// Struct containing data that does not change over the course of the
/// character state
pub static_data: StaticData, pub static_data: StaticData,
/// Whether the charge should end /// Whether the charge should end
pub end_charge: bool, pub end_charge: bool,
@ -58,7 +62,21 @@ impl CharacterBehavior for Data {
handle_orientation(data, &mut update, 1.0); handle_orientation(data, &mut update, 1.0);
handle_move(data, &mut update, 0.1); handle_move(data, &mut update, 0.1);
if self.stage_section == StageSection::Buildup && self.timer < self.static_data.buildup_duration { // Allows for other states to interrupt this state
if self.static_data.is_interruptible && !data.inputs.secondary.is_pressed() {
if data.inputs.roll.is_pressed() {
handle_dodge_input(data, &mut update);
return update;
}
if data.inputs.primary.is_pressed() {
handle_ability1_input(data, &mut update);
return update;
}
}
if self.stage_section == StageSection::Buildup
&& self.timer < self.static_data.buildup_duration
{
// Build up // Build up
update.character = CharacterState::DashMelee(Data { update.character = CharacterState::DashMelee(Data {
static_data: self.static_data, static_data: self.static_data,
@ -80,23 +98,26 @@ impl CharacterBehavior for Data {
exhausted: self.exhausted, exhausted: self.exhausted,
}) })
} else if self.stage_section == StageSection::Charge } else if self.stage_section == StageSection::Charge
&& ((self.timer < self.static_data.charge_duration && !self.static_data.infinite_charge) && (self.timer < self.static_data.charge_duration
|| (data.inputs.secondary.is_pressed() && self.static_data.infinite_charge)) || (self.static_data.infinite_charge && data.inputs.secondary.is_pressed()))
&& update.energy.current() > 0 && update.energy.current() > 0
&& !self.end_charge && !self.end_charge
{ {
// Forward movement // Forward movement
forward_move(data, &mut update, 0.1, self.static_data.forward_speed); forward_move(data, &mut update, 0.1, self.static_data.forward_speed);
// Hit attempt // Hit attempt (also checks if player is moving)
if !self.exhausted { if !self.exhausted && update.vel.0.distance_squared(Vec3::zero()) > 1.0 {
let charge_frac = (self.timer.as_secs_f32() let charge_frac = (self.timer.as_secs_f32()
/ self.static_data.charge_duration.as_secs_f32()) / self.static_data.charge_duration.as_secs_f32())
.min(1.0); .min(1.0);
let damage = (self.static_data.max_damage as f32 - self.static_data.base_damage as f32) * charge_frac let damage = (self.static_data.max_damage as f32
- self.static_data.base_damage as f32)
* charge_frac
+ self.static_data.base_damage as f32; + self.static_data.base_damage as f32;
let knockback = let knockback = (self.static_data.max_knockback - self.static_data.base_knockback)
(self.static_data.max_knockback - self.static_data.base_knockback) * charge_frac + self.static_data.base_knockback; * charge_frac
+ self.static_data.base_knockback;
data.updater.insert(data.entity, Attacking { data.updater.insert(data.entity, Attacking {
base_healthchange: -damage as i32, base_healthchange: -damage as i32,
range: self.static_data.range, range: self.static_data.range,
@ -107,7 +128,8 @@ impl CharacterBehavior for Data {
}); });
} }
// This logic basically just decides if a charge should end, and prevents the character state spamming attacks while checking if it has hit something // This logic basically just decides if a charge should end, and prevents the
// character state spamming attacks while checking if it has hit something
if !self.exhausted { if !self.exhausted {
update.character = CharacterState::DashMelee(Data { update.character = CharacterState::DashMelee(Data {
static_data: self.static_data, static_data: self.static_data,
@ -119,42 +141,29 @@ impl CharacterBehavior for Data {
stage_section: StageSection::Charge, stage_section: StageSection::Charge,
exhausted: true, exhausted: true,
}) })
} else { } else if let Some(attack) = data.attacking {
if let Some(attack) = data.attacking { if attack.applied && attack.hit_count > 0 {
if attack.applied && attack.hit_count > 0 { update.character = CharacterState::DashMelee(Data {
update.character = CharacterState::DashMelee(Data { static_data: self.static_data,
static_data: self.static_data, end_charge: !self.static_data.infinite_charge,
end_charge: !self.static_data.infinite_charge, timer: self
timer: self .timer
.timer .checked_add(Duration::from_secs_f32(data.dt.0))
.checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(),
.unwrap_or_default(), stage_section: StageSection::Charge,
stage_section: StageSection::Charge, exhausted: false,
exhausted: false, })
}) } else if attack.applied {
} else if attack.applied { update.character = CharacterState::DashMelee(Data {
update.character = CharacterState::DashMelee(Data { static_data: self.static_data,
static_data: self.static_data, end_charge: self.end_charge,
end_charge: self.end_charge, timer: self
timer: self .timer
.timer .checked_add(Duration::from_secs_f32(data.dt.0))
.checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(),
.unwrap_or_default(), stage_section: StageSection::Charge,
stage_section: StageSection::Charge, exhausted: false,
exhausted: false, })
})
} else {
update.character = CharacterState::DashMelee(Data {
static_data: self.static_data,
end_charge: !self.static_data.infinite_charge,
timer: self
.timer
.checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
stage_section: StageSection::Charge,
exhausted: self.exhausted,
})
}
} else { } else {
update.character = CharacterState::DashMelee(Data { update.character = CharacterState::DashMelee(Data {
static_data: self.static_data, static_data: self.static_data,
@ -167,6 +176,17 @@ impl CharacterBehavior for Data {
exhausted: self.exhausted, exhausted: self.exhausted,
}) })
} }
} else {
update.character = CharacterState::DashMelee(Data {
static_data: self.static_data,
end_charge: !self.static_data.infinite_charge,
timer: self
.timer
.checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
stage_section: StageSection::Charge,
exhausted: self.exhausted,
})
} }
// Consumes energy if there's enough left and charge has not stopped // Consumes energy if there's enough left and charge has not stopped
@ -183,7 +203,9 @@ impl CharacterBehavior for Data {
stage_section: StageSection::Swing, stage_section: StageSection::Swing,
exhausted: self.exhausted, exhausted: self.exhausted,
}) })
} else if self.stage_section == StageSection::Swing && self.timer < self.static_data.swing_duration { } else if self.stage_section == StageSection::Swing
&& self.timer < self.static_data.swing_duration
{
// Swings // Swings
update.character = CharacterState::DashMelee(Data { update.character = CharacterState::DashMelee(Data {
static_data: self.static_data, static_data: self.static_data,
@ -204,7 +226,8 @@ impl CharacterBehavior for Data {
stage_section: StageSection::Recover, stage_section: StageSection::Recover,
exhausted: self.exhausted, exhausted: self.exhausted,
}) })
} else if self.stage_section == StageSection::Recover && self.timer < self.static_data.recover_duration } else if self.stage_section == StageSection::Recover
&& self.timer < self.static_data.recover_duration
{ {
// Recover // Recover
update.character = CharacterState::DashMelee(Data { update.character = CharacterState::DashMelee(Data {

View File

@ -98,10 +98,9 @@ pub fn forward_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32,
BASE_HUMANOID_AIR_ACCEL BASE_HUMANOID_AIR_ACCEL
}; };
update.vel.0 = update.vel.0 update.vel.0 += Vec2::broadcast(data.dt.0)
+ Vec2::broadcast(data.dt.0) * accel
* accel * (data.inputs.move_dir * efficiency + (*update.ori.0).xy() * forward);
* (data.inputs.move_dir * efficiency + (*update.ori.0).xy() * forward);
handle_orientation(data, update, data.body.base_ori_rate() * efficiency); handle_orientation(data, update, data.body.base_ori_rate() * efficiency);
} }

View File

@ -115,11 +115,17 @@ impl<'a> System<'a> for Sys {
let mut body = entity.body; let mut body = entity.body;
let name = entity.name.unwrap_or_else(|| "Unnamed".to_string()); let name = entity.name.unwrap_or_else(|| "Unnamed".to_string());
let alignment = entity.alignment; let alignment = entity.alignment;
let main_tool = entity.main_tool; let mut main_tool = entity.main_tool;
let mut stats = comp::Stats::new(name, body); let mut stats = comp::Stats::new(name, body);
// let damage = stats.level.level() as i32; TODO: Make NPC base damage // let damage = stats.level.level() as i32; TODO: Make NPC base damage
// non-linearly depend on their level // non-linearly depend on their level
if entity.is_giant {
main_tool = Some(comp::Item::new_from_asset_expect(
"common.items.npc_weapons.sword.zweihander_sword_0",
));
}
let mut loadout = LoadoutBuilder::build_loadout(body, alignment, main_tool).build(); let mut loadout = LoadoutBuilder::build_loadout(body, alignment, main_tool).build();
let mut scale = entity.scale; let mut scale = entity.scale;
@ -152,24 +158,7 @@ impl<'a> System<'a> for Sys {
); );
} }
loadout = comp::Loadout { loadout = comp::Loadout {
active_item: Some(comp::ItemConfig { active_item,
item: comp::Item::new_from_asset_expect(
"common.items.npc_weapons.sword.zweihander_sword_0",
),
ability1: Some(CharacterAbility::BasicMelee {
energy_cost: 0,
buildup_duration: Duration::from_millis(800),
recover_duration: Duration::from_millis(200),
base_healthchange: -100,
knockback: 0.0,
range: 3.5,
max_angle: 60.0,
}),
ability2: None,
ability3: None,
block_ability: None,
dodge_ability: None,
}),
second_item: None, second_item: None,
shoulder: Some(comp::Item::new_from_asset_expect( shoulder: Some(comp::Item::new_from_asset_expect(
"common.items.armor.shoulder.plate_0", "common.items.armor.shoulder.plate_0",

View File

@ -13,7 +13,12 @@ pub struct Input {
pub struct DashAnimation; pub struct DashAnimation;
impl Animation for DashAnimation { impl Animation for DashAnimation {
type Dependency = (Option<ToolKind>, Option<ToolKind>, f64, Option<StageSection>); type Dependency = (
Option<ToolKind>,
Option<ToolKind>,
f64,
Option<StageSection>,
);
type Skeleton = CharacterSkeleton; type Skeleton = CharacterSkeleton;
#[cfg(feature = "use-dyn-lib")] #[cfg(feature = "use-dyn-lib")]
@ -47,21 +52,13 @@ impl Animation for DashAnimation {
Some(ToolKind::Sword(_)) => { Some(ToolKind::Sword(_)) => {
if let Some(stage_section) = stage_section { if let Some(stage_section) = stage_section {
match stage_section { match stage_section {
StageSection::Buildup => { StageSection::Buildup => {},
StageSection::Charge => {},
}, StageSection::Swing => {},
StageSection::Charge => { StageSection::Recover => {},
},
StageSection::Swing => {
},
StageSection::Recover => {
}
} }
} }
next.head.position = Vec3::new( next.head.position = Vec3::new(
0.0, 0.0,
-2.0 + skeleton_attr.head.0, -2.0 + skeleton_attr.head.0,

View File

@ -901,34 +901,26 @@ impl FigureMgr {
let stage_time = s.timer.as_secs_f64(); let stage_time = s.timer.as_secs_f64();
let stage_progress = match s.stage_section { let stage_progress = match s.stage_section {
StageSection::Buildup => { StageSection::Buildup => {
stage_time stage_time / s.static_data.buildup_duration.as_secs_f64()
/ s.static_data
.buildup_duration
.as_secs_f64()
}, },
StageSection::Charge => { StageSection::Charge => {
stage_time stage_time / s.static_data.charge_duration.as_secs_f64()
/ s.static_data
.charge_duration
.as_secs_f64()
}, },
StageSection::Swing => { StageSection::Swing => {
stage_time stage_time / s.static_data.swing_duration.as_secs_f64()
/ s.static_data
.swing_duration
.as_secs_f64()
}, },
StageSection::Recover => { StageSection::Recover => {
stage_time stage_time / s.static_data.recover_duration.as_secs_f64()
/ s.static_data
.recover_duration
.as_secs_f64()
}, },
_ => 0.0,
}; };
anim::character::DashAnimation::update_skeleton( anim::character::DashAnimation::update_skeleton(
&target_base, &target_base,
(active_tool_kind, second_tool_kind, time, Some(s.stage_section)), (
active_tool_kind,
second_tool_kind,
time,
Some(s.stage_section),
),
stage_progress, stage_progress,
&mut state_animation_rate, &mut state_animation_rate,
skeleton_attr, skeleton_attr,