Sync reloading and cash (#66)

This commit is contained in:
PROMETHIA-27
2025-09-27 16:04:19 -04:00
committed by GitHub
parent 83c59519e5
commit fb4c6f501c
12 changed files with 285 additions and 225 deletions

View File

@@ -1,7 +1,16 @@
use super::{ActiveHeads, HEAD_SLOTS, HeadsImages};
use crate::{GameState, backpack::UiHeadState, loading_assets::UIAssets, player::Player};
#[cfg(feature = "server")]
use super::ActiveHeads;
use super::HEAD_SLOTS;
#[cfg(feature = "client")]
use super::HeadsImages;
#[cfg(feature = "server")]
use crate::player::Player;
use crate::{GameState, backpack::UiHeadState, loading_assets::UIAssets};
use bevy::{ecs::spawn::SpawnIter, prelude::*};
use bevy_ui_gradients::{AngularColorStop, BackgroundGradient, ConicGradient, Gradient, Position};
#[cfg(feature = "client")]
use bevy_ui_gradients::Gradient;
use bevy_ui_gradients::{AngularColorStop, BackgroundGradient, ConicGradient, Position};
use serde::{Deserialize, Serialize};
use std::f32::consts::PI;
#[derive(Component, Reflect, Default)]
@@ -16,9 +25,9 @@ struct HeadImage(pub usize);
#[reflect(Component)]
struct HeadDamage(pub usize);
#[derive(Resource, Default, Reflect)]
#[reflect(Resource)]
struct UiActiveHeads {
#[derive(Component, Default, Reflect, Serialize, Deserialize, PartialEq)]
#[reflect(Component)]
pub struct UiActiveHeads {
heads: [Option<UiHeadState>; 5],
selected_slot: usize,
}
@@ -28,9 +37,12 @@ pub fn plugin(app: &mut App) {
app.register_type::<UiActiveHeads>();
app.add_systems(OnEnter(GameState::Playing), setup);
#[cfg(feature = "server")]
app.add_systems(FixedUpdate, sync.run_if(in_state(GameState::Playing)));
#[cfg(feature = "client")]
app.add_systems(
Update,
(sync, update, update_ammo, update_health).run_if(in_state(GameState::Playing)),
FixedUpdate,
(update, update_ammo, update_health).run_if(in_state(GameState::Playing)),
);
}
@@ -61,8 +73,6 @@ fn setup(mut commands: Commands, assets: Res<UIAssets>) {
}
}))),
));
commands.init_resource::<UiActiveHeads>();
}
fn spawn_head_ui(
@@ -153,69 +163,69 @@ fn spawn_head_ui(
)
}
#[cfg(feature = "client")]
fn update(
res: Res<UiActiveHeads>,
res: Single<&UiActiveHeads, Changed<UiActiveHeads>>,
heads_images: Res<HeadsImages>,
mut head_image: Query<(&HeadImage, &mut Visibility, &mut ImageNode), Without<HeadSelector>>,
mut head_selector: Query<(&HeadSelector, &mut Visibility), Without<HeadImage>>,
) {
if res.is_changed() {
for (HeadImage(head), mut vis, mut image) in head_image.iter_mut() {
if let Some(head) = res.heads[*head] {
*vis = Visibility::Visible;
image.image = heads_images.heads[head.head].clone();
} else {
*vis = Visibility::Hidden;
}
}
for (HeadSelector(head), mut vis) in head_selector.iter_mut() {
*vis = if *head == res.selected_slot {
Visibility::Visible
} else {
Visibility::Hidden
};
for (HeadImage(head), mut vis, mut image) in head_image.iter_mut() {
if let Some(head) = res.heads[*head] {
*vis = Visibility::Visible;
image.image = heads_images.heads[head.head].clone();
} else {
*vis = Visibility::Hidden;
}
}
for (HeadSelector(head), mut vis) in head_selector.iter_mut() {
*vis = if *head == res.selected_slot {
Visibility::Visible
} else {
Visibility::Hidden
};
}
}
#[cfg(feature = "client")]
fn update_ammo(
res: Res<UiActiveHeads>,
res: Single<&UiActiveHeads, Changed<UiActiveHeads>>,
mut gradients: Query<(&mut BackgroundGradient, &HeadImage)>,
) {
if res.is_changed() {
for (mut gradient, HeadImage(head)) in gradients.iter_mut() {
if let Some(head) = res.heads[*head] {
let Gradient::Conic(gradient) = &mut gradient.0[0] else {
continue;
};
for (mut gradient, HeadImage(head)) in gradients.iter_mut() {
if let Some(head) = res.heads[*head] {
let Gradient::Conic(gradient) = &mut gradient.0[0] else {
continue;
};
let progress = if let Some(reloading) = head.reloading() {
1. - reloading
} else {
head.ammo_used()
};
let progress = if let Some(reloading) = head.reloading() {
1. - reloading
} else {
head.ammo_used()
};
let angle = progress * PI * 2.;
let angle = progress * PI * 2.;
gradient.stops[1].angle = Some(angle);
gradient.stops[2].angle = Some(angle);
}
gradient.stops[1].angle = Some(angle);
gradient.stops[2].angle = Some(angle);
}
}
}
fn update_health(res: Res<UiActiveHeads>, mut query: Query<(&mut Node, &HeadDamage)>) {
if res.is_changed() {
for (mut node, HeadDamage(head)) in query.iter_mut() {
node.height =
Val::Percent(res.heads[*head].map(|head| head.damage()).unwrap_or(0.) * 100.);
}
#[cfg(feature = "client")]
fn update_health(
res: Single<&UiActiveHeads, Changed<UiActiveHeads>>,
mut query: Query<(&mut Node, &HeadDamage)>,
) {
for (mut node, HeadDamage(head)) in query.iter_mut() {
node.height = Val::Percent(res.heads[*head].map(|head| head.damage()).unwrap_or(0.) * 100.);
}
}
#[cfg(feature = "server")]
fn sync(
active_heads: Query<Ref<ActiveHeads>, With<Player>>,
mut state: ResMut<UiActiveHeads>,
mut state: Single<&mut UiActiveHeads>,
time: Res<Time>,
) {
let Ok(active_heads) = active_heads.single() else {