use std::{collections::HashMap, f32::consts::PI}; use godot::{classes::RandomNumberGenerator, prelude::*}; use crate::{ game::{Game, GameManager}, map::map_static::StaticMap, player::menu_player::MenuPlayer, ui::lobby::LobbyPanel, }; #[derive(GodotClass)] #[class(base=Node3D, init)] pub struct LobbyWorld { #[export] menu_player_scene: Option>, #[export] lobby: Option>, #[export] pivot: Option>, rng: Gd, menu_players: HashMap>, background: Option>, base: Base, } #[godot_api] impl INode3D for LobbyWorld { fn ready(&mut self) { if let Some(game) = Game::singleton() { for player in &game.bind().players { self.spawn_player(player.id()); } self.change_map(game.bind().selected_map_idx); game.signals() .on_new_player() .connect_other(self, Self::on_new_player); game.signals() .on_player_disconnected() .connect_other(self, Self::on_player_disconnected); game.signals() .on_players_updated() .connect_other(self, Self::update_players); game.signals() .on_map_changed() .connect_other(self, Self::change_map); } if let Some(lobby) = &self.lobby { lobby .signals() .on_alt_colors_changed() .connect_other(self, |s| s.update_players()); } } } impl LobbyWorld { fn change_map(&mut self, map: u8) { self.run_deferred(move |s| { if let Some(mut background) = s.background.take() { background.queue_free(); } if let Some(map) = GameManager::singleton().bind().maps.get(map as usize) { if let Some(scene) = &map.bind().static_scene { let mut background = scene.instantiate_as::(); if let Some(center) = &background.clone().bind().lobby_center { background.set_position(-center.get_position()); if let Some(camera_pivot) = &mut s.pivot { camera_pivot.set_rotation(center.get_rotation()); } } s.base_mut().add_child(&background); s.background = Some(background); } } }); } fn on_new_player(&mut self, player_id: u16) { self.spawn_player(player_id); } fn on_player_disconnected(&mut self, player_id: u16) { if let Some(mut player) = self.menu_players.remove(&player_id) { player.queue_free(); } } fn spawn_player(&mut self, player_id: u16) { self.run_deferred(move |s| { if let Some(scene) = s.menu_player_scene.clone() { let x = s.rng.randf_range(-2., 2.); let z = s.rng.randf_range(-2., 2.); let rotation = s.rng.randf_range(-PI / 4., PI / 4.); let mut menu_player = scene.instantiate_as::(); menu_player.bind_mut().player_id = Some(player_id); s.menu_players.insert(player_id, menu_player.clone()); if let Some(pivot) = &mut s.pivot { pivot.add_child(&menu_player); } menu_player.bind_mut().update(); menu_player.set_position(Vector3::new(x, 0., z)); menu_player.set_rotation(Vector3::UP * rotation); } }); } fn update_players(&mut self) { for (_, player) in &mut self.menu_players { player.bind_mut().update(); } } }