Compare commits

..
4 Commits
Author SHA1 Message Date
EIREXE e57a0eeaad Fix being unable to do forward tilts from a walk
CI / build-and-test (pull_request) Failing after 1m59s
CI / production-build (pull_request) Successful in 11m15s
2026-09-27 17:56:56 +02:00
EIREXE f63effb067 Fix being hit not causing velocity to reset 2026-09-27 17:55:11 +02:00
EIREXE 60ed07a247 Fix move compiler "angle" function 2026-09-27 17:54:40 +02:00
EIREXE 527ca3be75 Fix airdodge being able to pass through platforms when holding down. 2026-09-27 17:54:40 +02:00
10 changed files with 32 additions and 12 deletions
+17 -2
View File
@@ -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<AirCollisionWithStageResult> {
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]
+2 -1
View File
@@ -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<FighterState> {
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;
+1 -1
View File
@@ -45,7 +45,7 @@ impl FighterStateImpl for AirDodgeState {
&mut self,
state_context: &mut CollisionContext,
) -> Option<FighterState> {
air::collision_interrupt(state_context, LandingType::Special)
air::collision_interrupt(state_context, LandingType::Special, false)
}
fn on_enter(&mut self, state_context: &mut EnterContext) {
+1
View File
@@ -38,6 +38,7 @@ impl FighterStateImpl for FallState {
air::collision_interrupt(
state_context,
crate::fighter::state::land::LandingType::Normal,
true,
)
}
+3 -3
View File
@@ -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)
}
}
}
+1
View File
@@ -180,6 +180,7 @@ impl FighterStateImpl for JumpState {
air::collision_interrupt(
state_context,
crate::fighter::state::land::LandingType::Normal,
true,
)
}
+3 -2
View File
@@ -214,10 +214,11 @@ pub struct CollisionContext<'a> {
impl CollisionContext<'_> {
pub fn air_collide_with_stage(
&self,
can_ignore_soft_platforms: bool,
) -> 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;
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,
+1
View File
@@ -46,6 +46,7 @@ impl FighterStateImpl for PlatformPassState {
air::collision_interrupt(
state_context,
crate::fighter::state::land::LandingType::Normal,
true,
)
}
+2 -2
View File
@@ -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) {
+1 -1
View File
@@ -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::<AttackAngle>("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>("Knockback")
.register_fn("knockback", Knockback::lit)