use godot::{classes::CharacterBody3D, prelude::*}; use crate::{ ball::Ball, game_manager::Game, player::{IPlayer, LocalPlayer, NetTransform, RemotePlayer}, }; #[derive(GodotClass)] #[class(base=Node3D, init)] pub struct Map { #[export] pub spawner: Option>, #[export] pub ball_spawner: Option>, #[export] pub local_player: Option>, #[export] pub remote_player: Option>, #[export] pub ball: Option>, base: Base, } #[godot_api] impl INode3D for Map { fn ready(&mut self) { if let Some(game) = &mut Game::singleton() { game.bind_mut().on_map_loaded(self.to_gd()); } } } #[godot_api] impl Map { #[signal] pub fn on_loaded(); pub fn spawn_player( &mut self, player_id: u16, is_local: bool, transform: Option, ) -> Option> { if is_local { if let Some(local_player) = &self.local_player { let mut node = local_player.instantiate_as::(); node.bind_mut().player_id = Some(player_id); self.base_mut().add_child(&node); if let Some(transform) = transform { node.bind_mut() .base_mut() .set_global_position(transform.location.into()); node.bind_mut() .base_mut() .set_global_rotation(transform.rotation.into()); } else { if let Some(spawner) = &self.spawner { node.bind_mut() .base_mut() .set_global_position(spawner.get_global_position()); } } Some(node.into_dyn::().upcast()) } else { None } } else if let Some(remote_player) = &self.remote_player { let mut node = remote_player.instantiate_as::(); node.bind_mut().player_id = Some(player_id); self.base_mut().add_child(&node); if let Some(transform) = transform { node.bind_mut() .base_mut() .set_global_position(transform.location.into()); node.bind_mut() .base_mut() .set_global_rotation(transform.rotation.into()); } else { if let Some(spawner) = &self.spawner { node.bind_mut() .base_mut() .set_global_position(spawner.get_global_position()); } } Some(node.into_dyn::().upcast()) } else { None } } pub fn spawn_ball(&mut self, transform: Option) -> Option> { if let Some(ball_spawner) = self.ball_spawner.clone() && let Some(ball_prefab) = &self.ball { let mut ball = ball_prefab.instantiate_as::(); self.base_mut().add_child(&ball); if let Some(transform) = transform { ball.set_global_position(transform.location.into()); ball.set_global_rotation(transform.rotation.into()); } else { ball.set_global_position(ball_spawner.get_global_position()); } Some(ball) } else { None } } }