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:
@@ -0,0 +1,62 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::stage::line::StageLineID;
|
||||
|
||||
/// The stage surface currently supporting a fighter.
|
||||
///
|
||||
/// This is physics state rather than fighter-state-machine state. Keeping it
|
||||
/// separate means grounded, landing, and hitstun states all share one source
|
||||
/// of truth for stage contact.
|
||||
#[derive(Component, Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
|
||||
pub enum FighterSurfaceState {
|
||||
#[default]
|
||||
Airborne,
|
||||
Grounded {
|
||||
line_id: StageLineID,
|
||||
},
|
||||
}
|
||||
|
||||
impl FighterSurfaceState {
|
||||
pub fn is_grounded(self) -> bool {
|
||||
matches!(self, Self::Grounded { .. })
|
||||
}
|
||||
|
||||
pub fn line_id(self) -> Option<StageLineID> {
|
||||
match self {
|
||||
Self::Airborne => None,
|
||||
Self::Grounded { line_id } => Some(line_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn land(&mut self, line_id: StageLineID) {
|
||||
*self = Self::Grounded { line_id };
|
||||
}
|
||||
|
||||
pub(crate) fn leave_ground(&mut self) {
|
||||
*self = Self::Airborne;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn contact_lifecycle_has_one_source_of_truth() {
|
||||
let mut surface = FighterSurfaceState::default();
|
||||
assert!(!surface.is_grounded());
|
||||
assert_eq!(surface.line_id(), None);
|
||||
|
||||
let line_id = StageLineID {
|
||||
polygon: 2,
|
||||
segment: 3,
|
||||
};
|
||||
surface.land(line_id);
|
||||
assert!(surface.is_grounded());
|
||||
assert_eq!(surface.line_id(), Some(line_id));
|
||||
|
||||
surface.leave_ground();
|
||||
assert!(!surface.is_grounded());
|
||||
assert_eq!(surface.line_id(), None);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user