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);
#[signal]
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>> {
if GameManager::singleton().get_children().len() > 0 {
@ -734,6 +738,7 @@ impl Game {
velocity: Option<NetVector3>,
player_id: Option<u16>,
) {
godot_print!("Spawned ball");
if let Some(map) = &mut self.current_map {
let mut ball = map.bind_mut().spawn_ball(transform, velocity, player_id);
if let Some(ball) = &mut ball {
@ -759,6 +764,7 @@ impl Game {
}
});
}
self.signals().on_drop_ball().emit();
}
pub fn despawn_ball(&mut self) {
@ -860,6 +866,21 @@ impl Game {
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)
&& let Some(character) = &mut player.character
{

View File

@ -26,6 +26,19 @@ pub struct Goal {
#[godot_api]
impl IArea3D for Goal {
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.base()
.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() {
return;
}
@ -85,7 +113,7 @@ impl Goal {
}
if let Some(player_id) = is_goal {
if let Some(mut game) = Game::singleton() {
if let Some(game) = Game::singleton() {
let teams = game
.bind()
.get_teams()
@ -94,8 +122,12 @@ impl Goal {
.map(|(id, _)| id as u8)
.filter(|id| *id != self.team)
.collect();
game.bind_mut().respawn_ball();
game.bind_mut().handle_goal(player_id, teams);
self.run_deferred_gd(move |_| {
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);
}
if let Some(game) = &mut Game::singleton() {
game.bind_mut().ball_holder.take();
}
if NetworkManager::singleton().bind().is_host() {
if let Some(mut game) = Game::singleton() {
if let Some(ball_origin) = &s.get_camera_origin() {