skullball/rust/src/ui/game_finished_screen.rs

113 lines
3.3 KiB
Rust

use godot::{
classes::{Button, FileDialog, HBoxContainer, IPanel, Label, Panel},
prelude::*,
};
use crate::{
game::{Game, GameManager},
ui::player_listings::PlayerListings,
};
#[derive(GodotClass)]
#[class(base=Panel, init)]
pub struct GameFinishedScreen {
#[export]
title_container: Option<Gd<HBoxContainer>>,
#[export]
back_button: Option<Gd<Button>>,
#[export]
player_listings: Option<Gd<PlayerListings>>,
#[export]
save_file_dialog: Option<Gd<FileDialog>>,
base: Base<Panel>,
}
#[godot_api]
impl IPanel for GameFinishedScreen {
fn ready(&mut self) {
self.produce_title();
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() {
game.bind_mut().reset_game();
}
GameManager::singleton().bind().go_to_lobby();
});
}
if let Some(file_dialog) = self.save_file_dialog.clone() {
file_dialog
.signals()
.file_selected()
.connect_other(self, Self::save_replay);
}
}
}
#[godot_api]
impl GameFinishedScreen {
#[func]
pub fn open_file_dialog(&mut self) {
if let Some(file_dialog) = &mut self.save_file_dialog {
file_dialog.popup_file_dialog();
}
}
fn produce_title(&mut self) {
if let Some(game) = Game::singleton() {
let max_goals = game
.bind()
.goals
.iter()
.map(|(_, v)| v)
.max()
.copied()
.unwrap_or(0);
let winning_team_ids = game
.bind()
.goals
.iter()
.filter(|(_, goals)| **goals == max_goals)
.map(|(team, _)| *team)
.collect::<Vec<_>>();
let winning_teams = game
.bind()
.get_teams()
.iter_shared()
.enumerate()
.filter(|(id, _)| winning_team_ids.contains(&((*id) as u8)))
.map(|(_, team)| team)
.collect::<Vec<_>>();
if let Some(container) = &mut self.title_container {
for (idx, team) in winning_teams.iter().enumerate() {
let mut label = Label::new_alloc();
label.set_text(&team.bind().name);
label.set_modulate(team.bind().color);
if idx > 0 {
let mut and_label = Label::new_alloc();
and_label.set_text(" and ");
container.add_child(&and_label);
}
container.add_child(&label);
}
let mut end = Label::new_alloc();
end.set_text(" victory!");
container.add_child(&end);
}
}
}
pub fn save_replay(&mut self, path: GString) {
if let Some(game) = &Game::singleton()
&& let Some(recorder) = &game.bind().replay_recorder
{
recorder.bind().save_to(&path);
}
}
}