diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 172577c76f..32efaa0611 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -653,7 +653,8 @@ impl CharacterAbility { scales_with_combo, .. } => { - ((*scales_with_combo && data.combo.counter() > 0) | !*scales_with_combo) + ((*scales_with_combo && data.combo.map_or(false, |c| c.counter() > 0)) + | !*scales_with_combo) && update.energy.try_change_by(-*energy_cost).is_ok() }, CharacterAbility::ComboMelee { .. } @@ -2096,7 +2097,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { range: *range, ability_info, scales_with_combo: *scales_with_combo, - combo_at_cast: data.combo.counter(), + combo_at_cast: data.combo.map_or(0, |c| c.counter()), specifier: *specifier, }, timer: Duration::default(), diff --git a/common/src/states/behavior.rs b/common/src/states/behavior.rs index 0c7e21207d..bb59414af2 100644 --- a/common/src/states/behavior.rs +++ b/common/src/states/behavior.rs @@ -124,9 +124,9 @@ pub struct JoinData<'a> { pub updater: &'a LazyUpdate, pub stats: &'a Stats, pub skill_set: &'a SkillSet, - pub active_abilities: &'a ActiveAbilities, + pub active_abilities: Option<&'a ActiveAbilities>, pub msm: &'a MaterialStatManifest, - pub combo: &'a Combo, + pub combo: Option<&'a Combo>, pub alignment: Option<&'a comp::Alignment>, pub terrain: &'a TerrainGrid, } @@ -150,8 +150,8 @@ pub struct JoinStruct<'a> { pub beam: Option<&'a Beam>, pub stat: &'a Stats, pub skill_set: &'a SkillSet, - pub active_abilities: &'a ActiveAbilities, - pub combo: &'a Combo, + pub active_abilities: Option<&'a ActiveAbilities>, + pub combo: Option<&'a Combo>, pub alignment: Option<&'a comp::Alignment>, pub terrain: &'a TerrainGrid, } diff --git a/common/src/states/combo_melee.rs b/common/src/states/combo_melee.rs index 6ba9d7dabd..21d8afb667 100644 --- a/common/src/states/combo_melee.rs +++ b/common/src/states/combo_melee.rs @@ -160,6 +160,8 @@ impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate { let mut update = StateUpdate::from(data); + let combo_counter = data.combo.map_or(0, |c| c.counter()); + handle_move(data, &mut update, 0.4); // Index should be `self.stage - 1`, however in cases of client-server desync @@ -173,11 +175,7 @@ impl CharacterBehavior for Data { let speed_modifer = 1.0 + self.static_data.max_speed_increase - * (1.0 - - self - .static_data - .speed_increase - .powi(data.combo.counter() as i32)); + * (1.0 - self.static_data.speed_increase.powi(combo_counter as i32)); match self.stage_section { StageSection::Buildup => { @@ -225,7 +223,7 @@ impl CharacterBehavior for Data { + (self .static_data .scales_from_combo - .min(data.combo.counter() / self.static_data.num_stages) + .min(combo_counter / self.static_data.num_stages) as f32) * self.static_data.stage_data[stage_index].damage_increase; @@ -233,7 +231,7 @@ impl CharacterBehavior for Data { + (self .static_data .scales_from_combo - .min(data.combo.counter() / self.static_data.num_stages) + .min(combo_counter / self.static_data.num_stages) as f32) * self.static_data.stage_data[stage_index].poise_damage_increase; let poise = AttackEffect::new( @@ -253,7 +251,7 @@ impl CharacterBehavior for Data { let energy = self.static_data.max_energy_gain.min( self.static_data.initial_energy_gain - + data.combo.counter() as f32 * self.static_data.energy_increase, + + combo_counter as f32 * self.static_data.energy_increase, ); let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy)) diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 49a2baedb3..504bf8d5ff 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -861,12 +861,14 @@ fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKin if let Some(ability_input) = input.into() { if let Some((ability, from_offhand)) = data .active_abilities - .activate_ability( - ability_input, - data.inventory, - data.skill_set, - Some(data.body), - ) + .and_then(|a| { + a.activate_ability( + ability_input, + data.inventory, + data.skill_set, + Some(data.body), + ) + }) .filter(|(ability, _)| ability.requirements_paid(data, update)) { update.character = CharacterState::from(( diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index b46b214cb9..fd0531eb04 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -132,10 +132,10 @@ impl<'a> System<'a> for Sys { ( &read_data.stats, &read_data.skill_sets, - &read_data.active_abilities, + read_data.active_abilities.maybe(), read_data.is_riders.maybe(), ), - &read_data.combos, + read_data.combos.maybe(), ) .join() { diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 6322d7c486..35ab056d97 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -2788,7 +2788,6 @@ impl Hud { Some(inventory), Some(energy), Some(skillset), - Some(active_abilities), Some(body), Some(_character_state), Some(_controller), @@ -2797,7 +2796,6 @@ impl Hud { inventories.get(entity), energies.get(entity), skillsets.get(entity), - active_abilities.get(entity), bodies.get(entity), character_states.get(entity), controllers.get(entity).map(|c| &c.inputs), @@ -2813,7 +2811,7 @@ impl Hud { inventory, energy, skillset, - active_abilities, + active_abilities.get(entity), body, //&character_state, self.pulse, diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs index e4f5248f65..780bc0f38f 100644 --- a/voxygen/src/hud/skillbar.rs +++ b/voxygen/src/hud/skillbar.rs @@ -250,7 +250,7 @@ pub struct Skillbar<'a> { inventory: &'a Inventory, energy: &'a Energy, skillset: &'a SkillSet, - active_abilities: &'a ActiveAbilities, + active_abilities: Option<&'a ActiveAbilities>, body: &'a Body, // character_state: &'a CharacterState, // controller: &'a ControllerInputs, @@ -279,7 +279,7 @@ impl<'a> Skillbar<'a> { inventory: &'a Inventory, energy: &'a Energy, skillset: &'a SkillSet, - active_abilities: &'a ActiveAbilities, + active_abilities: Option<&'a ActiveAbilities>, body: &'a Body, // character_state: &'a CharacterState, pulse: f32, @@ -607,9 +607,11 @@ impl<'a> Skillbar<'a> { .get_by_hash(i) .map(|item| (item.name(), item.description())), hotbar::SlotContents::Ability(i) => active_abilities - .auxiliary_set(Some(inventory), Some(skill_set)) - .get(i) - .and_then(|a| Ability::from(*a).ability_id(Some(inventory))) + .and_then(|a| { + a.auxiliary_set(Some(inventory), Some(skill_set)) + .get(i) + .and_then(|a| Ability::from(*a).ability_id(Some(inventory))) + }) .map(util::ability_description), }) }; @@ -679,8 +681,9 @@ impl<'a> Skillbar<'a> { .right_from(state.ids.slot5, slot_offset) .set(state.ids.m1_slot_bg, ui); - let primary_ability_id = - Ability::from(self.active_abilities.primary).ability_id(Some(self.inventory)); + let primary_ability_id = self + .active_abilities + .and_then(|a| Ability::from(a.primary).ability_id(Some(self.inventory))); Button::image( primary_ability_id.map_or(self.imgs.nothing, |id| util::ability_image(self.imgs, id)), @@ -694,8 +697,9 @@ impl<'a> Skillbar<'a> { .right_from(state.ids.m1_slot_bg, slot_offset) .set(state.ids.m2_slot_bg, ui); - let secondary_ability_id = - Ability::from(self.active_abilities.secondary).ability_id(Some(self.inventory)); + let secondary_ability_id = self + .active_abilities + .and_then(|a| Ability::from(a.secondary).ability_id(Some(self.inventory))); Button::image( secondary_ability_id.map_or(self.imgs.nothing, |id| util::ability_image(self.imgs, id)), @@ -706,12 +710,14 @@ impl<'a> Skillbar<'a> { if self.energy.current() >= self .active_abilities - .activate_ability( - AbilityInput::Secondary, - Some(self.inventory), - self.skillset, - Some(self.body), - ) + .and_then(|a| { + a.activate_ability( + AbilityInput::Secondary, + Some(self.inventory), + self.skillset, + Some(self.body), + ) + }) .map_or(0.0, |(a, _)| a.get_energy_cost()) { Color::Rgba(1.0, 1.0, 1.0, 1.0) diff --git a/voxygen/src/hud/slots.rs b/voxygen/src/hud/slots.rs index ec2fd4fb7c..5c8f58973e 100644 --- a/voxygen/src/hud/slots.rs +++ b/voxygen/src/hud/slots.rs @@ -120,7 +120,7 @@ type HotbarSource<'a> = ( &'a Inventory, &'a Energy, &'a SkillSet, - &'a ActiveAbilities, + Option<&'a ActiveAbilities>, &'a Body, ); type HotbarImageSource<'a> = (&'a ItemImgs, &'a img_ids::Imgs); @@ -142,21 +142,24 @@ impl<'a> SlotKey, HotbarImageSource<'a>> for HotbarSlot { } }, hotbar::SlotContents::Ability(i) => { - let ability_id = active_abilities - .auxiliary_set(Some(inventory), Some(skillset)) - .get(i) - .and_then(|a| Ability::from(*a).ability_id(Some(inventory))); + let ability_id = active_abilities.and_then(|a| { + a.auxiliary_set(Some(inventory), Some(skillset)) + .get(i) + .and_then(|a| Ability::from(*a).ability_id(Some(inventory))) + }); ability_id .map(|id| HotbarImage::Ability(id.to_string())) .and_then(|image| { active_abilities - .activate_ability( - AbilityInput::Auxiliary(i), - Some(inventory), - skillset, - Some(body), - ) + .and_then(|a| { + a.activate_ability( + AbilityInput::Auxiliary(i), + Some(inventory), + skillset, + Some(body), + ) + }) .map(|(ability, _)| { ( image,