Add ledge getup, ledge intangibility limit & fix walk-off velocity #93

Merged
EIREXE merged 4 commits from ledge_getup into master 2026-10-13 15:52:10 +00:00
4 changed files with 12 additions and 4 deletions
Showing only changes of commit ea2756201e - Show all commits
+4 -1
View File
@@ -2,7 +2,7 @@ use bevy::prelude::*;
use crate::{ use crate::{
camera::MatchCamera, fighter::{ camera::MatchCamera, fighter::{
FighterECB, FighterFacingDirection, FighterHitboxes, FighterHitstop, FighterHitstopShake, FighterInvulnerabilityState, FighterPendingRespawn, FighterPreviousFacingDirection, FighterPreviousTranslation, FighterSurfaceState, FighterTranslation, FighterVelocity, animation::FighterAnimationFrame, attack::{ FighterECB, FighterFacingDirection, FighterHitboxes, FighterHitstop, FighterHitstopShake, FighterInvulnerabilityState, FighterLedgeInformation, FighterPendingRespawn, FighterPreviousFacingDirection, FighterPreviousTranslation, FighterSurfaceState, FighterTranslation, FighterVelocity, animation::FighterAnimationFrame, attack::{
FighterDamage, FighterKnockbackVelocity, FighterPendingHitReaction, FighterPendingHits, FighterDamage, FighterKnockbackVelocity, FighterPendingHitReaction, FighterPendingHits,
FighterSolvedHurtboxes, FighterStaleMoveQueue, FighterSolvedHurtboxes, FighterStaleMoveQueue,
}, baked_animation::FighterBoneMatrices, state::FighterState, }, baked_animation::FighterBoneMatrices, state::FighterState,
@@ -48,6 +48,7 @@ struct FighterCheckpoint {
surface: FighterSurfaceState, surface: FighterSurfaceState,
pending_respawn: FighterPendingRespawn, pending_respawn: FighterPendingRespawn,
invulnerability_state: FighterInvulnerabilityState, invulnerability_state: FighterInvulnerabilityState,
ledge_information: FighterLedgeInformation,
} }
pub(super) fn save_or_restore(world: &mut World) { pub(super) fn save_or_restore(world: &mut World) {
@@ -151,6 +152,7 @@ pub(super) fn save_or_restore(world: &mut World) {
entity.insert(saved.surface.clone()); entity.insert(saved.surface.clone());
entity.insert(saved.pending_respawn.clone()); entity.insert(saved.pending_respawn.clone());
entity.insert(saved.invulnerability_state.clone()); entity.insert(saved.invulnerability_state.clone());
entity.insert(saved.ledge_information.clone());
} }
world.insert_resource(checkpoint.pending_hits.clone()); world.insert_resource(checkpoint.pending_hits.clone());
world.insert_resource(checkpoint.stage_collision); world.insert_resource(checkpoint.stage_collision);
@@ -188,6 +190,7 @@ fn capture_fighter(world: &World, entity: Entity) -> Option<FighterCheckpoint> {
surface: fighter.get::<FighterSurfaceState>()?.clone(), surface: fighter.get::<FighterSurfaceState>()?.clone(),
pending_respawn: fighter.get::<FighterPendingRespawn>()?.clone(), pending_respawn: fighter.get::<FighterPendingRespawn>()?.clone(),
invulnerability_state: fighter.get::<FighterInvulnerabilityState>()?.clone(), invulnerability_state: fighter.get::<FighterInvulnerabilityState>()?.clone(),
ledge_information: fighter.get::<FighterLedgeInformation>()?.clone(),
}) })
} }
+1 -1
View File
@@ -66,7 +66,7 @@ impl FighterStateImpl for LedgeWaitState {
state_context.velocity.0 = FGVec2::ZERO; state_context.velocity.0 = FGVec2::ZERO;
state_context.knockback_velocity.0 = FGVec2::ZERO; state_context.knockback_velocity.0 = FGVec2::ZERO;
if state_context.ledge_info.grab_count < state_context.game_settings.fighter_common.max_ledge_regrab_count { if state_context.ledge_info.grab_count < state_context.game_settings.fighter_common.max_ledge_grab_count {
*state_context.vulnerability = FighterInvulnerabilityState::Intangible { *state_context.vulnerability = FighterInvulnerabilityState::Intangible {
frames_remaining: Some( frames_remaining: Some(
state_context state_context
+5
View File
@@ -500,6 +500,7 @@ pub struct StatefulFighterQuery {
pub player: &'static Player, pub player: &'static Player,
pub pending_hit_reaction: &'static mut FighterPendingHitReaction, pub pending_hit_reaction: &'static mut FighterPendingHitReaction,
pub hitstop: &'static mut FighterHitstop, pub hitstop: &'static mut FighterHitstop,
pub ledge_info: &'static mut FighterLedgeInformation,
pub hitstop_shake: &'static mut FighterHitstopShake, pub hitstop_shake: &'static mut FighterHitstopShake,
pub pending_respawn: &'static mut FighterPendingRespawn, pub pending_respawn: &'static mut FighterPendingRespawn,
pub damage: &'static mut FighterDamage, pub damage: &'static mut FighterDamage,
@@ -709,6 +710,7 @@ pub fn state_collision_interrupt_system(
mut pending_respawn, mut pending_respawn,
player, player,
mut damage, mut damage,
mut ledge_info,
.. ..
} = fighter; } = fighter;
@@ -757,6 +759,9 @@ pub fn state_collision_interrupt_system(
// reset percentage // reset percentage
*damage = FighterDamage::default(); *damage = FighterDamage::default();
// reset ledge
*ledge_info = FighterLedgeInformation::default();
transition_state( transition_state(
&mut state, &mut state,
+2 -2
View File
@@ -55,8 +55,8 @@ pub struct FighterSettingsCommon {
pub ledge_drop_regrab_lockout_duration_frames: u32, pub ledge_drop_regrab_lockout_duration_frames: u32,
/// How many frames (+ the ledge animation duration) the fighter will be invulnerable after grabbing the ledge /// How many frames (+ the ledge animation duration) the fighter will be invulnerable after grabbing the ledge
pub ledge_grab_invulnerability_duration: u32, pub ledge_grab_invulnerability_duration: u32,
/// How many times the fighter can regrab the ledge and still get invulnerability /// How many times the fighter can grab the ledge without landing and still get invulnerability
pub max_ledge_regrab_count: u32, pub max_ledge_grab_count: u32,
/// When hit while the receiver is in the air, use this angle /// When hit while the receiver is in the air, use this angle
pub sakurai_angle_aerial_angle: FGi32, pub sakurai_angle_aerial_angle: FGi32,