use bevy::{ecs::event::ManualEventReader, prelude::*};
use starkingdoms_common::{
packet::{Packet, Part, Planet},
proto_part_flags, proto_transform,
};
use crate::{
module::component::{Attach, PartFlags, PartType},
planet::PlanetType,
ws::{PacketMessageConvert, WsEvent},
CLIENT_SCALE,
};
use super::component::Player;
pub fn send_player_energy(player_query: Query<&Player>, mut packet_send: EventWriter<WsEvent>) {
for player in &player_query {
let packet = Packet::EnergyUpdate {
amount: player.energy,
max: player.energy_capacity,
};
packet_send.send(WsEvent::Send {
to: player.addr,
message: packet.into_message(),
});
}
}
pub fn on_position_change(
mut commands: Commands,
part_query: Query<(Entity, &PartType, &Transform, &PartFlags), Changed<Transform>>,
planet_query: Query<(Entity, &PlanetType, &Transform), Changed<Transform>>,
mut packet_send: EventWriter<WsEvent>,
) {
let mut updated_parts = Vec::new();
for (entity, part_type, transform, flags) in part_query.iter() {
let id = commands.entity(entity).id().index();
updated_parts.push((
id,
Part {
part_type: part_type.0,
transform: proto_transform!(Transform::from_translation(
transform.translation * CLIENT_SCALE,
)
.with_rotation(transform.rotation)),
flags: proto_part_flags!(flags),
},
));
}
if !updated_parts.is_empty() {
let packet = Packet::PartPositions {
parts: updated_parts,
};
packet_send.send(WsEvent::Broadcast {
message: packet.into_message(),
});
}
let mut planets = Vec::new();
for (entity, planet_type, transform) in planet_query.iter() {
let id = commands.entity(entity).id().index();
planets.push((
id,
Planet {
planet_type: planet_type.0,
transform: proto_transform!(Transform::from_translation(
transform.translation * CLIENT_SCALE
)),
radius: planet!(*planet_type).size * CLIENT_SCALE,
},
));
}
if !planets.is_empty() {
let packet = Packet::PlanetPositions { planets };
packet_send.send(WsEvent::Broadcast {
message: packet.into_message(),
});
}
}
pub fn on_close(
player_query: Query<(Entity, &Player, &Attach)>,
attached_query: Query<&Attach, With<PartType>>,
part_query: Query<&PartType>,
mut commands: Commands,
mut packet_recv: Local<ManualEventReader<WsEvent>>,
mut packet_send: ResMut<Events<WsEvent>>,
) {
let mut packets = Vec::new();
for packet in packet_recv.read(&packet_send) {
if let WsEvent::Close { addr } = packet {
for (entity, player, attach) in &player_query {
if player.addr == *addr {
crate::module::despawn_module_tree(
&mut commands,
attach,
&attached_query,
&part_query,
&mut packets,
);
commands.entity(entity).despawn_recursive();
let packet = Packet::PlayerLeave { id: entity.index() };
for (in_entity, player, _) in &player_query {
if entity != in_entity {
packets.push(WsEvent::Send {
to: player.addr,
message: packet.clone().into_message(),
});
}
}
}
}
}
}
for packet in packets {
packet_send.send(packet);
}
}