use super::{CollisionContext, EnterContext, FighterStateImpl, InterruptContext, UpdateContext}; use crate::fighter::animation::AnimKind; use crate::fighter::state::ground; use crate::fighter::state::{FighterState, dash, jump, wait, walk}; use crate::input::FighterCommands; #[derive(Debug, Clone, Hash)] pub struct TurnState; impl FighterStateImpl for TurnState { const NAME: &'static str = "Turn"; fn check_interrupt(&self, state_context: &mut InterruptContext) -> Option { // State chain that results in the turn completing if state_context.get_current_animation_frame() <= state_context .game_settings .input_common .turn_into_dashback_window as u32 { if let Some(state) = dash::check_input(state_context) { return Some(state); } } if let Some(state) = jump::check_input(state_context) { *state_context.facing_direction = state_context.facing_direction.reverse(); Some(state) } else if state_context.is_current_animation_finished() { if let Some(state) = dash::check_input(state_context) { Some(state) } else if let Some(state) = walk::check_input(state_context) { Some(state) } else if let Some(state) = wait::check_input(state_context) { Some(state) } else { None } } else { None } } fn on_enter(&mut self, state_context: &mut EnterContext) { state_context.play_animation(AnimKind::Turn, false); *state_context.facing_direction = state_context.facing_direction.reverse(); } fn update(&mut self, state_context: &mut UpdateContext) { ground::update_friction_motion(state_context); } fn check_collision_interrupt( &mut self, state_context: &mut CollisionContext, ) -> Option { ground::collision_interrupt(state_context, false) } fn is_visually_grounded<'a>(&'a self) -> bool { true } } pub fn check_input(state_context: &InterruptContext) -> Option { let input_frame = state_context.input.get_last_frame(); let has_smash_input = state_context .input .has_command(FighterCommands::SmashMoveLeft) || state_context .input .has_command(FighterCommands::SmashMoveRight); if !input_frame.movement.x.is_zero() && input_frame.movement.x.signum() != state_context.facing_direction.to_sign() && !has_smash_input { return Some(FighterState::Turn(TurnState)); } None }