Begin implementing triple attack

This commit is contained in:
Adam Whitehurst 2020-03-08 12:37:17 -07:00
parent fe1feebeb2
commit 5f8751e2d3
7 changed files with 142 additions and 11 deletions

View File

@ -6,6 +6,7 @@ pub enum AbilityState {
BasicBlock,
Roll,
ChargeAttack,
TripleAttack,
}
impl Default for AbilityState {
fn default() -> Self { Self::BasicAttack }
@ -27,7 +28,8 @@ impl Default for AbilityPool {
fn default() -> Self {
Self {
primary: Some(AbilityState::BasicAttack),
secondary: Some(AbilityState::ChargeAttack),
// primary: Some(AbilityState::TripleAttack),
secondary: Some(AbilityState::BasicBlock),
block: None,
dodge: Some(AbilityState::Roll),
}

View File

@ -50,6 +50,20 @@ pub enum CharacterState {
/// How long the state has until exiting
remaining_duration: Duration,
},
/// A three-stage attack where play must click at appropriate times
/// to continue attack chain.
TripleAttack {
/// 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,
/// Whether player has clicked at the proper time to go to next stage
can_transition: bool,
},
}
impl CharacterState {

View File

@ -1,8 +1,5 @@
use super::utils::*;
use crate::{
comp::{CharacterState, ItemKind, StateUpdate},
sys::character_behavior::JoinData,
};
use crate::{comp::StateUpdate, sys::character_behavior::JoinData};
use std::collections::VecDeque;
// const BLOCK_ACCEL: f32 = 30.0;

View File

@ -8,5 +8,6 @@ pub mod glide;
pub mod idle;
pub mod roll;
pub mod sit;
pub mod triple_attack;
pub mod utils;
pub mod wielding;

View File

@ -0,0 +1,92 @@
use crate::{
comp::{Attacking, CharacterState, ItemKind::Tool, StateUpdate},
states::utils::*,
sys::character_behavior::JoinData,
};
use std::{collections::VecDeque, time::Duration};
pub fn behavior(data: &JoinData) -> StateUpdate {
let mut update = StateUpdate {
pos: *data.pos,
vel: *data.vel,
ori: *data.ori,
energy: *data.energy,
character: *data.character,
local_events: VecDeque::new(),
server_events: VecDeque::new(),
};
if let CharacterState::TripleAttack {
tool,
stage,
stage_time_active,
stage_exhausted,
can_transition,
} = data.character
{
let mut new_can_transition = *can_transition;
let mut new_stage_exhausted = *stage_exhausted;
let new_stage_time_active = stage_time_active
.checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or(Duration::default());
match stage {
1 => {
if new_stage_time_active > tool.attack_buildup_duration() {
if !*stage_exhausted {
// Try to deal damage
data.updater.insert(data.entity, Attacking {
weapon: Some(*tool),
});
new_stage_exhausted = true;
} else {
// Make sure to remove Attacking component
data.updater.remove::<Attacking>(data.entity);
}
// Check if player has timed click right
if data.inputs.primary.is_just_pressed() {
println!("Can transition");
new_can_transition = true;
}
}
if new_stage_time_active > tool.attack_duration() {
if new_can_transition {
update.character = CharacterState::TripleAttack {
tool: *tool,
stage: 2,
stage_time_active: Duration::default(),
stage_exhausted: false,
can_transition: false,
}
} else {
println!("Failed");
attempt_wield(data, &mut update);
}
} else {
update.character = CharacterState::TripleAttack {
tool: *tool,
stage: 1,
stage_time_active: new_stage_time_active,
stage_exhausted: new_stage_exhausted,
can_transition: new_can_transition,
}
}
},
2 => {
println!("2");
attempt_wield(data, &mut update);
},
3 => {
println!("3");
attempt_wield(data, &mut update);
},
_ => {
// Should never get here.
},
}
}
update
}

View File

@ -1,11 +1,12 @@
use crate::{
comp::{AbilityState, CharacterState, EnergySource, ItemKind::Tool, StateUpdate},
comp::{AbilityState, CharacterState, EnergySource, ItemKind::Tool, StateUpdate, ToolData},
event::LocalEvent,
sys::{character_behavior::JoinData, phys::GRAVITY},
};
use std::time::Duration;
use vek::vec::{Vec2, Vec3};
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
const BASE_HUMANOID_ACCEL: f32 = 100.0;
const BASE_HUMANOID_SPEED: f32 = 150.0;
const BASE_HUMANOID_AIR_ACCEL: f32 = 15.0;
@ -24,8 +25,6 @@ const BASE_HUMANOID_WATER_SPEED: f32 = 120.0;
// const CLIMB_SPEED: f32 = 5.0;
// const CLIMB_COST: i32 = 5;
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
/// Handles updating `Components` to move player based on state of `JoinData`
pub fn handle_move(data: &JoinData, update: &mut StateUpdate) {
if data.physics.in_fluid {
@ -231,7 +230,7 @@ pub fn attempt_dodge_ability(data: &JoinData, update: &mut StateUpdate) {
}
}
// TODO: This might need a CharacterState::new(data, update) fn if
// TODO: Wight need a fn `CharacterState::new(data, update)` if
// initialization gets too lengthy.
/// Maps from `AbilityState`s to `CharacterStates`s. Also handles intializing
@ -239,13 +238,13 @@ pub fn attempt_dodge_ability(data: &JoinData, update: &mut StateUpdate) {
pub fn ability_to_character_state(data: &JoinData, ability_state: AbilityState) -> CharacterState {
match ability_state {
AbilityState::BasicAttack { .. } => {
if let Some(Tool(tool)) = data.stats.equipment.main.as_ref().map(|i| i.kind) {
if let Some(tool) = get_tool_data(data) {
CharacterState::BasicAttack {
exhausted: false,
remaining_duration: tool.attack_duration(),
}
} else {
CharacterState::Idle {}
*data.character
}
},
AbilityState::BasicBlock { .. } => CharacterState::BasicBlock {},
@ -255,5 +254,29 @@ pub fn ability_to_character_state(data: &JoinData, ability_state: AbilityState)
AbilityState::ChargeAttack { .. } => CharacterState::ChargeAttack {
remaining_duration: Duration::from_millis(600),
},
AbilityState::TripleAttack { .. } => {
if let Some(tool) = get_tool_data(data) {
CharacterState::TripleAttack {
tool,
stage: 1,
stage_time_active: Duration::default(),
stage_exhausted: false,
can_transition: false,
}
} else {
*data.character
}
},
// Do not use default match
// _ => *data.character
}
}
pub fn get_tool_data(data: &JoinData) -> Option<ToolData> {
if let Some(Tool(tool)) = data.stats.equipment.main.as_ref().map(|i| i.kind) {
Some(tool)
} else {
None
}
}

View File

@ -171,7 +171,9 @@ impl<'a> System<'a> for Sys {
CharacterState::BasicBlock { .. } => states::basic_block::behavior(&j),
CharacterState::ChargeAttack { .. } => states::charge_attack::behavior(&j),
CharacterState::Sit { .. } => states::sit::behavior(&j),
CharacterState::TripleAttack { .. } => states::triple_attack::behavior(&j),
// Do not use default match.
// _ => StateUpdate {
// character: *j.character,
// pos: *j.pos,