use std::collections::HashMap; use crate::components::{ Camera, Chat, Menu, Part, Player, PlayerResources, RecvPacket, SendPacket, ServerId, SpriteBundle, Texture, Transform, }; use bevy_ecs::{ entity::Entity, event::Events, query::{QuerySingleError, With}, world::World, }; use nalgebra::{Rotation2, Scale3, Translation3}; use starkingdoms_common::packet::Packet::{ DespawnPart, EnergyUpdate, LoginResponse, Message, OpenCraftingUi, PartPositions, PlanetPositions, PlayerLeave, PlayerList, SpawnPart, SpawnPlayer, }; use starkingdoms_common::packet::{ DespawnPartPacket, EnergyUpdatePacket, LoginResponsePacket, MessagePacket, OpenCraftingUiPacket, PartPositionsPacket, PlanetPositionsPacket, PlayerLeavePacket, PlayerListPacket, SpawnPartPacket, SpawnPlayerPacket, }; use starkingdoms_common::{PartType, PlanetType}; pub mod websocket; fn texture_name(part_type: PartType, attached: bool) -> String { use PartType::*; if attached { match part_type { Placeholder => panic!("AHHHH PLACEHOLDER PANIC"), Hearty => "hearty.svg", Chassis => "chassis.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", Chassis => "chassis.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, ) { let mut recv_cursor = recv_packet_events.get_cursor(); for recv in recv_cursor.read(recv_packet_events) { match &recv.0 { LoginResponse(LoginResponsePacket { id }) => { let mut player_query = world.query_filtered::>(); let entity = player_query.single(world); world.entity_mut(entity).insert(ServerId(*id)); } PlayerList(PlayerListPacket { 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(SpawnPlayerPacket { 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(SpawnPartPacket { 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(PartPositionsPacket { 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(PlanetPositionsPacket { planets }) => { for (server_id, planet) in planets { planet_types.entry(planet.planet_type).or_insert_with(|| { 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(), }, }); (entity.id(), *server_id) }); } } EnergyUpdate(EnergyUpdatePacket { amount, max }) => { let mut r = world.resource_mut::(); r.fuel_amount = *amount; r.fuel_max = *max; } OpenCraftingUi(OpenCraftingUiPacket { 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(MessagePacket { actor, content, .. }) => { let mut chat = world.get_resource_mut::().unwrap(); chat.messages .push(format!("{}: {}", actor.clone(), content.clone())); } PlayerLeave(PlayerLeavePacket { 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); } } if let Some(entity) = entity_to_remove { world.despawn(entity); } } DespawnPart(DespawnPartPacket { 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); } } if let Some(entity) = entity_to_remove { world.despawn(entity); } } _ => {} } } }