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>, #[export] back_button: Option>, #[export] player_listings: Option>, #[export] save_file_dialog: Option>, base: Base, } #[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::>(); let winning_teams = game .bind() .get_teams() .iter_shared() .enumerate() .filter(|(id, _)| winning_team_ids.contains(&((*id) as u8))) .map(|(_, team)| team) .collect::>(); 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); } } }