add triple strike timing

This commit is contained in:
AdamWhitehurst 2020-03-27 10:40:15 -07:00
parent 4bfc934772
commit 2ffac59aa3
3 changed files with 66 additions and 28 deletions

View File

@ -47,6 +47,7 @@ pub enum CharacterAbility {
},
TripleStrike {
base_damage: u32,
needs_timing: bool,
},
}
@ -55,7 +56,7 @@ impl CharacterAbility {
/// applicable.
pub fn requirements_paid(&self, data: &JoinData, update: &mut StateUpdate) -> bool {
match self {
CharacterAbility::TripleStrike { .. } => {
CharacterAbility::TimedCombo { .. } | CharacterAbility::TripleStrike { .. } => {
data.physics.on_ground
&& data.body.is_humanoid()
&& data.inputs.look_dir.xy().magnitude_squared() > 0.01
@ -179,16 +180,20 @@ impl From<&CharacterAbility> for CharacterState {
stage_time_active: Duration::default(),
base_damage: *base_damage,
}),
CharacterAbility::TripleStrike { base_damage } => {
CharacterState::TripleStrike(triple_strike::Data {
base_damage: *base_damage,
stage: triple_strike::Stage::First,
stage_exhausted: false,
stage_time_active: Duration::default(),
should_transition: true,
initialized: false,
})
},
CharacterAbility::TripleStrike {
base_damage,
needs_timing,
} => CharacterState::TripleStrike(triple_strike::Data {
base_damage: *base_damage,
stage: triple_strike::Stage::First,
stage_exhausted: false,
stage_time_active: Duration::default(),
needs_timing: *needs_timing,
// If `needs_timing`, prevent tansitioning by default,
// unless pressed at the right time.
should_transition: !*needs_timing,
initialized: false,
}),
}
}
}

View File

@ -70,11 +70,17 @@ impl ToolData {
use ToolKind::*;
match self.kind {
Sword(_) => vec![TripleStrike { base_damage: 5 }, DashMelee {
buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500),
base_damage: 10,
}],
Sword(_) => vec![
TripleStrike {
base_damage: 5,
needs_timing: false,
},
DashMelee {
buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500),
base_damage: 10,
},
],
Axe(_) => vec![BasicMelee {
energy_cost: 0,
buildup_duration: Duration::from_millis(700),
@ -83,14 +89,20 @@ impl ToolData {
range: 3.5,
max_angle: 30.0,
}],
Hammer(_) => vec![BasicMelee {
energy_cost: 0,
buildup_duration: Duration::from_millis(700),
recover_duration: Duration::from_millis(300),
base_healthchange: -10,
range: 3.5,
max_angle: 60.0,
}],
Hammer(_) => vec![
BasicMelee {
energy_cost: 0,
buildup_duration: Duration::from_millis(700),
recover_duration: Duration::from_millis(300),
base_healthchange: -10,
range: 3.5,
max_angle: 60.0,
},
TripleStrike {
base_damage: 7,
needs_timing: true,
},
],
Bow(_) => vec![BasicRanged {
energy_cost: 0,
holdable: true,

View File

@ -8,7 +8,6 @@ use vek::vec::Vec3;
// In millis
const STAGE_DURATION: u64 = 700;
const INITIAL_ACCEL: f32 = 90.0;
const BASE_SPEED: f32 = 25.0;
@ -39,6 +38,10 @@ pub struct Data {
pub should_transition: bool,
/// Whether state has performed intialization logic
pub initialized: bool,
/// Whether player must time button pressed properly to continue combo
pub needs_timing: bool,
/* /// Set to prevent transitioning, true by default when `needs_timing`
* pub prevent_transition: bool, */
}
impl CharacterBehavior for Data {
@ -50,9 +53,6 @@ impl CharacterBehavior for Data {
.checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or(Duration::default());
// If player stops holding input, don't go to the next stage
let should_transition = data.inputs.primary.is_pressed() && self.should_transition;
if !self.initialized {
update.vel.0 = Vec3::zero();
if let Some(dir) = data.inputs.look_dir.try_normalized() {
@ -61,6 +61,24 @@ impl CharacterBehavior for Data {
}
let initialized = true;
// If player stops holding input, don't go to the next stage
let mut should_transition = self.should_transition;
// Check inputs based on whether `needs_timing`
if self.needs_timing {
// Player must press at right time
if data.inputs.primary.is_pressed()
&& stage_time_active > Duration::from_millis(STAGE_DURATION * 0.7)
{
should_transition = true;
}
} else {
// Prevent transitioning if player ever stops holding input
if !data.inputs.primary.is_pressed() {
should_transition = false;
}
}
// Handle hit applied
if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 {
@ -125,6 +143,7 @@ impl CharacterBehavior for Data {
stage_exhausted: true,
should_transition,
initialized,
needs_timing: self.needs_timing,
})
} else if stage_time_active > Duration::from_millis(STAGE_DURATION) {
let next_stage = match self.stage {
@ -142,6 +161,7 @@ impl CharacterBehavior for Data {
stage_exhausted: false,
should_transition,
initialized,
needs_timing: self.needs_timing,
})
} else {
// Make sure attack component is removed
@ -157,6 +177,7 @@ impl CharacterBehavior for Data {
stage_exhausted: self.stage_exhausted,
should_transition,
initialized,
needs_timing: self.needs_timing,
})
};