mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Finish state struct data refactor
This commit is contained in:
parent
ee706fa32a
commit
7dfe00b674
@ -39,23 +39,25 @@ impl From<CharacterAbility> for CharacterState {
|
|||||||
CharacterAbility::BasicAttack {
|
CharacterAbility::BasicAttack {
|
||||||
buildup_duration,
|
buildup_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
} => CharacterState::BasicAttack(basic_attack::State {
|
} => CharacterState::BasicAttack(basic_attack::Data {
|
||||||
exhausted: false,
|
exhausted: false,
|
||||||
buildup_duration,
|
buildup_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
}),
|
}),
|
||||||
CharacterAbility::BasicBlock { .. } => CharacterState::BasicBlock {},
|
CharacterAbility::BasicBlock { .. } => CharacterState::BasicBlock,
|
||||||
CharacterAbility::Roll { .. } => CharacterState::Roll {
|
CharacterAbility::Roll { .. } => CharacterState::Roll(roll::Data {
|
||||||
remaining_duration: Duration::from_millis(600),
|
remaining_duration: Duration::from_millis(600),
|
||||||
},
|
}),
|
||||||
CharacterAbility::ChargeAttack { .. } => CharacterState::ChargeAttack {
|
CharacterAbility::ChargeAttack { .. } => {
|
||||||
|
CharacterState::ChargeAttack(charge_attack::Data {
|
||||||
remaining_duration: Duration::from_millis(600),
|
remaining_duration: Duration::from_millis(600),
|
||||||
|
})
|
||||||
},
|
},
|
||||||
CharacterAbility::TimedCombo {
|
CharacterAbility::TimedCombo {
|
||||||
tool,
|
tool,
|
||||||
buildup_duration,
|
buildup_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
} => CharacterState::TimedCombo(timed_combo::State {
|
} => CharacterState::TimedCombo(timed_combo::Data {
|
||||||
tool,
|
tool,
|
||||||
buildup_duration,
|
buildup_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, FlaggedStorage, HashMapStorage, VecStorage};
|
use specs::{Component, FlaggedStorage, HashMapStorage, VecStorage};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
/// Data returned from character behavior fn's to Character Behavior System.
|
/// Data returned from character behavior fn's to Character Behavior System.
|
||||||
pub struct StateUpdate {
|
pub struct StateUpdate {
|
||||||
@ -22,54 +22,35 @@ pub struct StateUpdate {
|
|||||||
pub enum CharacterState {
|
pub enum CharacterState {
|
||||||
Idle,
|
Idle,
|
||||||
Climb,
|
Climb,
|
||||||
Sit {},
|
Sit,
|
||||||
Equipping {
|
|
||||||
/// The weapon being equipped
|
|
||||||
tool: ToolData,
|
|
||||||
/// Time left before next state
|
|
||||||
time_left: Duration,
|
|
||||||
},
|
|
||||||
Wielding {
|
|
||||||
/// The weapon being wielded
|
|
||||||
tool: ToolData,
|
|
||||||
},
|
|
||||||
Glide,
|
Glide,
|
||||||
/// A basic blocking state
|
/// A basic blocking state
|
||||||
BasicBlock,
|
BasicBlock,
|
||||||
ChargeAttack {
|
/// Player is busy equipping or unequipping weapons
|
||||||
/// How long the state has until exiting
|
Equipping(equipping::Data),
|
||||||
remaining_duration: Duration,
|
/// Player is holding a weapon and can perform other actions
|
||||||
},
|
Wielding(wielding::Data),
|
||||||
Roll {
|
/// Player rushes forward and slams an enemy with their weapon
|
||||||
/// How long the state has until exiting
|
ChargeAttack(charge_attack::Data),
|
||||||
remaining_duration: Duration,
|
/// A dodge where player can roll
|
||||||
},
|
Roll(roll::Data),
|
||||||
/// A basic attacking state
|
/// A basic attacking state
|
||||||
BasicAttack(basic_attack::State),
|
BasicAttack(basic_attack::Data),
|
||||||
/// A three-stage attack where play must click at appropriate times
|
/// A three-stage attack where play must click at appropriate times
|
||||||
/// to continue attack chain.
|
/// to continue attack chain.
|
||||||
TimedCombo(timed_combo::State),
|
TimedCombo(timed_combo::Data),
|
||||||
/// A three-stage attack where each attack pushes player forward
|
/// A three-stage attack where each attack pushes player forward
|
||||||
/// and successive attacks increase in damage, while player holds button.
|
/// and successive attacks increase in damage, while player holds button.
|
||||||
TripleStrike {
|
TripleStrike(triple_strike::Data),
|
||||||
/// The tool this state will read to handle damage, etc.
|
|
||||||
tool: ToolData,
|
|
||||||
/// `int` denoting what stage (of 3) the attack is in.
|
|
||||||
stage: i8,
|
|
||||||
/// How long current stage has been active
|
|
||||||
stage_time_active: Duration,
|
|
||||||
/// Whether current stage has exhausted its attack
|
|
||||||
stage_exhausted: bool,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharacterState {
|
impl CharacterState {
|
||||||
pub fn is_wield(&self) -> bool {
|
pub fn is_wield(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CharacterState::Wielding { .. }
|
CharacterState::Wielding(_)
|
||||||
| CharacterState::BasicAttack(_)
|
| CharacterState::BasicAttack(_)
|
||||||
| CharacterState::TimedCombo(_)
|
| CharacterState::TimedCombo(_)
|
||||||
| CharacterState::BasicBlock { .. } => true,
|
| CharacterState::BasicBlock => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,21 +59,21 @@ impl CharacterState {
|
|||||||
match self {
|
match self {
|
||||||
CharacterState::BasicAttack(_)
|
CharacterState::BasicAttack(_)
|
||||||
| CharacterState::TimedCombo(_)
|
| CharacterState::TimedCombo(_)
|
||||||
| CharacterState::ChargeAttack { .. } => true,
|
| CharacterState::ChargeAttack(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_block(&self) -> bool {
|
pub fn is_block(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CharacterState::BasicBlock { .. } => true,
|
CharacterState::BasicBlock => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dodge(&self) -> bool {
|
pub fn is_dodge(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CharacterState::Roll { .. } => true,
|
CharacterState::Roll(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +86,7 @@ impl CharacterState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CharacterState {
|
impl Default for CharacterState {
|
||||||
fn default() -> Self { Self::Idle {} }
|
fn default() -> Self { Self::Idle }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for CharacterState {
|
impl Component for CharacterState {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, EnergySource, ItemKind::Tool, StateUpdate},
|
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||||
states::utils::*,
|
states::{utils::*, wielding},
|
||||||
sys::character_behavior::*,
|
sys::character_behavior::*,
|
||||||
};
|
};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::{collections::VecDeque, time::Duration};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
pub struct State {
|
pub struct Data {
|
||||||
/// How long until state should deal damage
|
/// How long until state should deal damage
|
||||||
pub buildup_duration: Duration,
|
pub buildup_duration: Duration,
|
||||||
/// How long the state has until exiting
|
/// How long the state has until exiting
|
||||||
@ -15,7 +15,7 @@ pub struct State {
|
|||||||
pub exhausted: bool,
|
pub exhausted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharacterBehavior for State {
|
impl CharacterBehavior for Data {
|
||||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
@ -32,7 +32,7 @@ impl CharacterBehavior for State {
|
|||||||
// Build up window
|
// Build up window
|
||||||
if self.buildup_duration != Duration::default() {
|
if self.buildup_duration != Duration::default() {
|
||||||
// Start to swing
|
// Start to swing
|
||||||
update.character = CharacterState::BasicAttack(State {
|
update.character = CharacterState::BasicAttack(Data {
|
||||||
buildup_duration: self
|
buildup_duration: self
|
||||||
.buildup_duration
|
.buildup_duration
|
||||||
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
||||||
@ -52,7 +52,7 @@ impl CharacterBehavior for State {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update.character = CharacterState::BasicAttack(State {
|
update.character = CharacterState::BasicAttack(Data {
|
||||||
buildup_duration: self.buildup_duration,
|
buildup_duration: self.buildup_duration,
|
||||||
recover_duration: self.recover_duration,
|
recover_duration: self.recover_duration,
|
||||||
exhausted: true,
|
exhausted: true,
|
||||||
@ -60,7 +60,7 @@ impl CharacterBehavior for State {
|
|||||||
}
|
}
|
||||||
// Swing recovery window
|
// Swing recovery window
|
||||||
else if self.recover_duration != Duration::default() {
|
else if self.recover_duration != Duration::default() {
|
||||||
update.character = CharacterState::BasicAttack(State {
|
update.character = CharacterState::BasicAttack(Data {
|
||||||
buildup_duration: self.buildup_duration,
|
buildup_duration: self.buildup_duration,
|
||||||
recover_duration: self
|
recover_duration: self
|
||||||
.recover_duration
|
.recover_duration
|
||||||
@ -72,7 +72,7 @@ impl CharacterBehavior for State {
|
|||||||
// Done
|
// Done
|
||||||
else {
|
else {
|
||||||
if let Some(tool) = unwrap_tool_data(data) {
|
if let Some(tool) = unwrap_tool_data(data) {
|
||||||
update.character = CharacterState::Wielding { tool };
|
update.character = CharacterState::Wielding(wielding::Data { tool });
|
||||||
// Make sure attack component is removed
|
// Make sure attack component is removed
|
||||||
data.updater.remove::<Attacking>(data.entity);
|
data.updater.remove::<Attacking>(data.entity);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
use super::utils::*;
|
use super::utils::*;
|
||||||
use crate::{comp::StateUpdate, sys::character_behavior::JoinData};
|
use crate::{
|
||||||
|
comp::StateUpdate,
|
||||||
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
// const BLOCK_ACCEL: f32 = 30.0;
|
// const BLOCK_ACCEL: f32 = 30.0;
|
||||||
// const BLOCK_SPEED: f32 = 75.0;
|
// const BLOCK_SPEED: f32 = 75.0;
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data;
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
vel: *data.vel,
|
vel: *data.vel,
|
||||||
@ -23,3 +30,4 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
}
|
}
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -2,14 +2,21 @@ use super::utils::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{CharacterState::*, HealthChange, HealthSource, StateUpdate},
|
comp::{CharacterState::*, HealthChange, HealthSource, StateUpdate},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
sys::character_behavior::JoinData,
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
};
|
};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::{collections::VecDeque, time::Duration};
|
||||||
use vek::Vec3;
|
use vek::Vec3;
|
||||||
|
|
||||||
const CHARGE_SPEED: f32 = 20.0;
|
const CHARGE_SPEED: f32 = 20.0;
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data {
|
||||||
|
/// How long the state has until exiting
|
||||||
|
pub remaining_duration: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
vel: *data.vel,
|
vel: *data.vel,
|
||||||
@ -19,8 +26,6 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
local_events: VecDeque::new(),
|
local_events: VecDeque::new(),
|
||||||
server_events: VecDeque::new(),
|
server_events: VecDeque::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let ChargeAttack { remaining_duration } = data.character {
|
|
||||||
// Move player
|
// Move player
|
||||||
update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z)
|
update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z)
|
||||||
+ (update.vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
+ (update.vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||||
@ -46,18 +51,20 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if charge timed out or can't keep moving forward
|
// Check if charge timed out or can't keep moving forward
|
||||||
if *remaining_duration == Duration::default() || update.vel.0.magnitude_squared() < 10.0 {
|
if self.remaining_duration == Duration::default() || update.vel.0.magnitude_squared() < 10.0
|
||||||
|
{
|
||||||
attempt_wield(data, &mut update);
|
attempt_wield(data, &mut update);
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tick remaining-duration and keep charging
|
// Tick remaining-duration and keep charging
|
||||||
update.character = ChargeAttack {
|
update.character = ChargeAttack(Data {
|
||||||
remaining_duration: remaining_duration
|
remaining_duration: self
|
||||||
|
.remaining_duration
|
||||||
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
};
|
});
|
||||||
}
|
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{CharacterState, EnergySource, StateUpdate},
|
comp::{CharacterState, EnergySource, StateUpdate},
|
||||||
event::LocalEvent,
|
event::LocalEvent,
|
||||||
sys::{character_behavior::JoinData, phys::GRAVITY},
|
sys::{
|
||||||
|
character_behavior::{CharacterBehavior, JoinData},
|
||||||
|
phys::GRAVITY,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use vek::{
|
use vek::{
|
||||||
@ -12,7 +15,11 @@ use vek::{
|
|||||||
const HUMANOID_CLIMB_ACCEL: f32 = 5.0;
|
const HUMANOID_CLIMB_ACCEL: f32 = 5.0;
|
||||||
const CLIMB_SPEED: f32 = 5.0;
|
const CLIMB_SPEED: f32 = 5.0;
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data;
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
vel: *data.vel,
|
vel: *data.vel,
|
||||||
@ -78,7 +85,8 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
data.physics.on_wall,
|
data.physics.on_wall,
|
||||||
) {
|
) {
|
||||||
if data.inputs.climb_down.is_pressed() && !data.inputs.climb.is_pressed() {
|
if data.inputs.climb_down.is_pressed() && !data.inputs.climb.is_pressed() {
|
||||||
update.vel.0 -= data.dt.0 * update.vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0);
|
update.vel.0 -=
|
||||||
|
data.dt.0 * update.vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0);
|
||||||
} else if data.inputs.climb.is_pressed() && !data.inputs.climb_down.is_pressed() {
|
} else if data.inputs.climb.is_pressed() && !data.inputs.climb_down.is_pressed() {
|
||||||
update.vel.0.z = (update.vel.0.z + data.dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED);
|
update.vel.0.z = (update.vel.0.z + data.dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED);
|
||||||
} else {
|
} else {
|
||||||
@ -93,3 +101,4 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
use super::utils::*;
|
use super::utils::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
comp::{CharacterState, StateUpdate},
|
comp::{CharacterState, StateUpdate, ToolData},
|
||||||
sys::character_behavior::JoinData,
|
states::wielding,
|
||||||
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
};
|
};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::{collections::VecDeque, time::Duration};
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data {
|
||||||
|
/// The weapon being equipped
|
||||||
|
pub tool: ToolData,
|
||||||
|
/// Time left before next state
|
||||||
|
pub time_left: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
character: *data.character,
|
character: *data.character,
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
@ -19,20 +29,21 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
handle_move(&data, &mut update);
|
handle_move(&data, &mut update);
|
||||||
handle_jump(&data, &mut update);
|
handle_jump(&data, &mut update);
|
||||||
|
|
||||||
if let CharacterState::Equipping { tool, time_left } = data.character {
|
if self.time_left == Duration::default() {
|
||||||
if *time_left == Duration::default() {
|
|
||||||
// Wield delay has expired
|
// Wield delay has expired
|
||||||
update.character = CharacterState::Wielding { tool: *tool };
|
update.character = CharacterState::Wielding(wielding::Data { tool: self.tool });
|
||||||
} else {
|
} else {
|
||||||
// Wield delay hasn't expired yet
|
// Wield delay hasn't expired yet
|
||||||
// Update wield delay
|
// Update wield delay
|
||||||
update.character = CharacterState::Equipping {
|
update.character = CharacterState::Equipping(Data {
|
||||||
time_left: time_left
|
time_left: self
|
||||||
|
.time_left
|
||||||
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
tool: *tool,
|
tool: self.tool,
|
||||||
};
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{CharacterState, StateUpdate},
|
comp::{CharacterState, StateUpdate},
|
||||||
sys::character_behavior::JoinData,
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
};
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use vek::{Vec2, Vec3};
|
use vek::{Vec2, Vec3};
|
||||||
@ -10,7 +10,11 @@ const GLIDE_ANTIGRAV: f32 = crate::sys::phys::GRAVITY * 0.96;
|
|||||||
const GLIDE_ACCEL: f32 = 15.0;
|
const GLIDE_ACCEL: f32 = 15.0;
|
||||||
const GLIDE_SPEED: f32 = 45.0;
|
const GLIDE_SPEED: f32 = 45.0;
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data;
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
vel: *data.vel,
|
vel: *data.vel,
|
||||||
@ -64,3 +68,4 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
// Otherwise keep gliding
|
// Otherwise keep gliding
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
use super::utils::*;
|
use super::utils::*;
|
||||||
use crate::{comp::StateUpdate, sys::character_behavior::JoinData};
|
use crate::{
|
||||||
|
comp::StateUpdate,
|
||||||
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
pub struct Data;
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
character: *data.character,
|
character: *data.character,
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
@ -22,3 +28,4 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{CharacterState, StateUpdate},
|
comp::{CharacterState, StateUpdate},
|
||||||
sys::character_behavior::JoinData,
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
};
|
};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::{collections::VecDeque, time::Duration};
|
||||||
use vek::Vec3;
|
use vek::Vec3;
|
||||||
|
|
||||||
const ROLL_SPEED: f32 = 17.0;
|
const ROLL_SPEED: f32 = 17.0;
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data {
|
||||||
|
/// How long the state has until exiting
|
||||||
|
pub remaining_duration: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
character: *data.character,
|
character: *data.character,
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
@ -18,7 +24,6 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
server_events: VecDeque::new(),
|
server_events: VecDeque::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let CharacterState::Roll { remaining_duration } = data.character {
|
|
||||||
// Update velocity
|
// Update velocity
|
||||||
update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z)
|
update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z)
|
||||||
+ (update.vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
+ (update.vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||||
@ -37,19 +42,20 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
vek::ops::Slerp::slerp(update.ori.0, update.vel.0.into(), 9.0 * data.dt.0);
|
vek::ops::Slerp::slerp(update.ori.0, update.vel.0.into(), 9.0 * data.dt.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if *remaining_duration == Duration::default() {
|
if self.remaining_duration == Duration::default() {
|
||||||
// Roll duration has expired
|
// Roll duration has expired
|
||||||
update.vel.0 *= 0.3;
|
update.vel.0 *= 0.3;
|
||||||
update.character = CharacterState::Idle {};
|
update.character = CharacterState::Idle {};
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, tick down remaining_duration
|
// Otherwise, tick down remaining_duration
|
||||||
update.character = CharacterState::Roll {
|
update.character = CharacterState::Roll(Data {
|
||||||
remaining_duration: remaining_duration
|
remaining_duration: self
|
||||||
|
.remaining_duration
|
||||||
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
};
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
use super::utils::*;
|
use super::utils::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
comp::{CharacterState, StateUpdate},
|
comp::{CharacterState, StateUpdate},
|
||||||
sys::character_behavior::JoinData,
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
};
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data;
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
character: *data.character,
|
character: *data.character,
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
@ -23,8 +27,9 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
|| data.inputs.sit.is_just_pressed()
|
|| data.inputs.sit.is_just_pressed()
|
||||||
|| data.inputs.move_dir.magnitude_squared() > 0.0
|
|| data.inputs.move_dir.magnitude_squared() > 0.0
|
||||||
{
|
{
|
||||||
update.character = CharacterState::Idle {};
|
update.character = CharacterState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate, ToolData},
|
comp::{Attacking, CharacterState, EnergySource, StateUpdate, ToolData},
|
||||||
states::utils::*,
|
states::wielding,
|
||||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
};
|
};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::{collections::VecDeque, time::Duration};
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
pub struct State {
|
pub struct Data {
|
||||||
/// Denotes what stage (of 3) the attack is in
|
/// Denotes what stage (of 3) the attack is in
|
||||||
pub stage: i8,
|
pub stage: i8,
|
||||||
/// Whether current stage has exhausted its attack
|
/// Whether current stage has exhausted its attack
|
||||||
@ -20,7 +20,7 @@ pub struct State {
|
|||||||
pub tool: ToolData,
|
pub tool: ToolData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharacterBehavior for State {
|
impl CharacterBehavior for Data {
|
||||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
@ -44,11 +44,11 @@ impl CharacterBehavior for State {
|
|||||||
if data.inputs.primary.is_just_pressed() {
|
if data.inputs.primary.is_just_pressed() {
|
||||||
println!("Failed");
|
println!("Failed");
|
||||||
// They failed, go back to `Wielding`
|
// They failed, go back to `Wielding`
|
||||||
update.character = CharacterState::Wielding { tool: self.tool };
|
update.character = CharacterState::Wielding(wielding::Data { tool: self.tool });
|
||||||
}
|
}
|
||||||
// Keep updating
|
// Keep updating
|
||||||
else {
|
else {
|
||||||
update.character = CharacterState::TimedCombo(State {
|
update.character = CharacterState::TimedCombo(Data {
|
||||||
tool: self.tool,
|
tool: self.tool,
|
||||||
stage: self.stage,
|
stage: self.stage,
|
||||||
buildup_duration: self.buildup_duration,
|
buildup_duration: self.buildup_duration,
|
||||||
@ -67,7 +67,7 @@ impl CharacterBehavior for State {
|
|||||||
hit_count: 0,
|
hit_count: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
update.character = CharacterState::TimedCombo(State {
|
update.character = CharacterState::TimedCombo(Data {
|
||||||
tool: self.tool,
|
tool: self.tool,
|
||||||
stage: self.stage,
|
stage: self.stage,
|
||||||
buildup_duration: self.buildup_duration,
|
buildup_duration: self.buildup_duration,
|
||||||
@ -86,7 +86,7 @@ impl CharacterBehavior for State {
|
|||||||
// Try to transition to next stage
|
// Try to transition to next stage
|
||||||
if data.inputs.primary.is_just_pressed() {
|
if data.inputs.primary.is_just_pressed() {
|
||||||
println!("Transition");
|
println!("Transition");
|
||||||
update.character = CharacterState::TimedCombo(State {
|
update.character = CharacterState::TimedCombo(Data {
|
||||||
tool: self.tool,
|
tool: self.tool,
|
||||||
stage: self.stage + 1,
|
stage: self.stage + 1,
|
||||||
buildup_duration: self.buildup_duration,
|
buildup_duration: self.buildup_duration,
|
||||||
@ -99,7 +99,7 @@ impl CharacterBehavior for State {
|
|||||||
else {
|
else {
|
||||||
// Update state
|
// Update state
|
||||||
println!("Missed");
|
println!("Missed");
|
||||||
update.character = CharacterState::TimedCombo(State {
|
update.character = CharacterState::TimedCombo(Data {
|
||||||
tool: self.tool,
|
tool: self.tool,
|
||||||
stage: self.stage,
|
stage: self.stage,
|
||||||
buildup_duration: self.buildup_duration,
|
buildup_duration: self.buildup_duration,
|
||||||
@ -112,7 +112,7 @@ impl CharacterBehavior for State {
|
|||||||
// Stage expired but missed transition to next stage
|
// Stage expired but missed transition to next stage
|
||||||
else {
|
else {
|
||||||
// Back to `Wielding`
|
// Back to `Wielding`
|
||||||
update.character = CharacterState::Wielding { tool: self.tool };
|
update.character = CharacterState::Wielding(wielding::Data { tool: self.tool });
|
||||||
// Make sure attack component is removed
|
// Make sure attack component is removed
|
||||||
data.updater.remove::<Attacking>(data.entity);
|
data.updater.remove::<Attacking>(data.entity);
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ impl CharacterBehavior for State {
|
|||||||
else {
|
else {
|
||||||
println!("Success!");
|
println!("Success!");
|
||||||
// Back to `Wielding`
|
// Back to `Wielding`
|
||||||
update.character = CharacterState::Wielding { tool: self.tool };
|
update.character = CharacterState::Wielding(wielding::Data { tool: self.tool });
|
||||||
// Make sure attack component is removed
|
// Make sure attack component is removed
|
||||||
data.updater.remove::<Attacking>(data.entity);
|
data.updater.remove::<Attacking>(data.entity);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, ItemKind::Tool, StateUpdate},
|
comp::{StateUpdate, ToolData},
|
||||||
states::utils::*,
|
states::utils::*,
|
||||||
sys::character_behavior::JoinData,
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
};
|
};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::{collections::VecDeque, time::Duration};
|
||||||
|
|
||||||
@ -14,7 +14,20 @@ const STAGE_DURATION: u64 = 600;
|
|||||||
/// each one pushes the player forward as the character steps into the swings.
|
/// each one pushes the player forward as the character steps into the swings.
|
||||||
/// The player can let go of the left mouse button at any time
|
/// The player can let go of the left mouse button at any time
|
||||||
/// and stop their attacks by interrupting the attack animation.
|
/// and stop their attacks by interrupting the attack animation.
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data {
|
||||||
|
/// The tool this state will read to handle damage, etc.
|
||||||
|
pub tool: ToolData,
|
||||||
|
/// `int` denoting what stage (of 3) the attack is in.
|
||||||
|
pub stage: i8,
|
||||||
|
/// How long current stage has been active
|
||||||
|
pub stage_time_active: Duration,
|
||||||
|
/// Whether current stage has exhausted its attack
|
||||||
|
stage_exhausted: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
vel: *data.vel,
|
vel: *data.vel,
|
||||||
@ -25,15 +38,9 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
server_events: VecDeque::new(),
|
server_events: VecDeque::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let CharacterState::TripleStrike {
|
let new_stage_exhausted = self.stage_exhausted;
|
||||||
tool,
|
let new_stage_time_active = self
|
||||||
stage,
|
.stage_time_active
|
||||||
stage_time_active,
|
|
||||||
stage_exhausted,
|
|
||||||
} = data.character
|
|
||||||
{
|
|
||||||
let mut new_stage_exhausted = *stage_exhausted;
|
|
||||||
let new_stage_time_active = stage_time_active
|
|
||||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||||
.unwrap_or(Duration::default());
|
.unwrap_or(Duration::default());
|
||||||
|
|
||||||
@ -43,7 +50,7 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
while *stage < 3 {
|
if self.stage < 3 {
|
||||||
if new_stage_time_active < Duration::from_millis(STAGE_DURATION / 3) {
|
if new_stage_time_active < Duration::from_millis(STAGE_DURATION / 3) {
|
||||||
// Move player forward while in first third of each stage
|
// Move player forward while in first third of each stage
|
||||||
handle_move(data, &mut update);
|
handle_move(data, &mut update);
|
||||||
@ -54,7 +61,7 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
// TODO: deal damage
|
// TODO: deal damage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{CharacterAbility, CharacterState, EnergySource, ItemKind::Tool, StateUpdate, ToolData},
|
comp::{CharacterState, EnergySource, ItemKind::Tool, StateUpdate, ToolData},
|
||||||
event::LocalEvent,
|
event::LocalEvent,
|
||||||
states::*,
|
states::*,
|
||||||
sys::{character_behavior::JoinData, phys::GRAVITY},
|
sys::{character_behavior::JoinData, phys::GRAVITY},
|
||||||
@ -120,10 +120,10 @@ pub fn handle_wield(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
/// If a tool is equipped, goes into Equipping state, otherwise goes to Idle
|
/// If a tool is equipped, goes into Equipping state, otherwise goes to Idle
|
||||||
pub fn attempt_wield(data: &JoinData, update: &mut StateUpdate) {
|
pub fn attempt_wield(data: &JoinData, update: &mut StateUpdate) {
|
||||||
if let Some(Tool(tool)) = data.stats.equipment.main.as_ref().map(|i| i.kind) {
|
if let Some(Tool(tool)) = data.stats.equipment.main.as_ref().map(|i| i.kind) {
|
||||||
update.character = CharacterState::Equipping {
|
update.character = CharacterState::Equipping(equipping::Data {
|
||||||
tool,
|
tool,
|
||||||
time_left: tool.equip_time(),
|
time_left: tool.equip_time(),
|
||||||
};
|
});
|
||||||
} else {
|
} else {
|
||||||
update.character = CharacterState::Idle {};
|
update.character = CharacterState::Idle {};
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
use super::utils::*;
|
use super::utils::*;
|
||||||
use crate::{comp::StateUpdate, sys::character_behavior::JoinData};
|
use crate::{
|
||||||
|
comp::{StateUpdate, ToolData},
|
||||||
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||||
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
||||||
|
pub struct Data {
|
||||||
|
/// The weapon being wielded
|
||||||
|
pub tool: ToolData,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn behavior(data: &JoinData) -> StateUpdate {
|
impl CharacterBehavior for Data {
|
||||||
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
character: *data.character,
|
character: *data.character,
|
||||||
pos: *data.pos,
|
pos: *data.pos,
|
||||||
@ -25,3 +34,4 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -172,18 +172,18 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut state_update = match j.character {
|
let mut state_update = match j.character {
|
||||||
CharacterState::Idle { .. } => states::idle::behavior(&j),
|
CharacterState::Idle => states::idle::Data::behavior(&states::idle::Data, &j),
|
||||||
CharacterState::Climb { .. } => states::climb::behavior(&j),
|
CharacterState::Climb => states::climb::Data::behavior(&states::climb::Data, &j),
|
||||||
CharacterState::Glide { .. } => states::glide::behavior(&j),
|
CharacterState::Glide => states::glide::Data::behavior(&states::glide::Data, &j),
|
||||||
CharacterState::Roll { .. } => states::roll::behavior(&j),
|
CharacterState::Sit => states::sit::Data::behavior(&states::sit::Data, &j),
|
||||||
CharacterState::Wielding { .. } => states::wielding::behavior(&j),
|
CharacterState::BasicBlock => states::basic_block::Data::behavior(&states::basic_block::Data, &j),
|
||||||
CharacterState::Equipping { .. } => states::equipping::behavior(&j),
|
CharacterState::Roll (data) => data.behavior(&j),
|
||||||
CharacterState::BasicBlock { .. } => states::basic_block::behavior(&j),
|
CharacterState::Wielding (data) => data.behavior(&j),
|
||||||
CharacterState::ChargeAttack { .. } => states::charge_attack::behavior(&j),
|
CharacterState::Equipping (data) => data.behavior(&j),
|
||||||
CharacterState::Sit { .. } => states::sit::behavior(&j),
|
CharacterState::ChargeAttack (data) => data.behavior(&j),
|
||||||
CharacterState::TripleStrike { .. } => states::triple_strike::behavior(&j),
|
CharacterState::TripleStrike (data) => data.behavior(&j),
|
||||||
CharacterState::BasicAttack (state) => state.behavior(&j),
|
CharacterState::BasicAttack (data) => data.behavior(&j),
|
||||||
CharacterState::TimedCombo(state) => state.behavior(&j),
|
CharacterState::TimedCombo(data) => data.behavior(&j),
|
||||||
|
|
||||||
// Do not use default match.
|
// Do not use default match.
|
||||||
// _ => StateUpdate {
|
// _ => StateUpdate {
|
||||||
|
Loading…
Reference in New Issue
Block a user