use std::collections::HashMap; use bevy_ecs::{ entity::Entity, event::Events, query::{QuerySingleError, With}, world::World, }; use nalgebra::{Rotation2, Scale3, Translation3}; use starkingdoms_common::{packet::Packet, PartType, PlanetType}; use crate::components::{Camera, Chat, Menu, Part, Player, PlayerResources, RecvPacket, SendPacket, ServerId, SpriteBundle, Texture, Transform}; #[cfg(target_arch = "wasm32")] #[path = "ws_wasm.rs"] pub mod ws; #[cfg(not(target_arch = "wasm32"))] #[path = "ws_native.rs"] pub mod ws; fn texture_name(part_type: PartType, attached: bool) -> String { use PartType::*; if attached { match part_type { Placeholder => panic!("AHHHH PLACEHOLDER PANIC"), Hearty => "hearty.svg", Cargo => "cargo_on.svg", Hub => "hub_on.svg", LandingThruster => "landingthruster_on.svg", LandingThrusterSuspension => "landingleg.svg", } .to_string() } else { match part_type { Placeholder => panic!("AHHHH PLACEHOLDER PANIC"), Hearty => "hearty.svg", Cargo => "cargo_off.svg", Hub => "hub_off.svg", LandingThruster => "landingthruster_off.svg", LandingThrusterSuspension => "landingleg.svg", } .to_string() } } pub fn process_packets( world: &mut World, _send_packet_events: &mut Events, recv_packet_events: &mut Events, planet_types: &mut HashMap, ) { use Packet::*; let mut recv_cursor = recv_packet_events.get_cursor(); for recv in recv_cursor.read(&recv_packet_events) { match &recv.0 { LoginResponse { id } => { let mut player_query = world.query_filtered::>(); let entity = player_query.single(world); world.entity_mut(entity).insert(ServerId(*id)); } PlayerList { players } => { // existing players // username sync, eventually for player in players { world.spawn(( Transform { translation: Translation3::new(0.0, 0.0, 0.0), rotation: Rotation2::new(0.0), scale: Scale3::new(25.0, 25.0, 1.0), }, Texture { name: "hearty.svg".to_string(), }, ServerId(player.0), Part(false), )); } } SpawnPlayer { id, .. } => { // username sync, eventually world.spawn(( Transform { translation: Translation3::new(0.0, 0.0, 0.0), rotation: Rotation2::new(0.0), scale: Scale3::new(25.0, 25.0, 1.0), }, Texture { name: "hearty.svg".to_string(), }, ServerId(*id), Part(false), )); } SpawnPart { id, part } => { world.spawn(( Transform { translation: Translation3::new(part.transform.x, part.transform.y, 0.0), rotation: Rotation2::new(part.transform.rot), scale: Scale3::new(25.0, 25.0, 1.0), }, Texture { name: texture_name(part.part_type, part.flags.attached), }, ServerId(*id), Part(part.flags.attached), )); } PartPositions { parts } => { for (id, part) in parts { if part.part_type == PartType::Hearty { let mut player_query = world.query_filtered::<&ServerId, With>(); let server_id = match player_query.get_single(world) { Ok(player) => player, Err(e) => match e { QuerySingleError::NoEntities(_) => { continue; } QuerySingleError::MultipleEntities(_) => { panic!("There should never multiple players marked as players"); } }, }; if server_id.0 == *id { let mut camera = world.resource_mut::(); camera.x = -part.transform.x; camera.y = -part.transform.y; } } let mut part_query = world .query::<(Entity, &ServerId, &mut Transform, &mut Texture, &mut Part)>( ); for (_, server_id, mut transform, mut texture, mut bevy_part) in part_query.iter_mut(world) { if server_id.0 == *id { transform.translation.x = part.transform.x; transform.translation.y = part.transform.y; transform.rotation = Rotation2::new(part.transform.rot); if part.flags.attached && !bevy_part.0 { texture.name = texture_name(part.part_type, part.flags.attached); bevy_part.0 = true; } else if !part.flags.attached && bevy_part.0 { texture.name = texture_name(part.part_type, part.flags.attached); bevy_part.0 = false; } } } } } PlanetPositions { planets } => { for (server_id, planet) in planets { if !planet_types.contains_key(&planet.planet_type) { let entity = world.spawn(SpriteBundle { transform: Transform { translation: Translation3::new( planet.transform.x, planet.transform.y, 0.0, ), rotation: Rotation2::new(planet.transform.rot), scale: Scale3::new(planet.radius, planet.radius, 1.0), }, texture: Texture { name: match planet.planet_type { /*PlanetType::Sun => "sun.svg", PlanetType::Mercury => "mercury.svg", PlanetType::Venus => "venus.svg", PlanetType::Earth => "earth.svg", PlanetType::Moon => "moon.svg", PlanetType::Mars => "mars.svg", PlanetType::Jupiter => "jupiter.svg", PlanetType::Saturn => "saturn.svg", PlanetType::Uranus => "uranus.svg", PlanetType::Neptune => "neptune.svg", PlanetType::Pluto => "pluto.svg",*/ PlanetType::Sun => "sun.svg", PlanetType::Mercury => "moon.svg", PlanetType::Venus => "venus.svg", PlanetType::Earth => "earth.svg", PlanetType::Moon => "moon.svg", PlanetType::Mars => "mars.svg", PlanetType::Jupiter => "jupiter.svg", PlanetType::Saturn => "sun.svg", PlanetType::Uranus => "venus.svg", PlanetType::Neptune => "mars.svg", PlanetType::Pluto => "earth.svg", } .to_string(), }, }); planet_types.insert(planet.planet_type, (entity.id(), *server_id)); } } } EnergyUpdate { amount, max, } => { let mut r = world.resource_mut::(); r.fuel_amount = *amount; r.fuel_max = *max; } OpenCraftingUi { id } => { let mut query = world.query::<(Entity, &ServerId)>(); let mut matching_id = None; for (entity, server_id) in query.iter(world) { if server_id.0 == *id { matching_id = Some(entity); } } if let Some(id) = matching_id { world.entity_mut(id).insert(Menu); } } Message { actor, content, .. } => { let mut chat = world.get_resource_mut::().unwrap(); chat.messages.push(format!("{}: {}", actor.clone(), content.clone())); } PlayerLeave { id } => { let mut part_query = world.query_filtered::<(Entity, &ServerId), With>(); let mut entity_to_remove = None; for (entity, server_id) in part_query.iter_mut(world) { if server_id.0 == *id { entity_to_remove = Some(entity); } } match entity_to_remove { Some(entity) => { world.despawn(entity); } None => {} } } DespawnPart { id } => { let mut part_query = world.query_filtered::<(Entity, &ServerId), With>(); let mut entity_to_remove = None; for (entity, server_id) in part_query.iter_mut(world) { if server_id.0 == *id { entity_to_remove = Some(entity); } } match entity_to_remove { Some(entity) => { world.despawn(entity); } None => {} } } _ => {} } } }