Add authoritative fighter surface state (#60)
## Summary - add a rollback-tracked `FighterSurfaceState` as the single source of truth for stage contact - move active stage line ownership out of individual grounded fighter states - update landing, airborne motion, ledge departure, hit reactions, and debug save states to maintain surface contact - add tests for contact lifecycle, connected-segment traversal, and ledge departure Reviewed-on: #60 Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
This commit was merged in pull request #60.
This commit is contained in:
+24
-23
@@ -2,10 +2,17 @@ use bevy::prelude::*;
|
||||
|
||||
use crate::{
|
||||
fighter::{
|
||||
animation::AnimKind, state::{
|
||||
CollisionContext, EnterContext, FighterState, FighterStateImpl, InterruptContext, UpdateContext, air::{self, AirborneStateCommon}, air_dodge::{self, AirDodgeState}, ground::{self, GroundedStateCommon},
|
||||
animation::AnimKind,
|
||||
state::{
|
||||
CollisionContext, EnterContext, FighterState, FighterStateImpl, InterruptContext,
|
||||
UpdateContext,
|
||||
air::{self, AirborneStateCommon},
|
||||
air_dodge::{self, AirDodgeState},
|
||||
ground,
|
||||
},
|
||||
}, input::FighterCommands, math::{int::FGi32, vec::FGVec2},
|
||||
},
|
||||
input::FighterCommands,
|
||||
math::{int::FGi32, vec::FGVec2},
|
||||
};
|
||||
#[derive(Debug, Hash, Clone, Copy)]
|
||||
pub enum JumpType {
|
||||
@@ -22,14 +29,12 @@ pub struct JumpState {
|
||||
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub struct JumpSquatState {
|
||||
pub grounded_common: GroundedStateCommon,
|
||||
pub duration_counter: u32,
|
||||
}
|
||||
|
||||
impl JumpSquatState {
|
||||
pub fn create(grounded_common: GroundedStateCommon) -> Self {
|
||||
pub fn create() -> Self {
|
||||
Self {
|
||||
grounded_common,
|
||||
duration_counter: 0,
|
||||
}
|
||||
}
|
||||
@@ -69,7 +74,10 @@ impl FighterStateImpl for JumpSquatState {
|
||||
} else {
|
||||
JumpType::ShortHop
|
||||
};
|
||||
Some(FighterState::Jump(JumpState { jump_type, airborne_state_common: AirborneStateCommon::default() }))
|
||||
Some(FighterState::Jump(JumpState {
|
||||
jump_type,
|
||||
airborne_state_common: AirborneStateCommon::default(),
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -84,17 +92,15 @@ impl FighterStateImpl for JumpSquatState {
|
||||
&mut self,
|
||||
state_context: &mut CollisionContext,
|
||||
) -> Option<FighterState> {
|
||||
ground::collision_interrupt(state_context, &mut self.grounded_common, false)
|
||||
ground::collision_interrupt(state_context, false)
|
||||
}
|
||||
|
||||
fn on_enter(&mut self, state_context: &mut EnterContext) {
|
||||
state_context.play_animation(AnimKind::JumpSquat, false);
|
||||
state_context.input.clear_command(FighterCommands::Jump);
|
||||
}
|
||||
|
||||
fn is_visually_grounded<'a>(
|
||||
&'a self,
|
||||
) -> bool {
|
||||
|
||||
fn is_visually_grounded<'a>(&'a self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -105,7 +111,7 @@ impl FighterStateImpl for JumpState {
|
||||
if state_context.input.has_command(FighterCommands::Jump) {
|
||||
Some(FighterState::Jump(JumpState {
|
||||
jump_type: JumpType::DoubleJump,
|
||||
airborne_state_common: AirborneStateCommon::default()
|
||||
airborne_state_common: AirborneStateCommon::default(),
|
||||
}))
|
||||
} else {
|
||||
air_dodge::check_input(state_context)
|
||||
@@ -176,22 +182,17 @@ impl FighterStateImpl for JumpState {
|
||||
crate::fighter::state::land::LandingType::Normal,
|
||||
)
|
||||
}
|
||||
|
||||
fn is_visually_grounded<'a>(
|
||||
&'a self,
|
||||
) -> bool {
|
||||
|
||||
fn is_visually_grounded<'a>(&'a self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_input(
|
||||
state_context: &InterruptContext,
|
||||
ground_common: &GroundedStateCommon,
|
||||
) -> Option<FighterState> {
|
||||
pub fn check_input(state_context: &InterruptContext) -> Option<FighterState> {
|
||||
state_context
|
||||
.input
|
||||
.has_command(FighterCommands::Jump)
|
||||
.then(|| FighterState::JumpSquat(JumpSquatState::create(ground_common.clone())))
|
||||
.then(|| FighterState::JumpSquat(JumpSquatState::create()))
|
||||
}
|
||||
|
||||
pub fn check_input_double_jump(state_context: &InterruptContext) -> Option<FighterState> {
|
||||
@@ -201,7 +202,7 @@ pub fn check_input_double_jump(state_context: &InterruptContext) -> Option<Fight
|
||||
.then(|| {
|
||||
FighterState::Jump(JumpState {
|
||||
jump_type: JumpType::DoubleJump,
|
||||
airborne_state_common: AirborneStateCommon::default()
|
||||
airborne_state_common: AirborneStateCommon::default(),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user