diff --git a/src/fighter/state/air.rs b/src/fighter/state/air.rs index 9557897..a049269 100644 --- a/src/fighter/state/air.rs +++ b/src/fighter/state/air.rs @@ -1,3 +1,6 @@ +use crate::fighter::state::ground::GroundedStateCommon; +use crate::fighter::state::land::{LandingState, LandingType}; +use crate::fighter::state::{CollisionContext, FighterState}; use crate::fighter::*; pub fn integrate_gravity(velocity: &mut FighterVelocity, attributes: &FighterAttributes) { @@ -53,6 +56,27 @@ pub fn apply_air_motion( translation.0 += velocity.0; } +pub fn update_standard_motion(ctx: &mut crate::fighter::state::UpdateContext) { + integrate_gravity(ctx.velocity, ctx.fighter_attributes); + apply_air_drift(ctx.velocity, ctx.fighter_attributes, ctx.input); + apply_air_motion(ctx.velocity, ctx.translation, ctx.prev_translation); +} + +pub fn collision_interrupt( + ctx: &mut CollisionContext, + landing_type: LandingType, +) -> Option { + let res = ctx.air_collide_with_stage()?; + ctx.translation.0 = res.hit_position - ctx.ecb.get_bottom_point(); + let grounded_common = GroundedStateCommon { + current_line_id: res.line_id, + }; + Some(FighterState::Land(LandingState::create( + grounded_common, + landing_type, + ))) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/fighter/state/air_dodge.rs b/src/fighter/state/air_dodge.rs index 8a177cc..1eb5745 100644 --- a/src/fighter/state/air_dodge.rs +++ b/src/fighter/state/air_dodge.rs @@ -3,10 +3,7 @@ use crate::{ animation::AnimKind, state::{ CollisionContext, EnterContext, FighterState, FighterStateImpl, InterruptContext, - UpdateContext, air, - fall::FallState, - ground::GroundedStateCommon, - land::{LandingState, LandingType}, + UpdateContext, air, fall::FallState, land::LandingType, }, }, input, @@ -43,19 +40,7 @@ impl FighterStateImpl for AirDodgeState { &mut self, state_context: &mut CollisionContext, ) -> Option { - if let Some(res) = state_context.air_collide_with_stage() { - // 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 - } + air::collision_interrupt(state_context, LandingType::Special) } fn on_enter(&mut self, state_context: &mut EnterContext) { diff --git a/src/fighter/state/dash.rs b/src/fighter/state/dash.rs index 61eb325..3ec424e 100644 --- a/src/fighter/state/dash.rs +++ b/src/fighter/state/dash.rs @@ -5,8 +5,7 @@ use super::{ use crate::fighter::FighterFacingDirection; use crate::fighter::animation::AnimKind; use crate::fighter::state::FighterState; -use crate::fighter::state::fall::FallState; -use crate::fighter::state::ground::{GroundedMotionResult, GroundedStateCommon}; +use crate::fighter::state::ground::GroundedStateCommon; use crate::input::FighterCommands::{SmashMoveLeft, SmashMoveRight}; #[derive(Debug, Clone, Hash)] @@ -107,13 +106,7 @@ impl FighterStateImpl for DashState { &mut self, state_context: &mut CollisionContext, ) -> Option { - if let GroundedMotionResult::InAir = - ground::collide_with_stage_grounded(state_context, &mut self.ground_common, true) - { - Some(FighterState::Fall(FallState)) - } else { - None - } + ground::collision_interrupt(state_context, &mut self.ground_common, true) } } diff --git a/src/fighter/state/fall.rs b/src/fighter/state/fall.rs index 08f42ae..46c812a 100644 --- a/src/fighter/state/fall.rs +++ b/src/fighter/state/fall.rs @@ -1,7 +1,5 @@ use super::{CollisionContext, EnterContext, FighterStateImpl, InterruptContext, UpdateContext}; use crate::fighter::animation::AnimKind; -use crate::fighter::state::ground::GroundedStateCommon; -use crate::fighter::state::land::{LandingState, LandingType}; use crate::fighter::state::{FighterState, air, jump}; #[derive(Debug, Clone, Copy, Hash)] @@ -18,36 +16,17 @@ impl FighterStateImpl for FallState { } fn update(&mut self, state_context: &mut UpdateContext) { - air::integrate_gravity(state_context.velocity, state_context.fighter_attributes); - air::apply_air_drift( - state_context.velocity, - state_context.fighter_attributes, - state_context.input, - ); - air::apply_air_motion( - state_context.velocity, - state_context.translation, - state_context.prev_translation, - ); + air::update_standard_motion(state_context); } fn check_collision_interrupt( &mut self, state_context: &mut CollisionContext, ) -> Option { - if let Some(res) = state_context.air_collide_with_stage() { - // 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::create( - grounded_common, - LandingType::Normal, - ))) - } else { - None - } + air::collision_interrupt( + state_context, + crate::fighter::state::land::LandingType::Normal, + ) } } diff --git a/src/fighter/state/ground.rs b/src/fighter/state/ground.rs index c784b47..597548e 100644 --- a/src/fighter/state/ground.rs +++ b/src/fighter/state/ground.rs @@ -3,7 +3,7 @@ //! bit-for-bit deterministic for rollback. use crate::fighter::state::{ - CollisionContext, FighterState, InterruptContext, dash, ground_attack, turn, wait, walk, + CollisionContext, FighterState, InterruptContext, dash, fall, ground_attack, turn, wait, walk, }; use crate::fighter::{ FighterAttributes, FighterPreviousTranslation, FighterTranslation, FighterVelocity, @@ -163,6 +163,22 @@ pub fn apply_grounded_motion( translation.0 += FGVec2::new(velocity.0.x, FGi32::ZERO); } +pub fn update_friction_motion(ctx: &mut crate::fighter::state::UpdateContext) { + let friction = if ctx.velocity.x.abs() > ctx.fighter_attributes.max_walk_vel { + ctx.fighter_attributes.ground_friction + * ctx + .game_settings + .fighter_common + .ground_friction_over_walk_speed_multiplier + } else { + ctx.fighter_attributes.ground_friction + }; + + let ground_velocity = ctx.velocity.x; + ctx.velocity.x += apply_grounded_friction(friction, ground_velocity); + apply_grounded_motion(ctx.velocity, ctx.translation, ctx.prev_translation); +} + pub fn collide_with_stage_grounded( state_context: &mut CollisionContext, ground_common: &mut GroundedStateCommon, @@ -210,6 +226,17 @@ pub fn collide_with_stage_grounded( } } +pub fn collision_interrupt( + ctx: &mut CollisionContext, + common: &mut GroundedStateCommon, + can_walk_off: bool, +) -> Option { + match collide_with_stage_grounded(ctx, common, can_walk_off) { + GroundedMotionResult::InGround => None, + GroundedMotionResult::InAir => Some(FighterState::Fall(fall::FallState)), + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/fighter/state/hitstun.rs b/src/fighter/state/hitstun.rs index cbcd879..5112729 100644 --- a/src/fighter/state/hitstun.rs +++ b/src/fighter/state/hitstun.rs @@ -6,8 +6,8 @@ use crate::{ CollisionContext, EnterContext, ExitContext, FighterState, FighterStateImpl, InterruptContext, UpdateContext, air, fall::FallState, - ground::{GroundedMotionResult, GroundedStateCommon, collide_with_stage_grounded}, - land::{LandingState, LandingType}, + ground::{GroundedStateCommon, collision_interrupt}, + land::LandingType, wait::WaitState, }, }, @@ -88,29 +88,10 @@ impl FighterStateImpl for HitstunState { ) -> Option { match &mut self.hitstop_kind { HitstopStateKind::Grounded(grounded_state_common) => { - if let GroundedMotionResult::InAir = - collide_with_stage_grounded(state_context, grounded_state_common, true) - { - Some(FighterState::Fall(FallState {})) - } else { - None - } + collision_interrupt(state_context, grounded_state_common, true) } HitstopStateKind::Airborne => { - if let Some(res) = state_context.air_collide_with_stage() { - // 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::create( - grounded_common, - LandingType::Normal, - ))) - } else { - None - } + air::collision_interrupt(state_context, LandingType::Normal) } } } diff --git a/src/fighter/state/jump.rs b/src/fighter/state/jump.rs index a6d5e03..1c773c8 100644 --- a/src/fighter/state/jump.rs +++ b/src/fighter/state/jump.rs @@ -7,9 +7,7 @@ use crate::{ CollisionContext, EnterContext, FighterState, FighterStateImpl, InterruptContext, UpdateContext, air, air_dodge::{self, AirDodgeState}, - fall::FallState, - ground::{self, GroundedMotionResult, GroundedStateCommon}, - land::{LandingState, LandingType}, + ground::{self, GroundedStateCommon}, }, }, input::FighterCommands, @@ -84,40 +82,14 @@ impl FighterStateImpl for JumpSquatState { fn update(&mut self, state_context: &mut UpdateContext) { self.duration_counter += 1; - - let friction = - if state_context.velocity.x.abs() > state_context.fighter_attributes.max_walk_vel { - state_context.fighter_attributes.ground_friction - * state_context - .game_settings - .fighter_common - .ground_friction_over_walk_speed_multiplier - } else { - state_context.fighter_attributes.ground_friction - }; - - let ground_velocity = state_context.velocity.x; - - state_context.velocity.x += ground::apply_grounded_friction(friction, ground_velocity); - - ground::apply_grounded_motion( - state_context.velocity, - state_context.translation, - state_context.prev_translation, - ); + ground::update_friction_motion(state_context); } fn check_collision_interrupt( &mut self, state_context: &mut CollisionContext, ) -> Option { - if let GroundedMotionResult::InAir = - ground::collide_with_stage_grounded(state_context, &mut self.grounded_common, false) - { - Some(FighterState::Fall(FallState)) - } else { - None - } + ground::collision_interrupt(state_context, &mut self.grounded_common, false) } fn on_enter(&mut self, state_context: &mut EnterContext) { @@ -139,17 +111,7 @@ impl FighterStateImpl for JumpState { } fn update(&mut self, state_context: &mut UpdateContext) { - air::integrate_gravity(state_context.velocity, state_context.fighter_attributes); - air::apply_air_drift( - state_context.velocity, - state_context.fighter_attributes, - state_context.input, - ); - air::apply_air_motion( - state_context.velocity, - state_context.translation, - state_context.prev_translation, - ); + air::update_standard_motion(state_context); } fn on_enter(&mut self, state_context: &mut EnterContext) { @@ -207,19 +169,10 @@ impl FighterStateImpl for JumpState { &mut self, state_context: &mut CollisionContext, ) -> Option { - if let Some(res) = state_context.air_collide_with_stage() { - // 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::create( - grounded_common, - LandingType::Normal, - ))) - } else { - None - } + air::collision_interrupt( + state_context, + crate::fighter::state::land::LandingType::Normal, + ) } } diff --git a/src/fighter/state/land.rs b/src/fighter/state/land.rs index e4df973..7989171 100644 --- a/src/fighter/state/land.rs +++ b/src/fighter/state/land.rs @@ -3,11 +3,7 @@ use crate::fighter::{ state::{ CollisionContext, EnterContext, FighterState, FighterStateImpl, InterruptContext, UpdateContext, dash, - fall::FallState, - ground::{ - self, GroundedMotionResult, GroundedStateCommon, - grounded_movement_standstill_common_interrupts, - }, + ground::{self, GroundedStateCommon, grounded_movement_standstill_common_interrupts}, walk, }, }; @@ -53,39 +49,14 @@ impl FighterStateImpl for LandingState { } fn update(&mut self, state_context: &mut UpdateContext) { - let friction = - if state_context.velocity.x.abs() > state_context.fighter_attributes.max_walk_vel { - state_context.fighter_attributes.ground_friction - * state_context - .game_settings - .fighter_common - .ground_friction_over_walk_speed_multiplier - } else { - state_context.fighter_attributes.ground_friction - }; - - let ground_velocity = state_context.velocity.x; - - state_context.velocity.x += ground::apply_grounded_friction(friction, ground_velocity); - - ground::apply_grounded_motion( - state_context.velocity, - state_context.translation, - state_context.prev_translation, - ); + ground::update_friction_motion(state_context); } fn check_collision_interrupt( &mut self, state_context: &mut CollisionContext, ) -> Option { - if let GroundedMotionResult::InAir = - ground::collide_with_stage_grounded(state_context, &mut self.grounded_common, true) - { - Some(FighterState::Fall(FallState)) - } else { - None - } + ground::collision_interrupt(state_context, &mut self.grounded_common, true) } fn on_enter(&mut self, state_context: &mut EnterContext) { diff --git a/src/fighter/state/run.rs b/src/fighter/state/run.rs index 6d5d26a..afb40d6 100644 --- a/src/fighter/state/run.rs +++ b/src/fighter/state/run.rs @@ -6,9 +6,7 @@ use super::{ }; use crate::fighter::animation::AnimKind; use crate::fighter::state::FighterState; -use crate::fighter::state::fall::FallState; -use crate::fighter::state::ground::{GroundedMotionResult, GroundedStateCommon}; -use crate::math::int::FGi32; +use crate::fighter::state::ground::GroundedStateCommon; #[derive(Component, Debug, Clone, Hash)] pub struct RunState { @@ -64,13 +62,7 @@ impl FighterStateImpl for RunState { &mut self, state_context: &mut CollisionContext, ) -> Option { - if let GroundedMotionResult::InAir = - ground::collide_with_stage_grounded(state_context, &mut self.grounded_common, false) - { - Some(FighterState::Fall(FallState)) - } else { - None - } + ground::collision_interrupt(state_context, &mut self.grounded_common, true) } } diff --git a/src/fighter/state/turn.rs b/src/fighter/state/turn.rs index a24d242..05a10b3 100644 --- a/src/fighter/state/turn.rs +++ b/src/fighter/state/turn.rs @@ -1,7 +1,6 @@ use super::{CollisionContext, EnterContext, FighterStateImpl, InterruptContext, UpdateContext}; use crate::fighter::animation::AnimKind; -use crate::fighter::state::fall::FallState; -use crate::fighter::state::ground::{self, GroundedMotionResult, GroundedStateCommon}; +use crate::fighter::state::ground::{self, GroundedStateCommon}; use crate::fighter::state::{FighterState, dash, jump, wait, walk}; use crate::input::FighterCommands; @@ -48,39 +47,14 @@ impl FighterStateImpl for TurnState { } fn update(&mut self, state_context: &mut UpdateContext) { - let friction = - if state_context.velocity.x.abs() > state_context.fighter_attributes.max_walk_vel { - state_context.fighter_attributes.ground_friction - * state_context - .game_settings - .fighter_common - .ground_friction_over_walk_speed_multiplier - } else { - state_context.fighter_attributes.ground_friction - }; - - let ground_velocity = state_context.velocity.x; - - state_context.velocity.x += ground::apply_grounded_friction(friction, ground_velocity); - - ground::apply_grounded_motion( - state_context.velocity, - state_context.translation, - state_context.prev_translation, - ); + ground::update_friction_motion(state_context); } fn check_collision_interrupt( &mut self, state_context: &mut CollisionContext, ) -> Option { - if let GroundedMotionResult::InAir = - ground::collide_with_stage_grounded(state_context, &mut self.grounded_common, false) - { - Some(FighterState::Fall(FallState)) - } else { - None - } + ground::collision_interrupt(state_context, &mut self.grounded_common, false) } } diff --git a/src/fighter/state/wait.rs b/src/fighter/state/wait.rs index 6b0bf57..d4327d8 100644 --- a/src/fighter/state/wait.rs +++ b/src/fighter/state/wait.rs @@ -3,8 +3,7 @@ use super::{ }; use crate::fighter::animation::AnimKind; use crate::fighter::state::FighterState; -use crate::fighter::state::fall::FallState; -use crate::fighter::state::ground::{GroundedMotionResult, GroundedStateCommon}; +use crate::fighter::state::ground::GroundedStateCommon; #[derive(Debug, Clone, Hash)] pub struct WaitState { @@ -38,39 +37,14 @@ impl FighterStateImpl for WaitState { } fn update(&mut self, state_context: &mut UpdateContext) { - let friction = - if state_context.velocity.x.abs() > state_context.fighter_attributes.max_walk_vel { - state_context.fighter_attributes.ground_friction - * state_context - .game_settings - .fighter_common - .ground_friction_over_walk_speed_multiplier - } else { - state_context.fighter_attributes.ground_friction - }; - - let ground_velocity = state_context.velocity.x; - - state_context.velocity.x += ground::apply_grounded_friction(friction, ground_velocity); - - ground::apply_grounded_motion( - state_context.velocity, - state_context.translation, - state_context.prev_translation, - ); + ground::update_friction_motion(state_context); } fn check_collision_interrupt( &mut self, state_context: &mut CollisionContext, ) -> Option { - if let GroundedMotionResult::InAir = - ground::collide_with_stage_grounded(state_context, &mut self.grounded_common, false) - { - Some(FighterState::Fall(FallState)) - } else { - None - } + ground::collision_interrupt(state_context, &mut self.grounded_common, false) } } diff --git a/src/fighter/state/walk.rs b/src/fighter/state/walk.rs index 8fa2f42..dc8814e 100644 --- a/src/fighter/state/walk.rs +++ b/src/fighter/state/walk.rs @@ -4,8 +4,7 @@ use super::{ }; use crate::fighter::animation::AnimKind; use crate::fighter::state::FighterState; -use crate::fighter::state::fall::FallState; -use crate::fighter::state::ground::{GroundedMotionResult, GroundedStateCommon}; +use crate::fighter::state::ground::GroundedStateCommon; #[derive(Debug, Clone, Hash)] pub struct WalkState { @@ -55,13 +54,7 @@ impl FighterStateImpl for WalkState { &mut self, state_context: &mut CollisionContext, ) -> Option { - if let GroundedMotionResult::InAir = - ground::collide_with_stage_grounded(state_context, &mut self.grounded_common, false) - { - Some(FighterState::Fall(FallState)) - } else { - None - } + ground::collision_interrupt(state_context, &mut self.grounded_common, false) } }