diff --git a/Cargo.lock b/Cargo.lock index 5f37820b..5ed18d13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2609,6 +2609,8 @@ dependencies = [ "criterion", "de_core", "de_map", + "de_messages", + "de_multiplayer", "de_objects", "de_types", "futures-lite", diff --git a/crates/messages/src/players/mod.rs b/crates/messages/src/players/mod.rs index d66719e8..ad452e13 100644 --- a/crates/messages/src/players/mod.rs +++ b/crates/messages/src/players/mod.rs @@ -70,7 +70,7 @@ pub enum ToPlayers { /// replaced by this one. SetPath { entity: EntityNet, - waypoints: PathNet, + waypoints: Option, }, /// Instantaneously transform an object. /// diff --git a/crates/pathing/Cargo.toml b/crates/pathing/Cargo.toml index 1c311735..9c8130bb 100644 --- a/crates/pathing/Cargo.toml +++ b/crates/pathing/Cargo.toml @@ -15,6 +15,8 @@ categories.workspace = true # DE de_core.workspace = true de_map.workspace = true +de_messages.workspace = true +de_multiplayer.workspace = true de_objects.workspace = true de_types.workspace = true diff --git a/crates/pathing/src/lib.rs b/crates/pathing/src/lib.rs index 4fff8164..7a03814a 100644 --- a/crates/pathing/src/lib.rs +++ b/crates/pathing/src/lib.rs @@ -13,6 +13,7 @@ mod graph; mod path; mod pplugin; mod query; +mod syncing; mod triangulation; mod utils; @@ -24,6 +25,7 @@ pub use path::ScheduledPath; use pplugin::PathingPlugin; pub use pplugin::UpdateEntityPathEvent; pub use query::{PathQueryProps, PathTarget}; +use syncing::SyncingPlugin; pub struct PathingPluginGroup; @@ -32,5 +34,6 @@ impl PluginGroup for PathingPluginGroup { PluginGroupBuilder::start::() .add(FinderPlugin) .add(PathingPlugin) + .add(SyncingPlugin) } } diff --git a/crates/pathing/src/path.rs b/crates/pathing/src/path.rs index a8cd7731..6bbc642f 100644 --- a/crates/pathing/src/path.rs +++ b/crates/pathing/src/path.rs @@ -25,6 +25,10 @@ impl ScheduledPath { Self { path, current } } + pub(crate) fn path(&self) -> &Path { + &self.path + } + /// Returns the final point of the path schedule. pub fn destination(&self) -> Vec2 { self.path.waypoints()[0] diff --git a/crates/pathing/src/syncing.rs b/crates/pathing/src/syncing.rs new file mode 100644 index 00000000..d63ad8f3 --- /dev/null +++ b/crates/pathing/src/syncing.rs @@ -0,0 +1,55 @@ +use bevy::prelude::*; +use de_core::{objects::Local, schedule::Movement, state::AppState}; +use de_messages::ToPlayers; +use de_multiplayer::{NetEntities, ToPlayersEvent}; + +use crate::ScheduledPath; + +pub struct SyncingPlugin; + +impl Plugin for SyncingPlugin { + fn build(&self, app: &mut App) { + app.add_systems( + Movement, + (send_new_paths, send_removed_paths).run_if(in_state(AppState::InGame)), + ); + } +} + +// TODO rename +fn send_new_paths( + net_entities: NetEntities, + updates: Query<(Entity, &ScheduledPath), (With, Changed)>, + mut net_events: EventWriter, +) { + // TODO only if is multiplayer + + for (entity, scheduled_path) in updates.iter() { + net_events.send(ToPlayersEvent::new(ToPlayers::SetPath { + entity: net_entities.local_net_id(entity), + waypoints: Some(scheduled_path.path().try_into().unwrap()), + })); + } +} + +// TODO rename +fn send_removed_paths( + net_entities: NetEntities, + locals: Query>, + mut removes: RemovedComponents, + mut net_events: EventWriter, +) { + // TODO only if multiplayer + + for entity in removes.iter() { + if !locals.contains(entity) { + // It is either a spawned entity or non-local entity. + continue; + } + + net_events.send(ToPlayersEvent::new(ToPlayers::SetPath { + entity: net_entities.local_net_id(entity), + waypoints: None, + })); + } +}