use crate::fighter::{ animation::AnimKind, state::{ CollisionContext, EnterContext, FighterState, FighterStateImpl, InterruptContext, UpdateContext, dash, ground::{self, GroundedStateCommon, grounded_movement_standstill_common_interrupts}, walk, }, }; #[derive(Debug, Clone, Hash)] pub enum LandingType { Normal, Special, } #[derive(Debug, Clone, Hash)] pub struct LandingState { pub grounded_common: GroundedStateCommon, pub landing_type: LandingType, } impl LandingState { pub fn create(grounded_common: GroundedStateCommon, landing_type: LandingType) -> Self { Self { grounded_common, landing_type, } } } impl FighterStateImpl for LandingState { const NAME: &'static str = "Landing"; fn check_interrupt(&self, state_context: &mut InterruptContext) -> Option { if state_context.is_current_animation_finished() { grounded_movement_standstill_common_interrupts(state_context, &self.grounded_common) } else if state_context.get_current_animation_frame() >= state_context.fighter_attributes.landing_iasa && let LandingType::Normal = self.landing_type { dash::check_input(state_context, &self.grounded_common).or_else(|| { ground::grounded_movement_common_interrupts(state_context, &self.grounded_common) .or_else(|| walk::check_input(state_context, &self.grounded_common)) }) } else { None } } 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, &mut self.grounded_common, true) } fn on_enter(&mut self, state_context: &mut EnterContext) { match self.landing_type { LandingType::Normal => { state_context.play_animation(AnimKind::Landing, false); } LandingType::Special => { state_context.play_animation(AnimKind::LandingSpecial, false); } }; } fn is_visually_grounded<'a>( &'a self, ) -> bool { true } }