Add possibility for alternate team colors

This commit is contained in:
Sofia 2026-08-03 20:33:40 +03:00
parent a7fcaeb2ff
commit 40c119d1c8
19 changed files with 63 additions and 26 deletions

View File

@ -7,11 +7,9 @@
[sub_resource type="TeamResource" id="TeamResource_w4gl8"] [sub_resource type="TeamResource" id="TeamResource_w4gl8"]
name = "Copper Team" name = "Copper Team"
color = Color(0.41, 0.82, 0.54666674, 1)
[sub_resource type="TeamResource" id="TeamResource_iftcq"] [sub_resource type="TeamResource" id="TeamResource_iftcq"]
name = "Silver Team" name = "Silver Team"
color = Color(0.74, 0.7876666, 1, 1)
[resource] [resource]
name = "Precipice" name = "Precipice"

View File

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

View File

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

View File

@ -8,11 +8,13 @@
[sub_resource type="TeamResource" id="TeamResource_64qm8"] [sub_resource type="TeamResource" id="TeamResource_64qm8"]
name = "Shadow Team" name = "Shadow Team"
color = Color(0.5380128, 0.5138385, 1, 1) primary_color = Color(0.05000019, 0, 1, 1)
alt_color = Color(0, 1, 0.0666666, 1)
[sub_resource type="TeamResource" id="TeamResource_47vax"] [sub_resource type="TeamResource" id="TeamResource_47vax"]
name = "Sunshine Team" name = "Sunshine Team"
color = Color(0.99999994, 0.83743095, 0.5094259, 1) primary_color = Color(1, 0, 0, 1)
alt_color = Color(0.9333333, 1, 0, 1)
[resource] [resource]
name = "Two Towers" name = "Two Towers"

View File

@ -20,10 +20,11 @@ font_size = 32
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jbm04"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jbm04"]
bg_color = Color(0.30692267, 0.3069227, 0.30692264, 1) bg_color = Color(0.30692267, 0.3069227, 0.30692264, 1)
[node name="lobby_world" type="LobbyWorld" unique_id=129662054] [node name="lobby_world" type="LobbyWorld" unique_id=129662054 node_paths=PackedStringArray("lobby")]
menu_player_scene = ExtResource("3_q60fs") menu_player_scene = ExtResource("3_q60fs")
lobby = NodePath("lobby")
[node name="lobby" type="LobbyPanel" parent="." unique_id=915192272 node_paths=PackedStringArray("players_list", "name_field", "ready_button", "map_selection", "options_panel", "options_grid")] [node name="lobby" type="LobbyPanel" parent="." unique_id=915192272 node_paths=PackedStringArray("players_list", "name_field", "ready_button", "map_selection", "options_panel", "options_grid", "alt_colors")]
players_list = NodePath("v_box_container/players_list") players_list = NodePath("v_box_container/players_list")
name_field = NodePath("v_box_container/h_box_container/text_edit") name_field = NodePath("v_box_container/h_box_container/text_edit")
player_listing_prefab = ExtResource("1_o1atq") player_listing_prefab = ExtResource("1_o1atq")
@ -31,6 +32,7 @@ ready_button = NodePath("v_box_container3/ready_button")
map_selection = NodePath("v_box_container2/option_button") map_selection = NodePath("v_box_container2/option_button")
options_panel = NodePath("options_panel") options_panel = NodePath("options_panel")
options_grid = NodePath("options_panel/h_box_container/options_grid") options_grid = NodePath("options_panel/h_box_container/options_grid")
alt_colors = NodePath("v_box_container/h_box_container/check_box")
start_game_icon = ExtResource("3_oipnb") start_game_icon = ExtResource("3_oipnb")
ready_icon = ExtResource("4_yad6j") ready_icon = ExtResource("4_yad6j")
not_ready_icon = ExtResource("5_ncsg4") not_ready_icon = ExtResource("5_ncsg4")

View File

@ -105,7 +105,7 @@ impl ChatMessage {
if idx > 0 { if idx > 0 {
label.add_text(" and "); label.add_text(" and ");
} }
label.push_color(team.bind().color); label.push_color(team.bind().color());
label.add_text(&team.bind().name); label.add_text(&team.bind().name);
label.pop(); label.pop();
} }
@ -120,7 +120,7 @@ fn add_player(label: &mut Gd<RichTextLabel>, player: &Player) {
if let Some(game) = Game::singleton() if let Some(game) = Game::singleton()
&& let Some(team) = game.bind().get_team(player.data.team) && let Some(team) = game.bind().get_team(player.data.team)
{ {
label.push_color(team.bind().color); label.push_color(team.bind().color());
label.add_text(&player.data.name); label.add_text(&player.data.name);
label.pop(); label.pop();
} }

View File

@ -1185,7 +1185,7 @@ impl Game {
{ {
chat.bind_mut().new_message(ChatMessage::ChatMessage( chat.bind_mut().new_message(ChatMessage::ChatMessage(
player.data.name.clone(), player.data.name.clone(),
team.bind().color, team.bind().color(),
message.clone(), message.clone(),
)); ));
} }

View File

@ -44,7 +44,7 @@ impl Goal {
if let Some(game) = Game::singleton() if let Some(game) = Game::singleton()
&& let Some(team) = game.bind().get_team(self.team) && let Some(team) = game.bind().get_team(self.team)
{ {
mat.set_shader_parameter("goal_color", &team.bind().color.to_variant()); mat.set_shader_parameter("goal_color", &team.bind().color().to_variant());
} else if let Some(playback) = &StandaloneReplayManager::singleton().bind().playback } else if let Some(playback) = &StandaloneReplayManager::singleton().bind().playback
&& let Some(team) = playback.bind().replay.teams.get(self.team as usize) && let Some(team) = playback.bind().replay.teams.get(self.team as usize)
{ {

View File

@ -2,13 +2,15 @@ use std::{collections::HashMap, f32::consts::PI};
use godot::{classes::RandomNumberGenerator, prelude::*}; use godot::{classes::RandomNumberGenerator, prelude::*};
use crate::{game::Game, player::menu_player::MenuPlayer}; use crate::{game::Game, player::menu_player::MenuPlayer, ui::lobby::LobbyPanel};
#[derive(GodotClass)] #[derive(GodotClass)]
#[class(base=Node3D, init)] #[class(base=Node3D, init)]
pub struct LobbyWorld { pub struct LobbyWorld {
#[export] #[export]
menu_player_scene: Option<Gd<PackedScene>>, menu_player_scene: Option<Gd<PackedScene>>,
#[export]
lobby: Option<Gd<LobbyPanel>>,
rng: Gd<RandomNumberGenerator>, rng: Gd<RandomNumberGenerator>,
@ -35,6 +37,13 @@ impl INode3D for LobbyWorld {
.on_players_updated() .on_players_updated()
.connect_other(self, Self::update_players); .connect_other(self, Self::update_players);
} }
if let Some(lobby) = &self.lobby {
lobby
.signals()
.on_alt_colors_changed()
.connect_other(self, |s| s.update_players());
}
} }
} }

View File

@ -87,7 +87,7 @@ impl Map {
&& let Some(team) = game.bind().get_team(player.data.team) && let Some(team) = game.bind().get_team(player.data.team)
{ {
node_clone.bind_mut().player_name = player.data.name.clone(); node_clone.bind_mut().player_name = player.data.name.clone();
node_clone.bind_mut().player_color = team.bind().color.clone(); node_clone.bind_mut().player_color = team.bind().color().clone();
} }
}); });
} }

View File

@ -459,7 +459,7 @@ impl ICharacterBody3D for LocalPlayer {
&& let Some(team) = game.bind().get_team(player.data.team) && let Some(team) = game.bind().get_team(player.data.team)
{ {
if let Some(mesh) = &mut s.soldier_mesh { if let Some(mesh) = &mut s.soldier_mesh {
mesh.bind_mut().set_color(team.bind().color); mesh.bind_mut().set_color(team.bind().color());
} }
} }
}); });

View File

@ -42,10 +42,10 @@ impl MenuPlayer {
{ {
if let Some(name_label) = &mut self.name_label { if let Some(name_label) = &mut self.name_label {
name_label.set_text(&player.data.name); name_label.set_text(&player.data.name);
name_label.set_modulate(team.bind().color); name_label.set_modulate(team.bind().color());
} }
if let Some(mesh) = &mut self.mesh { if let Some(mesh) = &mut self.mesh {
mesh.bind_mut().set_color(team.bind().color); mesh.bind_mut().set_color(team.bind().color());
} }
} }
} }

View File

@ -525,7 +525,7 @@ impl INode for ReplayRecorder {
ReplayPlayer { ReplayPlayer {
id: player.id(), id: player.id(),
name: player.data.name.clone(), name: player.data.name.clone(),
color: team.bind().color.into(), color: team.bind().color().into(),
team: player.data.team, team: player.data.team,
stats: Default::default(), stats: Default::default(),
}, },
@ -539,7 +539,7 @@ impl INode for ReplayRecorder {
.iter_shared() .iter_shared()
.map(|t| ReplayTeam { .map(|t| ReplayTeam {
name: t.bind().name.to_string(), name: t.bind().name.to_string(),
color: t.bind().color.into(), color: t.bind().color().into(),
}) })
.collect(); .collect();
} }

View File

@ -1,15 +1,37 @@
use godot::prelude::*; use godot::prelude::*;
use crate::game::{Game, opts::PrivateGameOptions};
#[derive(GodotClass)] #[derive(GodotClass)]
#[class(base=Resource, init, tool)] #[class(base=Resource, init, tool)]
pub struct TeamResource { pub struct TeamResource {
#[export] #[export]
pub name: GString, pub name: GString,
#[export] #[export]
pub color: Color, pub primary_color: Color,
#[export]
pub alt_color: Color,
base: Base<Resource>, base: Base<Resource>,
} }
#[godot_api] #[godot_api]
impl IResource for TeamResource {} impl IResource for TeamResource {}
impl TeamResource {
pub fn color_from(&self, opts: &PrivateGameOptions) -> Color {
match opts.use_alternate_team_colors {
true => self.alt_color,
false => self.primary_color,
}
}
pub fn color(&self) -> Color {
godot_print!("Fetching color");
if let Some(game) = Game::singleton() {
self.color_from(&game.bind().private_opts)
} else {
self.primary_color
}
}
}

View File

@ -101,7 +101,7 @@ impl GameFinishedScreen {
for (idx, team) in winning_teams.iter().enumerate() { for (idx, team) in winning_teams.iter().enumerate() {
let mut label = Label::new_alloc(); let mut label = Label::new_alloc();
label.set_text(&team.bind().name); label.set_text(&team.bind().name);
label.set_modulate(team.bind().color); label.set_modulate(team.bind().color());
if idx > 0 { if idx > 0 {
let mut and_label = Label::new_alloc(); let mut and_label = Label::new_alloc();
and_label.set_text(" and "); and_label.set_text(" and ");

View File

@ -14,6 +14,7 @@ use crate::{
Game, GameManager, Game, GameManager,
opts::{GameOption, GameOptionValue, GameOptions}, opts::{GameOption, GameOptionValue, GameOptions},
}, },
lobby_world::LobbyWorld,
net::network_manager::{NetworkManager, Package, PeerKind}, net::network_manager::{NetworkManager, Package, PeerKind},
ui::lobby_player_listing::LobbyPlayerListing, ui::lobby_player_listing::LobbyPlayerListing,
}; };
@ -96,6 +97,8 @@ impl IPanel for LobbyPanel {
if let Some(alt_colors) = &s.alt_colors { if let Some(alt_colors) = &s.alt_colors {
s.use_alt_colors_changed(alt_colors.is_pressed()); s.use_alt_colors_changed(alt_colors.is_pressed());
} }
s.update_players(false);
s.signals().on_alt_colors_changed().emit();
}); });
} }
@ -245,6 +248,9 @@ impl IPanel for LobbyPanel {
#[godot_api] #[godot_api]
impl LobbyPanel { impl LobbyPanel {
#[signal]
pub fn on_alt_colors_changed();
#[func] #[func]
fn open_options(&mut self) { fn open_options(&mut self) {
if let Some(panel) = &mut self.options_panel { if let Some(panel) = &mut self.options_panel {

View File

@ -91,7 +91,7 @@ impl LobbyPlayerListing {
)); ));
if let Some(team) = game.bind().get_team(player.data.team) { if let Some(team) = game.bind().get_team(player.data.team) {
player_label.add_theme_color_override("font_color", team.bind().color); player_label.add_theme_color_override("font_color", team.bind().color());
} }
} }
@ -133,7 +133,7 @@ impl LobbyPlayerListing {
&& let Some(player_label) = &mut self.name_label && let Some(player_label) = &mut self.name_label
&& let Some(team) = game.bind().get_team(player.data.team) && let Some(team) = game.bind().get_team(player.data.team)
{ {
player_label.add_theme_color_override("font_color", team.bind().color); player_label.add_theme_color_override("font_color", team.bind().color());
} }
} }
} }
@ -148,7 +148,7 @@ impl LobbyPlayerListing {
&& let Some(player_label) = &mut self.name_label && let Some(player_label) = &mut self.name_label
&& let Some(team) = game.bind().get_team(player.data.team) && let Some(team) = game.bind().get_team(player.data.team)
{ {
player_label.add_theme_color_override("font_color", team.bind().color); player_label.add_theme_color_override("font_color", team.bind().color());
} }
} }
} }

View File

@ -52,7 +52,7 @@ impl PlayerListings {
vbox.set_custom_minimum_size(Vector2::new(300., 0.)); vbox.set_custom_minimum_size(Vector2::new(300., 0.));
let mut team_label = Label::new_alloc(); let mut team_label = Label::new_alloc();
team_label.set_modulate(team.bind().color); team_label.set_modulate(team.bind().color());
team_label.set_text(&team.bind().name); team_label.set_text(&team.bind().name);
team_label.set_horizontal_alignment(HorizontalAlignment::CENTER); team_label.set_horizontal_alignment(HorizontalAlignment::CENTER);
vbox.add_child(&team_label); vbox.add_child(&team_label);

View File

@ -21,7 +21,7 @@ impl IHBoxContainer for SimpleScoreView {
if let Some(game) = Game::singleton() { if let Some(game) = Game::singleton() {
for (id, team) in game.bind().get_teams().iter_shared().enumerate() { for (id, team) in game.bind().get_teams().iter_shared().enumerate() {
let mut goals_label = Label::new_alloc(); let mut goals_label = Label::new_alloc();
goals_label.set_modulate(team.bind().color); goals_label.set_modulate(team.bind().color());
goals_label.set_text("0"); goals_label.set_text("0");
if !s.team_goals.is_empty() { if !s.team_goals.is_empty() {
let mut dash = Label::new_alloc(); let mut dash = Label::new_alloc();