Clientside Backpack UI (#84)

This commit is contained in:
PROMETHIA-27
2025-12-10 18:31:42 -05:00
committed by GitHub
parent 668ed93475
commit 65663f682f
12 changed files with 178 additions and 270 deletions

View File

@@ -1,128 +0,0 @@
use bevy::prelude::*;
use bevy_replicon::prelude::{ClientState, FromClient, SendMode, ServerTriggerExt, ToClients};
use shared::{
GameState,
backpack::{
BackbackSwapEvent, Backpack, UiHeadState,
backpack_ui::{BackpackUiState, HEAD_SLOTS},
},
control::{
BackpackLeftPressed, BackpackRightPressed, BackpackSwapPressed, BackpackTogglePressed,
},
protocol::{ClientToController, PlaySound},
};
pub fn plugin(app: &mut App) {
app.add_systems(
FixedUpdate,
sync_on_change.run_if(in_state(GameState::Playing)),
);
app.add_systems(
FixedUpdate,
swap_head_inputs.run_if(in_state(ClientState::Disconnected)),
);
}
#[allow(clippy::too_many_arguments)]
fn swap_head_inputs(
backpacks: Query<Ref<Backpack>>,
clients: ClientToController,
mut backpack_toggles: MessageReader<FromClient<BackpackTogglePressed>>,
mut backpack_lefts: MessageReader<FromClient<BackpackLeftPressed>>,
mut backpack_rights: MessageReader<FromClient<BackpackRightPressed>>,
mut backpack_swaps: MessageReader<FromClient<BackpackSwapPressed>>,
mut commands: Commands,
mut state: Single<&mut BackpackUiState>,
time: Res<Time>,
) {
for _ in backpack_toggles.read() {
if state.count == 0 {
return;
}
state.open = !state.open;
commands.server_trigger(ToClients {
mode: SendMode::Broadcast,
message: PlaySound::Backpack { open: state.open },
});
}
for press in backpack_lefts.read() {
let player = clients.get_controller(press.client_id);
let backpack = backpacks.get(player).unwrap();
if !state.open {
return;
}
if state.current_slot > 0 {
state.current_slot -= 1;
commands.server_trigger(ToClients {
mode: SendMode::Broadcast,
message: PlaySound::Selection,
});
sync(&backpack, &mut state, time.elapsed_secs());
}
}
for press in backpack_rights.read() {
let player = clients.get_controller(press.client_id);
let backpack = backpacks.get(player).unwrap();
if !state.open {
return;
}
if state.current_slot < state.count.saturating_sub(1) {
state.current_slot += 1;
commands.server_trigger(ToClients {
mode: SendMode::Broadcast,
message: PlaySound::Selection,
});
sync(&backpack, &mut state, time.elapsed_secs());
}
}
for _ in backpack_swaps.read() {
if !state.open {
return;
}
commands.trigger(BackbackSwapEvent(state.current_slot));
}
}
fn sync_on_change(
backpack: Query<Ref<Backpack>>,
mut state: Single<&mut 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: &Backpack, state: &mut Single<&mut BackpackUiState>, time: f32) {
state.count = backpack.heads.len();
state.scroll = state.scroll.min(state.count.saturating_sub(HEAD_SLOTS));
if state.current_slot >= state.scroll + HEAD_SLOTS {
state.scroll = state.current_slot.saturating_sub(HEAD_SLOTS - 1);
}
if state.current_slot < state.scroll {
state.scroll = state.current_slot;
}
for i in 0..HEAD_SLOTS {
if let Some(head) = backpack.heads.get(i + state.scroll) {
state.heads[i] = Some(UiHeadState::new(*head, time));
} else {
state.heads[i] = None;
}
}
}

View File

@@ -1,7 +0,0 @@
pub mod backpack_ui;
use bevy::prelude::*;
pub fn plugin(app: &mut App) {
app.add_plugins(backpack_ui::plugin);
}

View File

@@ -6,7 +6,6 @@ use bevy_trenchbroom::prelude::*;
use bevy_trenchbroom_avian::AvianPhysicsBackend;
use shared::{DebugVisuals, GameState, heads_database::HeadDatabaseAsset};
mod backpack;
mod config;
mod head_drop;
mod platforms;
@@ -119,7 +118,6 @@ fn main() {
app.add_plugins(server::plugin);
app.add_plugins(shared::protocol::plugin);
app.add_plugins(backpack::plugin);
app.add_plugins(config::plugin);
app.add_plugins(head_drop::plugin);
app.add_plugins(platforms::plugin);