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>, q_moved_planets: Query<(Entity, &Transform, &LastStagedTransform), Changed>, q_changed_planets: Query>, q_planets: Query<(&Planet, &Transform)>, mut update_packets_out: MessageWriter>, mut commands: Commands ) { let mut planets_to_send: BTreeSet = 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 = 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, }); }