UiActiveHeads can be a local player resource only

This commit is contained in:
2025-12-21 12:36:51 -05:00
parent 0735c429ca
commit fcb13eed31
3 changed files with 21 additions and 20 deletions

View File

@@ -21,9 +21,9 @@ struct HeadImage(pub usize);
#[reflect(Component)] #[reflect(Component)]
struct HeadDamage(pub usize); struct HeadDamage(pub usize);
#[derive(Component, Default, Reflect, Serialize, Deserialize, PartialEq)] #[derive(Resource, Default, Reflect, Serialize, Deserialize, PartialEq)]
#[reflect(Component)] #[reflect(Resource)]
pub struct UiActiveHeads { struct UiActiveHeads {
heads: [Option<UiHeadState>; 5], heads: [Option<UiHeadState>; 5],
selected_slot: usize, selected_slot: usize,
} }
@@ -32,11 +32,10 @@ pub fn plugin(app: &mut App) {
app.register_type::<HeadDamage>(); app.register_type::<HeadDamage>();
app.register_type::<UiActiveHeads>(); app.register_type::<UiActiveHeads>();
app.init_resource::<UiActiveHeads>();
app.add_systems(OnEnter(GameState::Playing), setup); app.add_systems(OnEnter(GameState::Playing), setup);
app.add_systems( app.add_systems(FixedUpdate, sync.run_if(in_state(GameState::Playing)));
FixedUpdate,
sync.run_if(in_state(GameState::Playing).and(is_server)),
);
#[cfg(feature = "client")] #[cfg(feature = "client")]
app.add_systems( app.add_systems(
FixedUpdate, FixedUpdate,
@@ -177,7 +176,7 @@ fn spawn_head_ui(
#[cfg(feature = "client")] #[cfg(feature = "client")]
fn update( fn update(
res: Single<&UiActiveHeads>, res: Res<UiActiveHeads>,
heads_images: Res<HeadsImages>, heads_images: Res<HeadsImages>,
mut head_image: Query<(&HeadImage, &mut Visibility, &mut ImageNode), Without<HeadSelector>>, mut head_image: Query<(&HeadImage, &mut Visibility, &mut ImageNode), Without<HeadSelector>>,
mut head_selector: Query<(&HeadSelector, &mut Visibility), Without<HeadImage>>, mut head_selector: Query<(&HeadSelector, &mut Visibility), Without<HeadImage>>,
@@ -201,10 +200,14 @@ fn update(
#[cfg(feature = "client")] #[cfg(feature = "client")]
fn update_ammo( fn update_ammo(
res: Single<&UiActiveHeads, Changed<UiActiveHeads>>, res: Res<UiActiveHeads>,
heads: Query<&HeadImage>, heads: Query<&HeadImage>,
mut gradients: Query<(&mut BackgroundGradient, &ChildOf)>, mut gradients: Query<(&mut BackgroundGradient, &ChildOf)>,
) { ) {
if !res.is_changed() {
return;
}
for (mut gradient, child_of) in gradients.iter_mut() { for (mut gradient, child_of) in gradients.iter_mut() {
let Ok(HeadImage(head)) = heads.get(child_of.parent()) else { let Ok(HeadImage(head)) = heads.get(child_of.parent()) else {
continue; continue;
@@ -230,18 +233,18 @@ fn update_ammo(
} }
#[cfg(feature = "client")] #[cfg(feature = "client")]
fn update_health( fn update_health(res: Res<UiActiveHeads>, mut query: Query<(&mut Node, &HeadDamage)>) {
res: Single<&UiActiveHeads, Changed<UiActiveHeads>>, if res.is_changed() {
mut query: Query<(&mut Node, &HeadDamage)>, for (mut node, HeadDamage(head)) in query.iter_mut() {
) { node.height =
for (mut node, HeadDamage(head)) in query.iter_mut() { Val::Percent(res.heads[*head].map(|head| head.damage()).unwrap_or(0.) * 100.);
node.height = Val::Percent(res.heads[*head].map(|head| head.damage()).unwrap_or(0.) * 100.); }
} }
} }
fn sync( fn sync(
active_heads: Single<Ref<ActiveHeads>, With<LocalPlayer>>, active_heads: Single<Ref<ActiveHeads>, With<LocalPlayer>>,
mut state: Single<&mut UiActiveHeads>, mut state: ResMut<UiActiveHeads>,
time: Res<Time>, time: Res<Time>,
) { ) {
if active_heads.is_changed() || active_heads.reloading() { if active_heads.is_changed() || active_heads.reloading() {

View File

@@ -9,7 +9,7 @@ use crate::{
global_observer, global_observer,
head::ActiveHead, head::ActiveHead,
head_drop::HeadDrops, head_drop::HeadDrops,
heads::{ActiveHeads, HeadChanged, HeadState, heads_ui::UiActiveHeads}, heads::{ActiveHeads, HeadChanged, HeadState},
heads_database::HeadsDatabase, heads_database::HeadsDatabase,
hitpoints::{Hitpoints, Kill}, hitpoints::{Hitpoints, Kill},
npc::SpawnCharacter, npc::SpawnCharacter,
@@ -96,7 +96,6 @@ pub fn spawn(
), ),
Backpack::default(), Backpack::default(),
BackpackUiState::default(), BackpackUiState::default(),
UiActiveHeads::default(),
Inputs::default(), Inputs::default(),
Replicated, Replicated,
)) ))

View File

@@ -16,7 +16,7 @@ use crate::{
cutscene::StartCutscene, cutscene::StartCutscene,
global_observer, global_observer,
head::ActiveHead, head::ActiveHead,
heads::{ActiveHeads, heads_ui::UiActiveHeads}, heads::ActiveHeads,
hitpoints::Hitpoints, hitpoints::Hitpoints,
npc::Npc, npc::Npc,
platforms::ActivePlatform, platforms::ActivePlatform,
@@ -107,7 +107,6 @@ pub fn plugin(app: &mut App) {
.replicate::<SquishAnimation>() .replicate::<SquishAnimation>()
.replicate_once::<Transform>() .replicate_once::<Transform>()
.replicate_once::<SpawnTrail>() .replicate_once::<SpawnTrail>()
.replicate::<UiActiveHeads>()
.replicate_as::<Visibility, SerVisibility>(); .replicate_as::<Visibility, SerVisibility>();
app.replicate_once::<ThrownProjectile>() app.replicate_once::<ThrownProjectile>()