mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed first round of feedback on sword overhaul.
This commit is contained in:
parent
c99e4c3c18
commit
b06ab250cc
@ -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,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -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",
|
||||||
],
|
],
|
||||||
|
@ -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: _,
|
||||||
|
@ -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![
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user