use bevy::{ecs::relationship::RelationshipSourceCollection, prelude::*}; use crate::{fighter::{FighterAttributes, states}, game_settings::GameSettings, input::player::FighterInput}; pub enum FighterStateTransition { Wait, Walk, Dash } pub trait FighterState : Component + Sized { fn remove(&self, state_context: &FighterStateContext, commands: &mut Commands) { commands.entity(state_context.entity).remove::(); } fn check_interrupt( &self, state_context: &FighterStateContext, ) -> Option; } pub struct FighterStateContext<'a> { pub input: &'a mut FighterInput, pub fighter_attribs: &'a FighterAttributes, pub game_settings: &'a Res<'a, GameSettings>, pub entity: Entity, } fn create_state(transition: FighterStateTransition, state_context: FighterStateContext, commands: &mut Commands) { let mut ent_cmd = commands.entity(state_context.entity); match transition { FighterStateTransition::Wait => ent_cmd.insert(states::wait::WaitState), FighterStateTransition::Walk => ent_cmd.insert(states::walk::WalkState), FighterStateTransition::Dash => ent_cmd.insert(states::dash::DashState::default()), }; } pub fn state_interrupt_system( query: Query<(Entity, &T, &mut FighterInput, &FighterAttributes)>, game_settings: Res, mut commands: Commands, ) { for (ent, state, mut input, attribs) in query { info!("{:?}", state); let state_context = FighterStateContext { input: &mut input, fighter_attribs: &attribs, game_settings: &game_settings, entity: ent, }; if let Some(new_state) = state.check_interrupt(&state_context) { commands.entity(ent).remove::(); create_state(new_state, state_context, &mut commands); } } }