diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 2faf68ce69..dc293fbc6c 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -1,6 +1,7 @@ use crate::{ - comp::{Body, CharacterState, Item, Projectile, ToolData}, + comp::{Body, CharacterState, EnergySource, Item, Projectile, StateUpdate, ToolData}, states::*, + sys::character_behavior::JoinData, }; use specs::{Component, DenseVecStorage, FlaggedStorage, HashMapStorage}; use std::time::Duration; @@ -37,6 +38,31 @@ pub enum CharacterAbility { }, } +impl CharacterAbility { + pub fn test_requirements(&self, data: &JoinData, update: &mut StateUpdate) -> bool { + match self { + CharacterAbility::Roll => { + data.physics.on_ground + && !data.physics.in_fluid + && data.body.is_humanoid() + && update + .energy + .try_change_by(-200, EnergySource::Ability) + .is_ok() + }, + CharacterAbility::DashMelee { .. } => { + data.physics.on_ground + && !data.physics.in_fluid + && update + .energy + .try_change_by(-300, EnergySource::Ability) + .is_ok() + }, + _ => true, + } + } +} + impl Component for CharacterAbility { type Storage = DenseVecStorage; } diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs index cb7fabee44..bbc481daca 100644 --- a/common/src/comp/energy.rs +++ b/common/src/comp/energy.rs @@ -11,8 +11,7 @@ pub struct Energy { #[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub enum EnergySource { - CastSpell, - Roll, + Ability, Climb, LevelUp, HitEnemy, diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index e3c36f1887..c039db1310 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -183,78 +183,53 @@ pub fn handle_jump(data: &JoinData, update: &mut StateUpdate) { } /// If `inputs.primary` is pressed and in `Wielding` state, -/// will attempt to go into `ability_pool.primary` +/// will attempt to go into `loadout.active_item.primary_ability` pub fn handle_primary_input(data: &JoinData, update: &mut StateUpdate) { if data.inputs.primary.is_pressed() { - if let CharacterState::Wielding { .. } = update.character { - attempt_primary_ability(data, update); + if let Some(ability) = data + .loadout + .active_item + .as_ref() + .and_then(|i| i.primary_ability.as_ref()) + .filter(|ability| ability.test_requirements(data, update)) + { + update.character = ability.into(); } } } -/// Attempts to go into `ability_pool.primary` if is `Some()` on `AbilityPool` -pub fn attempt_primary_ability(data: &JoinData, update: &mut StateUpdate) { - if let Some(ability) = data - .loadout - .active_item - .as_ref() - .and_then(|i| i.primary_ability.as_ref()) - { - update.character = ability.into(); - } -} - /// If `inputs.secondary` is pressed and in `Wielding` state, -/// will attempt to go into `ability_pool.secondary` +/// will attempt to go into `loadout.active_item.secondary_ability` pub fn handle_secondary_input(data: &JoinData, update: &mut StateUpdate) { if data.inputs.secondary.is_pressed() { - if let CharacterState::Wielding { .. } = update.character { - attempt_secondary_ability(data, update); + if let Some(ability) = data + .loadout + .active_item + .as_ref() + .and_then(|i| i.secondary_ability.as_ref()) + .filter(|ability| ability.test_requirements(data, update)) + { + update.character = ability.into(); } } } -/// Attempts to go into `ability_pool.secondary` if is `Some()` on `AbilityPool` -pub fn attempt_secondary_ability(data: &JoinData, update: &mut StateUpdate) { - if let Some(ability) = data - .loadout - .active_item - .as_ref() - .and_then(|i| i.secondary_ability.as_ref()) - { - update.character = ability.into(); - } -} - /// Checks that player can perform a dodge, then -/// attempts to go into `ability_pool.dodge` +/// attempts to go into `loadout.active_item.dodge_ability` pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) { - if let CharacterState::Idle { .. } | CharacterState::Wielding { .. } = update.character { - if data.inputs.roll.is_pressed() - && data.physics.on_ground - && !data.physics.in_fluid - && data.body.is_humanoid() - && update - .energy - .try_change_by(-200, EnergySource::Roll) - .is_ok() + if data.inputs.roll.is_pressed() { + if let Some(ability) = data + .loadout + .active_item + .as_ref() + .and_then(|i| i.dodge_ability.as_ref()) + .filter(|ability| ability.test_requirements(data, update)) { - attempt_dodge_ability(data, update); + update.character = ability.into(); } } } -pub fn attempt_dodge_ability(data: &JoinData, update: &mut StateUpdate) { - if let Some(ability) = data - .loadout - .active_item - .as_ref() - .and_then(|i| i.dodge_ability.as_ref()) - { - update.character = ability.into(); - } -} - pub fn unwrap_tool_data<'a>(data: &'a JoinData) -> Option<&'a ToolData> { if let Some(Tool(tool)) = data.loadout.active_item.as_ref().map(|i| &i.item.kind) { Some(tool)