mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Combo melee 2 state
This commit is contained in:
parent
38c9d87624
commit
17258975fc
@ -2,11 +2,9 @@
|
||||
// A set of abilities is a primary, a secondary, and a vec of all extra abilities
|
||||
({
|
||||
Tool(Sword): (
|
||||
primary: "common.abilities.sword.triplestrike",
|
||||
secondary: "common.abilities.sword.dash",
|
||||
abilities: [
|
||||
(Some(Sword(UnlockSpin)), "common.abilities.sword.spin"),
|
||||
],
|
||||
primary: "common.abilities.sword.balancedstance",
|
||||
secondary: "common.abilities.sword.balancedstance",
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Axe): (
|
||||
primary: "common.abilities.axe.doublestrike",
|
||||
|
58
assets/common/abilities/sword/balancedstance.ron
Normal file
58
assets/common/abilities/sword/balancedstance.ron
Normal file
@ -0,0 +1,58 @@
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 5.0,
|
||||
poise: 0.0,
|
||||
knockback: 0.0,
|
||||
energy_regen: 5.0,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.5,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.3,
|
||||
forward_movement: 0.0,
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 10.0,
|
||||
poise: 0.0,
|
||||
knockback: 0.0,
|
||||
energy_regen: 5.0,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.5,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.3,
|
||||
forward_movement: 0.0,
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 15.0,
|
||||
poise: 0.0,
|
||||
knockback: 0.0,
|
||||
energy_regen: 5.0,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.5,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.3,
|
||||
forward_movement: 0.0,
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
]
|
||||
)
|
@ -1,28 +0,0 @@
|
||||
DashMelee(
|
||||
energy_cost: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Stab(
|
||||
damage: 4.0,
|
||||
poise: 0.0,
|
||||
knockback: 8.0,
|
||||
energy_regen: 0.0,
|
||||
),
|
||||
scaled: Some(Stab(
|
||||
damage: 16.0,
|
||||
poise: 0.0,
|
||||
knockback: 7.0,
|
||||
energy_regen: 0.0,
|
||||
)),
|
||||
range: 4.0,
|
||||
angle: 60.0,
|
||||
),
|
||||
energy_drain: 30.0,
|
||||
forward_speed: 2.5,
|
||||
buildup_duration: 0.2,
|
||||
charge_duration: 1.2,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.5,
|
||||
ori_modifier: 0.3,
|
||||
charge_through: true,
|
||||
is_interruptible: true,
|
||||
)
|
@ -1,22 +0,0 @@
|
||||
SpinMelee(
|
||||
buildup_duration: 0.35,
|
||||
swing_duration: 0.4,
|
||||
recover_duration: 0.5,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 12.0,
|
||||
poise: 10.0,
|
||||
knockback: 10.0,
|
||||
energy_regen: 0.0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 360.0,
|
||||
),
|
||||
energy_cost: 20.0,
|
||||
is_infinite: false,
|
||||
movement_behavior: ForwardGround,
|
||||
is_interruptible: true,
|
||||
forward_speed: 1.0,
|
||||
num_spins: 3,
|
||||
specifier: None,
|
||||
)
|
@ -1,78 +0,0 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 8.0,
|
||||
damage_increase: 0.5,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 0.0,
|
||||
range: 4.0,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.1,
|
||||
base_swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.25,
|
||||
forward_movement: 0.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 9.0,
|
||||
damage_increase: 0.5,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 2.0,
|
||||
range: 3.5,
|
||||
angle: 40.0,
|
||||
base_buildup_duration: 0.1,
|
||||
base_swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.3,
|
||||
forward_movement: 0.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 10.0,
|
||||
damage_increase: 0.5,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 2.0,
|
||||
range: 6.0,
|
||||
angle: 10.0,
|
||||
base_buildup_duration: 0.15,
|
||||
base_swing_duration: 0.1,
|
||||
hit_timing: 0.2,
|
||||
base_recover_duration: 0.35,
|
||||
forward_movement: 1.2,
|
||||
damage_kind: Piercing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 12.5,
|
||||
energy_increase: 2.5,
|
||||
speed_increase: 0.1,
|
||||
max_speed_increase: 0.8,
|
||||
scales_from_combo: 2,
|
||||
is_interruptible: true,
|
||||
ori_modifier: 1.0,
|
||||
)
|
@ -1,17 +1,6 @@
|
||||
({
|
||||
General(HealthIncrease): 10,
|
||||
General(EnergyIncrease): 5,
|
||||
Sword(TsDamage): 3,
|
||||
Sword(TsRegen): 2,
|
||||
Sword(TsSpeed): 3,
|
||||
Sword(DCost): 2,
|
||||
Sword(DDrain): 2,
|
||||
Sword(DDamage): 2,
|
||||
Sword(DScaling): 3,
|
||||
Sword(SDamage): 2,
|
||||
Sword(SSpeed): 2,
|
||||
Sword(SCost): 2,
|
||||
Sword(SSpins): 2,
|
||||
Axe(DsDamage): 3,
|
||||
Axe(DsRegen): 2,
|
||||
Axe(DsSpeed): 3,
|
||||
|
@ -1,8 +1,4 @@
|
||||
({
|
||||
Sword(SDamage): {Sword(UnlockSpin): 1},
|
||||
Sword(SSpeed): {Sword(UnlockSpin): 1},
|
||||
Sword(SCost): {Sword(UnlockSpin): 1},
|
||||
Sword(SSpins): {Sword(UnlockSpin): 1},
|
||||
Axe(LDamage): {Axe(UnlockLeap): 1},
|
||||
Axe(LKnockback): {Axe(UnlockLeap): 1},
|
||||
Axe(LCost): {Axe(UnlockLeap): 1},
|
||||
|
@ -15,24 +15,7 @@
|
||||
Climb(Speed),
|
||||
Swim(Speed),
|
||||
],
|
||||
Weapon(Sword): [
|
||||
Sword(InterruptingAttacks),
|
||||
Sword(TsCombo),
|
||||
Sword(TsDamage),
|
||||
Sword(TsRegen),
|
||||
Sword(TsSpeed),
|
||||
Sword(DCost),
|
||||
Sword(DDrain),
|
||||
Sword(DDamage),
|
||||
Sword(DScaling),
|
||||
Sword(DSpeed),
|
||||
Sword(DChargeThrough),
|
||||
Sword(UnlockSpin),
|
||||
Sword(SDamage),
|
||||
Sword(SSpeed),
|
||||
Sword(SCost),
|
||||
Sword(SSpins),
|
||||
],
|
||||
Weapon(Sword): [],
|
||||
Weapon(Axe): [
|
||||
Axe(DsCombo),
|
||||
Axe(DsDamage),
|
||||
|
@ -1,14 +1,3 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 1)),
|
||||
Skill((Sword(TsRegen), 1)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), 1)),
|
||||
|
||||
])
|
||||
|
@ -1,17 +1,3 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 1)),
|
||||
Skill((Sword(TsRegen), 1)),
|
||||
Skill((Sword(TsSpeed), 1)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), 1)),
|
||||
Skill((Sword(DDrain), 1)),
|
||||
Skill((Sword(DDamage), 1)),
|
||||
|
||||
])
|
||||
|
@ -1,23 +1,3 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 2)),
|
||||
Skill((Sword(TsRegen), 2)),
|
||||
Skill((Sword(TsSpeed), 1)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), 2)),
|
||||
Skill((Sword(DDrain), 2)),
|
||||
Skill((Sword(DDamage), 1)),
|
||||
Skill((Sword(DScaling), 1)),
|
||||
Skill((Sword(DSpeed), 1)),
|
||||
|
||||
// Spin of death
|
||||
Skill((Sword(UnlockSpin), 1)),
|
||||
Skill((Sword(SDamage), 1)),
|
||||
Skill((Sword(SSpeed), 1)),
|
||||
])
|
||||
|
@ -1,26 +1,3 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 2)),
|
||||
Skill((Sword(TsRegen), 2)),
|
||||
Skill((Sword(TsSpeed), 3)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), 2)),
|
||||
Skill((Sword(DDrain), 2)),
|
||||
Skill((Sword(DDamage), 2)),
|
||||
Skill((Sword(DScaling), 2)),
|
||||
Skill((Sword(DSpeed), 1)),
|
||||
Skill((Sword(DChargeThrough), 1)),
|
||||
|
||||
// Spin of death
|
||||
Skill((Sword(UnlockSpin), 1)),
|
||||
Skill((Sword(SDamage), 1)),
|
||||
Skill((Sword(SSpeed), 1)),
|
||||
Skill((Sword(SSpins), 1)),
|
||||
Skill((Sword(SCost), 1)),
|
||||
])
|
||||
|
@ -1,26 +1,3 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 3)),
|
||||
Skill((Sword(TsRegen), 2)),
|
||||
Skill((Sword(TsSpeed), 3)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), 2)),
|
||||
Skill((Sword(DDrain), 2)),
|
||||
Skill((Sword(DDamage), 2)),
|
||||
Skill((Sword(DScaling), 3)),
|
||||
Skill((Sword(DSpeed), 1)),
|
||||
Skill((Sword(DChargeThrough), 1)),
|
||||
|
||||
// Spin of death
|
||||
Skill((Sword(UnlockSpin), 1)),
|
||||
Skill((Sword(SDamage), 2)),
|
||||
Skill((Sword(SSpeed), 2)),
|
||||
Skill((Sword(SSpins), 2)),
|
||||
Skill((Sword(SCost), 2)),
|
||||
])
|
||||
|
@ -15,25 +15,6 @@
|
||||
// Sword
|
||||
(UnlockGroup(Weapon(Sword)), 1),
|
||||
|
||||
(Sword(InterruptingAttacks), 1),
|
||||
|
||||
(Sword(TsCombo), 1),
|
||||
(Sword(TsDamage), 3),
|
||||
(Sword(TsRegen), 2),
|
||||
(Sword(TsSpeed), 3),
|
||||
|
||||
(Sword(DCost), 2),
|
||||
(Sword(DDrain), 2),
|
||||
(Sword(DDamage), 2),
|
||||
(Sword(DScaling), 3),
|
||||
(Sword(DSpeed), 1),
|
||||
(Sword(DChargeThrough), 1),
|
||||
|
||||
(Sword(UnlockSpin), 1),
|
||||
(Sword(SDamage), 2),
|
||||
(Sword(SSpeed), 2),
|
||||
(Sword(SCost), 2),
|
||||
(Sword(SSpins), 2),
|
||||
// Axe
|
||||
(UnlockGroup(Weapon(Axe)), 1),
|
||||
|
||||
@ -145,25 +126,6 @@
|
||||
// Sword
|
||||
(UnlockGroup(Weapon(Sword)), 1),
|
||||
|
||||
(Sword(InterruptingAttacks), 1),
|
||||
|
||||
(Sword(TsCombo), 1),
|
||||
(Sword(TsDamage), 2),
|
||||
(Sword(TsRegen), 1),
|
||||
(Sword(TsSpeed), 2),
|
||||
|
||||
(Sword(DCost), 1),
|
||||
(Sword(DDrain), 2),
|
||||
(Sword(DDamage), 2),
|
||||
(Sword(DScaling), 2),
|
||||
(Sword(DSpeed), 1),
|
||||
(Sword(DChargeThrough), 1),
|
||||
|
||||
(Sword(UnlockSpin), 1),
|
||||
(Sword(SDamage), 1),
|
||||
(Sword(SSpeed), 2),
|
||||
(Sword(SCost), 2),
|
||||
(Sword(SSpins), 2),
|
||||
// Axe
|
||||
(UnlockGroup(Weapon(Axe)), 1),
|
||||
|
||||
@ -265,8 +227,6 @@
|
||||
// Sword
|
||||
(UnlockGroup(Weapon(Sword)), 1),
|
||||
|
||||
(Sword(UnlockSpin), 1),
|
||||
|
||||
// Axe
|
||||
(UnlockGroup(Weapon(Axe)), 1),
|
||||
|
||||
|
@ -404,7 +404,8 @@ impl From<&CharacterState> for CharacterAbilityType {
|
||||
| CharacterState::UseItem(_)
|
||||
| CharacterState::SpriteInteract(_)
|
||||
| CharacterState::Skate(_)
|
||||
| CharacterState::Wallrun(_) => Self::Other,
|
||||
| CharacterState::Wallrun(_)
|
||||
| CharacterState::ComboMelee2(_) => Self::Other,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -487,6 +488,9 @@ pub enum CharacterAbility {
|
||||
is_interruptible: bool,
|
||||
ori_modifier: f32,
|
||||
},
|
||||
ComboMelee2 {
|
||||
strikes: Vec<combo_melee2::Strike<f32>>,
|
||||
},
|
||||
LeapMelee {
|
||||
energy_cost: f32,
|
||||
buildup_duration: f32,
|
||||
@ -687,6 +691,7 @@ impl CharacterAbility {
|
||||
&& update.energy.try_change_by(-*energy_cost).is_ok()
|
||||
},
|
||||
CharacterAbility::ComboMelee { .. }
|
||||
| CharacterAbility::ComboMelee2 { .. }
|
||||
| CharacterAbility::Boost { .. }
|
||||
| CharacterAbility::BasicBeam { .. }
|
||||
| CharacterAbility::Blink { .. }
|
||||
@ -733,7 +738,7 @@ impl CharacterAbility {
|
||||
*swing_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
*energy_cost /= stats.energy_efficiency;
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats, 1.0);
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
|
||||
},
|
||||
BasicRanged {
|
||||
ref mut energy_cost,
|
||||
@ -798,7 +803,7 @@ impl CharacterAbility {
|
||||
*recover_duration /= stats.speed;
|
||||
*energy_cost /= stats.energy_efficiency;
|
||||
*energy_drain /= stats.energy_efficiency;
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats, 1.0);
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
|
||||
},
|
||||
BasicBlock {
|
||||
ref mut buildup_duration,
|
||||
@ -842,6 +847,12 @@ impl CharacterAbility {
|
||||
.map(|s| s.adjusted_by_stats(stats))
|
||||
.collect();
|
||||
},
|
||||
ComboMelee2 { ref mut strikes } => {
|
||||
*strikes = strikes
|
||||
.iter_mut()
|
||||
.map(|s| s.adjusted_by_stats(stats))
|
||||
.collect();
|
||||
},
|
||||
LeapMelee {
|
||||
ref mut energy_cost,
|
||||
ref mut buildup_duration,
|
||||
@ -856,7 +867,7 @@ impl CharacterAbility {
|
||||
*swing_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
*energy_cost /= stats.energy_efficiency;
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats, 1.0);
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
|
||||
},
|
||||
SpinMelee {
|
||||
ref mut buildup_duration,
|
||||
@ -875,7 +886,7 @@ impl CharacterAbility {
|
||||
*swing_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
*energy_cost /= stats.energy_efficiency;
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats, 1.0);
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
|
||||
},
|
||||
ChargedMelee {
|
||||
ref mut energy_cost,
|
||||
@ -891,7 +902,7 @@ impl CharacterAbility {
|
||||
*recover_duration /= stats.speed;
|
||||
*energy_cost /= stats.energy_efficiency;
|
||||
*energy_drain /= stats.energy_efficiency;
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats, 1.0);
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
|
||||
},
|
||||
ChargedRanged {
|
||||
ref mut energy_cost,
|
||||
@ -1105,6 +1116,7 @@ impl CharacterAbility {
|
||||
},
|
||||
Boost { .. }
|
||||
| ComboMelee { .. }
|
||||
| ComboMelee2 { .. }
|
||||
| Blink { .. }
|
||||
| Music { .. }
|
||||
| BasicSummon { .. }
|
||||
@ -1115,7 +1127,6 @@ impl CharacterAbility {
|
||||
#[must_use = "method returns new ability and doesn't mutate the original value"]
|
||||
pub fn adjusted_by_skills(mut self, skillset: &SkillSet, tool: Option<ToolKind>) -> Self {
|
||||
match tool {
|
||||
Some(ToolKind::Sword) => self.adjusted_by_sword_skills(skillset),
|
||||
Some(ToolKind::Axe) => self.adjusted_by_axe_skills(skillset),
|
||||
Some(ToolKind::Hammer) => self.adjusted_by_hammer_skills(skillset),
|
||||
Some(ToolKind::Bow) => self.adjusted_by_bow_skills(skillset),
|
||||
@ -1173,103 +1184,6 @@ impl CharacterAbility {
|
||||
}
|
||||
}
|
||||
|
||||
fn adjusted_by_sword_skills(&mut self, skillset: &SkillSet) {
|
||||
use skills::{Skill::Sword, SwordSkill::*};
|
||||
|
||||
match self {
|
||||
CharacterAbility::ComboMelee {
|
||||
ref mut is_interruptible,
|
||||
ref mut speed_increase,
|
||||
ref mut max_speed_increase,
|
||||
ref stage_data,
|
||||
ref mut max_energy_gain,
|
||||
ref mut scales_from_combo,
|
||||
..
|
||||
} => {
|
||||
*is_interruptible = skillset.has_skill(Sword(InterruptingAttacks));
|
||||
|
||||
if skillset.has_skill(Sword(TsCombo)) {
|
||||
let speed_segments = f32::from(Sword(TsSpeed).max_level()) + 1.0;
|
||||
let speed_level = f32::from(skillset.skill_level(Sword(TsSpeed)).unwrap_or(0));
|
||||
*speed_increase = (speed_level + 1.0) / speed_segments;
|
||||
*max_speed_increase = (speed_level + 1.0) / speed_segments;
|
||||
} else {
|
||||
*speed_increase = 0.0;
|
||||
*max_speed_increase = 0.0;
|
||||
}
|
||||
|
||||
let energy_level = skillset.skill_level(Sword(TsRegen)).unwrap_or(0);
|
||||
|
||||
let stages = u16::try_from(stage_data.len())
|
||||
.expect("number of stages can't be more than u16");
|
||||
|
||||
*max_energy_gain *= f32::from((energy_level + 1) * stages - 1)
|
||||
* f32::from(stages - 1)
|
||||
/ f32::from(Sword(TsRegen).max_level() + 1);
|
||||
*scales_from_combo = skillset.skill_level(Sword(TsDamage)).unwrap_or(0).into();
|
||||
},
|
||||
CharacterAbility::DashMelee {
|
||||
ref mut is_interruptible,
|
||||
ref mut energy_cost,
|
||||
ref mut energy_drain,
|
||||
ref mut forward_speed,
|
||||
ref mut charge_through,
|
||||
ref mut melee_constructor,
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.sword_tree.dash;
|
||||
*is_interruptible = skillset.has_skill(Sword(InterruptingAttacks));
|
||||
if let Ok(level) = skillset.skill_level(Sword(DCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(level) = skillset.skill_level(Sword(DDrain)) {
|
||||
*energy_drain *= modifiers.energy_drain.powi(level.into());
|
||||
}
|
||||
if let MeleeConstructorKind::Slash { ref mut damage, .. } = melee_constructor.kind {
|
||||
if let Ok(level) = skillset.skill_level(Sword(DDamage)) {
|
||||
*damage *= modifiers.base_damage.powi(level.into());
|
||||
}
|
||||
}
|
||||
if let Some(MeleeConstructorKind::Slash { ref mut damage, .. }) =
|
||||
melee_constructor.scaled
|
||||
{
|
||||
if let Ok(level) = skillset.skill_level(Sword(DScaling)) {
|
||||
*damage *= modifiers.scaled_damage.powi(level.into());
|
||||
}
|
||||
}
|
||||
if skillset.has_skill(Sword(DSpeed)) {
|
||||
*forward_speed *= modifiers.forward_speed;
|
||||
}
|
||||
*charge_through = skillset.has_skill(Sword(DChargeThrough));
|
||||
},
|
||||
CharacterAbility::SpinMelee {
|
||||
ref mut is_interruptible,
|
||||
ref mut swing_duration,
|
||||
ref mut energy_cost,
|
||||
ref mut num_spins,
|
||||
ref mut melee_constructor,
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.sword_tree.spin;
|
||||
*is_interruptible = skillset.has_skill(Sword(InterruptingAttacks));
|
||||
if let MeleeConstructorKind::Slash { ref mut damage, .. } = melee_constructor.kind {
|
||||
if let Ok(level) = skillset.skill_level(Sword(SDamage)) {
|
||||
*damage *= modifiers.base_damage.powi(level.into());
|
||||
}
|
||||
}
|
||||
if let Ok(level) = skillset.skill_level(Sword(SSpeed)) {
|
||||
*swing_duration *= modifiers.swing_duration.powi(level.into());
|
||||
}
|
||||
if let Ok(level) = skillset.skill_level(Sword(SCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
let spin_level = skillset.skill_level(Sword(SSpins)).unwrap_or(0);
|
||||
*num_spins = u32::from(spin_level) * modifiers.num + 1;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn adjusted_by_axe_skills(&mut self, skillset: &SkillSet) {
|
||||
#![allow(clippy::enum_glob_use)]
|
||||
use skills::{AxeSkill::*, Skill::Axe};
|
||||
@ -1890,6 +1804,18 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
}),
|
||||
CharacterAbility::ComboMelee2 { strikes } => {
|
||||
CharacterState::ComboMelee2(combo_melee2::Data {
|
||||
static_data: combo_melee2::StaticData {
|
||||
strikes: strikes.iter().map(|s| s.to_duration()).collect(),
|
||||
ability_info,
|
||||
},
|
||||
exhausted: false,
|
||||
timer: Duration::default(),
|
||||
stage_section: None,
|
||||
completed_strikes: 0,
|
||||
})
|
||||
},
|
||||
CharacterAbility::LeapMelee {
|
||||
energy_cost: _,
|
||||
buildup_duration,
|
||||
|
@ -91,6 +91,8 @@ pub enum CharacterState {
|
||||
/// A three-stage attack where each attack pushes player forward
|
||||
/// and successive attacks increase in damage, while player holds button.
|
||||
ComboMelee(combo_melee::Data),
|
||||
/// A state where you progress through multiple melee attacks
|
||||
ComboMelee2(combo_melee2::Data),
|
||||
/// A leap followed by a small aoe ground attack
|
||||
LeapMelee(leap_melee::Data),
|
||||
/// Spin around, dealing damage to enemies surrounding you
|
||||
@ -138,6 +140,7 @@ impl CharacterState {
|
||||
| CharacterState::BasicRanged(_)
|
||||
| CharacterState::DashMelee(_)
|
||||
| CharacterState::ComboMelee(_)
|
||||
| CharacterState::ComboMelee2(_)
|
||||
| CharacterState::BasicBlock(_)
|
||||
| CharacterState::LeapMelee(_)
|
||||
| CharacterState::SpinMelee(_)
|
||||
@ -186,6 +189,7 @@ impl CharacterState {
|
||||
| CharacterState::BasicRanged(_)
|
||||
| CharacterState::DashMelee(_)
|
||||
| CharacterState::ComboMelee(_)
|
||||
| CharacterState::ComboMelee2(_)
|
||||
| CharacterState::LeapMelee(_)
|
||||
| CharacterState::SpinMelee(_)
|
||||
| CharacterState::ChargedMelee(_)
|
||||
@ -208,6 +212,7 @@ impl CharacterState {
|
||||
| CharacterState::BasicRanged(_)
|
||||
| CharacterState::DashMelee(_)
|
||||
| CharacterState::ComboMelee(_)
|
||||
| CharacterState::ComboMelee2(_)
|
||||
| CharacterState::BasicBlock(_)
|
||||
| CharacterState::LeapMelee(_)
|
||||
| CharacterState::ChargedMelee(_)
|
||||
@ -254,6 +259,7 @@ impl CharacterState {
|
||||
pub fn is_forced_movement(&self) -> bool {
|
||||
matches!(self,
|
||||
CharacterState::ComboMelee(s) if s.stage_section == StageSection::Action)
|
||||
|| matches!(self, CharacterState::ComboMelee2(s) if s.stage_section == Some(StageSection::Action))
|
||||
|| matches!(self, CharacterState::DashMelee(s) if s.stage_section == StageSection::Charge)
|
||||
|| matches!(self, CharacterState::LeapMelee(s) if s.stage_section == StageSection::Movement)
|
||||
|| matches!(self, CharacterState::SpinMelee(s) if s.stage_section == StageSection::Action)
|
||||
@ -274,6 +280,7 @@ impl CharacterState {
|
||||
| CharacterState::BasicMelee(_)
|
||||
| CharacterState::BasicRanged(_)
|
||||
| CharacterState::ComboMelee(_)
|
||||
| CharacterState::ComboMelee2(_)
|
||||
| CharacterState::ChargedRanged(_)
|
||||
| CharacterState::RepeaterRanged(_)
|
||||
| CharacterState::BasicBeam(_)
|
||||
@ -326,6 +333,7 @@ impl CharacterState {
|
||||
CharacterState::Wielding(data) => data.behavior(j, output_events),
|
||||
CharacterState::Equipping(data) => data.behavior(j, output_events),
|
||||
CharacterState::ComboMelee(data) => data.behavior(j, output_events),
|
||||
CharacterState::ComboMelee2(data) => data.behavior(j, output_events),
|
||||
CharacterState::BasicMelee(data) => data.behavior(j, output_events),
|
||||
CharacterState::BasicRanged(data) => data.behavior(j, output_events),
|
||||
CharacterState::Boost(data) => data.behavior(j, output_events),
|
||||
@ -374,6 +382,7 @@ impl CharacterState {
|
||||
CharacterState::Wielding(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::Equipping(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::ComboMelee(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::ComboMelee2(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::BasicMelee(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::BasicRanged(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::Boost(data) => data.handle_event(j, output_events, action),
|
||||
|
@ -399,11 +399,11 @@ impl MeleeConstructor {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn adjusted_by_stats(mut self, stats: Stats, regen: f32) -> Self {
|
||||
pub fn adjusted_by_stats(mut self, stats: Stats) -> Self {
|
||||
self.range *= stats.range;
|
||||
self.kind = self.kind.adjusted_by_stats(stats, regen);
|
||||
self.kind = self.kind.adjusted_by_stats(stats);
|
||||
if let Some(ref mut scaled) = &mut self.scaled {
|
||||
*scaled = scaled.adjusted_by_stats(stats, regen);
|
||||
*scaled = scaled.adjusted_by_stats(stats);
|
||||
}
|
||||
if let Some(CombatEffect::Buff(CombatBuff { strength, .. })) = &mut self.damage_effect {
|
||||
*strength *= stats.buff_strength;
|
||||
@ -447,38 +447,35 @@ pub enum MeleeConstructorKind {
|
||||
|
||||
impl MeleeConstructorKind {
|
||||
#[must_use]
|
||||
pub fn adjusted_by_stats(mut self, stats: Stats, regen: f32) -> Self {
|
||||
pub fn adjusted_by_stats(mut self, stats: Stats) -> Self {
|
||||
use MeleeConstructorKind::*;
|
||||
match self {
|
||||
Slash {
|
||||
ref mut damage,
|
||||
ref mut poise,
|
||||
knockback: _,
|
||||
ref mut energy_regen,
|
||||
energy_regen: _,
|
||||
} => {
|
||||
*damage *= stats.power;
|
||||
*poise *= stats.effect_power;
|
||||
*energy_regen *= regen;
|
||||
},
|
||||
Stab {
|
||||
ref mut damage,
|
||||
ref mut poise,
|
||||
knockback: _,
|
||||
ref mut energy_regen,
|
||||
energy_regen: _,
|
||||
} => {
|
||||
*damage *= stats.power;
|
||||
*poise *= stats.effect_power;
|
||||
*energy_regen *= regen;
|
||||
},
|
||||
Bash {
|
||||
ref mut damage,
|
||||
ref mut poise,
|
||||
knockback: _,
|
||||
ref mut energy_regen,
|
||||
energy_regen: _,
|
||||
} => {
|
||||
*damage *= stats.power;
|
||||
*poise *= stats.effect_power;
|
||||
*energy_regen *= regen;
|
||||
},
|
||||
NecroticVortex {
|
||||
ref mut damage,
|
||||
|
@ -26,28 +26,7 @@ pub enum Skill {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
|
||||
pub enum SwordSkill {
|
||||
// Sword passives
|
||||
InterruptingAttacks,
|
||||
// Triple strike upgrades
|
||||
TsCombo,
|
||||
TsDamage,
|
||||
TsRegen,
|
||||
TsSpeed,
|
||||
// Dash upgrades
|
||||
DCost,
|
||||
DDrain,
|
||||
DDamage,
|
||||
DScaling,
|
||||
DSpeed,
|
||||
DChargeThrough,
|
||||
// Spin upgrades
|
||||
UnlockSpin,
|
||||
SDamage,
|
||||
SSpeed,
|
||||
SCost,
|
||||
SSpins,
|
||||
}
|
||||
pub enum SwordSkill {}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
|
||||
pub enum AxeSkill {
|
||||
@ -227,7 +206,6 @@ impl Skill {
|
||||
pub const SKILL_MODIFIERS: SkillTreeModifiers = SkillTreeModifiers::get();
|
||||
|
||||
pub struct SkillTreeModifiers {
|
||||
pub sword_tree: SwordTreeModifiers,
|
||||
pub axe_tree: AxeTreeModifiers,
|
||||
pub hammer_tree: HammerTreeModifiers,
|
||||
pub bow_tree: BowTreeModifiers,
|
||||
@ -240,7 +218,6 @@ pub struct SkillTreeModifiers {
|
||||
impl SkillTreeModifiers {
|
||||
const fn get() -> Self {
|
||||
Self {
|
||||
sword_tree: SwordTreeModifiers::get(),
|
||||
axe_tree: AxeTreeModifiers::get(),
|
||||
hammer_tree: HammerTreeModifiers::get(),
|
||||
bow_tree: BowTreeModifiers::get(),
|
||||
@ -252,46 +229,6 @@ impl SkillTreeModifiers {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SwordTreeModifiers {
|
||||
pub dash: SwordDashModifiers,
|
||||
pub spin: SwordSpinModifiers,
|
||||
}
|
||||
|
||||
pub struct SwordDashModifiers {
|
||||
pub energy_cost: f32,
|
||||
pub energy_drain: f32,
|
||||
pub base_damage: f32,
|
||||
pub scaled_damage: f32,
|
||||
pub forward_speed: f32,
|
||||
}
|
||||
|
||||
pub struct SwordSpinModifiers {
|
||||
pub base_damage: f32,
|
||||
pub swing_duration: f32,
|
||||
pub energy_cost: f32,
|
||||
pub num: u32,
|
||||
}
|
||||
|
||||
impl SwordTreeModifiers {
|
||||
const fn get() -> Self {
|
||||
Self {
|
||||
dash: SwordDashModifiers {
|
||||
energy_cost: 0.95,
|
||||
energy_drain: 0.95,
|
||||
base_damage: 1.05,
|
||||
scaled_damage: 1.05,
|
||||
forward_speed: 1.025,
|
||||
},
|
||||
spin: SwordSpinModifiers {
|
||||
base_damage: 1.1,
|
||||
swing_duration: 0.95,
|
||||
energy_cost: 0.95,
|
||||
num: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AxeTreeModifiers {
|
||||
pub spin: AxeSpinModifiers,
|
||||
pub leap: AxeLeapModifiers,
|
||||
|
@ -148,7 +148,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -222,7 +222,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -98,7 +98,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -137,7 +137,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -140,7 +140,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -173,7 +173,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -185,7 +185,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -362,7 +362,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, self.static_data.is_interruptible);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
220
common/src/states/combo_melee2.rs
Normal file
220
common/src/states/combo_melee2.rs
Normal file
@ -0,0 +1,220 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
character_state::OutputEvents, tool::Stats, CharacterState, InputKind, Melee,
|
||||
MeleeConstructor, StateUpdate,
|
||||
},
|
||||
states::{
|
||||
behavior::{CharacterBehavior, JoinData},
|
||||
utils::*,
|
||||
wielding,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Strike<T> {
|
||||
/// Used to construct the Melee attack
|
||||
pub melee_constructor: MeleeConstructor,
|
||||
/// Initial buildup duration of stage (how long until state can deal damage)
|
||||
pub buildup_duration: T,
|
||||
/// Duration of stage spent in swing (controls animation stuff, and can also
|
||||
/// be used to handle movement separately to buildup)
|
||||
pub swing_duration: T,
|
||||
/// At what fraction of the swing duration to apply the melee "hit"
|
||||
pub hit_timing: f32,
|
||||
/// Initial recover duration of stage (how long until character exits state)
|
||||
pub recover_duration: T,
|
||||
/// How much forward movement there is in the swing portion of the stage
|
||||
pub forward_movement: f32,
|
||||
/// Adjusts turning rate during the attack
|
||||
pub ori_modifier: f32,
|
||||
}
|
||||
|
||||
impl Strike<f32> {
|
||||
pub fn to_duration(self) -> Strike<Duration> {
|
||||
Strike::<Duration> {
|
||||
melee_constructor: self.melee_constructor,
|
||||
buildup_duration: Duration::from_secs_f32(self.buildup_duration),
|
||||
swing_duration: Duration::from_secs_f32(self.swing_duration),
|
||||
hit_timing: self.hit_timing,
|
||||
recover_duration: Duration::from_secs_f32(self.recover_duration),
|
||||
forward_movement: self.forward_movement,
|
||||
ori_modifier: self.ori_modifier,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn adjusted_by_stats(self, stats: Stats) -> Self {
|
||||
Self {
|
||||
melee_constructor: self.melee_constructor.adjusted_by_stats(stats),
|
||||
buildup_duration: self.buildup_duration / stats.speed,
|
||||
swing_duration: self.swing_duration / stats.speed,
|
||||
hit_timing: self.hit_timing,
|
||||
recover_duration: self.recover_duration / stats.speed,
|
||||
forward_movement: self.forward_movement,
|
||||
ori_modifier: self.ori_modifier,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Completely rewrite this with skill tree rework. Don't bother converting
|
||||
// to melee constructor.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
/// Separated out to condense update portions of character state
|
||||
pub struct StaticData {
|
||||
/// Data for each stage
|
||||
pub strikes: Vec<Strike<Duration>>,
|
||||
/// What key is used to press ability
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
/// A sequence of attacks that can incrementally become faster and more
|
||||
/// damaging.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
/// Struct containing data that does not change over the course of the
|
||||
/// character state
|
||||
pub static_data: StaticData,
|
||||
/// Whether the attack was executed already
|
||||
pub exhausted: bool,
|
||||
/// Timer for each stage
|
||||
pub timer: Duration,
|
||||
/// Checks what section a strike is in, if a strike is currently being
|
||||
/// performed
|
||||
pub stage_section: Option<StageSection>,
|
||||
/// Index of the strike that is currently in progress, or if not in a strike
|
||||
/// currently the next strike that will occur
|
||||
pub completed_strikes: usize,
|
||||
}
|
||||
|
||||
pub const STANCE_TIME: Duration = Duration::from_secs(5);
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
handle_orientation(data, &mut update, 1.0, None);
|
||||
handle_move(data, &mut update, 0.7);
|
||||
handle_jump(data, output_events, &mut update, 1.0);
|
||||
|
||||
let strike_data =
|
||||
self.static_data.strikes[self.completed_strikes % self.static_data.strikes.len()];
|
||||
|
||||
match self.stage_section {
|
||||
Some(StageSection::Buildup) => {
|
||||
if self.timer < strike_data.buildup_duration {
|
||||
// Build up
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Transitions to swing section of stage
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: Some(StageSection::Action),
|
||||
..*self
|
||||
});
|
||||
}
|
||||
},
|
||||
Some(StageSection::Action) => {
|
||||
if self.timer.as_secs_f32()
|
||||
> strike_data.hit_timing * strike_data.swing_duration.as_secs_f32()
|
||||
&& !self.exhausted
|
||||
{
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
exhausted: true,
|
||||
..*self
|
||||
});
|
||||
|
||||
let crit_data = get_crit_data(data, self.static_data.ability_info);
|
||||
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
|
||||
|
||||
data.updater.insert(
|
||||
data.entity,
|
||||
strike_data
|
||||
.melee_constructor
|
||||
.create_melee(crit_data, buff_strength),
|
||||
);
|
||||
} else if self.timer < strike_data.swing_duration {
|
||||
// Swings
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Transitions to recover section of stage
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: Some(StageSection::Recover),
|
||||
..*self
|
||||
});
|
||||
}
|
||||
},
|
||||
Some(StageSection::Recover) => {
|
||||
if self.timer < strike_data.recover_duration {
|
||||
// Recovery
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
completed_strikes: self.completed_strikes + 1,
|
||||
stage_section: None,
|
||||
..*self
|
||||
});
|
||||
}
|
||||
},
|
||||
Some(_) => {
|
||||
// If it somehow ends up in an incorrect stage section
|
||||
update.character = CharacterState::Wielding(wielding::Data { is_sneaking: false });
|
||||
// Make sure attack component is removed
|
||||
data.updater.remove::<Melee>(data.entity);
|
||||
},
|
||||
None => {
|
||||
if self.timer < STANCE_TIME {
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
update.character =
|
||||
CharacterState::Wielding(wielding::Data { is_sneaking: false });
|
||||
// Make sure melee component is removed
|
||||
data.updater.remove::<Melee>(data.entity);
|
||||
}
|
||||
if input_is_pressed(data, InputKind::Primary) {
|
||||
next_strike(&mut update)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, InputKind::Primary) {
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
}
|
||||
|
||||
fn next_strike(update: &mut StateUpdate) {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.exhausted = false;
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = Some(StageSection::Buildup);
|
||||
}
|
||||
}
|
@ -248,7 +248,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, self.static_data.is_interruptible);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -156,7 +156,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -11,6 +11,7 @@ pub mod charged_melee;
|
||||
pub mod charged_ranged;
|
||||
pub mod climb;
|
||||
pub mod combo_melee;
|
||||
pub mod combo_melee2;
|
||||
pub mod dance;
|
||||
pub mod dash_melee;
|
||||
pub mod equipping;
|
||||
|
@ -75,7 +75,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -161,7 +161,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -117,7 +117,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -170,7 +170,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -168,7 +168,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_state_interrupt(data, &mut update, self.static_data.is_interruptible);
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
|
@ -121,7 +121,7 @@ impl CharacterBehavior for Data {
|
||||
handle_wield(data, &mut update);
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
|
||||
update
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
handle_dodge_input(data, &mut update);
|
||||
|
||||
if matches!(update.character, CharacterState::Roll(_)) {
|
||||
// Remove potion/saturation effect if left the use item state early by rolling
|
||||
|
@ -1137,17 +1137,6 @@ pub fn get_buff_strength(data: &JoinData<'_>, ai: AbilityInfo) -> f32 {
|
||||
.unwrap_or(1.0)
|
||||
}
|
||||
|
||||
pub fn handle_state_interrupt(
|
||||
data: &JoinData<'_>,
|
||||
update: &mut StateUpdate,
|
||||
attacks_interrupt: bool,
|
||||
) {
|
||||
if attacks_interrupt {
|
||||
handle_ability_input(data, update);
|
||||
}
|
||||
handle_dodge_input(data, update);
|
||||
}
|
||||
|
||||
pub fn input_is_pressed(data: &JoinData<'_>, input: InputKind) -> bool {
|
||||
data.controller.queued_inputs.contains_key(&input)
|
||||
}
|
||||
|
@ -184,6 +184,7 @@ impl<'a> System<'a> for Sys {
|
||||
| CharacterState::LeapMelee { .. }
|
||||
| CharacterState::SpinMelee { .. }
|
||||
| CharacterState::ComboMelee { .. }
|
||||
| CharacterState::ComboMelee2 { .. }
|
||||
| CharacterState::BasicRanged { .. }
|
||||
| CharacterState::Music { .. }
|
||||
| CharacterState::ChargedMelee { .. }
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
use common::{
|
||||
comp::{
|
||||
buff::BuffKind,
|
||||
skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill, SwordSkill},
|
||||
skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill},
|
||||
AbilityInput, Agent, CharacterAbility, CharacterState, ControlAction, Controller,
|
||||
InputKind,
|
||||
},
|
||||
@ -410,6 +410,7 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn handle_sword_attack(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
@ -419,73 +420,7 @@ impl<'a> AgentData<'a> {
|
||||
read_data: &ReadData,
|
||||
rng: &mut impl Rng,
|
||||
) {
|
||||
enum ActionStateTimers {
|
||||
TimerHandleSwordAttack = 0,
|
||||
}
|
||||
if attack_data.in_min_range() && attack_data.angle < 45.0 {
|
||||
controller.inputs.move_dir = Vec2::zero();
|
||||
if self
|
||||
.skill_set
|
||||
.has_skill(Skill::Sword(SwordSkill::UnlockSpin))
|
||||
&& agent.action_state.timers[ActionStateTimers::TimerHandleSwordAttack as usize]
|
||||
< 2.0
|
||||
&& self.energy.current() > 60.0
|
||||
{
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
agent.action_state.timers[ActionStateTimers::TimerHandleSwordAttack as usize] +=
|
||||
read_data.dt.0;
|
||||
} else if agent.action_state.timers[ActionStateTimers::TimerHandleSwordAttack as usize]
|
||||
> 2.0
|
||||
{
|
||||
agent.action_state.timers[ActionStateTimers::TimerHandleSwordAttack as usize] = 0.0;
|
||||
} else {
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
agent.action_state.timers[ActionStateTimers::TimerHandleSwordAttack as usize] +=
|
||||
read_data.dt.0;
|
||||
}
|
||||
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
|
||||
if self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
tgt_data.pos.0,
|
||||
read_data,
|
||||
Path::Separate,
|
||||
None,
|
||||
) && entities_have_line_of_sight(
|
||||
self.pos,
|
||||
self.body,
|
||||
tgt_data.pos,
|
||||
tgt_data.body,
|
||||
read_data,
|
||||
) {
|
||||
if agent.action_state.timers[ActionStateTimers::TimerHandleSwordAttack as usize]
|
||||
> 4.0
|
||||
&& attack_data.angle < 45.0
|
||||
{
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
agent.action_state.timers[ActionStateTimers::TimerHandleSwordAttack as usize] =
|
||||
0.0;
|
||||
} else {
|
||||
agent.action_state.timers
|
||||
[ActionStateTimers::TimerHandleSwordAttack as usize] += read_data.dt.0;
|
||||
}
|
||||
}
|
||||
if self.body.map(|b| b.is_humanoid()).unwrap_or(false)
|
||||
&& attack_data.dist_sqrd < 16.0f32.powi(2)
|
||||
&& rng.gen::<f32>() < 0.02
|
||||
{
|
||||
controller.push_basic_input(InputKind::Roll);
|
||||
}
|
||||
} else {
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
tgt_data.pos.0,
|
||||
read_data,
|
||||
Path::Partial,
|
||||
None,
|
||||
);
|
||||
}
|
||||
// Rewrite before merging
|
||||
}
|
||||
|
||||
pub fn handle_bow_attack(
|
||||
|
@ -1536,8 +1536,6 @@ impl<'a> Diary<'a> {
|
||||
skills_bot_r,
|
||||
);
|
||||
|
||||
// Skill icons and buttons
|
||||
use skills::SwordSkill::*;
|
||||
// Sword
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
@ -1549,126 +1547,7 @@ impl<'a> Diary<'a> {
|
||||
.middle_of(state.ids.content_align)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 1.0)))
|
||||
.set(state.ids.sword_render, ui);
|
||||
use PositionSpecifier::MidTopWithMarginOn;
|
||||
let skill_buttons = &[
|
||||
// Top Left skills
|
||||
// 5 1 6
|
||||
// 3 0 4
|
||||
// 8 2 7
|
||||
SkillIcon::Descriptive {
|
||||
title: "hud-skill-sw_trip_str_title",
|
||||
desc: "hud-skill-sw_trip_str",
|
||||
image: self.imgs.twohsword_m1,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_l[0], 3.0),
|
||||
id: state.ids.skill_sword_combo_0,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(TsCombo),
|
||||
image: self.imgs.physical_combo_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_l[1], 3.0),
|
||||
id: state.ids.skill_sword_combo_1,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(TsDamage),
|
||||
image: self.imgs.physical_damage_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_l[2], 3.0),
|
||||
id: state.ids.skill_sword_combo_2,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(TsSpeed),
|
||||
image: self.imgs.physical_speed_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_l[3], 3.0),
|
||||
id: state.ids.skill_sword_combo_3,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(TsRegen),
|
||||
image: self.imgs.physical_energy_regen_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_l[4], 3.0),
|
||||
id: state.ids.skill_sword_combo_4,
|
||||
},
|
||||
// Top right skills
|
||||
SkillIcon::Descriptive {
|
||||
title: "hud-skill-sw_dash_title",
|
||||
desc: "hud-skill-sw_dash",
|
||||
image: self.imgs.twohsword_m2,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_r[0], 3.0),
|
||||
id: state.ids.skill_sword_dash_0,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(DDamage),
|
||||
image: self.imgs.physical_damage_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_r[1], 3.0),
|
||||
id: state.ids.skill_sword_dash_1,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(DDrain),
|
||||
image: self.imgs.physical_energy_drain_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_r[2], 3.0),
|
||||
id: state.ids.skill_sword_dash_2,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(DCost),
|
||||
image: self.imgs.physical_cost_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_r[3], 3.0),
|
||||
id: state.ids.skill_sword_dash_3,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(DSpeed),
|
||||
image: self.imgs.physical_speed_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_r[4], 3.0),
|
||||
id: state.ids.skill_sword_dash_4,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(DChargeThrough),
|
||||
image: self.imgs.physical_distance_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_r[5], 3.0),
|
||||
id: state.ids.skill_sword_dash_5,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(DScaling),
|
||||
image: self.imgs.physical_amount_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_top_r[6], 3.0),
|
||||
id: state.ids.skill_sword_dash_6,
|
||||
},
|
||||
// Bottom left skills
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(UnlockSpin),
|
||||
image: self.imgs.sword_whirlwind,
|
||||
position: MidTopWithMarginOn(state.ids.skills_bot_l[0], 3.0),
|
||||
id: state.ids.skill_sword_spin_0,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(SDamage),
|
||||
image: self.imgs.physical_damage_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_bot_l[1], 3.0),
|
||||
id: state.ids.skill_sword_spin_1,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(SSpeed),
|
||||
image: self.imgs.physical_damage_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_bot_l[2], 3.0),
|
||||
id: state.ids.skill_sword_spin_2,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(SCost),
|
||||
image: self.imgs.physical_cost_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_bot_l[3], 3.0),
|
||||
id: state.ids.skill_sword_spin_3,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(SSpins),
|
||||
image: self.imgs.physical_amount_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_bot_l[4], 3.0),
|
||||
id: state.ids.skill_sword_spin_4,
|
||||
},
|
||||
// Bottom right skills
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(InterruptingAttacks),
|
||||
image: self.imgs.physical_damage_skill,
|
||||
position: MidTopWithMarginOn(state.ids.skills_bot_r[0], 3.0),
|
||||
id: state.ids.skill_sword_passive_0,
|
||||
},
|
||||
];
|
||||
let skill_buttons = &[];
|
||||
|
||||
self.handle_skill_buttons(skill_buttons, ui, &mut events, diary_tooltip);
|
||||
events
|
||||
@ -2844,85 +2723,7 @@ fn unlock_skill_strings(group: SkillGroupKind) -> SkillStrings<'static> {
|
||||
}
|
||||
}
|
||||
|
||||
fn sword_skill_strings(skill: SwordSkill) -> SkillStrings<'static> {
|
||||
let modifiers = SKILL_MODIFIERS.sword_tree;
|
||||
match skill {
|
||||
// triple strike
|
||||
SwordSkill::TsCombo => SkillStrings::plain(
|
||||
"hud-skill-sw_trip_str_combo_title",
|
||||
"hud-skill-sw_trip_str_combo",
|
||||
),
|
||||
SwordSkill::TsDamage => SkillStrings::plain(
|
||||
"hud-skill-sw_trip_str_dmg_title",
|
||||
"hud-skill-sw_trip_str_dmg",
|
||||
),
|
||||
SwordSkill::TsSpeed => {
|
||||
SkillStrings::plain("hud-skill-sw_trip_str_sp_title", "hud-skill-sw_trip_str_sp")
|
||||
},
|
||||
SwordSkill::TsRegen => SkillStrings::plain(
|
||||
"hud-skill-sw_trip_str_reg_title",
|
||||
"hud-skill-sw_trip_str_reg",
|
||||
),
|
||||
// dash
|
||||
SwordSkill::DDamage => SkillStrings::with_mult(
|
||||
"hud-skill-sw_dash_dmg_title",
|
||||
"hud-skill-sw_dash_dmg",
|
||||
modifiers.dash.base_damage,
|
||||
),
|
||||
SwordSkill::DDrain => SkillStrings::with_mult(
|
||||
"hud-skill-sw_dash_drain_title",
|
||||
"hud-skill-sw_dash_drain",
|
||||
modifiers.dash.energy_drain,
|
||||
),
|
||||
SwordSkill::DCost => SkillStrings::with_mult(
|
||||
"hud-skill-sw_dash_cost_title",
|
||||
"hud-skill-sw_dash_cost",
|
||||
modifiers.dash.energy_cost,
|
||||
),
|
||||
SwordSkill::DSpeed => SkillStrings::with_mult(
|
||||
"hud-skill-sw_dash_speed_title",
|
||||
"hud-skill-sw_dash_speed",
|
||||
modifiers.dash.forward_speed,
|
||||
),
|
||||
SwordSkill::DChargeThrough => SkillStrings::plain(
|
||||
"hud-skill-sw_dash_charge_through_title",
|
||||
"hud-skill-sw_dash_charge_through",
|
||||
),
|
||||
SwordSkill::DScaling => SkillStrings::with_mult(
|
||||
"hud-skill-sw_dash_scale_title",
|
||||
"hud-skill-sw_dash_scale",
|
||||
modifiers.dash.scaled_damage,
|
||||
),
|
||||
// spin
|
||||
SwordSkill::UnlockSpin => {
|
||||
SkillStrings::plain("hud-skill-sw_spin_title", "hud-skill-sw_spin")
|
||||
},
|
||||
SwordSkill::SDamage => SkillStrings::with_mult(
|
||||
"hud-skill-sw_spin_dmg_title",
|
||||
"hud-skill-sw_spin_dmg",
|
||||
modifiers.spin.base_damage,
|
||||
),
|
||||
SwordSkill::SSpeed => SkillStrings::with_mult(
|
||||
"hud-skill-sw_spin_spd_title",
|
||||
"hud-skill-sw_spin_spd",
|
||||
modifiers.spin.swing_duration,
|
||||
),
|
||||
SwordSkill::SCost => SkillStrings::with_mult(
|
||||
"hud-skill-sw_spin_cost_title",
|
||||
"hud-skill-sw_spin_cost",
|
||||
modifiers.spin.energy_cost,
|
||||
),
|
||||
SwordSkill::SSpins => SkillStrings::with_const(
|
||||
"hud-skill-sw_spin_spins_title",
|
||||
"hud-skill-sw_spin_spins",
|
||||
modifiers.spin.num,
|
||||
),
|
||||
// independent skills
|
||||
SwordSkill::InterruptingAttacks => {
|
||||
SkillStrings::plain("hud-skill-sw_interrupt_title", "hud-skill-sw_interrupt")
|
||||
},
|
||||
}
|
||||
}
|
||||
fn sword_skill_strings(_skill: SwordSkill) -> SkillStrings<'static> { SkillStrings::plain("", "") }
|
||||
|
||||
fn axe_skill_strings(skill: AxeSkill) -> SkillStrings<'static> {
|
||||
let modifiers = SKILL_MODIFIERS.axe_tree;
|
||||
|
@ -1623,6 +1623,115 @@ impl FigureMgr {
|
||||
),
|
||||
}
|
||||
},
|
||||
CharacterState::ComboMelee2(s) => {
|
||||
if let Some(stage_section) = s.stage_section {
|
||||
let timer = s.timer.as_secs_f32();
|
||||
let strike_data = s.static_data.strikes
|
||||
[s.completed_strikes % s.static_data.strikes.len()];
|
||||
let progress = match stage_section {
|
||||
StageSection::Buildup => {
|
||||
timer / strike_data.buildup_duration.as_secs_f32()
|
||||
},
|
||||
StageSection::Action => {
|
||||
timer / strike_data.swing_duration.as_secs_f32()
|
||||
},
|
||||
StageSection::Recover => {
|
||||
timer / strike_data.recover_duration.as_secs_f32()
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
match s.completed_strikes % s.static_data.strikes.len() {
|
||||
0 => anim::character::AlphaAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
hands,
|
||||
Some(stage_section),
|
||||
(Some(s.static_data.ability_info), active_tool_spec),
|
||||
),
|
||||
progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
1 => anim::character::SpinAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
hands,
|
||||
rel_vel,
|
||||
time,
|
||||
Some(stage_section),
|
||||
Some(s.static_data.ability_info),
|
||||
),
|
||||
progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
_ => anim::character::BetaAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
hands,
|
||||
rel_vel.magnitude(),
|
||||
time,
|
||||
Some(stage_section),
|
||||
Some(s.static_data.ability_info),
|
||||
),
|
||||
progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
}
|
||||
} else if physics.in_liquid().is_some() {
|
||||
anim::character::SwimWieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
active_tool_kind,
|
||||
second_tool_kind,
|
||||
hands,
|
||||
rel_vel.magnitude(),
|
||||
time,
|
||||
),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
} else if false {
|
||||
// Check for sneaking here if we want combo melee 2 to be able to
|
||||
// sneak when not actively swinging
|
||||
anim::character::SneakWieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
(active_tool_kind, active_tool_spec),
|
||||
second_tool_kind,
|
||||
hands,
|
||||
rel_vel,
|
||||
// TODO: Update to use the quaternion.
|
||||
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
time,
|
||||
),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
} else {
|
||||
anim::character::WieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
(active_tool_kind, active_tool_spec),
|
||||
second_tool_kind,
|
||||
hands,
|
||||
// TODO: Update to use the quaternion.
|
||||
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
look_dir,
|
||||
rel_vel,
|
||||
time,
|
||||
),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
},
|
||||
CharacterState::BasicBlock(s) => {
|
||||
let stage_time = s.timer.as_secs_f32();
|
||||
let stage_progress = match s.stage_section {
|
||||
|
Loading…
Reference in New Issue
Block a user