Input replication (#62)

This commit is contained in:
PROMETHIA-27
2025-08-25 03:41:28 -04:00
committed by GitHub
parent c650924d68
commit 7f6c00b5d6
20 changed files with 345 additions and 280 deletions

View File

@@ -1,20 +1,13 @@
use super::{BackbackSwapEvent, Backpack, UiHeadState};
use super::{Backpack, UiHeadState};
use crate::{
GameState, HEDZ_GREEN, global_observer, heads::HeadsImages, loading_assets::UIAssets,
sounds::PlaySound,
GameState, HEDZ_GREEN, backpack::BackbackSwapEvent, control::ControlState, heads::HeadsImages,
loading_assets::UIAssets, sounds::PlaySound,
};
use bevy::{ecs::spawn::SpawnIter, prelude::*};
use lightyear::prelude::input::native::ActionState;
static HEAD_SLOTS: usize = 5;
#[derive(Event, Clone, Copy, Reflect, PartialEq)]
pub enum BackpackAction {
Left,
Right,
Swap,
OpenClose,
}
#[derive(Component, Default)]
struct BackpackMarker;
@@ -30,7 +23,8 @@ struct HeadImage(pub usize);
#[derive(Component, Default)]
struct HeadDamage(pub usize);
#[derive(Resource, Default, Debug)]
#[derive(Resource, Default, Debug, Reflect)]
#[reflect(Resource, Default)]
struct BackpackUiState {
heads: [Option<UiHeadState>; 5],
scroll: usize,
@@ -46,6 +40,7 @@ impl BackpackUiState {
}
pub fn plugin(app: &mut App) {
app.register_type::<BackpackUiState>();
app.init_resource::<BackpackUiState>();
app.add_systems(OnEnter(GameState::Playing), setup);
app.add_systems(
@@ -53,8 +48,7 @@ pub fn plugin(app: &mut App) {
(update, sync_on_change, update_visibility, update_count)
.run_if(in_state(GameState::Playing)),
);
global_observer!(app, swap_head_inputs);
app.add_systems(FixedUpdate, swap_head_inputs);
}
fn setup(mut commands: Commands, assets: Res<UIAssets>) {
@@ -262,52 +256,58 @@ fn update(
}
fn swap_head_inputs(
trigger: Trigger<BackpackAction>,
backpack: Res<Backpack>,
player: Query<(&ActionState<ControlState>, Ref<Backpack>)>,
mut commands: Commands,
mut state: ResMut<BackpackUiState>,
time: Res<Time>,
) {
if state.count == 0 {
return;
}
for (controls, backpack) in player.iter() {
if state.count == 0 {
return;
}
let action = *trigger.event();
if action == BackpackAction::OpenClose {
state.open = !state.open;
commands.trigger(PlaySound::Backpack { open: state.open });
}
if controls.backpack_toggle {
state.open = !state.open;
commands.trigger(PlaySound::Backpack { open: state.open });
}
if !state.open {
return;
}
if !state.open {
return;
}
let mut changed = false;
if action == BackpackAction::Left && state.current_slot > 0 {
state.current_slot -= 1;
changed = true;
}
if action == BackpackAction::Right && state.current_slot < state.count.saturating_sub(1) {
state.current_slot += 1;
changed = true;
}
if action == BackpackAction::Swap {
commands.trigger(BackbackSwapEvent(state.current_slot));
}
let mut changed = false;
if controls.backpack_left && state.current_slot > 0 {
state.current_slot -= 1;
changed = true;
}
if controls.backpack_right && state.current_slot < state.count.saturating_sub(1) {
state.current_slot += 1;
changed = true;
}
if controls.backpack_swap {
commands.trigger(BackbackSwapEvent(state.current_slot));
}
if changed {
commands.trigger(PlaySound::Selection);
sync(&backpack, &mut state, time.elapsed_secs());
if changed {
commands.trigger(PlaySound::Selection);
sync(&backpack, &mut state, time.elapsed_secs());
}
}
}
fn sync_on_change(backpack: Res<Backpack>, mut state: ResMut<BackpackUiState>, time: Res<Time>) {
if backpack.is_changed() || backpack.reloading() {
sync(&backpack, &mut state, time.elapsed_secs());
fn sync_on_change(
backpack: Query<Ref<Backpack>>,
mut state: ResMut<BackpackUiState>,
time: Res<Time>,
) {
for backpack in backpack.iter() {
if backpack.is_changed() || backpack.reloading() {
sync(&backpack, &mut state, time.elapsed_secs());
}
}
}
fn sync(backpack: &Res<Backpack>, state: &mut ResMut<BackpackUiState>, time: f32) {
fn sync(backpack: &Backpack, state: &mut ResMut<BackpackUiState>, time: f32) {
state.count = backpack.heads.len();
state.scroll = state.scroll.min(state.count.saturating_sub(HEAD_SLOTS));

View File

@@ -5,11 +5,12 @@ use crate::{
cash::CashCollectEvent, global_observer, head_drop::HeadCollected, heads::HeadState,
heads_database::HeadsDatabase,
};
pub use backpack_ui::BackpackAction;
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
pub use ui_head_state::UiHeadState;
#[derive(Resource, Default)]
#[derive(Component, Default, Reflect, Serialize, Deserialize, PartialEq)]
#[reflect(Component)]
pub struct Backpack {
pub heads: Vec<HeadState>,
}
@@ -38,7 +39,7 @@ impl Backpack {
pub struct BackbackSwapEvent(pub usize);
pub fn plugin(app: &mut App) {
app.init_resource::<Backpack>();
app.register_type::<Backpack>();
app.add_plugins(backpack_ui::plugin);
@@ -48,14 +49,18 @@ pub fn plugin(app: &mut App) {
fn on_head_collect(
trigger: Trigger<HeadCollected>,
mut cmds: Commands,
mut backpack: ResMut<Backpack>,
mut backpack: Query<&mut Backpack>,
heads_db: Res<HeadsDatabase>,
) {
) -> Result {
let HeadCollected(head) = *trigger.event();
let mut backpack = backpack.get_mut(trigger.target())?;
if backpack.contains(head) {
cmds.trigger(CashCollectEvent);
} else {
backpack.insert(head, heads_db.as_ref());
}
Ok(())
}