diff --git a/godot/project.godot b/godot/project.godot index 3d8b409..8a16272 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -93,6 +93,11 @@ pause={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +scoreboard={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} [physics] diff --git a/godot/scenes/game_finished.tscn b/godot/scenes/game_finished.tscn index e8e5c44..591d74a 100644 --- a/godot/scenes/game_finished.tscn +++ b/godot/scenes/game_finished.tscn @@ -2,11 +2,9 @@ [ext_resource type="PackedScene" uid="uid://2sfy0vq0fqt3" path="res://scenes/ui/player_listing.tscn" id="1_ou354"] -[node name="game_finished" type="GameFinishedScreen" unique_id=700430082 node_paths=PackedStringArray("title_container", "back_button", "players_hbox")] +[node name="game_finished" type="GameFinishedScreen" unique_id=700430082 node_paths=PackedStringArray("title_container", "back_button")] title_container = NodePath("title_container") back_button = NodePath("button") -players_hbox = NodePath("player_listings") -player_listing_scene = ExtResource("1_ou354") anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -32,26 +30,27 @@ anchor_left = 0.5 anchor_top = 1.0 anchor_right = 0.5 anchor_bottom = 1.0 -offset_left = -22.0 -offset_top = -103.0 -offset_right = 23.0 -offset_bottom = -69.0 +offset_left = -40.0 +offset_top = -87.0 +offset_right = 42.0 +offset_bottom = -34.0 grow_horizontal = 2 grow_vertical = 0 theme_override_font_sizes/font_size = 32 text = "Back" -[node name="player_listings" type="HBoxContainer" parent="." unique_id=588134370] +[node name="player_listings" type="PlayerListings" parent="." unique_id=602626392] +player_listing_scene = ExtResource("1_ou354") layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 -offset_left = -186.0 -offset_top = -193.0 -offset_right = 186.0 -offset_bottom = -153.0 +offset_left = -554.5 +offset_top = -210.0 +offset_right = 554.5 +offset_bottom = 210.0 grow_horizontal = 2 grow_vertical = 2 alignment = 1 diff --git a/godot/scenes/player/local_player.tscn b/godot/scenes/player/local_player.tscn index 7d20893..a163f28 100644 --- a/godot/scenes/player/local_player.tscn +++ b/godot/scenes/player/local_player.tscn @@ -3,13 +3,14 @@ [ext_resource type="PackedScene" uid="uid://bod6b3befmyt5" path="res://scenes/player/soldier_m.tscn" id="1_jd651"] [ext_resource type="PackedScene" uid="uid://cl66unms2gim0" path="res://scenes/player/splorch.tscn" id="2_ywmwa"] [ext_resource type="PackedScene" uid="uid://n3u0jr4wiib1" path="res://scenes/ui/settings.tscn" id="3_beej8"] +[ext_resource type="PackedScene" uid="uid://2sfy0vq0fqt3" path="res://scenes/ui/player_listing.tscn" id="4_okac2"] [sub_resource type="Environment" id="Environment_3nx84"] glow_enabled = true [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"] -[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label", "ball_origin", "weapon_node", "pause_panel", "exit_to_lobby", "settings_panel")] +[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label", "ball_origin", "weapon_node", "pause_panel", "exit_to_lobby", "settings_panel", "scoreboard")] look_sensitivity = 1.5 camera = NodePath("camera_3d") move_speed = 5.0 @@ -23,6 +24,7 @@ weapon_node = NodePath("camera_3d/weapon_node") pause_panel = NodePath("pause_menu") exit_to_lobby = NodePath("pause_menu/v_box_container/exit_to_lobby") settings_panel = NodePath("settings") +scoreboard = NodePath("scoreboard") health = 100 collision_mask = 4 @@ -117,6 +119,24 @@ text = "Exit" [node name="settings" parent="." unique_id=999912383 instance=ExtResource("3_beej8")] visible = false +[node name="scoreboard" type="PanelContainer" parent="." unique_id=1276565374] +custom_minimum_size = Vector2(0, -1) +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -76.0 +offset_top = 58.0 +offset_right = 77.0 +offset_bottom = 100.0 +grow_horizontal = 2 +size_flags_vertical = 3 + +[node name="h_box_container" type="PlayerListings" parent="scoreboard" unique_id=256898638] +player_listing_scene = ExtResource("4_okac2") +layout_mode = 2 +alignment = 1 +metadata/_edit_lock_ = true + [connection signal="pressed" from="pause_menu/v_box_container/settings" to="settings" method="open"] [connection signal="pressed" from="pause_menu/v_box_container/exit_to_lobby" to="." method="exit_to_lobby"] [connection signal="pressed" from="pause_menu/v_box_container/exit" to="." method="exit"] diff --git a/godot/scenes/ui/player_listing.tscn b/godot/scenes/ui/player_listing.tscn index 5d7a5d9..5a903fe 100644 --- a/godot/scenes/ui/player_listing.tscn +++ b/godot/scenes/ui/player_listing.tscn @@ -5,24 +5,24 @@ name_label = NodePath("name") kills_label = NodePath("kills") deaths_label = NodePath("deaths") ping_label = NodePath("ping") +size_flags_horizontal = 3 [node name="name" type="Label" parent="." unique_id=1361759955] -custom_minimum_size = Vector2(200, 0) -custom_maximum_size = Vector2(200, -1) clip_contents = true layout_mode = 2 +size_flags_horizontal = 2 text = "Player Name" [node name="kills" type="Label" parent="." unique_id=690390687] -custom_minimum_size = Vector2(30, 0) -custom_maximum_size = Vector2(30, -1) +custom_minimum_size = Vector2(50, 0) +custom_maximum_size = Vector2(50, -1) layout_mode = 2 text = "0" horizontal_alignment = 1 [node name="deaths" type="Label" parent="." unique_id=1615203485] -custom_minimum_size = Vector2(30, 0) -custom_maximum_size = Vector2(30, -1) +custom_minimum_size = Vector2(50, 0) +custom_maximum_size = Vector2(50, -1) layout_mode = 2 text = "0" horizontal_alignment = 1 diff --git a/rust/src/player.rs b/rust/src/player.rs index 29a7feb..409db05 100644 --- a/rust/src/player.rs +++ b/rust/src/player.rs @@ -3,7 +3,8 @@ use std::{f32::consts::PI, ops::Neg}; use godot::{ classes::{ Button, Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D, ICharacterBody3D, - Input, InputEvent, InputEventMouseMotion, Label, Label3D, Panel, input::MouseMode, + Input, InputEvent, InputEventMouseMotion, Label, Label3D, Panel, PanelContainer, + input::MouseMode, }, obj::WithBaseField, prelude::*, @@ -198,6 +199,8 @@ pub struct LocalPlayer { #[export] settings_panel: Option>, #[export] + scoreboard: Option>, + #[export] health: i32, pub player_id: Option, @@ -491,6 +494,10 @@ impl ICharacterBody3D for LocalPlayer { let new_pos = camera_prev_pos.lerp(target.get_global_position(), 0.1); camera.set_global_position(new_pos); } + + if let Some(scoreboard) = &mut self.scoreboard { + scoreboard.set_visible(Input::singleton().is_action_pressed("scoreboard")); + } } fn input(&mut self, event: Gd) { diff --git a/rust/src/ui/game_finished_screen.rs b/rust/src/ui/game_finished_screen.rs index ec35e60..db6146c 100644 --- a/rust/src/ui/game_finished_screen.rs +++ b/rust/src/ui/game_finished_screen.rs @@ -1,15 +1,14 @@ use godot::{ classes::{ Button, HBoxContainer, IPanel, Label, Panel, VBoxContainer, box_container::AlignmentMode, - control::LayoutDirection, }, - global::{HorizontalAlignment, VerticalAlignment}, + global::HorizontalAlignment, prelude::*, }; use crate::{ game_manager::{Game, GameManager}, - ui::player_listing::PlayerListing, + ui::{player_listing::PlayerListing, player_listings::PlayerListings}, }; #[derive(GodotClass)] @@ -20,9 +19,7 @@ pub struct GameFinishedScreen { #[export] back_button: Option>, #[export] - players_hbox: Option>, - #[export] - player_listing_scene: Option>, + player_listings: Option>, base: Base, } @@ -31,7 +28,9 @@ pub struct GameFinishedScreen { impl IPanel for GameFinishedScreen { fn ready(&mut self) { self.produce_title(); - self.produce_player_listings(); + if let Some(listings) = &mut self.player_listings { + listings.bind_mut().update_player_listings(); + } if let Some(back) = &self.back_button { back.signals().pressed().connect_other(self, |_| { if let Some(mut game) = Game::singleton() { @@ -44,39 +43,6 @@ impl IPanel for GameFinishedScreen { } impl GameFinishedScreen { - fn produce_player_listings(&mut self) { - if let Some(game) = Game::singleton() { - for (id, team) in game.bind().get_teams().iter_shared().enumerate() { - let mut vbox = VBoxContainer::new_alloc(); - vbox.set_alignment(AlignmentMode::CENTER); - - let mut team_label = Label::new_alloc(); - team_label.set_modulate(team.bind().color); - team_label.set_text(&team.bind().name); - team_label.set_horizontal_alignment(HorizontalAlignment::CENTER); - vbox.add_child(&team_label); - - if let Some(listing_scene) = &self.player_listing_scene { - let game = game.bind(); - let players = game - .players - .iter() - .filter(|p| p.data.team == id as u8) - .collect::>(); - for player in players { - let mut listing = listing_scene.instantiate_as::(); - listing.bind_mut().player_id = Some(player.id()); - vbox.add_child(&listing); - } - } - - if let Some(hbox) = &mut self.players_hbox { - hbox.add_child(&vbox); - } - } - } - } - fn produce_title(&mut self) { if let Some(game) = Game::singleton() { let max_goals = game diff --git a/rust/src/ui/mod.rs b/rust/src/ui/mod.rs index 401c73e..07ae55a 100644 --- a/rust/src/ui/mod.rs +++ b/rust/src/ui/mod.rs @@ -6,6 +6,7 @@ pub mod main_menu; pub mod menu_player; pub mod net_stats; pub mod player_listing; +pub mod player_listings; pub mod settings; pub mod simple_score_view; pub mod slider; diff --git a/rust/src/ui/player_listing.rs b/rust/src/ui/player_listing.rs index 0d0dbe3..f7da487 100644 --- a/rust/src/ui/player_listing.rs +++ b/rust/src/ui/player_listing.rs @@ -36,14 +36,29 @@ impl IHBoxContainer for PlayerListing { impl PlayerListing { pub fn update(&mut self) { - if let Some(game) = Game::singleton() - && let Some(player) = game.bind().find_player(self.player_id.unwrap_or(0)) - { - if let Some(name_label) = &mut self.name_label { - name_label.set_text(&player.data.name); - } - if let Some(ping_label) = &mut self.ping_label { - ping_label.set_text(&format!("{}ms", player.data.ping)); + if let Some(game) = Game::singleton() { + if let Some(player_id) = self.player_id + && let Some(player) = game.bind().find_player(player_id) + { + if let Some(name_label) = &mut self.name_label { + name_label.set_text(&player.data.name); + } + if let Some(ping_label) = &mut self.ping_label { + ping_label.set_text(&player.data.ping.to_string()); + } + } else { + if let Some(name_label) = &mut self.name_label { + name_label.set_text("Name"); + } + if let Some(kills_label) = &mut self.kills_label { + kills_label.set_text("Kills"); + } + if let Some(deaths_label) = &mut self.deaths_label { + deaths_label.set_text("Deaths"); + } + if let Some(ping_label) = &mut self.ping_label { + ping_label.set_text("Ping"); + } } } } diff --git a/rust/src/ui/player_listings.rs b/rust/src/ui/player_listings.rs new file mode 100644 index 0000000..dd0c846 --- /dev/null +++ b/rust/src/ui/player_listings.rs @@ -0,0 +1,66 @@ +use godot::{ + classes::{HBoxContainer, IHBoxContainer, Label, VBoxContainer, box_container::AlignmentMode}, + global::HorizontalAlignment, + prelude::*, +}; + +use crate::{game_manager::Game, ui::player_listing::PlayerListing}; + +#[derive(GodotClass)] +#[class(base=HBoxContainer, init)] +pub struct PlayerListings { + #[export] + player_listing_scene: Option>, + + base: Base, +} + +#[godot_api] +impl IHBoxContainer for PlayerListings { + fn ready(&mut self) { + self.run_deferred(|s| s.update_player_listings()); + } +} + +impl PlayerListings { + pub fn update_player_listings(&mut self) { + for child in self.base().get_children().iter_shared() { + self.base_mut().remove_child(&child); + } + + if let Some(game) = Game::singleton() { + for (id, team) in game.bind().get_teams().iter_shared().enumerate() { + let mut vbox = VBoxContainer::new_alloc(); + + vbox.set_alignment(AlignmentMode::BEGIN); + vbox.set_custom_minimum_size(Vector2::new(300., 0.)); + + let mut team_label = Label::new_alloc(); + team_label.set_modulate(team.bind().color); + team_label.set_text(&team.bind().name); + team_label.set_horizontal_alignment(HorizontalAlignment::CENTER); + vbox.add_child(&team_label); + + if let Some(listing_scene) = &self.player_listing_scene { + let game = game.bind(); + let players = game + .players + .iter() + .filter(|p| p.data.team == id as u8) + .collect::>(); + + let header = listing_scene.instantiate_as::(); + vbox.add_child(&header); + + for player in players { + let mut listing = listing_scene.instantiate_as::(); + listing.bind_mut().player_id = Some(player.id()); + vbox.add_child(&listing); + } + } + + self.base_mut().add_child(&vbox); + } + } + } +}