83 lines
2.4 KiB
Rust
83 lines
2.4 KiB
Rust
use crate::{
|
|
fighter::{
|
|
animation::AnimKind,
|
|
collision,
|
|
state::{
|
|
FighterState, FighterStateContext, FighterStateImpl, air,
|
|
fall::FallState,
|
|
ground::GroundedStateCommon,
|
|
land::{LandingState, LandingType},
|
|
},
|
|
},
|
|
input,
|
|
math::vec::FGVec2,
|
|
};
|
|
|
|
#[derive(Debug, Clone, Hash)]
|
|
pub struct AirDodgeState {
|
|
pub direction: FGVec2,
|
|
}
|
|
|
|
impl FighterStateImpl for AirDodgeState {
|
|
const NAME: &'static str = "AirDodge";
|
|
|
|
fn check_interrupt(&self, state_context: &mut FighterStateContext) -> Option<FighterState> {
|
|
if state_context.is_current_animation_finished() {
|
|
Some(FighterState::Fall(FallState))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn update(&mut self, state_context: &mut FighterStateContext) {
|
|
state_context.velocity.0 *= state_context.fighter_manifest.attributes.air_dodge_decay;
|
|
|
|
air::apply_air_motion(
|
|
state_context.velocity,
|
|
state_context.translation,
|
|
state_context.prev_translation,
|
|
);
|
|
}
|
|
|
|
fn check_collision_interrupt(
|
|
&mut self,
|
|
state_context: &mut FighterStateContext,
|
|
) -> Option<FighterState> {
|
|
if let Some(res) = collision::air_collide_with_stage(state_context) {
|
|
// Adjust translation
|
|
state_context.translation.0 = res.hit_position - state_context.ecb.get_bottom_point();
|
|
let grounded_common = GroundedStateCommon {
|
|
current_line_id: res.line_id,
|
|
};
|
|
Some(FighterState::Land(LandingState {
|
|
grounded_common,
|
|
landing_type: LandingType::Special,
|
|
}))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn on_enter(&mut self, state_context: &mut FighterStateContext) {
|
|
state_context.play_animation(AnimKind::AirDodge, false);
|
|
|
|
state_context.velocity.0 =
|
|
self.direction * state_context.fighter_manifest.attributes.air_dodge_velocity;
|
|
}
|
|
}
|
|
|
|
pub fn check_input(state_context: &FighterStateContext) -> Option<FighterState> {
|
|
state_context
|
|
.input
|
|
.has_command(input::FighterCommands::Shield)
|
|
.then(|| {
|
|
FighterState::AirDodge(AirDodgeState {
|
|
direction: state_context
|
|
.input
|
|
.get_last_frame()
|
|
.movement
|
|
.normalize_or_zero(),
|
|
})
|
|
})
|
|
}
|