mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Grooming
This commit is contained in:
parent
dc33f6ad6a
commit
8648641362
@ -30,5 +30,5 @@ pub struct AbilityPool {
|
||||
}
|
||||
|
||||
impl Component for AbilityPool {
|
||||
type Storage = HashMapStorage<Self>;
|
||||
type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::comp::{
|
||||
ActionState::Attack, AttackKind::BasicAttack, EcsStateData, ItemKind::Tool, MoveState,
|
||||
StateHandler, StateUpdate, ToolData,
|
||||
ActionState::Attack, AttackKind::BasicAttack, EcsStateData, ItemKind::Tool, StateHandler,
|
||||
StateUpdate, ToolData,
|
||||
};
|
||||
use crate::util::state_utils::*;
|
||||
use std::time::Duration;
|
||||
|
@ -1,9 +1,11 @@
|
||||
use super::{BLOCK_ACCEL, BLOCK_SPEED};
|
||||
use crate::comp::{EcsStateData, StateHandler, StateUpdate};
|
||||
use crate::util::state_utils::*;
|
||||
use std::time::Duration;
|
||||
use vek::Vec2;
|
||||
|
||||
const BLOCK_ACCEL: f32 = 30.0;
|
||||
const BLOCK_SPEED: f32 = 75.0;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct BasicBlockState {
|
||||
/// How long the blocking state has been active
|
||||
@ -11,7 +13,7 @@ pub struct BasicBlockState {
|
||||
}
|
||||
|
||||
impl StateHandler for BasicBlockState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {
|
||||
active_duration: Duration::default(),
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::comp::{
|
||||
ActionState::Attack, AttackKind::Charge, EcsStateData, HealthChange, HealthSource,
|
||||
ItemKind::Tool, MoveState::Run, RunState, StateHandler, StateUpdate, ToolData,
|
||||
ItemKind::Tool, MoveState::Run, StateHandler, StateUpdate, ToolData,
|
||||
};
|
||||
use crate::event::ServerEvent;
|
||||
use crate::util::state_utils::*;
|
||||
use std::time::Duration;
|
||||
use vek::Vec3;
|
||||
|
||||
use super::CHARGE_SPEED;
|
||||
const CHARGE_SPEED: f32 = 20.0;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct ChargeAttackState {
|
||||
@ -37,7 +37,7 @@ impl StateHandler for ChargeAttackState {
|
||||
};
|
||||
|
||||
// Prevent move state handling, handled here
|
||||
update.character.move_state = Run(Some(RunState));
|
||||
update.character.move_state = Run(None);
|
||||
|
||||
// Move player
|
||||
update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z)
|
||||
|
@ -1,17 +1,16 @@
|
||||
use super::{
|
||||
ActionState::*, EcsStateData, FallState, IdleState, JumpState, MoveState::*, StandState,
|
||||
StateHandler, StateUpdate,
|
||||
};
|
||||
use super::{CLIMB_SPEED, HUMANOID_CLIMB_ACCEL, HUMANOID_SPEED};
|
||||
use super::{ActionState::*, EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
use crate::sys::phys::GRAVITY;
|
||||
use vek::vec::{Vec2, Vec3};
|
||||
use vek::Lerp;
|
||||
|
||||
const HUMANOID_CLIMB_ACCEL: f32 = 5.0;
|
||||
const CLIMB_SPEED: f32 = 5.0;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct ClimbState;
|
||||
|
||||
impl StateHandler for ClimbState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -23,12 +22,33 @@ impl StateHandler for ClimbState {
|
||||
character: *ecs_data.character,
|
||||
};
|
||||
|
||||
update.character.action_state = Idle(Some(IdleState));
|
||||
update.character.action_state = Idle(None);
|
||||
|
||||
// If no wall is in front of character ...
|
||||
if let None = ecs_data.physics.on_wall {
|
||||
if ecs_data.inputs.jump.is_pressed() {
|
||||
// They've climbed atop something, give them a boost
|
||||
update.character.move_state = Jump(None);
|
||||
|
||||
return update;
|
||||
} else {
|
||||
// Just fall off
|
||||
update.character.move_state = Fall(None);
|
||||
|
||||
return update;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove climb state on ground, otherwise character will get stuck
|
||||
if ecs_data.physics.on_ground {
|
||||
update.character.move_state = Stand(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Move player
|
||||
update.vel.0 += Vec2::broadcast(ecs_data.dt.0)
|
||||
* ecs_data.inputs.move_dir
|
||||
* if update.vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) {
|
||||
* if update.vel.0.magnitude_squared() < CLIMB_SPEED.powf(2.0) {
|
||||
HUMANOID_CLIMB_ACCEL
|
||||
} else {
|
||||
0.0
|
||||
@ -78,27 +98,6 @@ impl StateHandler for ClimbState {
|
||||
}
|
||||
}
|
||||
|
||||
// If no wall is infront of character ...
|
||||
if let None = ecs_data.physics.on_wall {
|
||||
if ecs_data.inputs.jump.is_pressed() {
|
||||
// They've climbed atop something, give them a boost
|
||||
update.character.move_state = Jump(Some(JumpState));
|
||||
|
||||
return update;
|
||||
} else {
|
||||
// Just fall off
|
||||
update.character.move_state = Fall(Some(FallState));
|
||||
|
||||
return update;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove climb state on ground, otherwise character will get stuck
|
||||
if ecs_data.physics.on_ground {
|
||||
update.character.move_state = Stand(Some(StandState));
|
||||
return update;
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
use super::{HUMANOID_AIR_ACCEL, HUMANOID_AIR_SPEED};
|
||||
use crate::comp::{ClimbState, EcsStateData, GlideState, MoveState::*, StateHandler, StateUpdate};
|
||||
use crate::comp::{EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
|
||||
use crate::util::state_utils::*;
|
||||
use vek::{Vec2, Vec3};
|
||||
|
||||
const HUMANOID_AIR_ACCEL: f32 = 10.0;
|
||||
const HUMANOID_AIR_SPEED: f32 = 100.0;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct FallState;
|
||||
|
||||
impl StateHandler for FallState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -48,13 +50,13 @@ impl StateHandler for FallState {
|
||||
|
||||
// Check to start climbing
|
||||
if can_climb(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
update.character.move_state = Climb(Some(ClimbState));
|
||||
update.character.move_state = Climb(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Check gliding
|
||||
if ecs_data.inputs.glide.is_pressed() {
|
||||
update.character.move_state = Glide(Some(GlideState));
|
||||
update.character.move_state = Glide(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
use super::{GLIDE_ACCEL, GLIDE_ANTIGRAV, GLIDE_SPEED};
|
||||
use crate::comp::{
|
||||
ActionState::*, ClimbState, EcsStateData, FallState, IdleState, MoveState::*, StandState,
|
||||
StateHandler, StateUpdate,
|
||||
};
|
||||
use crate::comp::{ActionState::*, EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
use vek::{Vec2, Vec3};
|
||||
|
||||
// Gravity is 9.81 * 4, so this makes gravity equal to .15
|
||||
const GLIDE_ANTIGRAV: f32 = crate::sys::phys::GRAVITY * 0.96;
|
||||
const GLIDE_ACCEL: f32 = 15.0;
|
||||
const GLIDE_SPEED: f32 = 45.0;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct GlideState;
|
||||
|
||||
impl StateHandler for GlideState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -22,8 +23,26 @@ impl StateHandler for GlideState {
|
||||
};
|
||||
|
||||
// Defaults for this state
|
||||
update.character.action_state = Idle(Some(IdleState));
|
||||
update.character.move_state = Glide(Some(GlideState));
|
||||
update.character.action_state = Idle(None);
|
||||
update.character.move_state = Glide(None);
|
||||
|
||||
// If glide button isn't held, start falling
|
||||
if !ecs_data.inputs.glide.is_pressed() {
|
||||
update.character.move_state = Fall(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// If there is a wall in front of character go to climb
|
||||
if let Some(_wall_dir) = ecs_data.physics.on_wall {
|
||||
update.character.move_state = Climb(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// If on ground go to stand
|
||||
if ecs_data.physics.on_ground {
|
||||
update.character.move_state = Stand(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Move player according to movement direction vector
|
||||
update.vel.0 += Vec2::broadcast(ecs_data.dt.0)
|
||||
@ -56,24 +75,6 @@ impl StateHandler for GlideState {
|
||||
.max(0.2);
|
||||
}
|
||||
|
||||
// If glide button isn't held, start falling
|
||||
if !ecs_data.inputs.glide.is_pressed() {
|
||||
update.character.move_state = Fall(Some(FallState));
|
||||
return update;
|
||||
}
|
||||
|
||||
// If there is a wall in front of character go to climb
|
||||
if let Some(_wall_dir) = ecs_data.physics.on_wall {
|
||||
update.character.move_state = Climb(Some(ClimbState));
|
||||
return update;
|
||||
}
|
||||
|
||||
// If on ground go to stand
|
||||
if ecs_data.physics.on_ground {
|
||||
update.character.move_state = Stand(Some(StandState));
|
||||
return update;
|
||||
}
|
||||
|
||||
// Otherwise keep gliding
|
||||
return update;
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
use super::TEMP_EQUIP_DELAY;
|
||||
use crate::comp::{
|
||||
ActionState::Wield, EcsStateData, ItemKind::Tool, StateHandler, StateUpdate, WieldState,
|
||||
};
|
||||
use std::time::Duration;
|
||||
use crate::comp::{ActionState::Wield, EcsStateData, ItemKind::Tool, StateHandler, StateUpdate};
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct IdleState;
|
||||
|
||||
impl StateHandler for IdleState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -26,10 +22,8 @@ impl StateHandler for IdleState {
|
||||
|| (ecs_data.inputs.toggle_wield.is_just_pressed()
|
||||
&& update.character.action_state.is_equip_finished())
|
||||
{
|
||||
if let Some(Tool(data)) = ecs_data.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
update.character.action_state = Wield(Some(WieldState {
|
||||
equip_delay: data.equip_time(),
|
||||
}));
|
||||
if let Some(Tool(_)) = ecs_data.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
update.character.action_state = Wield(None);
|
||||
}
|
||||
|
||||
// else unarmed stuff?
|
||||
|
@ -1,11 +1,11 @@
|
||||
use super::{EcsStateData, FallState, MoveState::*, StateHandler, StateUpdate};
|
||||
use super::{EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
use crate::event::LocalEvent;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct JumpState;
|
||||
|
||||
impl StateHandler for JumpState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ impl StateHandler for JumpState {
|
||||
.emit(LocalEvent::Jump(*ecs_data.entity));
|
||||
|
||||
// Immediately go to falling state after jump impulse
|
||||
update.character.move_state = Fall(Some(FallState));
|
||||
update.character.move_state = Fall(None);
|
||||
return update;
|
||||
}
|
||||
}
|
||||
|
@ -30,47 +30,106 @@ pub use stand::*;
|
||||
pub use swim::*;
|
||||
pub use wield::*;
|
||||
|
||||
// TODO: Attach these to racial components and/or ecs resources
|
||||
pub const HUMANOID_ACCEL: f32 = 50.0;
|
||||
pub const HUMANOID_SPEED: f32 = 120.0;
|
||||
pub const HUMANOID_AIR_ACCEL: f32 = 10.0;
|
||||
pub const HUMANOID_AIR_SPEED: f32 = 100.0;
|
||||
pub const HUMANOID_WATER_ACCEL: f32 = 70.0;
|
||||
pub const HUMANOID_WATER_SPEED: f32 = 120.0;
|
||||
pub const HUMANOID_CLIMB_ACCEL: f32 = 5.0;
|
||||
pub const ROLL_SPEED: f32 = 17.0;
|
||||
pub const CHARGE_SPEED: f32 = 20.0;
|
||||
pub const GLIDE_ACCEL: f32 = 15.0;
|
||||
pub const GLIDE_SPEED: f32 = 45.0;
|
||||
pub const BLOCK_ACCEL: f32 = 30.0;
|
||||
pub const BLOCK_SPEED: f32 = 75.0;
|
||||
pub const TEMP_EQUIP_DELAY: u64 = 100;
|
||||
// Gravity is 9.81 * 4, so this makes gravity equal to .15
|
||||
pub const GLIDE_ANTIGRAV: f32 = crate::sys::phys::GRAVITY * 0.96;
|
||||
pub const CLIMB_SPEED: f32 = 5.0;
|
||||
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
|
||||
|
||||
use super::{
|
||||
ActionState, ActionState::*, AttackKind::*, BlockKind::*, DodgeKind::*, EcsStateData,
|
||||
MoveState, MoveState::*, StateUpdate,
|
||||
};
|
||||
|
||||
/// #### A trait for implementing state `handle()`ing logic.
|
||||
/// _Mimics the typical OOP style state machine pattern where states implement their own behavior,
|
||||
/// exit conditions, and return new states to the state machine upon exit.
|
||||
/// This is still performant and consistent with ECS data-behavior-separation constraint
|
||||
/// since trait fn's are syntactic sugar for static fn's that accept their implementor's
|
||||
/// object type as its first parameter. This allows for several benefits over implementing
|
||||
/// each state's behavior within the `CharacterState` update `System` itself:_
|
||||
///
|
||||
/// 1. Less cognitive overhead: State's handling logic is next to the its data, and component (inside the state's .rs file).
|
||||
/// 2. Separation of concerns (between states): all logic within a state's `handle()` is relevant only to that state.
|
||||
/// States can be added/editted without concerns of affecting other state's logic.
|
||||
/// 3. Clearly defined API and pattern: All states accept the same `EcsStateData` struct, which can be added to as necessary,
|
||||
/// without the need for updating every state's implementation. All states return the same `StateUpdate` component.
|
||||
/// `CharacterState` update `System` passes `EcsStateData` to `ActionState`/`MoveState` `handle()` which matches the character's
|
||||
/// current state to its `handle()` fn, hiding the implementation details, since the System is only concerned with
|
||||
/// how the update flow occurs and is in charge of updating the ECS components.
|
||||
/// ## A type for implementing State Handling Behavior.
|
||||
///
|
||||
/// Called by state machines' update functions to allow current states to handle updating
|
||||
/// their parent machine's current state.
|
||||
///
|
||||
/// Structures must implement a `handle()` fn to handle update behavior, and a `new()` for
|
||||
/// instantiating new instances of a state. `handle()` function recieves `EcsStateData`, a struct
|
||||
/// of readonly ECS Component data, and returns a `StateUpdate` tuple, with new components that will
|
||||
/// overwrite an entitie's old components.
|
||||
///
|
||||
/// ## Example Implementation:
|
||||
/// ```
|
||||
/// use crate::comp::{
|
||||
/// ClimbState, EcsStateData, GlideState, JumpState, MoveState::*, SitState, StateHandler,
|
||||
/// StateUpdate,
|
||||
/// };
|
||||
/// use crate::util::state_utils::*
|
||||
/// #[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
/// pub struct RunState {
|
||||
/// active_duration: Duration,
|
||||
/// }
|
||||
///
|
||||
/// impl StateHandler for RunState {
|
||||
/// fn new(ecs_data: &EcsStateData) -> Self {
|
||||
/// Self {
|
||||
/// active_duration: Duration::default(),
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn handle(&self, ecs_data: &EcsStateData) -> StateUpdate {
|
||||
/// let mut update = StateUpdate {
|
||||
/// character: *ecs_data.character,
|
||||
/// pos: *ecs_data.pos,
|
||||
/// vel: *ecs_data.vel,
|
||||
/// ori: *ecs_data.ori,
|
||||
/// };
|
||||
///
|
||||
/// // Move player according to move_dir
|
||||
/// update.vel.0 += Vec2::broadcast(ecs_data.dt.0)
|
||||
/// * ecs_data.inputs.move_dir
|
||||
/// * if update.vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) {
|
||||
/// HUMANOID_ACCEL
|
||||
/// } else {
|
||||
/// 0.0
|
||||
/// };
|
||||
///
|
||||
/// // Set direction based on move direction when on the ground
|
||||
/// let ori_dir = if update.character.action_state.is_attacking()
|
||||
/// || update.character.action_state.is_blocking()
|
||||
/// {
|
||||
/// Vec2::from(ecs_data.inputs.look_dir).normalized()
|
||||
/// } else {
|
||||
/// Vec2::from(update.vel.0)
|
||||
/// };
|
||||
///
|
||||
/// if ori_dir.magnitude_squared() > 0.0001
|
||||
/// && (update.ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared()
|
||||
/// > 0.001
|
||||
/// {
|
||||
/// update.ori.0 =
|
||||
/// vek::ops::Slerp::slerp(update.ori.0, ori_dir.into(), 9.0 * ecs_data.dt.0);
|
||||
/// }
|
||||
///
|
||||
/// // Try to sit
|
||||
/// if can_sit(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
/// update.character.move_state = Sit(Some(SitState));
|
||||
/// return update;
|
||||
/// }
|
||||
///
|
||||
/// // Try to climb
|
||||
/// if can_climb(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
/// update.character.move_state = Climb(Some(ClimbState));
|
||||
/// return update;
|
||||
/// }
|
||||
///
|
||||
/// // Try to jump
|
||||
/// if can_jump(ecs_data.physics, ecs_data.inputs) {
|
||||
/// update.character.move_state = Jump(Some(JumpState));
|
||||
/// return update;
|
||||
/// }
|
||||
///
|
||||
/// // Try to glide
|
||||
/// if can_glide(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
/// update.character.move_state = Glide(Some(GlideState));
|
||||
/// return update;
|
||||
/// }
|
||||
///
|
||||
/// // Update based on groundedness
|
||||
/// update.character.move_state =
|
||||
/// determine_move_from_grounded_state(ecs_data.physics, ecs_data.inputs);
|
||||
///
|
||||
/// return update;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub trait StateHandler: Default {
|
||||
fn handle(&self, ecs_data: &EcsStateData) -> StateUpdate;
|
||||
fn new(ecs_data: &EcsStateData) -> Self;
|
||||
|
@ -1,4 +1,3 @@
|
||||
use super::ROLL_SPEED;
|
||||
use crate::comp::{
|
||||
ActionState::*, DodgeKind::*, EcsStateData, ItemKind::Tool, StateHandler, StateUpdate, ToolData,
|
||||
};
|
||||
@ -6,6 +5,8 @@ use crate::util::state_utils::*;
|
||||
use std::time::Duration;
|
||||
use vek::Vec3;
|
||||
|
||||
const ROLL_SPEED: f32 = 17.0;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct RollState {
|
||||
/// How long the state has until exitting
|
||||
|
@ -1,16 +1,15 @@
|
||||
use super::{HUMANOID_ACCEL, HUMANOID_SPEED};
|
||||
use crate::comp::{
|
||||
ClimbState, EcsStateData, GlideState, JumpState, MoveState::*, SitState, StateHandler,
|
||||
StateUpdate,
|
||||
};
|
||||
use crate::comp::{EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
use crate::util::state_utils::*;
|
||||
use vek::vec::{Vec2, Vec3};
|
||||
|
||||
const HUMANOID_ACCEL: f32 = 50.0;
|
||||
const HUMANOID_SPEED: f32 = 120.0;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct RunState;
|
||||
|
||||
impl StateHandler for RunState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -50,25 +49,25 @@ impl StateHandler for RunState {
|
||||
|
||||
// Try to sit
|
||||
if can_sit(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
update.character.move_state = Sit(Some(SitState));
|
||||
update.character.move_state = Sit(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Try to climb
|
||||
if can_climb(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
update.character.move_state = Climb(Some(ClimbState));
|
||||
update.character.move_state = Climb(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Try to jump
|
||||
if can_jump(ecs_data.physics, ecs_data.inputs) {
|
||||
update.character.move_state = Jump(Some(JumpState));
|
||||
update.character.move_state = Jump(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Try to glide
|
||||
if can_glide(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
update.character.move_state = Glide(Some(GlideState));
|
||||
update.character.move_state = Glide(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,11 @@
|
||||
use crate::comp::{
|
||||
ActionState::*, EcsStateData, IdleState, JumpState, MoveState::*, RunState, StandState,
|
||||
StateHandler, StateUpdate,
|
||||
};
|
||||
use crate::comp::{ActionState::*, EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
use crate::util::state_utils::*;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct SitState;
|
||||
|
||||
impl StateHandler for SitState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -21,8 +18,8 @@ impl StateHandler for SitState {
|
||||
};
|
||||
|
||||
// Prevent action state handling
|
||||
update.character.action_state = Idle(Some(IdleState));
|
||||
update.character.move_state = Sit(Some(SitState));
|
||||
update.character.action_state = Idle(None);
|
||||
update.character.move_state = Sit(None);
|
||||
|
||||
// Try to Fall
|
||||
// ... maybe the ground disappears,
|
||||
@ -34,19 +31,19 @@ impl StateHandler for SitState {
|
||||
}
|
||||
// Try to jump
|
||||
if ecs_data.inputs.jump.is_pressed() {
|
||||
update.character.move_state = Jump(Some(JumpState));
|
||||
update.character.move_state = Jump(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Try to Run
|
||||
if ecs_data.inputs.move_dir.magnitude_squared() > 0.0 {
|
||||
update.character.move_state = Run(Some(RunState));
|
||||
update.character.move_state = Run(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Try to Stand
|
||||
if ecs_data.inputs.sit.is_just_pressed() {
|
||||
update.character.move_state = Stand(Some(StandState));
|
||||
update.character.move_state = Stand(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,11 @@
|
||||
use crate::comp::{
|
||||
ClimbState, EcsStateData, GlideState, JumpState, MoveState::*, SitState, StateHandler,
|
||||
StateUpdate,
|
||||
};
|
||||
use crate::comp::{EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
use crate::util::state_utils::*;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct StandState;
|
||||
|
||||
impl StateHandler for StandState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -22,25 +19,25 @@ impl StateHandler for StandState {
|
||||
|
||||
// Try to sit
|
||||
if can_sit(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
update.character.move_state = Sit(Some(SitState));
|
||||
update.character.move_state = Sit(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Try to climb
|
||||
if can_climb(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
update.character.move_state = Climb(Some(ClimbState));
|
||||
update.character.move_state = Climb(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Try to jump
|
||||
if can_jump(ecs_data.physics, ecs_data.inputs) {
|
||||
update.character.move_state = Jump(Some(JumpState));
|
||||
update.character.move_state = Jump(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
// Check gliding
|
||||
if can_glide(ecs_data.physics, ecs_data.inputs, ecs_data.body) {
|
||||
update.character.move_state = Glide(Some(GlideState));
|
||||
update.character.move_state = Glide(None);
|
||||
return update;
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,15 @@
|
||||
use super::{HUMANOID_WATER_ACCEL, HUMANOID_WATER_SPEED};
|
||||
use crate::comp::{EcsStateData, MoveState::*, RunState, StandState, StateHandler, StateUpdate};
|
||||
use crate::comp::{EcsStateData, MoveState::*, StateHandler, StateUpdate};
|
||||
use crate::sys::phys::GRAVITY;
|
||||
use vek::{Vec2, Vec3};
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
pub struct SwimState;
|
||||
|
||||
const HUMANOID_WATER_ACCEL: f32 = 70.0;
|
||||
const HUMANOID_WATER_SPEED: f32 = 120.0;
|
||||
|
||||
impl StateHandler for SwimState {
|
||||
fn new(ecs_data: &EcsStateData) -> Self {
|
||||
fn new(_ecs_data: &EcsStateData) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
@ -55,16 +57,16 @@ impl StateHandler for SwimState {
|
||||
|
||||
// Not on ground
|
||||
if !ecs_data.physics.on_ground {
|
||||
update.character.move_state = Swim(Some(SwimState));
|
||||
update.character.move_state = Swim(None);
|
||||
return update;
|
||||
}
|
||||
// On ground
|
||||
else {
|
||||
// Return to running or standing based on move inputs
|
||||
update.character.move_state = if ecs_data.inputs.move_dir.magnitude_squared() > 0.0 {
|
||||
Run(Some(RunState))
|
||||
Run(None)
|
||||
} else {
|
||||
Stand(Some(StandState))
|
||||
Stand(None)
|
||||
};
|
||||
|
||||
return update;
|
||||
|
@ -1,8 +1,6 @@
|
||||
use crate::comp::{
|
||||
AbilityAction, AbilityActionKind::*, ActionState::*, EcsStateData, IdleState, ItemKind::Tool,
|
||||
StateHandler, StateUpdate, ToolData,
|
||||
ActionState::*, EcsStateData, IdleState, ItemKind::Tool, StateHandler, StateUpdate, ToolData,
|
||||
};
|
||||
use crate::util::state_utils::*;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||
|
@ -36,6 +36,8 @@ sphynx::sum_type! {
|
||||
OverrideAction(comp::OverrideAction),
|
||||
OverrideMove(comp::OverrideMove),
|
||||
OverrideState(comp::OverrideState),
|
||||
AbilityAction(comp::AbilityAction),
|
||||
AbilityPool(comp::AbilityPool),
|
||||
}
|
||||
}
|
||||
// Automatically derive From<T> for EcsCompPhantom
|
||||
@ -62,6 +64,8 @@ sphynx::sum_type! {
|
||||
OverrideAction(PhantomData<comp::OverrideAction>),
|
||||
OverrideMove(PhantomData<comp::OverrideMove>),
|
||||
OverrideState(PhantomData<comp::OverrideState>),
|
||||
AbilityAction(PhantomData<comp::AbilityAction>),
|
||||
AbilityPool(PhantomData<comp::AbilityPool>),
|
||||
}
|
||||
}
|
||||
impl sphynx::CompPacket for EcsCompPacket {
|
||||
|
@ -123,6 +123,8 @@ impl State {
|
||||
// TODO: Split up registering into server and client (e.g. move EventBus<ServerEvent> to the server)
|
||||
fn setup_sphynx_world(ecs: &mut sphynx::World<EcsCompPacket, EcsResPacket>) {
|
||||
// Register server -> all clients synced components.
|
||||
ecs.register_synced::<comp::AbilityPool>();
|
||||
ecs.register_synced::<comp::AbilityAction>();
|
||||
ecs.register_synced::<comp::Body>();
|
||||
ecs.register_synced::<comp::Player>();
|
||||
ecs.register_synced::<comp::Stats>();
|
||||
|
@ -25,13 +25,13 @@ impl<'a> System<'a> for Sys {
|
||||
&mut self,
|
||||
(
|
||||
entities,
|
||||
updater,
|
||||
_updater,
|
||||
mut character_state_storage,
|
||||
ability_action_storage,
|
||||
ability_pool_storage,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
for (entity, mut character, ability_action, ability_pool) in (
|
||||
for (_entity, mut _character, _ability_action, _ability_pool) in (
|
||||
&entities,
|
||||
&mut character_state_storage,
|
||||
&ability_action_storage,
|
||||
|
@ -1,8 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
states::*, Body, CharacterState, Controller, EcsStateData, Mounting, MoveState::*, Ori,
|
||||
OverrideAction, OverrideMove, OverrideState, PhysicsState, Pos, SitState, StateHandler,
|
||||
Stats, Vel,
|
||||
Body, CharacterState, Controller, EcsStateData, Mounting, MoveState::*, Ori,
|
||||
OverrideAction, OverrideMove, OverrideState, PhysicsState, Pos, Stats, Vel,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
state::DeltaTime,
|
||||
@ -11,18 +10,11 @@ use crate::{
|
||||
use specs::{Entities, Join, LazyUpdate, Read, ReadStorage, System, WriteStorage};
|
||||
use sphynx::{Uid, UidAllocator};
|
||||
|
||||
/// # Character State System
|
||||
/// #### Updates tuples of ( `CharacterState`, `Pos`, `Vel`, and `Ori` ) in parallel.
|
||||
/// _Each update for a single character involves first passing an `EcsStateData` struct of ECS components
|
||||
/// to the character's `MoveState`, then the character's `ActionState`. State update logic is
|
||||
/// is encapsulated in state's `handle()` fn, impl'd by the `StateHandle` trait. `handle()` fn's
|
||||
/// return a `StateUpdate` tuple containing new ( `CharacterState`, `Pos`, `Vel`, and `Ori` ) components.
|
||||
/// Since `handle()` accepts readonly components, component updates are contained within this system and ECS
|
||||
/// behavior constraints are satisfied._
|
||||
/// ## Character State System
|
||||
/// #### Calls updates to `CharacterState`s. Acts on tuples of ( `CharacterState`, `Pos`, `Vel`, and `Ori` ).
|
||||
///
|
||||
/// _This mimics the typical OOP style state machine pattern, but remains performant
|
||||
/// under ECS since trait fn's are syntactic sugar for static fn's that accept their implementor's
|
||||
/// object type as its first parameter. See `StateHandle` for more information._
|
||||
/// _System forms `EcsStateData` tuples and passes those to `ActionState` `update()` fn,
|
||||
/// then does the same for `MoveState` `update`_
|
||||
pub struct Sys;
|
||||
|
||||
impl<'a> System<'a> for Sys {
|
||||
@ -102,14 +94,14 @@ impl<'a> System<'a> for Sys {
|
||||
// If mounted, character state is controlled by mount
|
||||
// TODO: Make mounting a state
|
||||
if let Some(Mounting(_)) = mountings.get(entity) {
|
||||
character.move_state = Sit(Some(SitState));
|
||||
character.move_state = Sit(None);
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine new action if character can act
|
||||
if let (None, false) = (
|
||||
action_overrides.get(entity),
|
||||
character.action_state.overrides_move_state(),
|
||||
character.move_state.overrides_action_state(),
|
||||
) {
|
||||
let state_update = character.action_state.update(&EcsStateData {
|
||||
entity: &entity,
|
||||
@ -137,7 +129,7 @@ impl<'a> System<'a> for Sys {
|
||||
// Determine new move state if character can move
|
||||
if let (None, false) = (
|
||||
move_overrides.get(entity),
|
||||
character.move_state.overrides_action_state(),
|
||||
character.action_state.overrides_move_state(),
|
||||
) {
|
||||
let state_update = character.move_state.update(&EcsStateData {
|
||||
entity: &entity,
|
||||
|
@ -1,236 +0,0 @@
|
||||
use super::phys::GRAVITY;
|
||||
use crate::{
|
||||
comp::{
|
||||
CharacterState, Controller, Mounting, MoveState::*, Ori, PhysicsState, Pos, RunState,
|
||||
StandState, Stats, Vel,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::DeltaTime,
|
||||
terrain::TerrainGrid,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
use sphynx::Uid;
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
pub const ROLL_DURATION: Duration = Duration::from_millis(600);
|
||||
|
||||
const HUMANOID_ACCEL: f32 = 50.0;
|
||||
const HUMANOID_SPEED: f32 = 120.0;
|
||||
const HUMANOID_AIR_ACCEL: f32 = 10.0;
|
||||
const HUMANOID_AIR_SPEED: f32 = 100.0;
|
||||
const HUMANOID_WATER_ACCEL: f32 = 70.0;
|
||||
const HUMANOID_WATER_SPEED: f32 = 120.0;
|
||||
const HUMANOID_CLIMB_ACCEL: f32 = 5.0;
|
||||
const ROLL_SPEED: f32 = 17.0;
|
||||
const CHARGE_SPEED: f32 = 20.0;
|
||||
const GLIDE_ACCEL: f32 = 15.0;
|
||||
const GLIDE_SPEED: f32 = 45.0;
|
||||
const BLOCK_ACCEL: f32 = 30.0;
|
||||
const BLOCK_SPEED: f32 = 75.0;
|
||||
// Gravity is 9.81 * 4, so this makes gravity equal to .15
|
||||
const GLIDE_ANTIGRAV: f32 = GRAVITY * 0.96;
|
||||
const CLIMB_SPEED: f32 = 5.0;
|
||||
|
||||
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
|
||||
|
||||
/// # Movement System
|
||||
/// #### Applies forces, calculates new positions and velocities,7
|
||||
/// #### based on Controller(Inputs) and CharacterState.
|
||||
/// ----
|
||||
///
|
||||
/// **Writes:**
|
||||
/// Pos, Vel, Ori
|
||||
///
|
||||
/// **Reads:**
|
||||
/// Uid, Stats, Controller, PhysicsState, CharacterState, Mounting
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
ReadExpect<'a, TerrainGrid>,
|
||||
Read<'a, EventBus<ServerEvent>>,
|
||||
Read<'a, DeltaTime>,
|
||||
WriteStorage<'a, Pos>,
|
||||
WriteStorage<'a, Vel>,
|
||||
WriteStorage<'a, Ori>,
|
||||
ReadStorage<'a, Uid>,
|
||||
ReadStorage<'a, Stats>,
|
||||
ReadStorage<'a, Controller>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
ReadStorage<'a, CharacterState>,
|
||||
ReadStorage<'a, Mounting>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(
|
||||
entities,
|
||||
_terrain,
|
||||
_server_bus,
|
||||
dt,
|
||||
mut positions,
|
||||
mut velocities,
|
||||
mut orientations,
|
||||
uids,
|
||||
stats,
|
||||
controllers,
|
||||
physics_states,
|
||||
character_states,
|
||||
mountings,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
// Apply movement inputs
|
||||
for (
|
||||
_entity,
|
||||
mut _pos,
|
||||
mut vel,
|
||||
mut ori,
|
||||
_uid,
|
||||
stats,
|
||||
controller,
|
||||
physics,
|
||||
character,
|
||||
mount,
|
||||
) in (
|
||||
&entities,
|
||||
&mut positions,
|
||||
&mut velocities,
|
||||
&mut orientations,
|
||||
&uids,
|
||||
&stats,
|
||||
&controllers,
|
||||
&physics_states,
|
||||
&character_states,
|
||||
mountings.maybe(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// if character.movement == Run(RunState) || character.movement == Stand(StandState) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if stats.is_dead {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if mount.is_some() {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// let inputs = &controller.inputs;
|
||||
|
||||
// if character.action.is_roll() {
|
||||
// vel.0 = Vec3::new(0.0, 0.0, vel.0.z)
|
||||
// + (vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||
// + 1.5 * inputs.move_dir.try_normalized().unwrap_or_default())
|
||||
// .try_normalized()
|
||||
// .unwrap_or_default()
|
||||
// * ROLL_SPEED;
|
||||
// } else if character.action.is_charge() {
|
||||
// vel.0 = Vec3::new(0.0, 0.0, vel.0.z)
|
||||
// + (vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||
// + 1.5 * inputs.move_dir.try_normalized().unwrap_or_default())
|
||||
// .try_normalized()
|
||||
// .unwrap_or_default()
|
||||
// * CHARGE_SPEED;
|
||||
// } else if character.action.is_block() {
|
||||
// vel.0 += Vec2::broadcast(dt.0)
|
||||
// * inputs.move_dir
|
||||
// * match physics.on_ground {
|
||||
// true if vel.0.magnitude_squared() < BLOCK_SPEED.powf(2.0) => BLOCK_ACCEL,
|
||||
// _ => 0.0,
|
||||
// }
|
||||
// } else {
|
||||
// // Move player according to move_dir
|
||||
// vel.0 += Vec2::broadcast(dt.0)
|
||||
// * inputs.move_dir
|
||||
// * match (physics.on_ground, &character.movement) {
|
||||
// (true, Run(_)) if vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) => {
|
||||
// HUMANOID_ACCEL
|
||||
// }
|
||||
// (false, Climb) if vel.0.magnitude_squared() < HUMANOID_SPEED.powf(2.0) => {
|
||||
// HUMANOID_CLIMB_ACCEL
|
||||
// }
|
||||
// (false, Glide) if vel.0.magnitude_squared() < GLIDE_SPEED.powf(2.0) => {
|
||||
// GLIDE_ACCEL
|
||||
// }
|
||||
// (false, Fall) | (false, Jump)
|
||||
// if vel.0.magnitude_squared() < HUMANOID_AIR_SPEED.powf(2.0) =>
|
||||
// {
|
||||
// HUMANOID_AIR_ACCEL
|
||||
// }
|
||||
// (false, Swim)
|
||||
// if vel.0.magnitude_squared() < HUMANOID_WATER_SPEED.powf(2.0) =>
|
||||
// {
|
||||
// HUMANOID_WATER_ACCEL
|
||||
// }
|
||||
// _ => 0.0,
|
||||
// };
|
||||
// }
|
||||
|
||||
// // Set direction based on move direction when on the ground
|
||||
// let ori_dir = if
|
||||
// //character.action.is_wield() ||
|
||||
// character.action.is_attack() || character.action.is_block() {
|
||||
// Vec2::from(inputs.look_dir).normalized()
|
||||
// } else if let (Climb, Some(wall_dir)) = (character.movement, physics.on_wall) {
|
||||
// if Vec2::<f32>::from(wall_dir).magnitude_squared() > 0.001 {
|
||||
// Vec2::from(wall_dir).normalized()
|
||||
// } else {
|
||||
// Vec2::from(vel.0)
|
||||
// }
|
||||
// } else {
|
||||
// Vec2::from(vel.0)
|
||||
// };
|
||||
|
||||
// if ori_dir.magnitude_squared() > 0.0001
|
||||
// && (ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared()
|
||||
// > 0.001
|
||||
// {
|
||||
// ori.0 = vek::ops::Slerp::slerp(
|
||||
// ori.0,
|
||||
// ori_dir.into(),
|
||||
// if physics.on_ground { 9.0 } else { 2.0 } * dt.0,
|
||||
// );
|
||||
// }
|
||||
|
||||
// // Glide
|
||||
// if character.movement == Glide
|
||||
// && Vec2::<f32>::from(vel.0).magnitude_squared() < GLIDE_SPEED.powf(2.0)
|
||||
// && vel.0.z < 0.0
|
||||
// {
|
||||
// let lift = GLIDE_ANTIGRAV + vel.0.z.abs().powf(2.0) * 0.15;
|
||||
// vel.0.z += dt.0
|
||||
// * lift
|
||||
// * (Vec2::<f32>::from(vel.0).magnitude() * 0.075)
|
||||
// .min(1.0)
|
||||
// .max(0.2);
|
||||
// }
|
||||
|
||||
// // Climb
|
||||
// if let (true, Some(_wall_dir)) = (
|
||||
// (inputs.climb.is_pressed() | inputs.climb_down.is_pressed())
|
||||
// && vel.0.z <= CLIMB_SPEED,
|
||||
// physics.on_wall,
|
||||
// ) {
|
||||
// if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() {
|
||||
// vel.0 -= dt.0 * vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0);
|
||||
// } else if inputs.climb.is_pressed() && !inputs.climb_down.is_pressed() {
|
||||
// vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED);
|
||||
// } else {
|
||||
// vel.0.z = vel.0.z + dt.0 * GRAVITY * 1.5;
|
||||
// vel.0 = Lerp::lerp(
|
||||
// vel.0,
|
||||
// Vec3::zero(),
|
||||
// 30.0 * dt.0 / (1.0 - vel.0.z.min(0.0) * 5.0),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// if character.movement == Swim && inputs.jump.is_pressed() {
|
||||
// vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(HUMANOID_WATER_SPEED);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
use crate::comp::TEMP_EQUIP_DELAY;
|
||||
use crate::comp::{
|
||||
ActionState, ActionState::*, AttackKind::*, BasicAttackState, BasicBlockState, BlockKind::*,
|
||||
Body, ControllerInputs, FallState, IdleState, ItemKind::Tool, MoveState, MoveState::*,
|
||||
PhysicsState, RunState, StandState, Stats, SwimState, ToolData, WieldState,
|
||||
PhysicsState, RunState, StandState, Stats, SwimState, WieldState,
|
||||
};
|
||||
use std::time::Duration;
|
||||
|
||||
@ -23,7 +22,7 @@ pub fn determine_primary_ability(stats: &Stats) -> ActionState {
|
||||
/// and returns the corresponding `ActionState`
|
||||
/// ... or Idle if nothing it possible?_
|
||||
pub fn determine_secondary_ability(stats: &Stats) -> ActionState {
|
||||
if let Some(Tool(data)) = stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
if let Some(Tool(_data)) = stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Block(BasicBlock(Some(BasicBlockState {
|
||||
active_duration: Duration::default(),
|
||||
})))
|
||||
@ -32,7 +31,7 @@ pub fn determine_secondary_ability(stats: &Stats) -> ActionState {
|
||||
}
|
||||
}
|
||||
|
||||
/// __Returns a `MoveState` based on `in_fluid` condition__
|
||||
/// _Returns a `MoveState` based on `in_fluid` condition_
|
||||
pub fn determine_fall_or_swim(physics: &PhysicsState) -> MoveState {
|
||||
// Check if in fluid to go to swimming or back to falling
|
||||
if physics.in_fluid {
|
||||
@ -41,7 +40,7 @@ pub fn determine_fall_or_swim(physics: &PhysicsState) -> MoveState {
|
||||
Fall(Some(FallState))
|
||||
}
|
||||
}
|
||||
/// __Returns a `MoveState` based on `move_dir` magnitude__
|
||||
/// _Returns a `MoveState` based on `move_dir` magnitude_
|
||||
pub fn determine_stand_or_run(inputs: &ControllerInputs) -> MoveState {
|
||||
// Return to running or standing based on move inputs
|
||||
if inputs.move_dir.magnitude_squared() > 0.0 {
|
||||
@ -51,7 +50,7 @@ pub fn determine_stand_or_run(inputs: &ControllerInputs) -> MoveState {
|
||||
}
|
||||
}
|
||||
|
||||
/// __Returns a `MoveState` based on `on_ground` state.__
|
||||
/// _Returns a `MoveState` based on `on_ground` state._
|
||||
///
|
||||
/// _`FallState`, or `SwimState` if not `on_ground`,
|
||||
/// `StandState` or `RunState` if is `on_ground`_
|
||||
@ -69,11 +68,11 @@ pub fn determine_move_from_grounded_state(
|
||||
}
|
||||
}
|
||||
|
||||
/// __Returns an ActionState based on whether character has a weapon equipped.__
|
||||
/// _Returns an ActionState based on whether character has a weapon equipped._
|
||||
pub fn attempt_wield(stats: &Stats) -> ActionState {
|
||||
if let Some(Tool { .. }) = stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
if let Some(Tool(data)) = stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Wield(Some(WieldState {
|
||||
equip_delay: Duration::from_millis(TEMP_EQUIP_DELAY),
|
||||
equip_delay: data.equip_time(),
|
||||
}))
|
||||
} else {
|
||||
Idle(Some(IdleState))
|
||||
@ -82,7 +81,7 @@ pub fn attempt_wield(stats: &Stats) -> ActionState {
|
||||
|
||||
pub fn can_climb(physics: &PhysicsState, inputs: &ControllerInputs, body: &Body) -> bool {
|
||||
if let (true, Some(_wall_dir)) = (
|
||||
inputs.climb.is_pressed() | inputs.climb_down.is_pressed() && body.is_humanoid(),
|
||||
(inputs.climb.is_pressed() | inputs.climb_down.is_pressed()) && body.is_humanoid(),
|
||||
physics.on_wall,
|
||||
) {
|
||||
true
|
||||
|
@ -277,10 +277,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
move_state: MoveState::Stand(StandState),
|
||||
action_state: ActionState::Idle(IdleState),
|
||||
action_disabled_this_tick: false,
|
||||
move_disabled_this_tick: false,
|
||||
move_state: MoveState::Stand(None),
|
||||
action_state: ActionState::Idle(None),
|
||||
},
|
||||
SfxEvent::Idle,
|
||||
&stats,
|
||||
@ -295,10 +293,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
move_state: MoveState::Run(RunState),
|
||||
action_state: ActionState::Idle(IdleState),
|
||||
action_disabled_this_tick: false,
|
||||
move_disabled_this_tick: false,
|
||||
move_state: MoveState::Run(None),
|
||||
action_state: ActionState::Idle(None),
|
||||
},
|
||||
SfxEvent::Idle,
|
||||
&stats,
|
||||
@ -313,10 +309,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
action_state: ActionState::Dodge(Roll(RollState::default())),
|
||||
move_state: MoveState::Run(RunState),
|
||||
action_disabled_this_tick: false,
|
||||
move_disabled_this_tick: true,
|
||||
action_state: ActionState::Dodge(Roll(None)),
|
||||
move_state: MoveState::Run(None),
|
||||
},
|
||||
SfxEvent::Run,
|
||||
&stats,
|
||||
@ -331,10 +325,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
move_state: MoveState::Fall(FallState),
|
||||
action_state: ActionState::Idle(IdleState),
|
||||
action_disabled_this_tick: false,
|
||||
move_disabled_this_tick: false,
|
||||
move_state: MoveState::Fall((None)),
|
||||
action_state: ActionState::Idle((None)),
|
||||
},
|
||||
SfxEvent::Idle,
|
||||
&stats,
|
||||
@ -349,10 +341,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
move_state: MoveState::Glide(GlideState),
|
||||
action_state: ActionState::Idle(IdleState),
|
||||
action_disabled_this_tick: true,
|
||||
move_disabled_this_tick: false,
|
||||
move_state: MoveState::Glide(None),
|
||||
action_state: ActionState::Idle(None),
|
||||
},
|
||||
SfxEvent::Jump,
|
||||
&stats,
|
||||
@ -367,10 +357,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
move_state: MoveState::Glide(GlideState),
|
||||
action_state: ActionState::Idle(IdleState),
|
||||
action_disabled_this_tick: true,
|
||||
move_disabled_this_tick: false,
|
||||
move_state: MoveState::Glide(None),
|
||||
action_state: ActionState::Idle(None),
|
||||
},
|
||||
SfxEvent::Glide,
|
||||
&stats,
|
||||
@ -385,10 +373,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
move_state: MoveState::Fall(FallState),
|
||||
action_state: ActionState::Idle(IdleState),
|
||||
move_disabled_this_tick: false,
|
||||
action_disabled_this_tick: false,
|
||||
move_state: MoveState::Fall(None),
|
||||
action_state: ActionState::Idle(None),
|
||||
},
|
||||
SfxEvent::Glide,
|
||||
&stats,
|
||||
@ -408,10 +394,8 @@ mod tests {
|
||||
|
||||
let result = SfxEventMapper::map_character_event(
|
||||
&CharacterState {
|
||||
move_state: MoveState::Stand(StandState),
|
||||
action_state: ActionState::Attack(BasicAttack(BasicAttackState::default())),
|
||||
move_disabled_this_tick: false,
|
||||
action_disabled_this_tick: false,
|
||||
move_state: MoveState::Stand(None),
|
||||
action_state: ActionState::Attack(BasicAttack(None)),
|
||||
},
|
||||
SfxEvent::Idle,
|
||||
&stats,
|
||||
|
@ -1,9 +1,9 @@
|
||||
use super::{
|
||||
img_ids::Imgs, BarNumbers, Fonts, ShortcutNumbers, XpBar, CRITICAL_HP_COLOR,
|
||||
/*FOCUS_COLOR, RAGE_COLOR,*/ HP_COLOR, LOW_HP_COLOR, MANA_COLOR, TEXT_COLOR, XP_COLOR,
|
||||
img_ids::Imgs, BarNumbers, Fonts, ShortcutNumbers, XpBar, CRITICAL_HP_COLOR, HP_COLOR,
|
||||
LOW_HP_COLOR, MANA_COLOR, TEXT_COLOR, XP_COLOR,
|
||||
};
|
||||
use crate::GlobalState;
|
||||
use common::comp::{item::Debug, item::ToolData, item::ToolKind, Equipment, ItemKind, Stats};
|
||||
use common::comp::{item::Debug, item::ToolData, item::ToolKind, ItemKind, Stats};
|
||||
use conrod_core::{
|
||||
color,
|
||||
widget::{self, Button, Image, Rectangle, Text},
|
||||
|
Loading…
Reference in New Issue
Block a user