use crate::utils::global_observer; use bevy::{ecs::system::SystemParam, prelude::*}; use lightyear::prelude::{AppTriggerExt, Channel, NetworkDirection, RemoteTrigger, TriggerSender}; use serde::{Deserialize, Serialize}; #[derive(SystemParam)] pub struct ServerMultiTriggerSender<'w, 's, M: Event + Clone> { senders: Query<'w, 's, &'static mut TriggerSender>, } impl<'w, 's, M: Event + Clone> ServerMultiTriggerSender<'w, 's, M> { pub fn server_trigger_targets(&mut self, trigger: M, target: &[Entity]) { if cfg!(not(feature = "server")) { return; } for mut sender in self.senders.iter_mut() { sender.trigger_targets::(trigger.clone(), target.iter().copied()); } } } pub trait TriggerAppExt { fn replicate_trigger Deserialize<'de>, C: Channel>( &mut self, ); } impl TriggerAppExt for App { fn replicate_trigger Deserialize<'de>, C: Channel>( &mut self, ) { self.add_trigger::() .add_direction(NetworkDirection::ServerToClient); global_observer!(self, replicate_trigger_to_clients::); global_observer!(self, remote_to_local_trigger::); } } fn replicate_trigger_to_clients( trigger: Trigger, mut sender: ServerMultiTriggerSender, ) { let targets: &[Entity] = if trigger.target() == Entity::PLACEHOLDER { &[] } else { &[trigger.target()] }; sender.server_trigger_targets::(trigger.event().clone(), targets); } fn remote_to_local_trigger(trigger: Trigger>, mut c: Commands) { c.trigger_targets(trigger.event().trigger.clone(), trigger.target()); }