use crate::config::planet::Planet;
use crate::config::world::GlobalWorldConfig;
use crate::ecs::{Hi, Player, PlayerStorage};
use crate::prelude::*;
use crate::server::ConnectedGameEntity;
use crate::server::part::SpawnPartRequest;
use crate::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::<f32>() * 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(PlayerStorage {
fuel_capacity: 25.0,
fuel: 25.0,
power_capacity: 25.0,
power: 25.0,
})
.insert(Player {
client: joined_player,
})
.remove::<PendingPlayer>();
}
#[derive(Component)]
#[require(Replicated)]
pub struct PendingPlayer;
pub fn handle_new_players(
mut commands: Commands,
q_new_clients: Query<(Entity, &ConnectedGameEntity), Added<ConnectedGameEntity>>,
world_config: Res<WorldConfigResource>,
planets: Query<(&Transform, &Planet)>,
mut hi_writer: MessageWriter<ToClients<Hi>>,
asset_server: Res<AssetServer>,
) {
for joined_player in &q_new_clients {
hi_writer.write(ToClients {
mode: SendMode::Direct(ClientId::Client(joined_player.1.network_entity)),
message: Hi {
you_are: joined_player.0
}
});
}
let Some(wc) = &world_config.config else {
for joined_player in &q_new_clients {
commands.entity(joined_player.0).insert(PendingPlayer);
}
return;
};
for joined_player in &q_new_clients {
debug!(?joined_player, "new player!");
join_player(joined_player.0, commands.reborrow(), wc, planets, &asset_server);
}
}
pub fn handle_pending_players(
mut commands: Commands,
pending_players: Query<Entity, With<PendingPlayer>>,
world_config: Res<WorldConfigResource>,
planets: Query<(&Transform, &Planet)>,
asset_server: Res<AssetServer>,
) {
let Some(wc) = &world_config.config else {
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::ecs::Me
)).id();
debug!(?fake_network_entity, ?local_player, "listenserver: magically invented a player");
}