use crate::config::planet::Planet; use crate::config::world::GlobalWorldConfig; use crate::ecs::{Player, PlayerStorage, PlayerThrust}; use crate::prelude::*; use crate::server::ConnectedGameEntity; use crate::server::part::SpawnPartRequest; use crate::server::world_config::WorldConfigResource; fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldConfig, planets: Query<(&Transform, &Planet)>, asset_server: &AssetServer) { trace!(?joined_player, "detected joined player!"); // find earth if planets.is_empty() { warn!("planets have not loaded yet, setting this player to pending until they do!"); commands.entity(joined_player).insert(PendingPlayer); return; } let (spawn_planet_pos, spawn_planet) = planets .iter() .find(|p| p.1.name == wc.hearty.spawn_at) .unwrap_or_else(|| { panic!( "spawn planet {} is missing? (check that the planet is named exactly '{}')", wc.hearty.spawn_at, wc.hearty.spawn_at ) }); let angle = rand::random::() * std::f32::consts::TAU; let offset = spawn_planet.radius + 150.0; let mut new_transform = Transform::from_xyz(angle.cos() * offset, angle.sin() * offset, 0.0); new_transform.rotate_z(angle); new_transform.translation += spawn_planet_pos.translation; info!(?new_transform, ?joined_player, "set player's position!"); commands .entity(joined_player) .insert(new_transform) .insert(SpawnPartRequest( asset_server.load("config/parts/hearty.part.toml"), )) .insert(PlayerThrust::default()) .insert(PlayerStorage { fuel_capacity: 25.0, fuel: 25.0, power_capacity: 25.0, power: 25.0, }) .insert(Player { client: joined_player, }) .remove::(); } #[derive(Component)] pub struct PendingPlayer; pub fn handle_new_players( mut commands: Commands, q_new_clients: Query>, world_config: Res, planets: Query<(&Transform, &Planet)>, asset_server: Res, ) { let Some(wc) = &world_config.config else { warn!("got a joined player, but world config is not loaded! waiting until it is..."); for joined_player in &q_new_clients { commands.entity(joined_player).insert(PendingPlayer); } return; }; for joined_player in &q_new_clients { join_player(joined_player, commands.reborrow(), wc, planets, &asset_server); } } pub fn handle_pending_players( mut commands: Commands, pending_players: Query>, world_config: Res, planets: Query<(&Transform, &Planet)>, asset_server: Res, ) { let Some(wc) = &world_config.config else { warn!("there are pending players, but world config is not loaded! waiting until it is..."); return; }; for pending_player in &pending_players { warn!(?pending_player, "reprocessing pending player"); join_player(pending_player, commands.reborrow(), wc, planets, &asset_server); } } pub fn ls_magically_invent_player( mut commands: Commands, ) { // Magically invent a player for listenserver let fake_network_entity = commands.spawn(Replicated).id(); let local_player = commands.spawn(( ConnectedGameEntity { network_entity: fake_network_entity, }, Replicated, crate::client::Me )).id(); debug!(?fake_network_entity, ?local_player, "listenserver: magically invented a player"); }