Fix various minor issues #74
@@ -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]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -38,6 +38,7 @@ impl FighterStateImpl for FallState {
|
||||
air::collision_interrupt(
|
||||
state_context,
|
||||
crate::fighter::state::land::LandingType::Normal,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,7 @@ impl FighterStateImpl for JumpState {
|
||||
air::collision_interrupt(
|
||||
state_context,
|
||||
crate::fighter::state::land::LandingType::Normal,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -46,6 +46,7 @@ impl FighterStateImpl for PlatformPassState {
|
||||
air::collision_interrupt(
|
||||
state_context,
|
||||
crate::fighter::state::land::LandingType::Normal,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
@@ -261,18 +261,18 @@ pub fn compile_script(text: &str) -> Result<FighterAttackScript, String> {
|
||||
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);
|
||||
"#,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user