Compare commits
3 Commits
e4c7a8f54a
...
923c863583
| Author | SHA1 | Date | |
|---|---|---|---|
| 923c863583 | |||
| a1205635f0 | |||
| 654eeaeb5c |
@ -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]
|
||||
|
||||
|
||||
@ -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,35 @@ 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
|
||||
anchors_preset = 5
|
||||
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 = -88.0
|
||||
offset_top = 150.0
|
||||
offset_right = 87.5
|
||||
offset_bottom = 167.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="simple_score_view" type="SimpleScoreView" parent="." unique_id=1625972988]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -20.0
|
||||
offset_top = 93.0
|
||||
offset_right = 20.0
|
||||
offset_bottom = 133.0
|
||||
grow_horizontal = 2
|
||||
|
||||
@ -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"]
|
||||
|
||||
@ -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
|
||||
|
||||
@ -304,6 +304,8 @@ impl Game {
|
||||
pub fn on_goal();
|
||||
#[signal]
|
||||
pub fn on_game_finished();
|
||||
#[signal]
|
||||
pub fn on_player_killed(player: u16);
|
||||
|
||||
pub fn singleton() -> Option<Gd<Game>> {
|
||||
GameManager::singleton()
|
||||
@ -330,6 +332,8 @@ impl Game {
|
||||
character.queue_free();
|
||||
}
|
||||
player.data.ready = false;
|
||||
player.data.kills = 0;
|
||||
player.data.deaths = 0;
|
||||
}
|
||||
|
||||
self.run_deferred(|s| {
|
||||
@ -351,6 +355,7 @@ impl Game {
|
||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
|
||||
&& let PeerKind::Server(peer, _) = peer
|
||||
{
|
||||
peer.set_accepting_connections(true);
|
||||
peer.broadcast_reliable(Package::FinishGame);
|
||||
}
|
||||
s.signals().on_game_finished().emit()
|
||||
@ -474,6 +479,8 @@ impl Game {
|
||||
ping: 0,
|
||||
team: 0,
|
||||
ready: false,
|
||||
kills: 0,
|
||||
deaths: 0,
|
||||
},
|
||||
character: None,
|
||||
});
|
||||
@ -824,6 +831,19 @@ impl Game {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle for when a player is killed, run both on client and server
|
||||
pub fn on_kill(&mut self, source: DamageSource, player_id: u16) {
|
||||
if let DamageSource::Player(source_id) = source
|
||||
&& let Some(source_player) = self.find_player_mut(source_id)
|
||||
{
|
||||
source_player.data.kills += 1;
|
||||
}
|
||||
if let Some(player) = self.find_player_mut(player_id) {
|
||||
player.data.deaths += 1;
|
||||
}
|
||||
self.run_deferred(move |s| s.signals().on_player_killed().emit(player_id));
|
||||
}
|
||||
|
||||
// Handle taking damage, from server to client
|
||||
pub fn handle_take_damage(&mut self, source: DamageSource, player_id: u16, damage: i32) {
|
||||
if let Some(player) = self.find_player_mut(player_id) {
|
||||
@ -837,7 +857,8 @@ impl Game {
|
||||
pub fn handle_kill(&mut self, source: DamageSource, player_id: u16) {
|
||||
if let Some(player) = self.find_player_mut(player_id) {
|
||||
if let Some(character) = &mut player.character {
|
||||
character.dyn_bind_mut().kill(source);
|
||||
character.dyn_bind_mut().kill(source.clone());
|
||||
self.on_kill(source, player_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -855,7 +876,8 @@ impl Game {
|
||||
pub fn on_death(&mut self, source: DamageSource, target_player_id: u16) {
|
||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||
if let PeerKind::Server(peer, _) = peer {
|
||||
peer.broadcast_reliable(Kill(source, target_player_id));
|
||||
peer.broadcast_reliable(Kill(source.clone(), target_player_id));
|
||||
self.on_kill(source, target_player_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -971,6 +993,8 @@ pub struct NetPlayer {
|
||||
pub name: String,
|
||||
pub ping: u128,
|
||||
pub team: u8,
|
||||
pub kills: u16,
|
||||
pub deaths: u16,
|
||||
}
|
||||
|
||||
impl From<NetPlayer> for Player {
|
||||
|
||||
@ -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<Gd<SettingsPanel>>,
|
||||
#[export]
|
||||
scoreboard: Option<Gd<PanelContainer>>,
|
||||
#[export]
|
||||
health: i32,
|
||||
|
||||
pub player_id: Option<u16>,
|
||||
@ -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<InputEvent>) {
|
||||
|
||||
@ -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<Gd<Button>>,
|
||||
#[export]
|
||||
players_hbox: Option<Gd<HBoxContainer>>,
|
||||
#[export]
|
||||
player_listing_scene: Option<Gd<PackedScene>>,
|
||||
player_listings: Option<Gd<PlayerListings>>,
|
||||
|
||||
base: Base<Panel>,
|
||||
}
|
||||
@ -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::<Vec<_>>();
|
||||
for player in players {
|
||||
let mut listing = listing_scene.instantiate_as::<PlayerListing>();
|
||||
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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -30,20 +30,44 @@ impl IHBoxContainer for PlayerListing {
|
||||
game.signals()
|
||||
.on_players_updated()
|
||||
.connect_other(self, |s| s.update());
|
||||
game.signals()
|
||||
.on_player_killed()
|
||||
.connect_other(self, |s, _| s.update());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(kills_label) = &mut self.kills_label {
|
||||
kills_label.set_text(&player.data.kills.to_string());
|
||||
}
|
||||
if let Some(deaths_label) = &mut self.deaths_label {
|
||||
deaths_label.set_text(&player.data.deaths.to_string());
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
rust/src/ui/player_listings.rs
Normal file
66
rust/src/ui/player_listings.rs
Normal file
@ -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<Gd<PackedScene>>,
|
||||
|
||||
base: Base<HBoxContainer>,
|
||||
}
|
||||
|
||||
#[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::<Vec<_>>();
|
||||
|
||||
let header = listing_scene.instantiate_as::<PlayerListing>();
|
||||
vbox.add_child(&header);
|
||||
|
||||
for player in players {
|
||||
let mut listing = listing_scene.instantiate_as::<PlayerListing>();
|
||||
listing.bind_mut().player_id = Some(player.id());
|
||||
vbox.add_child(&listing);
|
||||
}
|
||||
}
|
||||
|
||||
self.base_mut().add_child(&vbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user