From 42945449445fa3c3b3f3f8b52918e8cb8b976f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20Rom=C3=A1n=20N=C3=BA=C3=B1ez?= Date: Tue, 13 Oct 2026 23:16:08 +0200 Subject: [PATCH] Fix unit tests and remove advanced_ecb --- src/fighter/state/air.rs | 1 + src/fighter/state/air_dodge.rs | 2 +- src/fighter/state/angel.rs | 5 +++-- src/fighter/state/ground.rs | 7 ++----- src/fighter/state/ledge_action.rs | 3 ++- src/fighter/state/ledge_wait.rs | 3 ++- src/fighter/state/mod.rs | 33 ++++++++----------------------- 7 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/fighter/state/air.rs b/src/fighter/state/air.rs index e8d3415..ed9c8ed 100644 --- a/src/fighter/state/air.rs +++ b/src/fighter/state/air.rs @@ -129,6 +129,7 @@ pub fn collision_interrupt( ) -> Option { if ctx.velocity.y <= FGi32::ZERO { if let Some(ledge_result) = ctx.air_collide_with_ledges() { + ctx.apply_desired_ecb(); return Some(FighterState::LedgeGrab(LedgeGrabState::new(ledge_result.ledge))); } } diff --git a/src/fighter/state/air_dodge.rs b/src/fighter/state/air_dodge.rs index e03608c..9d5f2f9 100644 --- a/src/fighter/state/air_dodge.rs +++ b/src/fighter/state/air_dodge.rs @@ -56,7 +56,7 @@ impl FighterStateImpl for AirDodgeState { let point_in_segment = segment.segment.closest_point(bottom_point); let dist_to_segment = point_in_segment.distance(bottom_point); if dist_to_segment <= state_context.waveland_snap_distance { - state_context.ecb.bottom = point_in_segment; + state_context.ecb.bottom = point_in_segment - state_context.translation.0; state_context.ecb.rebase_onto_bottom(); state_context.surface.land(StageLineID { polygon: poly_idx, segment: segment_idx }, state_context.ledge_info); return Some(FighterState::Land(LandingState::create(LandingType::Special))); diff --git a/src/fighter/state/angel.rs b/src/fighter/state/angel.rs index 6d021ce..fb5dcbe 100644 --- a/src/fighter/state/angel.rs +++ b/src/fighter/state/angel.rs @@ -43,12 +43,13 @@ impl FighterStateImpl for AngelState { fn check_collision_interrupt( &mut self, - _state_context: &mut super::CollisionContext, + state_context: &mut super::CollisionContext, ) -> Option { + state_context.apply_desired_ecb(); None } fn surface_policy(&self) -> super::SurfacePolicy { super::SurfacePolicy::Airborne(crate::fighter::surface::EcbLockPolicy::Clear) } -} \ No newline at end of file +} diff --git a/src/fighter/state/ground.rs b/src/fighter/state/ground.rs index 039ef75..9b124d6 100644 --- a/src/fighter/state/ground.rs +++ b/src/fighter/state/ground.rs @@ -211,7 +211,6 @@ pub fn collide_with_stage_grounded( crate::fighter::surface::EcbLockPolicy::StartOnDetach, state_context.leave_ground_ecb_lock_duration, ); - state_context.ecb_advanced = true; return GroundedMotionResult::InAir; }; match resolve_grounded_position( @@ -238,7 +237,6 @@ pub fn collide_with_stage_grounded( crate::fighter::surface::EcbLockPolicy::StartOnDetach, state_context.leave_ground_ecb_lock_duration, ); - state_context.ecb_advanced = true; return GroundedMotionResult::InAir; } } @@ -247,7 +245,6 @@ pub fn collide_with_stage_grounded( *state_context.ecb = current_ecb; state_context.translation.0 = current_position; state_context.surface.land(line_id, state_context.ledge_info); - state_context.ecb_advanced = true; GroundedMotionResult::InGround } @@ -419,7 +416,7 @@ mod tests { origin: FGVec2::ZERO, end: FGVec2::ZERO, }, - ecb_advanced: false, + waveland_snap_distance: FGi32::ZERO, }; assert!(matches!( @@ -484,7 +481,7 @@ mod tests { origin: FGVec2::ZERO, end: FGVec2::ZERO, }, - ecb_advanced: false, + waveland_snap_distance: FGi32::ZERO, }; assert!(matches!( diff --git a/src/fighter/state/ledge_action.rs b/src/fighter/state/ledge_action.rs index 04d8528..4c2dca5 100644 --- a/src/fighter/state/ledge_action.rs +++ b/src/fighter/state/ledge_action.rs @@ -144,8 +144,9 @@ impl FighterStateImpl for LedgeActionState { fn check_collision_interrupt( &mut self, - _state_context: &mut CollisionContext, + state_context: &mut CollisionContext, ) -> Option { + state_context.apply_desired_ecb(); None } diff --git a/src/fighter/state/ledge_wait.rs b/src/fighter/state/ledge_wait.rs index 9fe5524..c401dfe 100644 --- a/src/fighter/state/ledge_wait.rs +++ b/src/fighter/state/ledge_wait.rs @@ -102,8 +102,9 @@ impl FighterStateImpl for LedgeWaitState { fn check_collision_interrupt( &mut self, - _state_context: &mut CollisionContext, + state_context: &mut CollisionContext, ) -> Option { + state_context.apply_desired_ecb(); None } diff --git a/src/fighter/state/mod.rs b/src/fighter/state/mod.rs index f6f1d7e..156a471 100644 --- a/src/fighter/state/mod.rs +++ b/src/fighter/state/mod.rs @@ -120,8 +120,9 @@ pub trait FighterStateImpl: Sized { fn check_collision_interrupt( &mut self, - _state_context: &mut CollisionContext, + state_context: &mut CollisionContext, ) -> Option { + state_context.apply_desired_ecb(); None } @@ -261,7 +262,6 @@ pub struct CollisionContext<'a> { pub fighter_ledge_collision_box: FGRect, pub downward_stick_threshold: FGi32, pub waveland_snap_distance: FGi32, - pub(crate) ecb_advanced: bool, } impl CollisionContext<'_> { @@ -269,7 +269,6 @@ impl CollisionContext<'_> { /// substep resolver can later replace this with fractional steps. pub fn apply_desired_ecb(&mut self) { ecb::interpolate_ecb(self.ecb, *self.desired_ecb, FGi32::ONE); - self.ecb_advanced = true; } pub fn air_collide_with_stage( @@ -279,7 +278,7 @@ impl CollisionContext<'_> { let ignored_polys = self.surface.ignored_polygon_ids(); let ignore_soft_platforms = can_ignore_soft_platforms && self.input.get_last_frame().movement.y <= -self.downward_stick_threshold; - let result = crate::fighter::collision::air_collide_with_stage_substepped( + crate::fighter::collision::air_collide_with_stage_substepped( self.prev_translation, self.translation, self.velocity, @@ -288,15 +287,7 @@ impl CollisionContext<'_> { self.stage_collision, &ignored_polys, ignore_soft_platforms, - ); - self.ecb_advanced = true; - result - } - - fn finish_ecb_frame(&mut self) { - if !self.ecb_advanced { - self.apply_desired_ecb(); - } + ) } pub fn air_collide_with_ledges( &self, @@ -503,7 +494,6 @@ impl<'w, 's> FighterFrameQueryItem<'w, 's> { .leave_ground_ecb_frame_lock_duration, downward_stick_threshold: game_settings.input_common.run_stick_threshold, fighter_ledge_collision_box, - ecb_advanced: false, waveland_snap_distance: game_settings.fighter_common.waveland_snap_distance, } } @@ -799,13 +789,9 @@ pub fn state_collision_interrupt_system( continue; } - let new_state = { - let mut collision_context = - frame.collision_context(&stage_collision, manifest, &game_settings); - let new_state = state.check_collision_interrupt(&mut collision_context); - collision_context.finish_ecb_frame(); - new_state - }; + let new_state = state.check_collision_interrupt( + &mut frame.collision_context(&stage_collision, manifest, &game_settings), + ); if let Some(new_state) = new_state { transition_state( &mut state, @@ -874,7 +860,7 @@ mod tests { }; let previous_ecb = FighterPreviousECB::from(ecb); let mut presentation_snap = FighterPresentationSnap::default(); - let mut context = CollisionContext { + let context = CollisionContext { translation: &mut translation, prev_translation: &previous_translation, input: &input, @@ -892,7 +878,6 @@ mod tests { end: FGVec2::lit("1", "-1"), }, downward_stick_threshold: FGi32::ONE, - ecb_advanced: false, waveland_snap_distance: FGi32::ZERO, }; @@ -902,7 +887,5 @@ mod tests { context.air_collide_with_ledges().map(|result| result.ledge), Some(ledge_id) ); - context.finish_ecb_frame(); - assert_eq!(context.ecb.top, FGVec2::lit("0", "2")); } }