veloren/common/src/comp/character_state.rs

130 lines
4.4 KiB
Rust
Raw Normal View History

2019-12-26 14:43:59 +00:00
use crate::{
2020-02-03 10:54:50 +00:00
comp::{AbilityPool, Body, ControllerInputs, Ori, PhysicsState, Pos, Stats, Vel},
event::{LocalEvent, ServerEvent},
2019-12-26 14:43:59 +00:00
state::DeltaTime,
states::*,
2020-01-16 13:28:45 +00:00
sync::Uid,
2019-12-26 14:43:59 +00:00
};
use serde::{Deserialize, Serialize};
use specs::{Component, Entity, FlaggedStorage, HashMapStorage, LazyUpdate};
2020-02-03 10:54:50 +00:00
use std::collections::VecDeque;
2019-12-20 13:30:37 +00:00
2019-12-28 16:10:39 +00:00
pub struct EcsStateData<'a> {
2019-12-26 14:43:59 +00:00
pub entity: &'a Entity,
pub uid: &'a Uid,
pub character: &'a CharacterState,
pub pos: &'a Pos,
pub vel: &'a Vel,
pub ori: &'a Ori,
pub dt: &'a DeltaTime,
pub inputs: &'a ControllerInputs,
pub stats: &'a Stats,
pub body: &'a Body,
pub physics: &'a PhysicsState,
2020-02-03 10:54:50 +00:00
pub ability_pool: &'a AbilityPool,
2019-12-26 14:43:59 +00:00
pub updater: &'a LazyUpdate,
}
2019-12-28 16:10:39 +00:00
pub struct StateUpdate {
2019-12-26 14:43:59 +00:00
pub character: CharacterState,
pub pos: Pos,
pub vel: Vel,
pub ori: Ori,
2020-02-03 10:54:50 +00:00
pub local_events: VecDeque<LocalEvent>,
pub server_events: VecDeque<ServerEvent>,
2019-12-26 14:43:59 +00:00
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub enum CharacterState {
2020-01-08 16:56:36 +00:00
Idle(Option<idle::State>),
Climb(Option<climb::State>),
Sit(Option<sit::State>),
Wielding(Option<wielding::State>),
Wielded(Option<wielded::State>),
2020-02-03 10:54:50 +00:00
Glide(Option<glide::State>),
BasicAttack(Option<basic_attack::State>),
//BasicBlock(Option<basic_block::State>),
//Charge(Option<charge_attack::State>),
2020-01-08 16:56:36 +00:00
Roll(Option<roll::State>),
}
impl CharacterState {
pub fn is_attack(&self) -> bool {
match self {
2020-02-03 10:54:50 +00:00
CharacterState::BasicAttack(_) => true,
2019-12-26 14:43:59 +00:00
_ => false,
}
}
pub fn is_block(&self) -> bool {
2019-12-26 14:43:59 +00:00
match self {
//CharacterState::BasicBlock(_) => true,
2019-12-26 14:43:59 +00:00
_ => false,
}
}
pub fn is_dodge(&self) -> bool {
2019-12-26 14:43:59 +00:00
match self {
CharacterState::Roll(_) => true,
2019-12-26 14:43:59 +00:00
_ => false,
}
}
2020-01-08 19:31:42 +00:00
2020-01-22 12:48:55 +00:00
/// Compares for shallow equality (does not check internal struct equality)
2020-01-08 19:31:42 +00:00
pub fn equals(&self, other: &Self) -> bool {
// Check if state is the same without looking at the inner data
2020-01-22 12:48:55 +00:00
std::mem::discriminant(self) == std::mem::discriminant(other)
}
/// Passes data to variant or subvariant handlers
/// States contain `Option<StateHandler Implementor>`s, and will be
/// `None` if state data has not been initialized. So we have to
/// check and intialize new state data if so.
pub fn update(&self, ecs_data: &EcsStateData) -> StateUpdate {
match self {
CharacterState::Idle(opt_state) => opt_state
2020-02-03 10:54:50 +00:00
// If data hasn't been initialized, initialize a new one
.unwrap_or_else(|| idle::State::new(ecs_data))
2020-02-03 10:54:50 +00:00
// Call handler
.handle(ecs_data),
CharacterState::Climb(opt_state) => opt_state
.unwrap_or_else(|| climb::State::new(ecs_data))
.handle(ecs_data),
CharacterState::Sit(opt_state) => opt_state
.unwrap_or_else(|| sit::State::new(ecs_data))
.handle(ecs_data),
CharacterState::Wielding(opt_state) => opt_state
.unwrap_or_else(|| wielding::State::new(ecs_data))
.handle(ecs_data),
CharacterState::Wielded(opt_state) => opt_state
.unwrap_or_else(|| wielded::State::new(ecs_data))
.handle(ecs_data),
2020-02-03 10:54:50 +00:00
CharacterState::BasicAttack(opt_state) => opt_state
.unwrap_or_else(|| basic_attack::State::new(ecs_data))
.handle(ecs_data),
2020-02-03 10:54:50 +00:00
/*CharacterState::Charge(opt_state) => opt_state
.unwrap_or_else(|| charge_attack::State::new(ecs_data))
.handle(ecs_data),
CharacterState::BasicBlock(opt_state) => opt_state
.unwrap_or_else(|| basic_block::State::new(ecs_data))
.handle(ecs_data),*/
CharacterState::Roll(opt_state) => opt_state
.unwrap_or_else(|| roll::State::new(ecs_data))
.handle(ecs_data),
CharacterState::Glide(opt_state) => opt_state
.unwrap_or_else(|| glide::State::new(ecs_data))
.handle(ecs_data),
/* All states should be explicitly handled
* DO NOT use default match: _ => {}, */
}
}
}
impl Default for CharacterState {
fn default() -> Self { Self::Idle(None) }
}
impl Component for CharacterState {
type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
}