Replicate explosion effects (#56)
This commit is contained in:
@@ -1,21 +1,49 @@
|
||||
use bevy::ecs::{
|
||||
bundle::Bundle, resource::Resource, system::EntityCommands, world::EntityWorldMut,
|
||||
bundle::Bundle,
|
||||
event::Event,
|
||||
resource::Resource,
|
||||
system::{Commands, EntityCommands},
|
||||
world::{EntityWorldMut, World},
|
||||
};
|
||||
|
||||
#[derive(Default, Resource)]
|
||||
pub struct IsServer;
|
||||
|
||||
pub trait CommandExt {
|
||||
fn insert_server(&mut self, bundle: impl Bundle) -> &mut Self;
|
||||
fn trigger_server(&mut self, event: impl Event) -> &mut Self;
|
||||
}
|
||||
|
||||
impl<'w> CommandExt for EntityCommands<'w> {
|
||||
fn insert_server(&mut self, bundle: impl Bundle) -> &mut Self {
|
||||
self.queue(|mut entity: EntityWorldMut| {
|
||||
if entity.world().contains_resource::<IsServer>() {
|
||||
entity.insert(bundle);
|
||||
impl<'w, 's> CommandExt for Commands<'w, 's> {
|
||||
fn trigger_server(&mut self, event: impl Event) -> &mut Self {
|
||||
self.queue(|world: &mut World| {
|
||||
if world.contains_resource::<IsServer>() {
|
||||
world.trigger(event);
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EntityCommandExt {
|
||||
fn insert_server(&mut self, bundle: impl Bundle) -> &mut Self;
|
||||
|
||||
fn trigger_server(&mut self, event: impl Event) -> &mut Self;
|
||||
}
|
||||
|
||||
impl<'w> EntityCommandExt for EntityCommands<'w> {
|
||||
fn insert_server(&mut self, bundle: impl Bundle) -> &mut Self {
|
||||
self.queue(|mut entity: EntityWorldMut| {
|
||||
if entity.world().contains_resource::<IsServer>() {
|
||||
entity.insert(bundle);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn trigger_server(&mut self, event: impl Event) -> &mut Self {
|
||||
self.queue(|mut entity: EntityWorldMut| {
|
||||
if entity.world().contains_resource::<IsServer>() {
|
||||
entity.trigger(event);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ pub mod observers;
|
||||
pub mod sprite_3d_animation;
|
||||
pub mod squish_animation;
|
||||
pub mod trail;
|
||||
pub mod triggers;
|
||||
|
||||
use bevy::prelude::*;
|
||||
pub(crate) use observers::global_observer;
|
||||
|
||||
55
crates/shared/src/utils/triggers.rs
Normal file
55
crates/shared/src/utils/triggers.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use crate::utils::commands::IsServer;
|
||||
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<M>>,
|
||||
is_server: Option<Res<'w, IsServer>>,
|
||||
}
|
||||
|
||||
impl<'w, 's, M: Event + Clone> ServerMultiTriggerSender<'w, 's, M> {
|
||||
pub fn server_trigger_targets<C: Channel>(&mut self, trigger: M, target: &[Entity]) {
|
||||
if self.is_server.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
for mut sender in self.senders.iter_mut() {
|
||||
sender.trigger_targets::<C>(trigger.clone(), target.iter().copied());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TriggerAppExt {
|
||||
fn replicate_trigger<M: Event + Clone + Serialize + for<'de> Deserialize<'de>, C: Channel>(
|
||||
&mut self,
|
||||
);
|
||||
}
|
||||
|
||||
impl TriggerAppExt for App {
|
||||
fn replicate_trigger<M: Event + Clone + Serialize + for<'de> Deserialize<'de>, C: Channel>(
|
||||
&mut self,
|
||||
) {
|
||||
self.add_trigger::<M>()
|
||||
.add_direction(NetworkDirection::ServerToClient);
|
||||
self.add_observer(replicate_trigger_to_clients::<M, C>);
|
||||
self.add_observer(remote_to_local_trigger::<M>);
|
||||
}
|
||||
}
|
||||
|
||||
fn replicate_trigger_to_clients<M: Event + Clone, C: Channel>(
|
||||
trigger: Trigger<M>,
|
||||
mut sender: ServerMultiTriggerSender<M>,
|
||||
) {
|
||||
let targets: &[Entity] = if trigger.target() == Entity::PLACEHOLDER {
|
||||
&[]
|
||||
} else {
|
||||
&[trigger.target()]
|
||||
};
|
||||
sender.server_trigger_targets::<C>(trigger.event().clone(), targets);
|
||||
}
|
||||
|
||||
fn remote_to_local_trigger<M: Event + Clone>(trigger: Trigger<RemoteTrigger<M>>, mut c: Commands) {
|
||||
c.trigger_targets(trigger.event().trigger.clone(), trigger.target());
|
||||
}
|
||||
Reference in New Issue
Block a user