Compare commits

..

No commits in common. "949585dc5cff5c7c8d49c4f254084f009cb91646" and "17b5272a9e752cf0c473a03cd14278d0eeef7b76" have entirely different histories.

13 changed files with 60 additions and 289 deletions

View File

@ -1,10 +1,7 @@
[gd_resource type="MapResource" format=3 uid="uid://bsjoandgu476y"] [gd_resource type="MapResource" format=3 uid="uid://bsjoandgu476y"]
[ext_resource type="PackedScene" uid="uid://ylj40hkjsgjc" path="res://maps/diner/diner.tscn" id="1_yteo6"] [ext_resource type="PackedScene" uid="uid://ylj40hkjsgjc" path="res://maps/diner/diner.tscn" id="1_yteo6"]
[ext_resource type="TeamResource" uid="uid://p2fqqnaejjn7" path="res://maps/teams/blue_team.tres" id="2_47vax"]
[ext_resource type="TeamResource" uid="uid://db4b3sjsftg15" path="res://maps/teams/red_ream.tres" id="3_i3gdq"]
[resource] [resource]
name = "Diner" name = "Diner"
scene = ExtResource("1_yteo6") scene = ExtResource("1_yteo6")
teams = Array[TeamResource]([ExtResource("2_47vax"), ExtResource("3_i3gdq")])

Binary file not shown.

View File

@ -2,4 +2,4 @@
[resource] [resource]
name = "Blue Team" name = "Blue Team"
color = Color(0, 0.7411765, 1, 1) color = Color(0, 0, 1, 1)

View File

@ -2,4 +2,4 @@
[resource] [resource]
name = "Red Team" name = "Red Team"
color = Color(1, 0.35686275, 0.3647059, 1) color = Color(1, 0, 0, 1)

View File

@ -37,8 +37,6 @@ offset_bottom = 200.0
[node name="h_box_container" type="HBoxContainer" parent="v_box_container" unique_id=1789302658] [node name="h_box_container" type="HBoxContainer" parent="v_box_container" unique_id=1789302658]
layout_mode = 2 layout_mode = 2
offset_transform_enabled = true
offset_transform_position = Vector2(100, 0)
metadata/_edit_lock_ = true metadata/_edit_lock_ = true
[node name="label" type="Label" parent="v_box_container/h_box_container" unique_id=626633696] [node name="label" type="Label" parent="v_box_container/h_box_container" unique_id=626633696]

View File

@ -5,7 +5,7 @@
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "collider", "splorch", "spectator_camera", "ball_origin", "name_label")] [node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "collider", "splorch", "spectator_camera", "ball_origin")]
move_speed = 5.0 move_speed = 5.0
soldier_mesh = NodePath("soldier_m") soldier_mesh = NodePath("soldier_m")
collider = NodePath("collision_shape_3d") collider = NodePath("collision_shape_3d")
@ -13,7 +13,6 @@ splorch = NodePath("gpu_particles_3d")
health = 100 health = 100
spectator_camera = NodePath("spectate_root/spectate_camera") spectator_camera = NodePath("spectate_root/spectate_camera")
ball_origin = NodePath("ball_origin") ball_origin = NodePath("ball_origin")
name_label = NodePath("name_label")
collision_layer = 2 collision_layer = 2
collision_mask = 4 collision_mask = 4
@ -35,7 +34,3 @@ transform = Transform3D(1, 0, 0, 0, 0.89379096, 0.44848388, 0, -0.44848388, 0.89
[node name="ball_origin" type="Node3D" parent="." unique_id=1445680156] [node name="ball_origin" type="Node3D" parent="." unique_id=1445680156]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8724979, -0.2644562) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8724979, -0.2644562)
[node name="name_label" type="Label3D" parent="." unique_id=142179925]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.3304863, 0)
billboard = 1

View File

@ -1,23 +1,19 @@
[gd_scene format=3 uid="uid://ccd0wj2usx5os"] [gd_scene format=3 uid="uid://ccd0wj2usx5os"]
[node name="player_listing" type="PlayerListing" unique_id=772938280 node_paths=PackedStringArray("name_label", "ping_label", "ready_label", "team_dropdown")] [node name="player_listing" type="PlayerListing" unique_id=772938280 node_paths=PackedStringArray("name_label", "ping_label", "ready_label")]
name_label = NodePath("name") name_label = NodePath("name")
ping_label = NodePath("ping") ping_label = NodePath("ping")
ready_label = NodePath("ready") ready_label = NodePath("ready")
team_dropdown = NodePath("option_button")
offset_right = 319.0 offset_right = 319.0
offset_bottom = 23.0 offset_bottom = 23.0
columns = 4 columns = 4
[node name="option_button" type="OptionButton" parent="." unique_id=199328927] [node name="option_button" type="OptionButton" parent="." unique_id=199328927]
custom_minimum_size = Vector2(150, 0)
custom_maximum_size = Vector2(150, -1)
clip_contents = true
layout_mode = 2 layout_mode = 2
[node name="name" type="Label" parent="." unique_id=635700663] [node name="name" type="Label" parent="." unique_id=635700663]
custom_minimum_size = Vector2(350, 0) custom_minimum_size = Vector2(400, 0)
custom_maximum_size = Vector2(350, -1) custom_maximum_size = Vector2(400, -1)
layout_mode = 2 layout_mode = 2
text = "Name" text = "Name"
clip_text = true clip_text = true

View File

@ -10,7 +10,7 @@ use crate::{
net::{ net::{
network_manager::{ network_manager::{
BallSync, NetworkManager, BallSync, NetworkManager,
Package::{self, Kill, SelfSync, SetTeam, SpawnPlayer, TakeDamage}, Package::{self, Kill, SelfSync, SpawnPlayer, TakeDamage},
PeerKind, SyncPackage, PeerKind, SyncPackage,
}, },
util::NetVector3, util::NetVector3,
@ -88,20 +88,6 @@ impl GameManager {
} }
} }
pub struct GameOptions {
/// Wether anyone is allowed to change anyone's team, or just the host and
/// the player itself.
pub allow_any_team: bool,
}
impl Default for GameOptions {
fn default() -> Self {
Self {
allow_any_team: false,
}
}
}
#[derive(GodotClass)] #[derive(GodotClass)]
#[class(base=Node, init)] #[class(base=Node, init)]
pub struct Game { pub struct Game {
@ -112,8 +98,6 @@ pub struct Game {
pub selected_map: Option<Gd<MapResource>>, pub selected_map: Option<Gd<MapResource>>,
pub maps: Array<Gd<MapResource>>, pub maps: Array<Gd<MapResource>>,
pub opts: GameOptions,
is_host: bool, is_host: bool,
player_counter: u16, player_counter: u16,
pub self_id: Option<u16>, pub self_id: Option<u16>,
@ -140,7 +124,7 @@ impl INode for Game {
if let Some(player) = self if let Some(player) = self
.players .players
.iter() .iter()
.find(|p| p.id() == self.self_id.unwrap_or(0)) .find(|p| p.id == self.self_id.unwrap_or(0))
{ {
if let Some(data) = &player.get_self_sync() { if let Some(data) = &player.get_self_sync() {
peer.send_unreliable(socket_addr, SelfSync(data.clone())); peer.send_unreliable(socket_addr, SelfSync(data.clone()));
@ -161,7 +145,7 @@ impl INode for Game {
player.get_transform(), player.get_transform(),
) { ) {
sync_data.insert( sync_data.insert(
player.id(), player.id,
SyncPackage { SyncPackage {
movement_direction: dir, movement_direction: dir,
look_up, look_up,
@ -183,14 +167,13 @@ impl INode for Game {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
if let PeerKind::Server(peer, _) = peer { if let PeerKind::Server(peer, _) = peer {
for player in self.players.clone() { for player in self.players.clone() {
let player_id = player.id();
if let Some(character) = player.character { if let Some(character) = player.character {
if character.dyn_bind().dead_for() > self.respawn_timer { if character.dyn_bind().dead_for() > self.respawn_timer {
let character = self.spawn_player_server(player_id); let character = self.spawn_player_server(player.id);
if let Some(character) = character { if let Some(character) = character {
peer.broadcast_reliable(SpawnPlayer( peer.broadcast_reliable(SpawnPlayer(
player_id, player.id,
character.dyn_bind().get_transform(), character.dyn_bind().get_transform(),
)); ));
} }
@ -211,8 +194,6 @@ impl Game {
#[signal] #[signal]
pub fn on_player_disconnected(id: u16); pub fn on_player_disconnected(id: u16);
#[signal] #[signal]
pub fn on_player_team_changed(id: u16, team: u8);
#[signal]
pub fn on_map_changed(id: u8); pub fn on_map_changed(id: u8);
pub fn singleton() -> Option<Gd<Game>> { pub fn singleton() -> Option<Gd<Game>> {
@ -225,21 +206,6 @@ impl Game {
self.selected_map_idx = map_idx; self.selected_map_idx = map_idx;
if let Some(map) = self.maps.get(map_idx as usize) { if let Some(map) = self.maps.get(map_idx as usize) {
self.selected_map = Some(map); self.selected_map = Some(map);
let teams_max = (self.get_teams().len() - 1) as u8;
self.run_deferred(move |s| {
if NetworkManager::singleton().bind().is_host() {
for player in s.players.clone() {
s.run_deferred(move |s| {
s.try_set_player_team(
player.id(),
player.data.team.clamp(0, teams_max),
true,
)
});
}
}
});
if emit { if emit {
self.run_deferred(move |s| s.signals().on_map_changed().emit(map_idx)); self.run_deferred(move |s| s.signals().on_map_changed().emit(map_idx));
} }
@ -254,40 +220,6 @@ impl Game {
} }
} }
pub fn get_team(&self, team: u8) -> Option<Gd<TeamResource>> {
self.get_teams().get(team as usize)
}
pub fn try_set_player_team(&mut self, player_id: u16, team: u8, emit: bool) {
if let Some(player) = self.find_player_mut(player_id) {
player.data.team = team;
self.run_deferred(move |_| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
match peer {
PeerKind::Client(peer, socket_addr) => {
peer.send_reliable(socket_addr, SetTeam(player_id, team));
}
PeerKind::Server(peer, _) => {
peer.broadcast_reliable(SetTeam(player_id, team));
}
}
}
});
if emit {
self.run_deferred(move |s| {
s.signals().on_player_team_changed().emit(player_id, team)
});
}
}
}
pub fn handle_player_team_change(&mut self, player_id: u16, team: u8) {
if let Some(player) = self.find_player_mut(player_id) {
player.data.team = team;
self.run_deferred(move |s| s.signals().on_player_team_changed().emit(player_id, team));
}
}
pub fn start_game(&mut self) { pub fn start_game(&mut self) {
self.game_started = true; self.game_started = true;
if let Some(map) = &self.selected_map { if let Some(map) = &self.selected_map {
@ -319,46 +251,21 @@ impl Game {
id id
}; };
self.players.push(Player { self.players.push(Player {
id,
connection_addr: addr, connection_addr: addr,
data: NetPlayer { name,
id, ping: 0,
name,
ping: 0,
team: 0,
},
ready: false, ready: false,
character: None, character: None,
}); });
self.run_deferred(move |s| s.signals().on_new_player().emit(id)); self.run_deferred(move |s| s.signals().on_new_player().emit(id));
let team_with_least = self
.get_teams()
.iter_shared()
.enumerate()
.min_by(|(team_idx_a, _), (team_idx_b, _)| {
let a = self
.players
.iter()
.filter(|p| p.data.team == *team_idx_a as u8)
.count();
let b = self
.players
.iter()
.filter(|p| p.data.team == *team_idx_b as u8)
.count();
a.cmp(&b)
})
.map(|(team_idx, _)| team_idx)
.unwrap_or(0);
self.try_set_player_team(id, team_with_least as u8, true);
id id
} }
pub fn set_players(&mut self, players: Vec<Player>) { pub fn set_players(&mut self, players: Vec<Player>) {
self.players = players; self.players = players;
for player in self.players.clone() { for player in self.players.clone() {
self.run_deferred(move |s| s.signals().on_new_player().emit(player.id())); self.run_deferred(move |s| s.signals().on_new_player().emit(player.id));
} }
} }
@ -371,34 +278,34 @@ impl Game {
} }
pub fn find_player(&self, player_id: u16) -> Option<&Player> { pub fn find_player(&self, player_id: u16) -> Option<&Player> {
self.players.iter().find(|p| p.id() == player_id) self.players.iter().find(|p| p.id == player_id)
} }
pub fn find_player_mut(&mut self, player_id: u16) -> Option<&mut Player> { pub fn find_player_mut(&mut self, player_id: u16) -> Option<&mut Player> {
self.players.iter_mut().find(|p| p.id() == player_id) self.players.iter_mut().find(|p| p.id == player_id)
} }
pub fn remove_player(&mut self, id: u16) { pub fn remove_player(&mut self, id: u16) {
self.players.retain(|p| p.id() != id); self.players.retain(|p| p.id != id);
self.run_deferred(move |s| s.signals().on_player_disconnected().emit(id)); self.run_deferred(move |s| s.signals().on_player_disconnected().emit(id));
} }
pub fn update_player_nick(&mut self, player_id: u16, nick: String) { pub fn update_player_nick(&mut self, player_id: u16, nick: String) {
if let Some(player) = self.players.iter_mut().find(|p| p.id() == player_id) { if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
player.data.name = nick; player.name = nick;
} }
self.run_deferred(|s| s.signals().on_players_updated().emit()); self.run_deferred(|s| s.signals().on_players_updated().emit());
} }
pub fn update_player_ping(&mut self, player_id: u16, ping: u128) { pub fn update_player_ping(&mut self, player_id: u16, ping: u128) {
if let Some(player) = self.players.iter_mut().find(|p| p.id() == player_id) { if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
player.data.ping = ping; player.ping = ping;
} }
self.run_deferred(|s| s.signals().on_players_updated().emit()); self.run_deferred(|s| s.signals().on_players_updated().emit());
} }
pub fn update_player_ready(&mut self, player_id: u16, ready: bool) { pub fn update_player_ready(&mut self, player_id: u16, ready: bool) {
if let Some(player) = self.players.iter_mut().find(|p| p.id() == player_id) { if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
player.ready = ready; player.ready = ready;
} }
self.run_deferred(|s| s.signals().on_players_updated().emit()); self.run_deferred(|s| s.signals().on_players_updated().emit());
@ -412,7 +319,7 @@ impl Game {
} else { } else {
self.run_deferred(|s| { self.run_deferred(|s| {
for player in s.players.clone() { for player in s.players.clone() {
s.spawn_player_server(player.id()); s.spawn_player_server(player.id);
} }
s.spawn_ball(None, None, None); s.spawn_ball(None, None, None);
}); });
@ -489,7 +396,7 @@ impl Game {
&& let Some(character) = &mut player.character && let Some(character) = &mut player.character
{ {
character.dyn_bind_mut().swap_weapon(weapon_type); character.dyn_bind_mut().swap_weapon(weapon_type);
let player_id = player.id(); let player_id = player.id;
self.run_deferred(move |_| { self.run_deferred(move |_| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
&& let PeerKind::Server(peer, _) = peer && let PeerKind::Server(peer, _) = peer
@ -557,15 +464,15 @@ impl Game {
// Method called on the client-side whenever a player has spawned // Method called on the client-side whenever a player has spawned
pub fn spawn_player_client(&mut self, id: u16, transform: NetTransform) { pub fn spawn_player_client(&mut self, id: u16, transform: NetTransform) {
if let Some(map) = &mut self.current_map { if let Some(map) = &mut self.current_map {
if let Some(player) = self.players.iter_mut().find(|p| p.id() == id) { if let Some(player) = self.players.iter_mut().find(|p| p.id == id) {
if let Some(character) = &mut player.character { if let Some(character) = &mut player.character {
// This is a respawn, delete old character // This is a respawn, delete old character
character.queue_free(); character.queue_free();
} }
let character = map.bind_mut().spawn_player( let character = map.bind_mut().spawn_player(
player.id(), player.id,
player.id() == self.self_id.unwrap_or(0), player.id == self.self_id.unwrap_or(0),
Some(transform), Some(transform),
); );
player.character = character; player.character = character;
@ -588,8 +495,8 @@ impl Game {
}, },
) in sync_data ) in sync_data
{ {
if let Some(player) = self.players.iter_mut().find(|p| p.id() == player_id) { if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
if player.id() != self.self_id.unwrap_or(0) { if player.id != self.self_id.unwrap_or(0) {
// Sync remote players always // Sync remote players always
player.set_transform(transform); player.set_transform(transform);
player.set_move_dir(movement_direction); player.set_move_dir(movement_direction);
@ -634,7 +541,7 @@ impl Game {
) -> bool { ) -> bool {
let self_id = self.self_id.clone().unwrap_or(0); let self_id = self.self_id.clone().unwrap_or(0);
if let Some(player) = self.find_player_mut(player_id) { if let Some(player) = self.find_player_mut(player_id) {
if player.id() != self_id { if player.id != self_id {
player.try_shoot(to, transform, look_up, deal_damage) player.try_shoot(to, transform, look_up, deal_damage)
} else { } else {
false false
@ -683,8 +590,10 @@ impl Game {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Player { pub struct Player {
pub id: u16,
pub connection_addr: SocketAddr, pub connection_addr: SocketAddr,
pub data: NetPlayer, pub name: String,
pub ping: u128,
pub ready: bool, pub ready: bool,
pub character: Option<DynGd<CharacterBody3D, dyn IPlayer + 'static>>, pub character: Option<DynGd<CharacterBody3D, dyn IPlayer + 'static>>,
} }
@ -779,10 +688,6 @@ impl Player {
false false
} }
} }
pub fn id(&self) -> u16 {
self.data.id
}
} }
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
@ -790,14 +695,15 @@ pub struct NetPlayer {
pub id: u16, pub id: u16,
pub name: String, pub name: String,
pub ping: u128, pub ping: u128,
pub team: u8,
} }
impl From<NetPlayer> for Player { impl From<NetPlayer> for Player {
fn from(value: NetPlayer) -> Self { fn from(value: NetPlayer) -> Self {
Player { Player {
id: value.id,
connection_addr: SocketAddr::from(([0, 0, 0, 0], 0)), connection_addr: SocketAddr::from(([0, 0, 0, 0], 0)),
data: value, name: value.name,
ping: value.ping,
ready: false, ready: false,
character: None, character: None,
} }
@ -806,6 +712,10 @@ impl From<NetPlayer> for Player {
impl From<Player> for NetPlayer { impl From<Player> for NetPlayer {
fn from(value: Player) -> Self { fn from(value: Player) -> Self {
value.data NetPlayer {
id: value.id,
name: value.name,
ping: value.ping,
}
} }
} }

View File

@ -90,8 +90,8 @@ impl INode for NetworkManager {
.cloned(); .cloned();
if let Some(player) = player { if let Some(player) = player {
game.bind_mut() game.bind_mut()
.update_player_ping(player.id(), connection.ping.as_millis()); .update_player_ping(player.id, connection.ping.as_millis());
pings.insert(player.id(), connection.ping.as_millis()); pings.insert(player.id, connection.ping.as_millis());
} }
} }
} }
@ -255,7 +255,6 @@ pub enum Package {
SetSelfNick(String), SetSelfNick(String),
NewPlayer(NetPlayer), NewPlayer(NetPlayer),
PlayerLeft(NetPlayer), PlayerLeft(NetPlayer),
SetTeam(u16, u8),
// Lobby packages // Lobby packages
SetReady(u16, bool), SetReady(u16, bool),

View File

@ -161,11 +161,6 @@ impl NetworkManager {
game.bind_mut().handle_swap_weapon(id, weapon_type, true); game.bind_mut().handle_swap_weapon(id, weapon_type, true);
} }
} }
Package::SetTeam(player_id, team) => {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().handle_player_team_change(player_id, team);
}
}
_ => {} _ => {}
}, },
}, },
@ -217,7 +212,7 @@ impl NetworkManager {
let player_id = game let player_id = game
.bind() .bind()
.find_player_by_addr(&connection.address) .find_player_by_addr(&connection.address)
.map(|p| p.id()); .map(|p| p.id);
if let Some(player_id) = player_id { if let Some(player_id) = player_id {
peer.broadcast_reliable(Package::PlayerLeft( peer.broadcast_reliable(Package::PlayerLeft(
game.bind().find_player(player_id).unwrap().clone().into(), game.bind().find_player(player_id).unwrap().clone().into(),
@ -239,10 +234,10 @@ impl NetworkManager {
game.bind().find_player_by_addr(&conn.address).cloned(); game.bind().find_player_by_addr(&conn.address).cloned();
if let Some(player) = player { if let Some(player) = player {
peer.broadcast_reliable(Package::SetNick( peer.broadcast_reliable(Package::SetNick(
player.id(), player.id,
nick.clone(), nick.clone(),
)); ));
game.bind_mut().update_player_nick(player.id(), nick); game.bind_mut().update_player_nick(player.id, nick);
} }
} }
} }
@ -251,11 +246,8 @@ impl NetworkManager {
let player = let player =
game.bind().find_player_by_addr(&conn.address).cloned(); game.bind().find_player_by_addr(&conn.address).cloned();
if let Some(player) = player { if let Some(player) = player {
game.bind_mut().update_player_ready(player.id(), is_ready); game.bind_mut().update_player_ready(player.id, is_ready);
peer.broadcast_reliable(Package::SetReady( peer.broadcast_reliable(Package::SetReady(player.id, is_ready));
player.id(),
is_ready,
));
} }
} }
} }
@ -265,7 +257,7 @@ impl NetworkManager {
if let Some(transform) = player.get_transform() { if let Some(transform) = player.get_transform() {
peer.send_reliable( peer.send_reliable(
&conn.address, &conn.address,
Package::SpawnPlayer(player.id(), transform), Package::SpawnPlayer(player.id, transform),
); );
} }
} }
@ -285,8 +277,8 @@ impl NetworkManager {
let player = let player =
game.bind().find_player_by_addr(&conn.address).cloned(); game.bind().find_player_by_addr(&conn.address).cloned();
if let Some(player) = player { if let Some(player) = player {
game.bind_mut().handle_jump(player.id()); game.bind_mut().handle_jump(player.id);
peer.broadcast_reliable(Package::Jump(player.id())); peer.broadcast_reliable(Package::Jump(player.id));
} }
} }
} }
@ -296,35 +288,19 @@ impl NetworkManager {
game.bind().find_player_by_addr(&conn.address).cloned(); game.bind().find_player_by_addr(&conn.address).cloned();
if let Some(player) = player { if let Some(player) = player {
if game.bind_mut().handle_shoot( if game.bind_mut().handle_shoot(
player.id(), player.id,
to.into(), to.into(),
transform, transform,
look_up, look_up,
true, true,
) { ) {
peer.broadcast_reliable(Package::Shoot( peer.broadcast_reliable(Package::Shoot(
player.id(), player.id, to, transform, look_up,
to,
transform,
look_up,
)); ));
} }
} }
} }
} }
Package::SetTeam(player_id, team) => {
if let Some(game) = &mut Game::singleton() {
let self_id = game
.bind()
.find_player_by_addr(&conn.address)
.map(|p| p.id());
if let Some(self_id) = self_id {
if game.bind().opts.allow_any_team || self_id == player_id {
game.bind_mut().try_set_player_team(player_id, team, true);
}
}
}
}
_ => {} _ => {}
}, },
}, },

View File

@ -3,7 +3,7 @@ use std::{f32::consts::PI, ops::Neg};
use godot::{ use godot::{
classes::{ classes::{
Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D, ICharacterBody3D, Input, Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D, ICharacterBody3D, Input,
InputEvent, InputEventMouseMotion, Label, Label3D, input::MouseMode, InputEvent, InputEventMouseMotion, Label, input::MouseMode,
}, },
obj::WithBaseField, obj::WithBaseField,
prelude::*, prelude::*,
@ -535,8 +535,6 @@ pub struct RemotePlayer {
spectator_camera: Option<Gd<Camera3D>>, spectator_camera: Option<Gd<Camera3D>>,
#[export] #[export]
ball_origin: Option<Gd<Node3D>>, ball_origin: Option<Gd<Node3D>>,
#[export]
name_label: Option<Gd<Label3D>>,
pub player_id: Option<u16>, pub player_id: Option<u16>,
@ -694,18 +692,6 @@ impl IPlayer for RemotePlayer {
#[godot_api] #[godot_api]
impl ICharacterBody3D for RemotePlayer { impl ICharacterBody3D for RemotePlayer {
fn ready(&mut self) { fn ready(&mut self) {
self.run_deferred(|s| {
if let Some(player_id) = s.player_id
&& let Some(game) = Game::singleton()
&& let Some(player) = game.bind().find_player(player_id)
&& let Some(team) = game.bind().get_team(player.data.team)
&& let Some(name_label) = &mut s.name_label
{
name_label.set_text(&player.data.name);
name_label.set_modulate(team.bind().color);
}
});
self.swap_weapon(WeaponType::Raygun); self.swap_weapon(WeaponType::Raygun);
} }

View File

@ -143,7 +143,7 @@ impl LobbyPanel {
for player in &game.bind().players { for player in &game.bind().players {
if let Some(node) = prefab.instantiate() { if let Some(node) = prefab.instantiate() {
let mut listing = node.cast::<PlayerListing>(); let mut listing = node.cast::<PlayerListing>();
listing.bind_mut().player_id = Some(player.id()); listing.bind_mut().player_id = Some(player.id);
listing.bind_mut().update_teams(game.bind().get_teams()); listing.bind_mut().update_teams(game.bind().get_teams());
listing.bind_mut().update(); listing.bind_mut().update();
list.add_child(&listing); list.add_child(&listing);

View File

@ -1,13 +1,9 @@
use godot::{ use godot::{
classes::{GridContainer, IGridContainer, Label, OptionButton, TextEdit}, classes::{GridContainer, Label, OptionButton},
prelude::*, prelude::*,
}; };
use crate::{ use crate::{game_manager::Game, team_resource::TeamResource};
game_manager::{Game, GameOptions},
net::network_manager::NetworkManager,
team_resource::TeamResource,
};
#[derive(GodotClass)] #[derive(GodotClass)]
#[class(base=GridContainer, init)] #[class(base=GridContainer, init)]
@ -26,60 +22,14 @@ pub struct PlayerListing {
base: Base<GridContainer>, base: Base<GridContainer>,
} }
#[godot_api]
impl IGridContainer for PlayerListing {
fn ready(&mut self) {
self.run_deferred(|s| {
if let Some(game) = &mut Game::singleton() {
game.bind_mut()
.signals()
.on_player_team_changed()
.connect_other(s, |s, id, team| {
if id == s.player_id.unwrap_or(0) {
s.on_team_update(team);
}
});
}
});
if let Some(team_dropdown) = self.team_dropdown.clone() {
team_dropdown
.signals()
.item_selected()
.connect_other(self, |s, selection| {
s.on_team_selection_changed(selection as u8);
});
}
if let Some(game) = &Game::singleton() {
self.update_game_options(&game.bind().opts, game.bind().self_id);
}
}
}
impl PlayerListing { impl PlayerListing {
pub fn update_game_options(&mut self, opts: &GameOptions, self_id: Option<u16>) {
let is_host = NetworkManager::singleton().bind().is_host();
if let Some(dropdown) = &mut self.team_dropdown {
dropdown.set_disabled(!is_host && !opts.allow_any_team && self.player_id != self_id);
}
}
pub fn update(&mut self) { pub fn update(&mut self) {
if let Some(player_id) = &self.player_id if let Some(player_id) = &self.player_id
&& let Some(game) = Game::singleton() && let Some(game) = Game::singleton()
&& let Some(player) = game.bind().find_player(*player_id) && let Some(player) = game.bind().find_player(*player_id)
{ {
if let Some(player_label) = &mut self.name_label { if let Some(player_label) = &mut self.name_label {
player_label.set_text(&format!( player_label.set_text(&format!("{} ({})", player.name, player.connection_addr));
"{} ({})",
player.data.name, player.connection_addr
));
if let Some(team) = game.bind().get_team(player.data.team) {
player_label.add_theme_color_override("font_color", team.bind().color);
}
} }
if let Some(ready_label) = &mut self.ready_label { if let Some(ready_label) = &mut self.ready_label {
@ -91,53 +41,17 @@ impl PlayerListing {
} }
if let Some(ping_label) = &mut self.ping_label { if let Some(ping_label) = &mut self.ping_label {
ping_label.set_text(&format!("({}ms)", player.data.ping)); ping_label.set_text(&format!("({}ms)", player.ping));
}
if let Some(dropdown) = &mut self.team_dropdown {
dropdown.select(player.data.team as i32);
} }
} }
} }
pub fn update_teams(&mut self, teams: Array<Gd<TeamResource>>) { pub fn update_teams(&mut self, teams: Array<Gd<TeamResource>>) {
if let Some(dropdown) = &mut self.team_dropdown { if let Some(dropdown) = &mut self.team_dropdown {
let prev_selection = dropdown.get_selected();
dropdown.clear(); dropdown.clear();
for team in teams.iter_shared() { for team in teams.iter_shared() {
dropdown.add_item(&team.bind().name); dropdown.add_item(&team.bind().name);
} }
dropdown.select(prev_selection.min((teams.len() - 1) as i32));
}
}
pub fn on_team_selection_changed(&mut self, team: u8) {
if let Some(mut game) = Game::singleton() {
game.bind_mut()
.try_set_player_team(self.player_id.unwrap_or(0), team, false);
if let Some(player) = game.bind().find_player(self.player_id.unwrap_or(0))
&& let Some(player_label) = &mut self.name_label
&& let Some(team) = game.bind().get_team(player.data.team)
{
godot_print!("Setting color");
player_label.add_theme_color_override("font_color", team.bind().color);
}
}
}
fn on_team_update(&mut self, team: u8) {
if let Some(dropdown) = &mut self.team_dropdown {
dropdown.select(team as i32);
}
if let Some(game) = Game::singleton()
&& let Some(player) = game.bind().find_player(self.player_id.unwrap_or(0))
&& let Some(player_label) = &mut self.name_label
&& let Some(team) = game.bind().get_team(player.data.team)
{
godot_print!("Setting color");
player_label.add_theme_color_override("font_color", team.bind().color);
} }
} }
} }