125 lines
3.8 KiB
Rust
125 lines
3.8 KiB
Rust
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<Gd<PackedScene>>,
|
|
#[export]
|
|
lobby: Option<Gd<LobbyPanel>>,
|
|
#[export]
|
|
pivot: Option<Gd<Node3D>>,
|
|
|
|
rng: Gd<RandomNumberGenerator>,
|
|
|
|
menu_players: HashMap<u16, Gd<MenuPlayer>>,
|
|
|
|
background: Option<Gd<StaticMap>>,
|
|
|
|
base: Base<Node3D>,
|
|
}
|
|
|
|
#[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::<StaticMap>();
|
|
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::<MenuPlayer>();
|
|
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();
|
|
}
|
|
}
|
|
}
|