2020-01-12 23:06:52 +00:00
|
|
|
use crate::states::*;
|
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,
|
2020-01-16 13:28:45 +00:00
|
|
|
sync::Uid,
|
2019-12-26 14:43:59 +00:00
|
|
|
};
|
2020-01-05 18:19:09 +00:00
|
|
|
use serde::Deserialize;
|
|
|
|
use serde::Serialize;
|
2019-12-26 14:43:59 +00:00
|
|
|
use specs::LazyUpdate;
|
2020-01-17 16:39:21 +00:00
|
|
|
use specs::{Component, Entity, FlaggedStorage, HashMapStorage};
|
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
|
|
|
}
|
|
|
|
|
2020-01-21 22:54:32 +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>),
|
2020-01-21 22:54:32 +00:00
|
|
|
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>),
|
2020-01-21 22:54:32 +00:00
|
|
|
//BasicBlock(Option<basic_block::State>),
|
|
|
|
//Charge(Option<charge_attack::State>),
|
2020-01-08 16:56:36 +00:00
|
|
|
Roll(Option<roll::State>),
|
2019-08-23 10:11:37 +00:00
|
|
|
}
|
|
|
|
|
2020-01-21 22:54:32 +00:00
|
|
|
impl CharacterState {
|
|
|
|
pub fn is_attack(&self) -> bool {
|
2019-12-03 06:30:08 +00:00
|
|
|
match self {
|
2020-02-03 10:54:50 +00:00
|
|
|
CharacterState::BasicAttack(_) => true,
|
2019-12-26 14:43:59 +00:00
|
|
|
_ => false,
|
2019-12-03 06:30:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-21 22:54:32 +00:00
|
|
|
pub fn is_block(&self) -> bool {
|
2019-12-26 14:43:59 +00:00
|
|
|
match self {
|
2020-01-21 22:54:32 +00:00
|
|
|
//CharacterState::BasicBlock(_) => true,
|
2019-12-26 14:43:59 +00:00
|
|
|
_ => false,
|
2019-08-23 10:11:37 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-24 16:38:59 +00:00
|
|
|
|
2020-01-21 22:54:32 +00:00
|
|
|
pub fn is_dodge(&self) -> bool {
|
2019-12-26 14:43:59 +00:00
|
|
|
match self {
|
2020-01-21 22:54:32 +00:00
|
|
|
CharacterState::Roll(_) => true,
|
2019-12-26 14:43:59 +00:00
|
|
|
_ => false,
|
2019-08-24 16:38:59 +00:00
|
|
|
}
|
|
|
|
}
|
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)
|
2019-12-03 06:30:08 +00:00
|
|
|
}
|
2019-08-23 10:11:37 +00:00
|
|
|
|
2020-01-21 22:54:32 +00:00
|
|
|
/// 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
|
2020-01-21 22:54:32 +00:00
|
|
|
.unwrap_or_else(|| idle::State::new(ecs_data))
|
2020-02-03 10:54:50 +00:00
|
|
|
// Call handler
|
2020-01-21 22:54:32 +00:00
|
|
|
.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
|
2020-01-21 22:54:32 +00:00
|
|
|
.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
|
2020-01-21 22:54:32 +00:00
|
|
|
.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
|
2020-02-03 10:54:50 +00:00
|
|
|
// DO NOT use default match: _ => {},
|
2020-01-21 22:54:32 +00:00
|
|
|
}
|
2019-08-30 18:40:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-23 10:11:37 +00:00
|
|
|
impl Default for CharacterState {
|
|
|
|
fn default() -> Self {
|
2020-01-21 22:54:32 +00:00
|
|
|
Self::Idle(None)
|
2019-08-23 10:11:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Component for CharacterState {
|
|
|
|
type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
|
|
|
|
}
|