use bevy::prelude::*; use crate::{ GameState, head::ActiveHead, heads_database::{HeadControls, HeadsDatabase}, }; mod collisions; pub mod controller_common; pub mod controller_flying; pub mod controller_running; pub mod controls; #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone, Default)] enum ControllerSet { CollectInputs, ApplyControlsFly, #[default] ApplyControlsRun, } #[derive(Resource, Debug, Clone, Copy, Default, PartialEq)] pub struct ControlState { /// Movement direction with a maximum length of 1.0 pub move_dir: Vec2, pub look_dir: Vec2, pub jump: bool, /// Determines if the camera can rotate freely around the player pub view_mode: bool, } #[derive(Resource, Debug, Default)] struct Controls { keyboard_state: ControlState, gamepad_state: Option, } #[derive(Event)] pub struct ControllerSwitchEvent; #[derive(Resource, Debug, Default, PartialEq)] pub struct SelectedController(ControllerSet); pub fn plugin(app: &mut App) { app.init_resource::(); app.init_resource::(); app.add_plugins(controls::plugin); app.add_plugins(controller_common::plugin); app.add_plugins(controller_flying::CharacterControllerPlugin); app.add_plugins(controller_running::CharacterControllerPlugin); app.add_event::(); app.configure_sets( Update, ( ControllerSet::CollectInputs, ControllerSet::ApplyControlsFly.run_if(resource_equals(SelectedController( ControllerSet::ApplyControlsFly, ))), ControllerSet::ApplyControlsRun.run_if(resource_equals(SelectedController( ControllerSet::ApplyControlsRun, ))), ) .chain() .run_if(in_state(GameState::Playing)), ); app.add_systems(Update, head_change.run_if(in_state(GameState::Playing))); } fn head_change( query: Query<&ActiveHead, Changed>, heads_db: Res, mut selected_controller: ResMut, mut event_controller_switch: EventWriter, ) { for head in query.iter() { let stats = heads_db.head_stats(head.0); let controller = match stats.controls { HeadControls::Plane => ControllerSet::ApplyControlsFly, HeadControls::Walk => ControllerSet::ApplyControlsRun, }; if selected_controller.0 != controller { event_controller_switch.send(ControllerSwitchEvent); selected_controller.0 = controller; } } }