diff --git a/assets/common/abilities/sword/balanced_combo.ron b/assets/common/abilities/sword/balanced_combo.ron index 36b0372be8..624d0cae55 100644 --- a/assets/common/abilities/sword/balanced_combo.ron +++ b/assets/common/abilities/sword/balanced_combo.ron @@ -15,7 +15,6 @@ ComboMelee2( swing_duration: 0.1, hit_timing: 0.5, recover_duration: 0.5, - forward_movement: 0.0, ori_modifier: 0.6, ), ( @@ -33,11 +32,11 @@ ComboMelee2( swing_duration: 0.1, hit_timing: 0.5, recover_duration: 0.3, - forward_movement: 0.0, ori_modifier: 0.6, ), ], is_stance: true, + energy_cost_per_strike: 0, meta: ( kind: Some(Sword(Balanced)), ), diff --git a/assets/common/abilities/sword/balanced_finisher.ron b/assets/common/abilities/sword/balanced_finisher.ron index d25b5cf375..407aedd19c 100644 --- a/assets/common/abilities/sword/balanced_finisher.ron +++ b/assets/common/abilities/sword/balanced_finisher.ron @@ -14,4 +14,7 @@ FinisherMelee( angle: 15.0, ), minimum_combo: 10, + meta: ( + kind: Some(Sword(Balanced)), + ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/balanced_thrust.ron b/assets/common/abilities/sword/balanced_thrust.ron index f957c02050..878af1aaa4 100644 --- a/assets/common/abilities/sword/balanced_thrust.ron +++ b/assets/common/abilities/sword/balanced_thrust.ron @@ -3,7 +3,7 @@ ComboMelee2( ( melee_constructor: ( kind: Slash( - damage: 15, + damage: 12, poise: 0, knockback: 0, energy_regen: 5, @@ -15,11 +15,11 @@ ComboMelee2( swing_duration: 0.1, hit_timing: 0.6, recover_duration: 0.5, - forward_movement: 0.0, ori_modifier: 0.6, ), ], is_stance: false, + energy_cost_per_strike: 5, meta: ( kind: Some(Sword(Balanced)), ), diff --git a/assets/common/abilities/sword/offensive_advance.ron b/assets/common/abilities/sword/offensive_advance.ron index d311941ad4..b5a37a3866 100644 --- a/assets/common/abilities/sword/offensive_advance.ron +++ b/assets/common/abilities/sword/offensive_advance.ron @@ -1,25 +1,27 @@ -// TODO: Make actual ability, just for testing right now -BasicMelee( - energy_cost: 50, - buildup_duration: 0.3, - swing_duration: 0.1, - recover_duration: 0.2, - melee_constructor: ( - kind: Stab( - damage: 10, - poise: 0, - knockback: 0, - energy_regen: 0, +ComboMelee2( + strikes: [ + ( + melee_constructor: ( + kind: Slash( + damage: 15, + poise: 0, + knockback: 0, + energy_regen: 10, + ), + range: 6.0, + angle: 5.0, + ), + buildup_duration: 0.2, + swing_duration: 0.1, + hit_timing: 0.6, + recover_duration: 0.4, + movement: Some(Forward(2.5)), + ori_modifier: 0.6, ), - range: 5.0, - angle: 10.0, - ), - ori_modifier: 1.0, + ], + is_stance: false, + energy_cost_per_strike: 10, meta: ( - kind: Some(Sword(Balanced)), - capabilities: ( - // Block - bits: 0b00000010, - ), + kind: Some(Sword(Offensive)), ), -) +) \ No newline at end of file diff --git a/assets/common/abilities/sword/offensive_combo.ron b/assets/common/abilities/sword/offensive_combo.ron index d311941ad4..69d20f4c3a 100644 --- a/assets/common/abilities/sword/offensive_combo.ron +++ b/assets/common/abilities/sword/offensive_combo.ron @@ -1,25 +1,60 @@ -// TODO: Make actual ability, just for testing right now -BasicMelee( - energy_cost: 50, - buildup_duration: 0.3, - swing_duration: 0.1, - recover_duration: 0.2, - melee_constructor: ( - kind: Stab( - damage: 10, - poise: 0, - knockback: 0, - energy_regen: 0, +ComboMelee2( + strikes: [ + ( + melee_constructor: ( + kind: Slash( + damage: 10, + poise: 0, + knockback: 0, + energy_regen: 5, + ), + range: 3.0, + angle: 45.0, + ), + buildup_duration: 0.3, + swing_duration: 0.1, + hit_timing: 0.5, + recover_duration: 0.5, + ori_modifier: 0.6, ), - range: 5.0, - angle: 10.0, - ), - ori_modifier: 1.0, + ( + melee_constructor: ( + kind: Slash( + damage: 14, + poise: 0, + knockback: 0, + energy_regen: 8, + ), + range: 3.0, + angle: 45.0, + ), + buildup_duration: 0.3, + swing_duration: 0.1, + hit_timing: 0.5, + recover_duration: 0.3, + ori_modifier: 0.6, + ), + ( + melee_constructor: ( + kind: Slash( + damage: 9, + poise: 0, + knockback: 0, + energy_regen: 10, + ), + range: 3.0, + angle: 45.0, + ), + buildup_duration: 0.2, + swing_duration: 0.05, + hit_timing: 0.5, + recover_duration: 0.1, + ori_modifier: 0.6, + ), + ], + is_stance: true, + energy_cost_per_strike: 5, meta: ( - kind: Some(Sword(Balanced)), - capabilities: ( - // Block - bits: 0b00000010, - ), + kind: Some(Sword(Offensive)), ), -) +) \ No newline at end of file diff --git a/assets/common/abilities/sword/offensive_finisher.ron b/assets/common/abilities/sword/offensive_finisher.ron index d311941ad4..d411ea1f41 100644 --- a/assets/common/abilities/sword/offensive_finisher.ron +++ b/assets/common/abilities/sword/offensive_finisher.ron @@ -1,25 +1,30 @@ -// TODO: Make actual ability, just for testing right now -BasicMelee( - energy_cost: 50, - buildup_duration: 0.3, +FinisherMelee( + energy_cost: 40, + buildup_duration: 0.4, swing_duration: 0.1, - recover_duration: 0.2, + recover_duration: 0.4, melee_constructor: ( - kind: Stab( - damage: 10, + kind: Slash( + damage: 30, + poise: 0, + knockback: 0, + energy_regen: 10, + ), + scaled: Some(Slash( + damage: 15, poise: 0, knockback: 0, energy_regen: 0, - ), - range: 5.0, - angle: 10.0, + )), + range: 3.0, + angle: 15.0, ), - ori_modifier: 1.0, + scaling: Some(( + target: Attack, + kind: Linear, + )), + minimum_combo: 10, meta: ( - kind: Some(Sword(Balanced)), - capabilities: ( - // Block - bits: 0b00000010, - ), + kind: Some(Sword(Offensive)), ), -) +) \ No newline at end of file diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 7293f8f995..827aa4e3ad 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -506,6 +506,7 @@ pub enum CharacterAbility { ComboMelee2 { strikes: Vec>, is_stance: bool, + energy_cost_per_strike: f32, #[serde(default)] meta: AbilityMeta, }, @@ -744,6 +745,22 @@ impl CharacterAbility { | !*scales_with_combo) && update.energy.try_change_by(-*energy_cost).is_ok() }, + CharacterAbility::ComboMelee2 { + is_stance, + energy_cost_per_strike, + .. + } => { + // If it is a stance, just check that enough energy is present, otherwise + // consume the required energy now + if *is_stance { + update.energy.current() > *energy_cost_per_strike + } else { + update + .energy + .try_change_by(-*energy_cost_per_strike) + .is_ok() + } + }, CharacterAbility::FinisherMelee { energy_cost, minimum_combo, @@ -753,7 +770,6 @@ impl CharacterAbility { && update.energy.try_change_by(-*energy_cost).is_ok() }, CharacterAbility::ComboMelee { .. } - | CharacterAbility::ComboMelee2 { .. } | CharacterAbility::Boost { .. } | CharacterAbility::BasicBeam { .. } | CharacterAbility::Blink { .. } @@ -920,8 +936,10 @@ impl CharacterAbility { ComboMelee2 { ref mut strikes, is_stance: _, + ref mut energy_cost_per_strike, meta: _, } => { + *energy_cost_per_strike /= stats.energy_efficiency; *strikes = strikes .iter_mut() .map(|s| s.adjusted_by_stats(stats)) @@ -1208,7 +1226,11 @@ impl CharacterAbility { | BasicAura { energy_cost, .. } | BasicBlock { energy_cost, .. } | SelfBuff { energy_cost, .. } - | FinisherMelee { energy_cost, .. } => *energy_cost, + | FinisherMelee { energy_cost, .. } + | ComboMelee2 { + energy_cost_per_strike: energy_cost, + .. + } => *energy_cost, BasicBeam { energy_drain, .. } => { if *energy_drain > f32::EPSILON { 1.0 @@ -1218,7 +1240,6 @@ impl CharacterAbility { }, Boost { .. } | ComboMelee { .. } - | ComboMelee2 { .. } | Blink { .. } | Music { .. } | BasicSummon { .. } @@ -1963,12 +1984,14 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { }), CharacterAbility::ComboMelee2 { strikes, + energy_cost_per_strike, is_stance, meta: _, } => CharacterState::ComboMelee2(combo_melee2::Data { static_data: combo_melee2::StaticData { strikes: strikes.iter().map(|s| s.to_duration()).collect(), is_stance: *is_stance, + energy_cost_per_strike: *energy_cost_per_strike, ability_info, }, exhausted: false, diff --git a/common/src/states/combo_melee.rs b/common/src/states/combo_melee.rs index f1eb574cee..9ecce143a0 100644 --- a/common/src/states/combo_melee.rs +++ b/common/src/states/combo_melee.rs @@ -309,9 +309,13 @@ impl CharacterBehavior for Data { ); // Forward movement - handle_forced_movement(data, &mut update, ForcedMovement::Forward { - strength: self.static_data.stage_data[stage_index].forward_movement, - }); + handle_forced_movement( + data, + &mut update, + ForcedMovement::Forward( + self.static_data.stage_data[stage_index].forward_movement, + ), + ); // Swings update.character = CharacterState::ComboMelee(Data { diff --git a/common/src/states/combo_melee2.rs b/common/src/states/combo_melee2.rs index edf878b7cf..11ce3a2336 100644 --- a/common/src/states/combo_melee2.rs +++ b/common/src/states/combo_melee2.rs @@ -26,7 +26,7 @@ pub struct Strike { /// 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, + pub movement: Option, /// Adjusts turning rate during the attack pub ori_modifier: f32, } @@ -39,7 +39,7 @@ impl Strike { 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, + movement: self.movement, ori_modifier: self.ori_modifier, } } @@ -52,7 +52,7 @@ impl Strike { swing_duration: self.swing_duration / stats.speed, hit_timing: self.hit_timing, recover_duration: self.recover_duration / stats.speed, - forward_movement: self.forward_movement, + movement: self.movement, ori_modifier: self.ori_modifier, } } @@ -68,6 +68,8 @@ pub struct StaticData { /// Whether or not combo melee should function as a stance (where it remains /// in the character state after a strike has finished) pub is_stance: bool, + /// The amount of energy consumed with each swing + pub energy_cost_per_strike: f32, /// What key is used to press ability pub ability_info: AbilityInfo, } @@ -115,6 +117,9 @@ impl CharacterBehavior for Data { match self.stage_section { Some(StageSection::Buildup) => { + if let Some(movement) = strike_data.movement { + handle_forced_movement(data, &mut update, movement); + } if self.timer < strike_data.buildup_duration { // Build up if let CharacterState::ComboMelee2(c) = &mut update.character { @@ -129,9 +134,13 @@ impl CharacterBehavior for Data { } }, Some(StageSection::Action) => { + if let Some(movement) = strike_data.movement { + handle_forced_movement(data, &mut update, movement); + } if input_is_pressed(data, ability_input) { if let CharacterState::ComboMelee2(c) = &mut update.character { - c.skip_recover = true; + // Only allow recovery to be skipped if attack is a stance + c.skip_recover = c.static_data.is_stance; } } if self.timer.as_secs_f32() @@ -233,9 +242,15 @@ fn end_strike(update: &mut StateUpdate) { fn next_strike(update: &mut StateUpdate) { if let CharacterState::ComboMelee2(c) = &mut update.character { - c.exhausted = false; - c.skip_recover = false; - c.timer = Duration::default(); - c.stage_section = Some(StageSection::Buildup); + if update + .energy + .try_change_by(-c.static_data.energy_cost_per_strike) + .is_ok() + { + c.exhausted = false; + c.skip_recover = false; + c.timer = Duration::default(); + c.stage_section = Some(StageSection::Buildup); + } } } diff --git a/common/src/states/dash_melee.rs b/common/src/states/dash_melee.rs index fa3db6fd04..bf01d0ce82 100644 --- a/common/src/states/dash_melee.rs +++ b/common/src/states/dash_melee.rs @@ -89,9 +89,13 @@ impl CharacterBehavior for Data { .min(1.0); handle_orientation(data, &mut update, self.static_data.ori_modifier, None); - handle_forced_movement(data, &mut update, ForcedMovement::Forward { - strength: self.static_data.forward_speed * charge_frac.sqrt(), - }); + handle_forced_movement( + data, + &mut update, + ForcedMovement::Forward( + self.static_data.forward_speed * charge_frac.sqrt(), + ), + ); // This logic basically just decides if a charge should end, // and prevents the character state spamming attacks diff --git a/common/src/states/roll.rs b/common/src/states/roll.rs index 1d44e1428c..6cbe9d4677 100644 --- a/common/src/states/roll.rs +++ b/common/src/states/roll.rs @@ -84,14 +84,18 @@ impl CharacterBehavior for Data { }, StageSection::Movement => { // Update velocity - handle_forced_movement(data, &mut update, ForcedMovement::Forward { - strength: self.static_data.roll_strength - * ((1.0 - - self.timer.as_secs_f32() - / self.static_data.movement_duration.as_secs_f32()) - / 2.0 - + 0.25), - }); + handle_forced_movement( + data, + &mut update, + ForcedMovement::Forward( + self.static_data.roll_strength + * ((1.0 + - self.timer.as_secs_f32() + / self.static_data.movement_duration.as_secs_f32()) + / 2.0 + + 0.25), + ), + ); if self.timer < self.static_data.movement_duration { // Movement diff --git a/common/src/states/spin_melee.rs b/common/src/states/spin_melee.rs index 30e5a8c170..c7b158c0b1 100644 --- a/common/src/states/spin_melee.rs +++ b/common/src/states/spin_melee.rs @@ -107,9 +107,11 @@ impl CharacterBehavior for Data { self.static_data.movement_behavior, MovementBehavior::ForwardGround ) { - handle_forced_movement(data, &mut update, ForcedMovement::Forward { - strength: self.static_data.forward_speed, - }); + handle_forced_movement( + data, + &mut update, + ForcedMovement::Forward(self.static_data.forward_speed), + ); } // Swings diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index cbc786b201..03bced1482 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -408,7 +408,7 @@ pub fn handle_forced_movement( movement: ForcedMovement, ) { match movement { - ForcedMovement::Forward { strength } => { + ForcedMovement::Forward(strength) => { let strength = strength * data.stats.move_speed_modifier * data.stats.friction_modifier; if let Some(accel) = data.physics.on_ground.map(|block| { // FRIC_GROUND temporarily used to normalize things around expected values @@ -416,7 +416,7 @@ pub fn handle_forced_movement( }) { update.vel.0 += Vec2::broadcast(data.dt.0) * accel - * (data.inputs.move_dir * 0.5 + Vec2::from(update.ori) * 1.5) + * Vec2::from(update.ori) * strength; } }, @@ -1202,9 +1202,7 @@ pub enum StageSection { #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] pub enum ForcedMovement { - Forward { - strength: f32, - }, + Forward(f32), Leap { vertical: f32, forward: f32,