diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 69d328ba40..0100612828 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -1191,6 +1191,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState { stage_section: StageSection::Buildup, was_wielded: false, // false by default. utils might set it to true was_sneak: false, + was_combo: None, }), CharacterAbility::ComboMelee { stage_data, diff --git a/common/src/states/roll.rs b/common/src/states/roll.rs index 1667407b36..4f46f606de 100644 --- a/common/src/states/roll.rs +++ b/common/src/states/roll.rs @@ -36,6 +36,8 @@ pub struct Data { pub was_wielded: bool, /// Was sneaking pub was_sneak: bool, + /// Was in state with combo + pub was_combo: Option<(AbilityKey, u32)>, } impl CharacterBehavior for Data { @@ -112,7 +114,9 @@ impl CharacterBehavior for Data { }); } else { // Done - if self.was_wielded { + if let Some((key, stage)) = self.was_combo { + resume_combo(data, &mut update, key, stage); + } else if self.was_wielded { update.character = CharacterState::Wielding; } else if self.was_sneak { update.character = CharacterState::Sneak; @@ -123,7 +127,9 @@ impl CharacterBehavior for Data { }, _ => { // If it somehow ends up in an incorrect stage section - if self.was_wielded { + if let Some((key, stage)) = self.was_combo { + resume_combo(data, &mut update, key, stage); + } else if self.was_wielded { update.character = CharacterState::Wielding; } else if self.was_sneak { update.character = CharacterState::Sneak; diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 4c996ff15f..a39f20811e 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -529,7 +529,17 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) { }) .filter(|ability| ability.requirements_paid(data, update)) { - if data.character.is_wield() { + if let CharacterState::ComboMelee(c) = data.character { + update.character = ( + &ability, + AbilityInfo::from_key(data, AbilityKey::Dodge, false), + ) + .into(); + if let CharacterState::Roll(roll) = &mut update.character { + roll.was_combo = Some((c.static_data.ability_info.key, c.stage)); + roll.was_wielded = true; + } + } else if data.character.is_wield() { update.character = ( &ability, AbilityInfo::from_key(data, AbilityKey::Dodge, false), @@ -576,6 +586,16 @@ pub fn handle_interrupt(data: &JoinData, update: &mut StateUpdate, attacks_inter handle_dodge_input(data, update); } +pub fn resume_combo(data: &JoinData, update: &mut StateUpdate, key: AbilityKey, stage: u32) { + if ability_key_is_pressed(data, key) { + handle_interrupt(data, update, true); + } + // If other states are introduced that progress through stages, add them here + if let CharacterState::ComboMelee(c) = &mut update.character { + c.stage = stage; + } +} + pub fn ability_key_is_pressed(data: &JoinData, ability_key: AbilityKey) -> bool { match ability_key { AbilityKey::Mouse1 => data.inputs.primary.is_pressed(), diff --git a/voxygen/src/audio/sfx/event_mapper/movement/tests.rs b/voxygen/src/audio/sfx/event_mapper/movement/tests.rs index 1e36ffc7c7..018deaaa0c 100644 --- a/voxygen/src/audio/sfx/event_mapper/movement/tests.rs +++ b/voxygen/src/audio/sfx/event_mapper/movement/tests.rs @@ -189,6 +189,7 @@ fn maps_roll() { stage_section: states::utils::StageSection::Buildup, was_wielded: true, was_sneak: false, + was_combo: None, }), &PhysicsState { on_ground: true,