Add ability requirements system

This commit is contained in:
timokoesters 2020-03-17 15:01:41 +01:00
parent f32eb1db75
commit 19a09782a0
3 changed files with 55 additions and 55 deletions

View File

@ -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<Self>;
}

View File

@ -11,8 +11,7 @@ pub struct Energy {
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum EnergySource {
CastSpell,
Roll,
Ability,
Climb,
LevelUp,
HitEnemy,

View File

@ -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)