move clientside gated parts of control to the client (#70)
This commit is contained in:
@@ -1,21 +1,15 @@
|
||||
use super::{ControlState, Controls};
|
||||
#[cfg(feature = "client")]
|
||||
use crate::control::ControllerSet;
|
||||
use super::Controls;
|
||||
use crate::{GameState, control::CharacterInputEnabled};
|
||||
#[cfg(feature = "client")]
|
||||
use bevy::input::{
|
||||
ButtonState,
|
||||
gamepad::{GamepadConnection, GamepadEvent},
|
||||
mouse::{MouseButtonInput, MouseMotion},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
#[cfg(feature = "client")]
|
||||
use lightyear::input::client::InputSet;
|
||||
#[cfg(feature = "client")]
|
||||
use lightyear::prelude::input::native::{ActionState, InputMarker};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use shared::control::{ControlState, ControllerSet};
|
||||
use std::collections::HashMap;
|
||||
#[cfg(feature = "client")]
|
||||
use std::hash::Hash;
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
@@ -24,12 +18,8 @@ pub fn plugin(app: &mut App) {
|
||||
|
||||
app.register_required_components::<Gamepad, InputStateCache<GamepadButton>>();
|
||||
|
||||
app.register_type::<ControllerSettings>();
|
||||
|
||||
app.add_systems(PreUpdate, (cache_keyboard_state, cache_gamepad_state));
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
{
|
||||
app.add_systems(
|
||||
FixedPreUpdate,
|
||||
(
|
||||
@@ -54,7 +44,6 @@ pub fn plugin(app: &mut App) {
|
||||
FixedPreUpdate,
|
||||
buffer_inputs.in_set(InputSet::WriteClientInputs),
|
||||
);
|
||||
}
|
||||
|
||||
app.add_systems(
|
||||
Update,
|
||||
@@ -62,14 +51,6 @@ pub fn plugin(app: &mut App) {
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Component, Clone, PartialEq, Reflect, Serialize, Deserialize)]
|
||||
#[reflect(Component)]
|
||||
pub struct ControllerSettings {
|
||||
pub deceleration_factor: f32,
|
||||
pub jump_force: f32,
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Write inputs from combined keyboard/gamepad state into the networked input buffer
|
||||
/// for the local player.
|
||||
fn buffer_inputs(
|
||||
@@ -104,7 +85,6 @@ impl<Button> Default for InputStateCache<Button> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
impl<Button: Hash + Eq> InputStateCache<Button> {
|
||||
fn clear(&mut self) {
|
||||
for state in self.map.values_mut() {
|
||||
@@ -151,7 +131,6 @@ fn cache_keyboard_state(
|
||||
cache_key(KeyCode::KeyE);
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
fn clear_keyboard_state(mut cache: ResMut<InputStateCache<KeyCode>>) {
|
||||
cache.clear();
|
||||
}
|
||||
@@ -182,14 +161,12 @@ fn cache_gamepad_state(mut gamepads: Query<(&Gamepad, &mut InputStateCache<Gamep
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
fn clear_gamepad_state(mut caches: Query<&mut InputStateCache<GamepadButton>>) {
|
||||
for mut cache in caches.iter_mut() {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Take keyboard and gamepad state and combine them into unified input state
|
||||
fn combine_controls(controls: Res<Controls>, mut combined_controls: ResMut<ControlState>) {
|
||||
let keyboard = controls.keyboard_state;
|
||||
@@ -210,7 +187,6 @@ fn combine_controls(controls: Res<Controls>, mut combined_controls: ResMut<Contr
|
||||
combined_controls.cash_heal = gamepad.cash_heal | keyboard.cash_heal;
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Applies a square deadzone to a Vec2
|
||||
fn deadzone_square(v: Vec2, min: f32) -> Vec2 {
|
||||
Vec2::new(
|
||||
@@ -219,7 +195,6 @@ fn deadzone_square(v: Vec2, min: f32) -> Vec2 {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Collect gamepad inputs
|
||||
fn gamepad_controls(
|
||||
gamepads: Query<(Entity, &Gamepad, &InputStateCache<GamepadButton>)>,
|
||||
@@ -282,7 +257,6 @@ fn gamepad_controls(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Collect mouse movement input
|
||||
fn mouse_rotate(mut mouse: EventReader<MouseMotion>, mut controls: ResMut<Controls>) {
|
||||
controls.keyboard_state.look_dir = Vec2::ZERO;
|
||||
@@ -292,7 +266,6 @@ fn mouse_rotate(mut mouse: EventReader<MouseMotion>, mut controls: ResMut<Contro
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Collect keyboard input
|
||||
fn keyboard_controls(
|
||||
keyboard: Res<ButtonInput<KeyCode>>,
|
||||
@@ -325,7 +298,6 @@ fn keyboard_controls(
|
||||
controls.keyboard_state.cash_heal = cache.just_pressed(KeyCode::Enter);
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Collect mouse button input when pressed
|
||||
fn mouse_click(mut events: EventReader<MouseButtonInput>, mut controls: ResMut<Controls>) {
|
||||
controls.keyboard_state.just_triggered = false;
|
||||
@@ -352,7 +324,6 @@ fn mouse_click(mut events: EventReader<MouseButtonInput>, mut controls: ResMut<C
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
/// Receive gamepad connections and disconnections
|
||||
fn gamepad_connections(mut evr_gamepad: EventReader<GamepadEvent>) {
|
||||
for ev in evr_gamepad.read() {
|
||||
28
crates/client/src/control/mod.rs
Normal file
28
crates/client/src/control/mod.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use crate::GameState;
|
||||
use bevy::prelude::*;
|
||||
use shared::control::{ControlState, ControllerSet};
|
||||
|
||||
pub mod controls;
|
||||
|
||||
#[derive(Resource, Debug, Default)]
|
||||
struct Controls {
|
||||
keyboard_state: ControlState,
|
||||
gamepad_state: Option<ControlState>,
|
||||
}
|
||||
|
||||
#[derive(Resource, Debug, PartialEq, Eq)]
|
||||
pub enum CharacterInputEnabled {
|
||||
On,
|
||||
Off,
|
||||
}
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.insert_resource(CharacterInputEnabled::On);
|
||||
|
||||
app.add_plugins(controls::plugin);
|
||||
|
||||
app.configure_sets(
|
||||
FixedPreUpdate,
|
||||
ControllerSet::CollectInputs.run_if(in_state(GameState::Playing)),
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
mod backpack;
|
||||
mod client;
|
||||
mod control;
|
||||
mod debug;
|
||||
mod enemy;
|
||||
mod heal_effect;
|
||||
@@ -124,6 +125,7 @@ fn main() {
|
||||
|
||||
app.add_plugins(backpack::plugin);
|
||||
app.add_plugins(client::plugin);
|
||||
app.add_plugins(control::plugin);
|
||||
app.add_plugins(debug::plugin);
|
||||
app.add_plugins(enemy::plugin);
|
||||
app.add_plugins(heal_effect::plugin);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::GameState;
|
||||
use crate::{GameState, control::CharacterInputEnabled};
|
||||
use bevy::{color::palettes::css::BLACK, prelude::*};
|
||||
use shared::{HEDZ_GREEN, HEDZ_PURPLE, control::CharacterInputEnabled, loading_assets::UIAssets};
|
||||
use shared::{HEDZ_GREEN, HEDZ_PURPLE, loading_assets::UIAssets};
|
||||
|
||||
#[derive(States, Default, Clone, Eq, PartialEq, Debug, Hash)]
|
||||
#[states(scoped_entities)]
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
GameState,
|
||||
abilities::TriggerStateRes,
|
||||
animation::AnimationFlags,
|
||||
control::{ControlState, SelectedController, controls::ControllerSettings},
|
||||
control::{ControlState, ControllerSettings, SelectedController},
|
||||
head::ActiveHead,
|
||||
heads_database::{HeadControls, HeadsDatabase},
|
||||
physics_layers::GameLayer,
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::{ControlState, ControllerSet};
|
||||
use crate::{
|
||||
GameState,
|
||||
animation::AnimationFlags,
|
||||
control::{controller_common::MovementSpeedFactor, controls::ControllerSettings},
|
||||
control::{ControllerSettings, controller_common::MovementSpeedFactor},
|
||||
player::PlayerBodyMesh,
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
@@ -1,25 +1,60 @@
|
||||
use bevy::{ecs::entity::MapEntities, prelude::*};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
GameState,
|
||||
head::ActiveHead,
|
||||
heads_database::{HeadControls, HeadsDatabase},
|
||||
player::Player,
|
||||
};
|
||||
use bevy::{ecs::entity::MapEntities, prelude::*};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
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 {
|
||||
pub enum ControllerSet {
|
||||
CollectInputs,
|
||||
ApplyControlsFly,
|
||||
#[default]
|
||||
ApplyControlsRun,
|
||||
}
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct ControllerSwitchEvent;
|
||||
|
||||
#[derive(Resource, Debug, Default, PartialEq)]
|
||||
pub struct SelectedController(pub ControllerSet);
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.register_type::<ControllerSettings>();
|
||||
|
||||
app.init_resource::<SelectedController>();
|
||||
app.init_resource::<ControlState>();
|
||||
|
||||
app.add_event::<ControllerSwitchEvent>();
|
||||
|
||||
app.add_plugins(controller_common::plugin);
|
||||
app.add_plugins(controller_flying::CharacterControllerPlugin);
|
||||
app.add_plugins(controller_running::CharacterControllerPlugin);
|
||||
|
||||
app.configure_sets(
|
||||
FixedUpdate,
|
||||
(
|
||||
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)));
|
||||
}
|
||||
|
||||
#[derive(Resource, Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize, Reflect)]
|
||||
pub struct ControlState {
|
||||
/// Movement direction with a maximum length of 1.0
|
||||
@@ -43,57 +78,11 @@ impl MapEntities for ControlState {
|
||||
fn map_entities<E: EntityMapper>(&mut self, _entity_mapper: &mut E) {}
|
||||
}
|
||||
|
||||
#[derive(Resource, Debug, Default)]
|
||||
struct Controls {
|
||||
#[cfg(feature = "client")]
|
||||
keyboard_state: ControlState,
|
||||
#[cfg(feature = "client")]
|
||||
gamepad_state: Option<ControlState>,
|
||||
}
|
||||
|
||||
#[derive(Resource, Debug, PartialEq, Eq)]
|
||||
pub enum CharacterInputEnabled {
|
||||
On,
|
||||
Off,
|
||||
}
|
||||
|
||||
#[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.insert_resource(CharacterInputEnabled::On);
|
||||
|
||||
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(
|
||||
FixedPreUpdate,
|
||||
ControllerSet::CollectInputs.run_if(in_state(GameState::Playing)),
|
||||
)
|
||||
.configure_sets(
|
||||
FixedUpdate,
|
||||
(
|
||||
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)));
|
||||
#[derive(Component, Clone, PartialEq, Reflect, Serialize, Deserialize)]
|
||||
#[reflect(Component)]
|
||||
pub struct ControllerSettings {
|
||||
pub deceleration_factor: f32,
|
||||
pub jump_force: f32,
|
||||
}
|
||||
|
||||
fn head_change(
|
||||
|
||||
@@ -12,9 +12,8 @@ use crate::{
|
||||
cash::CashResource,
|
||||
character::{self, AnimatedCharacter},
|
||||
control::{
|
||||
ControlState,
|
||||
ControlState, ControllerSettings,
|
||||
controller_common::{MovementSpeedFactor, PlayerCharacterController},
|
||||
controls::ControllerSettings,
|
||||
},
|
||||
cutscene::StartCutscene,
|
||||
global_observer,
|
||||
|
||||
Reference in New Issue
Block a user