Files
HEDZReloaded/src/control/mod.rs
2025-04-13 19:07:11 +02:00

94 lines
2.6 KiB
Rust

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<ControlState>,
}
#[derive(Event)]
pub struct ControllerSwitchEvent;
#[derive(Resource, Debug, Default, PartialEq)]
pub struct SelectedController(ControllerSet);
pub fn plugin(app: &mut App) {
app.init_resource::<SelectedController>();
app.init_resource::<ControlState>();
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::<ControllerSwitchEvent>();
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<ActiveHead>>,
heads_db: Res<HeadsDatabase>,
mut selected_controller: ResMut<SelectedController>,
mut event_controller_switch: EventWriter<ControllerSwitchEvent>,
) {
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;
}
}
}