diff --git a/assets/common/abilities/sword/balanced_combo.ron b/assets/common/abilities/sword/balanced_combo.ron index 5de18eb045..36b0372be8 100644 --- a/assets/common/abilities/sword/balanced_combo.ron +++ b/assets/common/abilities/sword/balanced_combo.ron @@ -37,6 +37,7 @@ ComboMelee2( ori_modifier: 0.6, ), ], + is_stance: true, meta: ( kind: Some(Sword(Balanced)), ), diff --git a/assets/common/abilities/sword/balanced_thrust.ron b/assets/common/abilities/sword/balanced_thrust.ron index a7410530b8..f957c02050 100644 --- a/assets/common/abilities/sword/balanced_thrust.ron +++ b/assets/common/abilities/sword/balanced_thrust.ron @@ -19,6 +19,7 @@ ComboMelee2( ori_modifier: 0.6, ), ], + is_stance: false, meta: ( kind: Some(Sword(Balanced)), ), diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index a6da6547eb..b0bfbcc670 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -505,6 +505,7 @@ pub enum CharacterAbility { }, ComboMelee2 { strikes: Vec>, + is_stance: bool, #[serde(default)] meta: AbilityMeta, }, @@ -918,6 +919,7 @@ impl CharacterAbility { }, ComboMelee2 { ref mut strikes, + is_stance: _, meta: _, } => { *strikes = strikes @@ -1959,19 +1961,22 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { timer: Duration::default(), stage_section: StageSection::Buildup, }), - CharacterAbility::ComboMelee2 { strikes, meta: _ } => { - CharacterState::ComboMelee2(combo_melee2::Data { - static_data: combo_melee2::StaticData { - strikes: strikes.iter().map(|s| s.to_duration()).collect(), - ability_info, - }, - exhausted: false, - skip_recover: false, - timer: Duration::default(), - stage_section: Some(StageSection::Buildup), - completed_strikes: 0, - }) - }, + CharacterAbility::ComboMelee2 { + strikes, + 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, + ability_info, + }, + exhausted: false, + skip_recover: false, + timer: Duration::default(), + stage_section: Some(StageSection::Buildup), + completed_strikes: 0, + }), CharacterAbility::LeapMelee { energy_cost: _, buildup_duration, diff --git a/common/src/states/combo_melee2.rs b/common/src/states/combo_melee2.rs index bfaf7c4f19..2d165cdf0f 100644 --- a/common/src/states/combo_melee2.rs +++ b/common/src/states/combo_melee2.rs @@ -65,6 +65,9 @@ impl Strike { pub struct StaticData { /// Data for each stage pub strikes: Vec>, + /// 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, /// What key is used to press ability pub ability_info: AbilityInfo, } @@ -95,9 +98,17 @@ impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate { let mut update = StateUpdate::from(data); + // If is a stance, use M1 to control strikes, otherwise use the input that + // activated the ability + let ability_input = if self.static_data.is_stance { + InputKind::Primary + } else { + self.static_data.ability_info.input + }; + handle_orientation(data, &mut update, 1.0, None); handle_move(data, &mut update, 0.7); - handle_interrupts(data, &mut update, Some(InputKind::Primary)); + handle_interrupts(data, &mut update, Some(ability_input)); let strike_data = self.static_data.strikes[self.completed_strikes % self.static_data.strikes.len()]; @@ -118,7 +129,7 @@ impl CharacterBehavior for Data { } }, Some(StageSection::Action) => { - if input_is_pressed(data, InputKind::Primary) { + if input_is_pressed(data, ability_input) { if let CharacterState::ComboMelee2(c) = &mut update.character { c.skip_recover = true; } @@ -163,10 +174,18 @@ impl CharacterBehavior for Data { c.timer = tick_attack_or_default(data, self.timer, None); } } else { - // Done - if let CharacterState::ComboMelee2(c) = &mut update.character { - c.timer = Duration::default(); - c.stage_section = None; + // If is a stance, stay in combo melee, otherwise return to wielding + if self.static_data.is_stance { + if let CharacterState::ComboMelee2(c) = &mut update.character { + c.timer = Duration::default(); + c.stage_section = None; + } + } else { + // Return to wielding + update.character = + CharacterState::Wielding(wielding::Data { is_sneaking: false }); + // Make sure attack component is removed + data.updater.remove::(data.entity); } } }, @@ -192,7 +211,7 @@ impl CharacterBehavior for Data { handle_climb(data, &mut update); handle_jump(data, output_events, &mut update, 1.0); - if input_is_pressed(data, InputKind::Primary) { + if input_is_pressed(data, ability_input) { next_strike(&mut update) } else { attempt_input(data, output_events, &mut update);