1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use bevy::prelude::*;
use de_core::{
    gconfig::is_multiplayer,
    schedule::{Movement, PreMovement},
    state::AppState,
};
use de_messages::ToPlayers;
use de_multiplayer::{GameNetSet, NetEntities, NetRecvSetPathEvent, ToPlayersEvent};

use crate::{
    pplugin::{PathFoundEvent, PathingSet},
    ScheduledPath,
};

pub struct SyncingPlugin;

impl Plugin for SyncingPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(
            PreMovement,
            receive_paths
                .run_if(on_event::<NetRecvSetPathEvent>())
                .run_if(in_state(AppState::InGame))
                .after(GameNetSet::Messages),
        )
        .add_systems(
            Movement,
            send_new_paths
                .run_if(is_multiplayer)
                .run_if(in_state(AppState::InGame))
                .after(PathingSet::PathResults),
        );
    }
}

fn receive_paths(mut commands: Commands, mut events: EventReader<NetRecvSetPathEvent>) {
    for event in events.read() {
        let mut entity_commands = commands.entity(event.entity());

        match event.path() {
            Some(path) => {
                entity_commands.insert(ScheduledPath::new(path.clone()));
            }
            None => {
                entity_commands.remove::<ScheduledPath>();
            }
        }
    }
}

fn send_new_paths(
    net_entities: NetEntities,
    mut path_events: EventReader<PathFoundEvent>,
    mut net_events: EventWriter<ToPlayersEvent>,
) {
    for event in path_events.read() {
        net_events.send(ToPlayersEvent::new(ToPlayers::SetPath {
            entity: net_entities.local_net_id(event.entity()),
            waypoints: event.path().map(|p| p.try_into().unwrap()),
        }));
    }
}