mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add ability requirements system
This commit is contained in:
parent
f32eb1db75
commit
19a09782a0
@ -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>;
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ pub struct Energy {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub enum EnergySource {
|
||||
CastSpell,
|
||||
Roll,
|
||||
Ability,
|
||||
Climb,
|
||||
LevelUp,
|
||||
HitEnemy,
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user