diff --git a/godot/scenes/misc/ball.tscn b/godot/scenes/misc/ball.tscn index df93d50..20325c4 100644 --- a/godot/scenes/misc/ball.tscn +++ b/godot/scenes/misc/ball.tscn @@ -5,7 +5,7 @@ [sub_resource type="SphereShape3D" id="SphereShape3D_1cgct"] [node name="ball" type="Ball" unique_id=816748600] -collision_layer = 4 +collision_layer = 12 collision_mask = 7 contact_monitor = true max_contacts_reported = 10 diff --git a/godot/scenes/misc/goal.tscn b/godot/scenes/misc/goal.tscn index 939b1e3..5e09c53 100644 --- a/godot/scenes/misc/goal.tscn +++ b/godot/scenes/misc/goal.tscn @@ -21,6 +21,8 @@ radius = 2.0 [node name="goal" type="Goal" unique_id=177528504 node_paths=PackedStringArray("mesh")] mesh = NodePath("mesh_instance_3d") +collision_layer = 8 +collision_mask = 8 [node name="mesh_instance_3d" type="MeshInstance3D" parent="." unique_id=587608036] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index 73f100a..7eae5e8 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -158,6 +158,8 @@ pub struct Game { pub world_ball: Option>, since_last_sync: f64, + pub goals: HashMap, + base: Base, } @@ -515,6 +517,21 @@ impl Game { self.spawn_ball(None, None, None); } + pub fn handle_goal(&mut self, teams: Vec) { + godot_print!("Goal for {:?}", teams); + for team in &teams { + self.goals + .insert(*team, self.goals.get(&team).copied().unwrap_or(0) + 1); + } + self.run_deferred(move |_| { + if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { + if let PeerKind::Server(peer, _) = peer { + peer.broadcast_reliable(Package::Goal(teams)); + } + } + }); + } + pub fn handle_ball_pickup(&mut self, player_id: u16) { if NetworkManager::singleton().bind_mut().is_host() { self.despawn_ball(); diff --git a/rust/src/goal.rs b/rust/src/goal.rs index 39e1e6b..e90d889 100644 --- a/rust/src/goal.rs +++ b/rust/src/goal.rs @@ -3,7 +3,7 @@ use godot::{ prelude::*, }; -use crate::game_manager::Game; +use crate::{ball::Ball, game_manager::Game, net::network_manager::NetworkManager}; #[derive(GodotClass)] #[class(base=Area3D, init)] @@ -30,5 +30,31 @@ impl IArea3D for Goal { mat.set_shader_parameter("goal_color", &team.bind().color.to_variant()); } } + + self.base() + .signals() + .body_entered() + .connect_other(self, |s, other| s.on_enter(other)); + } +} + +impl Goal { + fn on_enter(&self, node: Gd) { + if let Ok(_) = node.try_cast::() { + if let Some(mut game) = Game::singleton() { + let teams = game + .bind() + .get_teams() + .iter_shared() + .enumerate() + .map(|(id, _)| id as u8) + .filter(|id| *id != self.team) + .collect(); + if NetworkManager::singleton().bind().is_host() { + game.bind_mut().respawn_ball(); + game.bind_mut().handle_goal(teams); + } + } + } } } diff --git a/rust/src/net/network_manager.rs b/rust/src/net/network_manager.rs index 425239c..973357a 100644 --- a/rust/src/net/network_manager.rs +++ b/rust/src/net/network_manager.rs @@ -275,6 +275,7 @@ pub enum Package { SpawnBall(NetTransform, NetVector3, Option), DespawnBall, SwapWeapon(u16, WeaponType), + Goal(Vec), } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/rust/src/net/protocol.rs b/rust/src/net/protocol.rs index 81e9c6d..805d067 100644 --- a/rust/src/net/protocol.rs +++ b/rust/src/net/protocol.rs @@ -171,6 +171,11 @@ impl NetworkManager { game.bind_mut().change_option(opt, value); } } + Package::Goal(teams) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().handle_goal(teams); + } + } _ => {} }, },