Make goal icon only show up when holding ball

This commit is contained in:
Sofia 2026-08-08 21:06:56 +03:00
parent 63cb3ef3fe
commit a267f22406
3 changed files with 60 additions and 4 deletions

View File

@ -336,6 +336,10 @@ impl Game {
pub fn on_player_killed(player: u16); pub fn on_player_killed(player: u16);
#[signal] #[signal]
pub fn on_map_loaded(map: Gd<Map>); pub fn on_map_loaded(map: Gd<Map>);
#[signal]
pub fn on_pickup_ball(player_id: u16);
#[signal]
pub fn on_drop_ball();
pub fn singleton() -> Option<Gd<Game>> { pub fn singleton() -> Option<Gd<Game>> {
if GameManager::singleton().get_children().len() > 0 { if GameManager::singleton().get_children().len() > 0 {
@ -734,6 +738,7 @@ impl Game {
velocity: Option<NetVector3>, velocity: Option<NetVector3>,
player_id: Option<u16>, player_id: Option<u16>,
) { ) {
godot_print!("Spawned ball");
if let Some(map) = &mut self.current_map { if let Some(map) = &mut self.current_map {
let mut ball = map.bind_mut().spawn_ball(transform, velocity, player_id); let mut ball = map.bind_mut().spawn_ball(transform, velocity, player_id);
if let Some(ball) = &mut ball { if let Some(ball) = &mut ball {
@ -759,6 +764,7 @@ impl Game {
} }
}); });
} }
self.signals().on_drop_ball().emit();
} }
pub fn despawn_ball(&mut self) { pub fn despawn_ball(&mut self) {
@ -860,6 +866,21 @@ impl Game {
return; return;
} }
if weapon_type == WeaponType::Ball {
self.run_deferred(move |s| s.signals().on_pickup_ball().emit(player_id));
}
if let Some(player) = self.find_player(player_id).clone()
&& let Some(character) = player.character.clone()
{
if let Some(weapon) = character.dyn_bind().get_weapon()
&& weapon.dyn_bind().get_type() == WeaponType::Ball
&& weapon_type != WeaponType::Ball
{
self.run_deferred(move |s| s.signals().on_drop_ball().emit());
}
}
if let Some(player) = self.find_player_mut(player_id) if let Some(player) = self.find_player_mut(player_id)
&& let Some(character) = &mut player.character && let Some(character) = &mut player.character
{ {

View File

@ -26,6 +26,19 @@ pub struct Goal {
#[godot_api] #[godot_api]
impl IArea3D for Goal { impl IArea3D for Goal {
fn ready(&mut self) { fn ready(&mut self) {
self.update_icon_visibility();
if let Some(game) = &mut Game::singleton() {
game.bind_mut()
.signals()
.on_pickup_ball()
.connect_other(self, |s, _| s.run_deferred(|s| s.update_icon_visibility()));
game.bind_mut()
.signals()
.on_drop_ball()
.connect_other(self, |s| s.run_deferred(|s| s.update_icon_visibility()));
}
self.update_color(); self.update_color();
self.base() self.base()
.signals() .signals()
@ -67,7 +80,22 @@ impl Goal {
} }
} }
fn on_enter(&self, node: Gd<Node3D>) { fn update_icon_visibility(&mut self) {
if let Some(icon) = &mut self.icon {
if let Some(game) = Game::singleton()
&& let Some(ball_holder) = game.bind().ball_holder
&& let Some(player) = game.bind().find_player(ball_holder)
&& ball_holder == game.bind().self_id.unwrap_or(0)
&& player.data.team != self.team
{
icon.set_visible(true);
} else {
icon.set_visible(false);
}
}
}
fn on_enter(&mut self, node: Gd<Node3D>) {
if !NetworkManager::singleton().bind().is_host() { if !NetworkManager::singleton().bind().is_host() {
return; return;
} }
@ -85,7 +113,7 @@ impl Goal {
} }
if let Some(player_id) = is_goal { if let Some(player_id) = is_goal {
if let Some(mut game) = Game::singleton() { if let Some(game) = Game::singleton() {
let teams = game let teams = game
.bind() .bind()
.get_teams() .get_teams()
@ -94,8 +122,12 @@ impl Goal {
.map(|(id, _)| id as u8) .map(|(id, _)| id as u8)
.filter(|id| *id != self.team) .filter(|id| *id != self.team)
.collect(); .collect();
game.bind_mut().respawn_ball(); self.run_deferred_gd(move |_| {
game.bind_mut().handle_goal(player_id, teams); if let Some(game) = &mut Game::singleton() {
game.bind_mut().respawn_ball();
game.bind_mut().handle_goal(player_id, teams);
}
});
} }
} }
} }

View File

@ -154,6 +154,9 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
{ {
s.swap_weapon(player.last_held_weapon, false); s.swap_weapon(player.last_held_weapon, false);
} }
if let Some(game) = &mut Game::singleton() {
game.bind_mut().ball_holder.take();
}
if NetworkManager::singleton().bind().is_host() { if NetworkManager::singleton().bind().is_host() {
if let Some(mut game) = Game::singleton() { if let Some(mut game) = Game::singleton() {
if let Some(ball_origin) = &s.get_camera_origin() { if let Some(ball_origin) = &s.get_camera_origin() {