~starkingdoms/starkingdoms

ref: 08355656f50d8e095c280962b250178acbd1299f starkingdoms/crates/unified/src/server/net/update_planets.rs -rw-r--r-- 2.6 KiB
08355656 — core netcode: planet updates 8 days ago
                                                                                
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
63
64
use std::collections::BTreeSet;
use bevy::prelude::{Added, Changed, Commands, MessageWriter, Query};
use crate::prelude::{Entity, Transform};
use crate::shared::config::planet::Planet;
use crate::shared::net::planet::{PlanetUpdatePacket, UpdatedPlanet};
use crate::shared::net::staged_transform::LastStagedTransform;
use crate::shared::net::{SendTargets, ToClients};

pub fn send_updated_planets(
    q_new_planets: Query<(Entity, &Transform), Added<Planet>>,
    q_moved_planets: Query<(Entity, &Transform, &LastStagedTransform), Changed<Transform>>,
    q_changed_planets: Query<Entity, Changed<Planet>>,

    q_planets: Query<(&Planet, &Transform)>,

    mut update_packets_out: MessageWriter<ToClients<PlanetUpdatePacket>>,
    mut commands: Commands
) {
    let mut planets_to_send: BTreeSet<Entity> = BTreeSet::new();

    // Updating the Planet behavior triggers sprite loading on the client. We don't want to send it every time the Transform changes
    let mut planets_with_planet_change: BTreeSet<Entity> = BTreeSet::new();

    for (new_planet, transform) in q_new_planets.iter() {
        planets_to_send.insert(new_planet); // Always send newly created planets...
        // ...and add LastStagedTransform...
        commands.entity(new_planet).insert(LastStagedTransform(*transform));
        // and put a marker, we need to copy planet data across
        planets_with_planet_change.insert(new_planet);
    }
    for (moved_planet, current_transform, maybe_staged_transform) in q_moved_planets.iter() {
        // have we had a significant transform change?
        if !maybe_staged_transform.should_update(current_transform) { continue; }
        // we have, resend
        planets_to_send.insert(moved_planet);
    }
    for changed_planet in q_changed_planets.iter() {
        // if Planet changed, always resend
        planets_to_send.insert(changed_planet);
        // and put a marker, we need to copy planet data across
        planets_with_planet_change.insert(changed_planet);
    }

    // process all planets to send
    let mut packet = PlanetUpdatePacket {
        updated_planets: vec![]
    };

    for planet_to_send in planets_to_send.iter() {
        let Ok(planet_info) = q_planets.get(*planet_to_send) else { continue };

        packet.updated_planets.push(UpdatedPlanet {
            server_entity: *planet_to_send,
            planet: planet_info.0.clone(),
            planet_data_changed: planets_with_planet_change.contains(planet_to_send),
            transform: *planet_info.1,
        });
    }

    update_packets_out.write(ToClients {
        message: packet,
        targets: SendTargets::All,
    });
}