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,
});
}