Allow airborne fighters to pass through platforms while holding down (#65)
CI / build-and-test (push) Successful in 1m50s
CI / production-build (push) Canceled after 18s

## Summary
- Ignore soft-platform collision while an airborne fighter holds down.
- Preserve existing momentum and collision with solid floors.
- Add regression coverage for soft and solid platform behavior.

Reviewed-on: #65
Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
This commit was merged in pull request #65.
This commit is contained in:
2026-09-26 12:07:38 +00:00
committed by EIREXE
parent 615872f29c
commit a58b5eeec7
3 changed files with 99 additions and 3 deletions
+5
View File
@@ -248,6 +248,7 @@ mod tests {
use crate::fighter::ecb::FighterPreviousECB;
use crate::fighter::{FighterECB, FighterSurfaceState};
use crate::stage::line::StagePolyType;
use crate::input::FighterInput;
fn two_segment_floor() -> StagePoly {
StagePoly::build(
@@ -378,12 +379,14 @@ mod tests {
let mut context = CollisionContext {
translation: &mut translation,
prev_translation: &previous_translation,
input: &FighterInput::default(),
velocity: &mut velocity,
surface: &mut surface,
ecb: &mut ecb,
prev_ecb: &previous_ecb,
stage_collision: &stage_collision,
leave_ground_ecb_lock_duration: 10,
downward_stick_threshold: FGi32::ONE,
};
assert!(matches!(
@@ -429,12 +432,14 @@ mod tests {
let mut context = CollisionContext {
translation: &mut translation,
prev_translation: &previous_translation,
input: &FighterInput::default(),
velocity: &mut velocity,
surface: &mut surface,
ecb: &mut ecb,
prev_ecb: &previous_ecb,
stage_collision: &stage_collision,
leave_ground_ecb_lock_duration: 10,
downward_stick_threshold: FGi32::ONE,
};
assert!(matches!(
+8 -1
View File
@@ -193,12 +193,14 @@ impl UpdateContext<'_> {
pub struct CollisionContext<'a> {
pub translation: &'a mut FighterTranslation,
pub prev_translation: &'a FighterPreviousTranslation,
pub input: &'a FighterInput,
pub velocity: &'a mut FighterVelocity,
pub surface: &'a mut FighterSurfaceState,
pub ecb: &'a mut FighterECB,
pub prev_ecb: &'a FighterPreviousECB,
pub stage_collision: &'a StageCollision,
pub leave_ground_ecb_lock_duration: u32,
pub downward_stick_threshold: FGi32,
}
impl CollisionContext<'_> {
@@ -206,6 +208,8 @@ impl CollisionContext<'_> {
&self,
) -> Option<crate::fighter::collision::AirCollisionWithStageResult> {
let ignored_polys = self.surface.ignored_polygon_ids();
let ignore_soft_platforms = self.input.get_last_frame().movement.y
<= -self.downward_stick_threshold;
crate::fighter::collision::air_collide_with_stage(
self.prev_translation,
self.translation,
@@ -213,6 +217,7 @@ impl CollisionContext<'_> {
self.ecb,
self.stage_collision,
&ignored_polys,
ignore_soft_platforms,
)
}
}
@@ -349,12 +354,14 @@ impl<'w, 's> FighterFrameQueryItem<'w, 's> {
CollisionContext {
translation: &mut self.translation,
prev_translation: &self.prev_translation,
input: &self.input,
velocity: &mut self.velocity,
surface: &mut self.surface,
ecb: &mut self.ecb,
prev_ecb: &self.prev_ecb,
stage_collision,
leave_ground_ecb_lock_duration: game_settings.fighter_common.leave_ground_ecb_frame_lock_duration
leave_ground_ecb_lock_duration: game_settings.fighter_common.leave_ground_ecb_frame_lock_duration,
downward_stick_threshold: game_settings.input_common.run_stick_threshold,
}
}
}