From ccf2657d29634f3940d995cc6e0e5c130a41d521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20Rom=C3=A1n=20N=C3=BA=C3=B1ez?= Date: Mon, 28 Sep 2026 15:08:39 +0000 Subject: [PATCH] Fix various minor issues (#74) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-on: https://git.eirexe.moe/EIREXE/shinespark/pulls/74 Co-authored-by: Álex Román Núñez --- src/fighter/collision.rs | 19 +++++++++++++++++-- src/fighter/state/air.rs | 3 ++- src/fighter/state/air_dodge.rs | 2 +- src/fighter/state/fall.rs | 1 + src/fighter/state/hitstun.rs | 6 +++--- src/fighter/state/jump.rs | 1 + src/fighter/state/mod.rs | 5 +++-- src/fighter/state/platform_pass.rs | 1 + src/fighter/state/walk.rs | 4 ++-- src/scripting/move_compiler.rs | 10 +++++----- 10 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/fighter/collision.rs b/src/fighter/collision.rs index 4ea1b55..f9eae3b 100644 --- a/src/fighter/collision.rs +++ b/src/fighter/collision.rs @@ -45,7 +45,7 @@ pub fn air_collide_with_stage( ecb: &FighterECB, stage_collision: &StageCollision, ignored_polys: &[usize], - ignore_soft_platforms: bool, + can_ignore_soft_platforms: bool, ) -> Option { let ray_segment = FGSegment2d::new( prev_translation.0 + prev_ecb.get_bottom_point(), @@ -58,7 +58,7 @@ pub fn air_collide_with_stage( .enumerate() .filter(|(poly_idx, poly)| { !ignored_polys.contains(poly_idx) - && !(ignore_soft_platforms && matches!(poly.poly_type, StagePolyType::Platform)) + && !(can_ignore_soft_platforms && matches!(poly.poly_type, StagePolyType::Platform)) }) .filter_map(|(poly_idx, poly)| { poly.intersect_ray(ray_segment).map(|intersect_result| { @@ -176,6 +176,21 @@ mod tests { true, ) .is_none()); + + assert_eq!( + air_collide_with_stage( + &previous_translation, + &translation, + &previous_ecb, + &ecb, + &stage_collision, + &[], + false, + ) + .expect("air dodges still collide with soft platforms") + .hit_position, + FGVec2::lit("0", "0") + ); } #[test] diff --git a/src/fighter/state/air.rs b/src/fighter/state/air.rs index a948a25..9f2b48f 100644 --- a/src/fighter/state/air.rs +++ b/src/fighter/state/air.rs @@ -115,8 +115,9 @@ pub fn update_standard_motion( pub fn collision_interrupt( ctx: &mut CollisionContext, landing_type: LandingType, + can_ignore_soft_platforms: bool, ) -> Option { - let res = ctx.air_collide_with_stage()?; + let res = ctx.air_collide_with_stage(can_ignore_soft_platforms)?; let diff = res.hit_position - ctx.translation.0; ctx.ecb.bottom -= diff; ctx.ecb.top -= diff; diff --git a/src/fighter/state/air_dodge.rs b/src/fighter/state/air_dodge.rs index 42165df..b894434 100644 --- a/src/fighter/state/air_dodge.rs +++ b/src/fighter/state/air_dodge.rs @@ -45,7 +45,7 @@ impl FighterStateImpl for AirDodgeState { &mut self, state_context: &mut CollisionContext, ) -> Option { - air::collision_interrupt(state_context, LandingType::Special) + air::collision_interrupt(state_context, LandingType::Special, false) } fn on_enter(&mut self, state_context: &mut EnterContext) { diff --git a/src/fighter/state/fall.rs b/src/fighter/state/fall.rs index 608ae82..e945184 100644 --- a/src/fighter/state/fall.rs +++ b/src/fighter/state/fall.rs @@ -38,6 +38,7 @@ impl FighterStateImpl for FallState { air::collision_interrupt( state_context, crate::fighter::state::land::LandingType::Normal, + true, ) } diff --git a/src/fighter/state/hitstun.rs b/src/fighter/state/hitstun.rs index 9849280..cb7d9e8 100644 --- a/src/fighter/state/hitstun.rs +++ b/src/fighter/state/hitstun.rs @@ -11,8 +11,7 @@ use crate::{ land::LandingType, wait::WaitState, }, - }, - math::int::FGi32, + }, math::{int::FGi32, vec::FGVec2}, }; #[derive(Clone, Debug, Hash)] @@ -103,6 +102,7 @@ impl FighterStateImpl for HitstunState { HitstopStateKind::Airborne => AnimKind::FlinchAir, }; state_context.play_animation(animation, false); + state_context.velocity.0 = FGVec2::ZERO; } fn on_exit(&mut self, _state_context: &mut ExitContext) {} @@ -114,7 +114,7 @@ impl FighterStateImpl for HitstunState { match &mut self.hitstop_kind { HitstopStateKind::Grounded => collision_interrupt(state_context, true), HitstopStateKind::Airborne => { - air::collision_interrupt(state_context, LandingType::Normal) + air::collision_interrupt(state_context, LandingType::Normal, false) } } } diff --git a/src/fighter/state/jump.rs b/src/fighter/state/jump.rs index 33e2119..77efb44 100644 --- a/src/fighter/state/jump.rs +++ b/src/fighter/state/jump.rs @@ -180,6 +180,7 @@ impl FighterStateImpl for JumpState { air::collision_interrupt( state_context, crate::fighter::state::land::LandingType::Normal, + true, ) } diff --git a/src/fighter/state/mod.rs b/src/fighter/state/mod.rs index 08bc6bf..64cd610 100644 --- a/src/fighter/state/mod.rs +++ b/src/fighter/state/mod.rs @@ -214,10 +214,11 @@ pub struct CollisionContext<'a> { impl CollisionContext<'_> { pub fn air_collide_with_stage( &self, + can_ignore_soft_platforms: bool, ) -> Option { let ignored_polys = self.surface.ignored_polygon_ids(); - let ignore_soft_platforms = - self.input.get_last_frame().movement.y <= -self.downward_stick_threshold; + let ignore_soft_platforms = can_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, diff --git a/src/fighter/state/platform_pass.rs b/src/fighter/state/platform_pass.rs index ff172d1..81105ad 100644 --- a/src/fighter/state/platform_pass.rs +++ b/src/fighter/state/platform_pass.rs @@ -46,6 +46,7 @@ impl FighterStateImpl for PlatformPassState { air::collision_interrupt( state_context, crate::fighter::state::land::LandingType::Normal, + true, ) } diff --git a/src/fighter/state/walk.rs b/src/fighter/state/walk.rs index 0403d99..383f47f 100644 --- a/src/fighter/state/walk.rs +++ b/src/fighter/state/walk.rs @@ -3,7 +3,7 @@ use super::{ ground, wait, }; use crate::fighter::animation::AnimKind; -use crate::fighter::state::FighterState; +use crate::fighter::state::{self, FighterState}; #[derive(Debug, Clone, Hash)] pub struct WalkState; @@ -14,7 +14,7 @@ impl FighterStateImpl for WalkState { if let Some(state) = ground::grounded_movement_common_interrupts(state_context) { return Some(state); } - wait::check_input(state_context).or_else(|| dash::check_input(state_context)) + wait::check_input(state_context).or_else(|| dash::check_input(state_context)).or_else(|| state::ground_attack::check_interrupt(state_context)) } fn on_enter(&mut self, state_context: &mut EnterContext) { diff --git a/src/scripting/move_compiler.rs b/src/scripting/move_compiler.rs index 474234b..65e1b98 100644 --- a/src/scripting/move_compiler.rs +++ b/src/scripting/move_compiler.rs @@ -117,7 +117,7 @@ pub fn register_common_types(engine: &mut rhai::Engine) { .register_fn("knockback_normal", KnockbackType::make_normal) .register_fn("knockback_fixed", KnockbackType::make_fixed) .register_type_with_name::("Angle") - .register_fn("angle", AttackAngle::make_normal) + .register_fn("angle", |str: &str| AttackAngle::make_normal(FGi32::lit(str))) .register_fn("angle_sakurai", AttackAngle::make_sakurai) .register_type_with_name::("Knockback") .register_fn("knockback", Knockback::lit) @@ -261,18 +261,18 @@ pub fn compile_script(text: &str) -> Result { mod tests { use super::*; - const HITBOX: &str = "hitbox(0, \"hand_l\", damage(\"1\"), vec3(\"0\", \"0\", \"0\"), fg32(\"1\"), angle(fg32(\"0\")), knockback_normal(), knockback(\"1\"), fg32(\"1\"));"; + const HITBOX: &str = "hitbox(0, \"hand_l\", damage(\"1\"), vec3(\"0\", \"0\", \"0\"), fg32(\"1\"), angle(\"0\"), knockback_normal(), knockback(\"1\"), fg32(\"1\"));"; #[test] fn compiled_hitboxes_are_sorted_by_authored_id() { let script = compile_script( r#" frame(1); - hitbox(20, "hand_l", damage("1"), vec3("0", "0", "0"), fg32("1"), angle(fg32("0")), knockback_normal(), knockback("1"), fg32("1")); + hitbox(20, "hand_l", damage("1"), vec3("0", "0", "0"), fg32("1"), angle("0"), knockback_normal(), knockback("1"), fg32("1")); frame(2); - hitbox(3, "hand_l", damage("2"), vec3("0", "0", "0"), fg32("1"), angle(fg32("0")), knockback_normal(), knockback("1"), fg32("1")); + hitbox(3, "hand_l", damage("2"), vec3("0", "0", "0"), fg32("1"), angle("0"), knockback_normal(), knockback("1"), fg32("1")); frame(3); - hitbox(10, "hand_l", damage("3"), vec3("0", "0", "0"), fg32("1"), angle(fg32("0")), knockback_normal(), knockback("1"), fg32("1")); + hitbox(10, "hand_l", damage("3"), vec3("0", "0", "0"), fg32("1"), angle("0"), knockback_normal(), knockback("1"), fg32("1")); frame(4); "#, )