diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 7e241908f3..1730c34d13 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -336,12 +336,14 @@ impl From<&CharacterAbility> for CharacterState { num_stages: stage_data.len() as u32, combo: 0, stage_data: stage_data.clone(), - exhausted: false, initial_energy_gain: *initial_energy_gain, max_energy_gain: *max_energy_gain, energy_increase: *energy_increase, combo_duration: *combo_duration, timer: Duration::default(), + in_buildup: true, + in_recover: false, + in_combo: false, }), CharacterAbility::LeapMelee { energy_cost: _, diff --git a/common/src/states/combo_melee.rs b/common/src/states/combo_melee.rs index 25b2d86342..3f4470c9f7 100644 --- a/common/src/states/combo_melee.rs +++ b/common/src/states/combo_melee.rs @@ -40,8 +40,6 @@ pub struct Data { pub combo: u32, /// Data for first stage pub stage_data: Vec, - /// Whether state can deal more damage - pub exhausted: bool, /// Initial energy gain per strike pub initial_energy_gain: u32, /// Max energy gain per strike @@ -52,6 +50,12 @@ pub struct Data { pub combo_duration: Duration, /// Timer for each stage pub timer: Duration, + /// Checks if state is in buildup duration + pub in_buildup: bool, + /// Checks if state is in recover duration + pub in_recover: bool, + /// Checks if state is in combo duration + pub in_combo: bool, } impl CharacterBehavior for Data { @@ -63,14 +67,13 @@ impl CharacterBehavior for Data { let stage_index = (self.stage - 1) as usize; - if !self.exhausted && self.timer < self.stage_data[stage_index].base_buildup_duration { + if self.in_buildup && self.timer < self.stage_data[stage_index].base_buildup_duration { // Build up update.character = CharacterState::ComboMelee(Data { stage: self.stage, num_stages: self.num_stages, combo: self.combo, stage_data: self.stage_data.clone(), - exhausted: self.exhausted, initial_energy_gain: self.initial_energy_gain, max_energy_gain: self.max_energy_gain, energy_increase: self.energy_increase, @@ -79,8 +82,11 @@ impl CharacterBehavior for Data { .timer .checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), + in_buildup: self.in_buildup, + in_recover: self.in_recover, + in_combo: self.in_combo, }); - } else if !self.exhausted { + } else if self.in_buildup { // Hit attempt data.updater.insert(data.entity, Attacking { base_healthchange: -((self.stage_data[stage_index].max_damage.min( @@ -100,20 +106,21 @@ impl CharacterBehavior for Data { num_stages: self.num_stages, combo: self.combo, stage_data: self.stage_data.clone(), - exhausted: true, initial_energy_gain: self.initial_energy_gain, max_energy_gain: self.max_energy_gain, energy_increase: self.energy_increase, combo_duration: self.combo_duration, timer: Duration::default(), + in_buildup: false, + in_recover: true, + in_combo: self.in_combo, }); - } else if self.timer < self.stage_data[stage_index].base_recover_duration { + } else if self.in_recover && self.timer < self.stage_data[stage_index].base_recover_duration { update.character = CharacterState::ComboMelee(Data { stage: self.stage, num_stages: self.num_stages, combo: self.combo, stage_data: self.stage_data.clone(), - exhausted: self.exhausted, initial_energy_gain: self.initial_energy_gain, max_energy_gain: self.max_energy_gain, energy_increase: self.energy_increase, @@ -122,22 +129,40 @@ impl CharacterBehavior for Data { .timer .checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), + in_buildup: self.in_buildup, + in_recover: self.in_recover, + in_combo: self.in_combo, }); - } else if self.timer - < self.combo_duration + self.stage_data[stage_index].base_recover_duration - { + } else if self.in_recover { + update.character = CharacterState::ComboMelee(Data { + stage: self.stage, + num_stages: self.num_stages, + combo: self.combo, + stage_data: self.stage_data.clone(), + initial_energy_gain: self.initial_energy_gain, + max_energy_gain: self.max_energy_gain, + energy_increase: self.energy_increase, + combo_duration: self.combo_duration, + timer: Duration::default(), + in_buildup: self.in_buildup, + in_recover: false, + in_combo: true, + }); + } else if self.in_combo && self.timer < self.combo_duration { if data.inputs.primary.is_pressed() { update.character = CharacterState::ComboMelee(Data { stage: (self.stage % self.num_stages) + 1, num_stages: self.num_stages, combo: self.combo + 1, stage_data: self.stage_data.clone(), - exhausted: false, initial_energy_gain: self.initial_energy_gain, max_energy_gain: self.max_energy_gain, energy_increase: self.energy_increase, combo_duration: self.combo_duration, timer: Duration::default(), + in_buildup: true, + in_recover: self.in_recover, + in_combo: false, }); } else { update.character = CharacterState::ComboMelee(Data { @@ -145,7 +170,6 @@ impl CharacterBehavior for Data { num_stages: self.num_stages, combo: self.combo, stage_data: self.stage_data.clone(), - exhausted: self.exhausted, initial_energy_gain: self.initial_energy_gain, max_energy_gain: self.max_energy_gain, energy_increase: self.energy_increase, @@ -154,6 +178,9 @@ impl CharacterBehavior for Data { .timer .checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), + in_buildup: self.in_buildup, + in_recover: self.in_recover, + in_combo: self.in_combo, }); } } else { diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 7c268fca19..de09039499 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -913,21 +913,23 @@ impl FigureMgr { }, CharacterState::ComboMelee(s) => { let stage_index = (s.stage - 1) as usize; - let stage_time = if !s.exhausted { - s.timer.as_secs_f64() + let stage_time = s.timer.as_secs_f64(); + let swing_frac = 0.5; // What percentage of buildup is swing animation + let in_swing: bool; + let stage_progress = if s.in_buildup { + let buildup_progress = stage_time / s.stage_data[stage_index].base_buildup_duration.as_secs_f64(); + if buildup_progress < swing_frac { + in_swing = false; + buildup_progress / (1.0 - swing_frac) + } else { + in_swing = true; + (buildup_progress - (1.0 - swing_frac)) / swing_frac + } + } else if s.in_recover { + stage_time / s.stage_data[stage_index].base_recover_duration.as_secs_f64() } else { - s.timer.as_secs_f64() - + s.stage_data[stage_index] - .base_buildup_duration - .as_secs_f64() + stage_time / s.combo_duration.as_secs_f64() }; - let stage_progress = stage_time - / (s.stage_data[stage_index] - .base_buildup_duration - .as_secs_f64() - + s.stage_data[stage_index] - .base_recover_duration - .as_secs_f64()); match s.stage { 1 => anim::character::AlphaAnimation::update_skeleton( &target_base,