~starkingdoms/starkingdoms

ref: d2b8956323d8e82903824637cdcfb2f978dd94e9 starkingdoms/crates/unified/src/server/player/join.rs -rw-r--r-- 4.0 KiB
d2b89563 — core chore: please thy lord clippy 15 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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 {
        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.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 {
        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::ecs::Me
    )).id();
    debug!(?fake_network_entity, ?local_player, "listenserver: magically invented a player");
}