mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add charging back
This commit is contained in:
parent
adf34d4f0f
commit
f769c74bf4
@ -5,6 +5,7 @@ pub enum AbilityState {
|
|||||||
BasicAttack,
|
BasicAttack,
|
||||||
BasicBlock,
|
BasicBlock,
|
||||||
Roll,
|
Roll,
|
||||||
|
ChargeAttack,
|
||||||
}
|
}
|
||||||
impl Default for AbilityState {
|
impl Default for AbilityState {
|
||||||
fn default() -> Self { Self::BasicAttack }
|
fn default() -> Self { Self::BasicAttack }
|
||||||
@ -26,7 +27,7 @@ impl Default for AbilityPool {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
primary: Some(AbilityState::BasicAttack),
|
primary: Some(AbilityState::BasicAttack),
|
||||||
secondary: Some(AbilityState::BasicBlock),
|
secondary: Some(AbilityState::ChargeAttack),
|
||||||
block: None,
|
block: None,
|
||||||
dodge: Some(AbilityState::Roll),
|
dodge: Some(AbilityState::Roll),
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,10 @@ pub enum CharacterState {
|
|||||||
},
|
},
|
||||||
/// A basic blocking state
|
/// A basic blocking state
|
||||||
BasicBlock {},
|
BasicBlock {},
|
||||||
//Charge{},
|
ChargeAttack {
|
||||||
|
/// How long the state has until exiting
|
||||||
|
remaining_duration: Duration,
|
||||||
|
},
|
||||||
Roll {
|
Roll {
|
||||||
/// How long the state has until exiting
|
/// How long the state has until exiting
|
||||||
remaining_duration: Duration,
|
remaining_duration: Duration,
|
||||||
@ -61,7 +64,7 @@ impl CharacterState {
|
|||||||
|
|
||||||
pub fn is_attack(&self) -> bool {
|
pub fn is_attack(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CharacterState::BasicAttack { .. } => true,
|
CharacterState::BasicAttack { .. } | CharacterState::ChargeAttack { .. } => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,7 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
handle_move(&data, &mut update);
|
handle_move(&data, &mut update);
|
||||||
|
|
||||||
if !data.physics.on_ground || !data.inputs.secondary.is_pressed() {
|
if !data.physics.on_ground || !data.inputs.secondary.is_pressed() {
|
||||||
if let Some(ItemKind::Tool(tool)) = data.stats.equipment.main.as_ref().map(|i| i.kind) {
|
attempt_wield(data, &mut update);
|
||||||
update.character = CharacterState::Equipping {
|
|
||||||
tool,
|
|
||||||
time_left: tool.equip_time(),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
update.character = CharacterState::Idle {};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
use super::utils::*;
|
use super::utils::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{CharacterState::*, HealthChange, HealthSource, StateUpdate},
|
||||||
ActionState::Attack, AttackKind::Charge, CharacterEntityData, HealthChange, HealthSource,
|
|
||||||
ItemKind::Tool, MoveState::Run, StateUpdate, ToolData,
|
|
||||||
},
|
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
sys::character_behavior::JoinData,
|
sys::character_behavior::JoinData,
|
||||||
};
|
};
|
||||||
use std::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;
|
||||||
@ -18,45 +15,49 @@ pub fn behavior(data: &JoinData) -> StateUpdate {
|
|||||||
vel: *data.vel,
|
vel: *data.vel,
|
||||||
ori: *data.ori,
|
ori: *data.ori,
|
||||||
character: *data.character,
|
character: *data.character,
|
||||||
|
energy: *data.energy,
|
||||||
|
local_events: VecDeque::new(),
|
||||||
|
server_events: VecDeque::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Move player
|
if let ChargeAttack { remaining_duration } = data.character {
|
||||||
update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z)
|
// Move player
|
||||||
+ (update.vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z)
|
||||||
+ 1.5 * data.inputs.move_dir.try_normalized().unwrap_or_default())
|
+ (update.vel.0 * Vec3::new(1.0, 1.0, 0.0)
|
||||||
.try_normalized()
|
+ 1.5 * data.inputs.move_dir.try_normalized().unwrap_or_default())
|
||||||
.unwrap_or_default()
|
.try_normalized()
|
||||||
* CHARGE_SPEED;
|
.unwrap_or_default()
|
||||||
|
* CHARGE_SPEED;
|
||||||
|
|
||||||
// Check if hitting another entity
|
// Check if hitting another entity
|
||||||
if let Some(uid_b) = data.physics.touch_entity {
|
if let Some(uid_b) = data.physics.touch_entity {
|
||||||
// Send Damage event
|
// Send Damage event
|
||||||
data.server_bus.emitter().emit(ServerEvent::Damage {
|
update.server_events.push_front(ServerEvent::Damage {
|
||||||
uid: uid_b,
|
uid: uid_b,
|
||||||
change: HealthChange {
|
change: HealthChange {
|
||||||
amount: -20,
|
amount: -20,
|
||||||
cause: HealthSource::Attack { by: *data.uid },
|
cause: HealthSource::Attack { by: *data.uid },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Go back to wielding or idling
|
// Go back to wielding or idling
|
||||||
update.character.action_state = attempt_wield(data.stats);
|
attempt_wield(data, &mut update);
|
||||||
return update;
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if charge timed out or can't keep moving forward
|
||||||
|
if *remaining_duration == Duration::default() || update.vel.0.magnitude_squared() < 10.0 {
|
||||||
|
attempt_wield(data, &mut update);
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tick remaining-duration and keep charging
|
||||||
|
update.character = ChargeAttack {
|
||||||
|
remaining_duration: remaining_duration
|
||||||
|
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if charge timed out or can't keep moving forward
|
|
||||||
if self.remaining_duration == Duration::default() || update.vel.0.magnitude_squared() < 10.0 {
|
|
||||||
update.character.action_state = attempt_wield(data.stats);
|
|
||||||
return update;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tick remaining-duration and keep charging
|
|
||||||
update.character.action_state = Attack(Charge(Some(State {
|
|
||||||
remaining_duration: self
|
|
||||||
.remaining_duration
|
|
||||||
.checked_sub(Duration::from_secs_f32(data.dt.0))
|
|
||||||
.unwrap_or_default(),
|
|
||||||
})));
|
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Module declarations
|
// Module declarations
|
||||||
pub mod basic_attack;
|
pub mod basic_attack;
|
||||||
pub mod basic_block;
|
pub mod basic_block;
|
||||||
|
pub mod charge_attack;
|
||||||
pub mod climb;
|
pub mod climb;
|
||||||
pub mod equipping;
|
pub mod equipping;
|
||||||
pub mod glide;
|
pub mod glide;
|
||||||
|
@ -105,19 +105,26 @@ fn swim_move(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// First checks whether `primary` input is pressed, then
|
||||||
|
/// attempts to go into Equipping state, otherwise Idle
|
||||||
pub fn handle_wield(data: &JoinData, update: &mut StateUpdate) {
|
pub fn handle_wield(data: &JoinData, update: &mut StateUpdate) {
|
||||||
if data.inputs.primary.is_pressed() {
|
if data.inputs.primary.is_pressed() {
|
||||||
if let Some(Tool(tool)) = data.stats.equipment.main.as_ref().map(|i| i.kind) {
|
attempt_wield(data, update);
|
||||||
update.character = CharacterState::Equipping {
|
|
||||||
tool,
|
|
||||||
time_left: tool.equip_time(),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
update.character = CharacterState::Idle {};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If a tool is equipped, goes into Equipping state, otherwise goes to Idle
|
||||||
|
pub fn attempt_wield(data: &JoinData, update: &mut StateUpdate) {
|
||||||
|
if let Some(Tool(tool)) = data.stats.equipment.main.as_ref().map(|i| i.kind) {
|
||||||
|
update.character = CharacterState::Equipping {
|
||||||
|
tool,
|
||||||
|
time_left: tool.equip_time(),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
update.character = CharacterState::Idle {};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_sit(data: &JoinData, update: &mut StateUpdate) {
|
pub fn handle_sit(data: &JoinData, update: &mut StateUpdate) {
|
||||||
if data.inputs.sit.is_pressed() && data.physics.on_ground && data.body.is_humanoid() {
|
if data.inputs.sit.is_pressed() && data.physics.on_ground && data.body.is_humanoid() {
|
||||||
update.character = CharacterState::Sit {};
|
update.character = CharacterState::Sit {};
|
||||||
@ -226,5 +233,8 @@ pub fn character_state_from_ability(
|
|||||||
AbilityState::Roll { .. } => CharacterState::Roll {
|
AbilityState::Roll { .. } => CharacterState::Roll {
|
||||||
remaining_duration: Duration::from_millis(600),
|
remaining_duration: Duration::from_millis(600),
|
||||||
},
|
},
|
||||||
|
AbilityState::ChargeAttack { .. } => CharacterState::ChargeAttack {
|
||||||
|
remaining_duration: Duration::from_millis(600),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,26 @@ use super::utils::*;
|
|||||||
use crate::{comp::StateUpdate, sys::character_behavior::JoinData};
|
use crate::{comp::StateUpdate, sys::character_behavior::JoinData};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
pub fn behavior(ecs_data: &JoinData) -> StateUpdate {
|
pub fn behavior(data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate {
|
let mut update = StateUpdate {
|
||||||
character: *ecs_data.character,
|
character: *data.character,
|
||||||
pos: *ecs_data.pos,
|
pos: *data.pos,
|
||||||
vel: *ecs_data.vel,
|
vel: *data.vel,
|
||||||
ori: *ecs_data.ori,
|
ori: *data.ori,
|
||||||
energy: *ecs_data.energy,
|
energy: *data.energy,
|
||||||
local_events: VecDeque::new(),
|
local_events: VecDeque::new(),
|
||||||
server_events: VecDeque::new(),
|
server_events: VecDeque::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
handle_move(&ecs_data, &mut update);
|
handle_move(&data, &mut update);
|
||||||
handle_jump(&ecs_data, &mut update);
|
handle_jump(&data, &mut update);
|
||||||
handle_sit(&ecs_data, &mut update);
|
handle_sit(&data, &mut update);
|
||||||
handle_climb(&ecs_data, &mut update);
|
handle_climb(&data, &mut update);
|
||||||
handle_glide(&ecs_data, &mut update);
|
handle_glide(&data, &mut update);
|
||||||
handle_unwield(&ecs_data, &mut update);
|
handle_unwield(&data, &mut update);
|
||||||
handle_primary(&ecs_data, &mut update);
|
handle_primary(&data, &mut update);
|
||||||
handle_secondary(&ecs_data, &mut update);
|
handle_secondary(&data, &mut update);
|
||||||
handle_dodge(&ecs_data, &mut update);
|
handle_dodge(&data, &mut update);
|
||||||
|
|
||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
CharacterState::Equipping { .. } => states::equipping::behavior(&j),
|
CharacterState::Equipping { .. } => states::equipping::behavior(&j),
|
||||||
CharacterState::BasicAttack { .. } => states::basic_attack::behavior(&j),
|
CharacterState::BasicAttack { .. } => states::basic_attack::behavior(&j),
|
||||||
CharacterState::BasicBlock { .. } => states::basic_block::behavior(&j),
|
CharacterState::BasicBlock { .. } => states::basic_block::behavior(&j),
|
||||||
|
CharacterState::ChargeAttack { .. } => states::charge_attack::behavior(&j),
|
||||||
CharacterState::Sit { .. } => states::sit::behavior(&j),
|
CharacterState::Sit { .. } => states::sit::behavior(&j),
|
||||||
|
|
||||||
// _ => StateUpdate {
|
// _ => StateUpdate {
|
||||||
|
Loading…
Reference in New Issue
Block a user