Implement invulnerability/intangibility and sakurai angle (#78)
CI / build-and-test (push) Successful in 1m22s
CI / production-build (push) Successful in 11m48s

Reviewed-on: #78
Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
This commit was merged in pull request #78.
This commit is contained in:
2026-10-03 10:47:00 +00:00
committed by EIREXE
parent aca3886113
commit 02d444f749
8 changed files with 170 additions and 44 deletions
+3 -8
View File
@@ -33,14 +33,9 @@ impl FighterStateImpl for AirDodgeState {
}
fn update(&mut self, state_context: &mut UpdateContext) {
let airdodge_intangible_end = state_context.fighter_attributes.air_dodge_intangible_start
+ state_context
.fighter_attributes
.air_dodge_intangible_duration;
if state_context.animation_frame
== state_context.fighter_attributes.air_dodge_intangible_start
{
*state_context.vulnerability = FighterInvulnerabilityState::Intangible;
let airdodge_intangible_end = state_context.fighter_attributes.air_dodge_intangible_start + state_context.fighter_attributes.air_dodge_intangible_duration;
if state_context.animation_frame == state_context.fighter_attributes.air_dodge_intangible_start {
*state_context.vulnerability = FighterInvulnerabilityState::Intangible { frames_remaining: Some(state_context.fighter_attributes.air_dodge_intangible_duration) };
} else if state_context.animation_frame >= airdodge_intangible_end {
*state_context.vulnerability = FighterInvulnerabilityState::Vulnerable;
}
+2 -1
View File
@@ -1,4 +1,4 @@
use crate::{fighter::{animation::AnimKind, state::{FighterState, FighterStateImpl, air::AirborneStateCommon, fall::FallState}}, math::vec::FGVec2};
use crate::{fighter::{FighterInvulnerabilityState, animation::AnimKind, state::{FighterState, FighterStateImpl, air::AirborneStateCommon, fall::FallState}}, math::vec::FGVec2};
#[derive(Debug, Clone, Hash)]
pub struct AngelState {
@@ -38,6 +38,7 @@ impl FighterStateImpl for AngelState {
fn on_enter(&mut self, state_context: &mut super::EnterContext) {
state_context.play_animation(AnimKind::Wait, true);
state_context.velocity.0 = FGVec2::ZERO;
*state_context.vulnerability = FighterInvulnerabilityState::Invulnerable { frames_remaining: Some(state_context.game_settings.fighter_common.angel_platform_invulnerability_duration) };
}
fn check_collision_interrupt(
+7 -1
View File
@@ -161,6 +161,7 @@ pub struct EnterContext<'a> {
pub facing_direction: &'a mut FighterFacingDirection,
pub animation_frame: &'a mut FighterAnimationFrame,
pub surface: &'a mut FighterSurfaceState,
pub vulnerability: &'a mut FighterInvulnerabilityState,
pub fighter_attributes: &'a FighterAttributes,
pub attack_script_assets: &'a FighterAttackScriptAssets,
pub game_settings: &'a GameSettings,
@@ -329,6 +330,7 @@ impl<'w, 's> FighterFrameQueryItem<'w, 's> {
facing_direction: &mut self.facing_direction,
animation_frame: &mut self.animation_frame,
surface: &mut self.surface,
vulnerability: &mut self.vulnerability,
fighter_attributes: attributes,
attack_script_assets,
game_settings,
@@ -599,7 +601,11 @@ pub fn state_collision_interrupt_system(
if pending_respawn.0 {
**pending_respawn = false;
let respawn_state = FighterState::Angel(angel::AngelState::new(60 * 3));
let respawn_state = FighterState::Angel(angel::AngelState::new(
game_settings
.fighter_common
.angel_platform_invulnerability_duration,
));
// Find the angel platform position
let respawn_point = stage_manifest