← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/game_end_summary into lp:widelands

 

cghislai has proposed merging lp:~widelands-dev/widelands/game_end_summary into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/game_end_summary/+merge/176000

So I have the game end screen prototypes and I need feedbacl. I am not sure if I must go for an ingame window or a fullscreen menu screen. If you test this branch, you will first see the ingame window, then if you click on Quit you will be warried to the fullscreen window.

To help you test, there is a Test Win win condition that will make the player 1 win after 15s - so make sure someone is occupying the 1st slot.
The layout and table sorting are not finished yet, but please voice your concerns.
-- 
https://code.launchpad.net/~widelands-dev/widelands/game_end_summary/+merge/176000
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/game_end_summary into lp:widelands.
=== modified file 'scripting/win_condition_functions.lua'
--- scripting/win_condition_functions.lua	2012-04-25 07:29:45 +0000
+++ scripting/win_condition_functions.lua	2013-07-20 12:16:25 +0000
@@ -115,3 +115,11 @@
        wl.game.report_result(p, true, 0, make_extra_data(p, wc_name, wc_ver))
    end
 end
+
+function broadcast_lost(plrs, header, msg, goptions, wc_name, wc_ver)
+   local options = goptions or {}
+   for idx, p in ipairs(plrs) do
+       p:send_message(header, msg, options)
+       wl.game.report_result(p, false, 0, make_extra_data(p, wc_name, wc_ver))
+   end
+end

=== added file 'scripting/win_conditions/02_test.lua'
--- scripting/win_conditions/02_test.lua	1970-01-01 00:00:00 +0000
+++ scripting/win_conditions/02_test.lua	2013-07-20 12:16:25 +0000
@@ -0,0 +1,34 @@
+-- =======================================================================
+--                         Defeat all Win condition
+-- =======================================================================
+
+use("aux", "coroutine") -- for sleep
+use("aux", "win_condition_functions")
+
+set_textdomain("win_conditions")
+
+use("aux", "win_condition_texts")
+
+local wc_name = _ "Test Win"
+local wc_version = 2
+local wc_desc = _ "The tribe or team that can defeat all others wins the game!"
+return {
+	name = wc_name,
+	description = wc_desc,
+	func = function()
+		local plrs = wl.Game().players
+
+		broadcast(plrs, wc_name, wc_desc)
+		sleep(15000)
+		wl.game.report_result(plrs[1], true, 0, make_extra_data(plrs[1], wc_name, wc_version))
+		table.remove(plrs, 1)
+
+		broadcast_lost(plrs,
+				wc_name,
+				"Bravo!",
+				{popup = true},
+				wc_name, wc_version
+		)
+
+	end,
+}

=== modified file 'src/gamecontroller.cc'
--- src/gamecontroller.cc	2013-07-18 05:40:10 +0000
+++ src/gamecontroller.cc	2013-07-20 12:16:25 +0000
@@ -43,6 +43,7 @@
 	void setDesiredSpeed(uint32_t speed);
 	bool isPaused();
 	void setPaused(bool paused);
+	void report_result(uint8_t player, int32_t score, bool win, std::string extra);
 
 	// Chat provider implementation
 	void send(const std::string & msg);
@@ -163,6 +164,20 @@
 	m_paused = paused;
 }
 
+void SinglePlayerGameController::report_result(uint8_t p_nr, int32_t score, bool win, std::string extra)
+{
+	Widelands::PlayerEndStatus pes;
+	Widelands::Player* player = m_game.get_player(p_nr);
+	assert(player);
+	pes.player = player->player_number();
+	pes.time = m_game.get_gametime();
+	pes.points = score;
+	pes.win = win;
+	pes.lost = !win;
+	pes.extra = extra;
+	m_game.add_player_end_status(pes);
+}
+
 void SinglePlayerGameController::send_local(const std::string& msg)
 {
 	ChatMessage c;

=== modified file 'src/logic/game.cc'
--- src/logic/game.cc	2013-07-20 09:56:51 +0000
+++ src/logic/game.cc	2013-07-20 12:16:25 +0000
@@ -54,6 +54,7 @@
 #include "wlapplication.h"
 #include "wui/game_tips.h"
 #include "wui/interactive_player.h"
+#include "wui/game_summary.h"
 #include "militarysite.h"
 
 #include <cstring>
@@ -1166,4 +1167,28 @@
 		}
 }
 
+/**
+ * Adds a new 'deceased' player status
+ */
+void Game::add_player_end_status(const PlayerEndStatus status)
+{
+	// Ensure we don't have a status for it yet
+	std::vector<PlayerEndStatus>::iterator it;
+	for (it = m_players_end_status.begin(); it != m_players_end_status.end(); ++it) {
+		PlayerEndStatus pes = *it;
+		if (pes.player == status.player) {
+			log("End status for player %i already registered\n", pes.player);
+			assert(false);
+		}
+	}
+	m_players_end_status.push_back(status);
+
+	// If all results have been gathered, save game ans show summary screen
+	if (m_players_end_status.size() < get_map()->get_nrplayers()) {
+		return;
+	}
+
+	get_ipl()->show_game_summary();
+}
+
 }

=== modified file 'src/logic/game.h'
--- src/logic/game.h	2013-07-20 09:56:51 +0000
+++ src/logic/game.h	2013-07-20 12:16:25 +0000
@@ -25,6 +25,7 @@
 #include "md5.h"
 #include "random.h"
 #include "save_handler.h"
+#include <boost/signal.hpp>
 
 namespace UI {struct ProgressWindow;}
 struct Computer_Player;
@@ -40,6 +41,7 @@
 struct Path;
 struct PlayerImmovable;
 struct Ship;
+struct PlayerEndStatus;
 class TrainingSite;
 class MilitarySite;
 
@@ -189,6 +191,9 @@
 	// Returns the number of players (human or ai) occupying a slot.
 	uint8_t get_number_of_players() {return m_number_of_players;}
 
+	const std::vector<PlayerEndStatus> & get_players_end_status() {return m_players_end_status;}
+	void add_player_end_status(PlayerEndStatus status);
+
 private:
 	void SyncReset();
 
@@ -254,6 +259,8 @@
 	/// For save games and statistics generation
 	std::string          m_win_condition_displayname;
 	uint8_t              m_number_of_players;
+
+	std::vector<PlayerEndStatus> m_players_end_status;
 };
 
 inline Coords Game::random_location(Coords location, uint8_t radius) {

=== modified file 'src/logic/player.h'
--- src/logic/player.h	2013-07-08 03:35:09 +0000
+++ src/logic/player.h	2013-07-20 12:16:25 +0000
@@ -45,6 +45,18 @@
 struct AttackController;
 
 /**
+ * Hold data once a player left the game, or on game ends.
+ */
+struct PlayerEndStatus {
+	Player_Number player;
+	bool win;
+	bool lost;
+	uint32_t time;
+	uint32_t points;
+	std::string extra;
+};
+
+/**
  * Manage in-game aspects of players, such as tribe, team, fog-of-war, statistics,
  * messages (notification when a resource has been found etc.) and so on.
  *

=== added file 'src/ui_fsmenu/game_end_summary.cc'
--- src/ui_fsmenu/game_end_summary.cc	1970-01-01 00:00:00 +0000
+++ src/ui_fsmenu/game_end_summary.cc	2013-07-20 12:16:25 +0000
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2002-2012 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include "game_end_summary.h"
+
+#include "ui_basic/unique_window.h"
+#include "ui_basic/textarea.h"
+#include "ui_basic/table.h"
+#include "ui_basic/button.h"
+
+#include "graphic/graphic.h"
+#include "logic/game.h"
+#include "logic/player.h"
+#include "wui/interactive_gamebase.h"
+#include "wui/interactive_player.h"
+#include "wlapplication.h"
+#include "i18n.h"
+#include "timestring.h"
+
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <boost/signal.hpp>
+
+
+namespace Columns {enum {Name, Status, Team, Time, Score};}
+
+Fullscreen_Menu_GameSummary::Fullscreen_Menu_GameSummary(Widelands::Game* game)
+	:Fullscreen_Menu_Base("choosemapmenu.jpg"),
+	// Values for alignment and size
+	m_fn   (ui_fn()),
+	m_fs   (fs_small()),
+	m_butwidth(get_w() * 25 / 100),
+	m_butheight(get_h() * 9 / 200)
+{
+	m_game = game;
+	// Elements
+	m_title_area = new UI::Textarea
+		(this,
+		 get_w() / 2, get_h() * 9 / 50,
+		 "", UI::Align_HCenter);
+	m_gametime_label = new UI::Textarea
+		(this, get_w() * 71 / 100,  get_h() * 17 / 50,
+		_("Game time :"));
+	m_gametime_value = new UI::Textarea(this, get_w() * 81 / 100, get_h() * 17 / 50);
+	m_stop_button = new UI::Button
+		(this, "back",
+		 get_w() * 71 / 100, get_h() * 85 / 100, m_butwidth, m_butheight,
+		 g_gr->images().get("pics/but0.png"),
+		 _("Back"), "", true, false);
+	m_continue_button = new UI::Button
+		(this, "back",
+		 get_w() * 71 / 100, get_h() * 91 / 100, m_butwidth, m_butheight,
+		 g_gr->images().get("pics/but0.png"),
+		 _("Continue"), "", true, false);
+	m_players_table = new UI::Table<const uintptr_t>
+		(this,
+		get_w() *  47 / 2500, get_h() * 3417 / 10000,
+		get_w() * 711 / 1250, get_h() * 6083 / 10000);
+	// Prepare table
+	uint32_t table_width = m_players_table->get_w();
+	m_players_table->add_column(table_width * 6 / 20, _("Player name"));
+	m_players_table->add_column(table_width * 4 / 20, _("Status"), UI::Align_HCenter);
+	m_players_table->add_column(table_width * 3 / 20, _("Team"), UI::Align_HCenter);
+	m_players_table->add_column(table_width * 4 / 20, _("Time"));
+	m_players_table->add_column(table_width * 3 / 20, _("Score"), UI::Align_Right);
+
+	// Prepare Elements
+	m_title_area->set_textstyle(UI::TextStyle::ui_big());
+
+	// Connections
+	m_stop_button->sigclicked.connect
+		(boost::bind(&Fullscreen_Menu_GameSummary::stop_clicked, this));
+	m_continue_button->sigclicked.connect
+		(boost::bind(&Fullscreen_Menu_GameSummary::continue_clicked, this));
+	m_players_table->selected.connect
+		(boost::bind(&Fullscreen_Menu_GameSummary::player_selection, this, _1));
+
+	m_continue_button->update();
+	fill_data();
+}
+
+void Fullscreen_Menu_GameSummary::fill_data()
+{
+	std::vector<Widelands::PlayerEndStatus> players_status
+		= m_game->get_players_end_status();
+	bool local_in_game = false;
+	bool local_won = false;
+	Widelands::Player* single_won = NULL;
+	Widelands::TeamNumber team_won = 0;
+	Interactive_Player* ipl = m_game->get_ipl();
+
+	BOOST_FOREACH(Widelands::PlayerEndStatus pes, players_status) {
+		if (pes.player == ipl->player_number()) {
+			local_in_game = true;
+			local_won = pes.win;
+		}
+		Widelands::Player* p = m_game->get_player(pes.player);
+		UI::Table<uintptr_t>::Entry_Record & te
+			= m_players_table->add(pes.player);
+		te.set_picture(0, NULL, p->get_name());
+		char buf[64];
+		sprintf(buf, "%i", p->team_number());
+		te.set_string(1, buf);
+		std::string stat_str = _("Resigned");
+		if (pes.lost) {
+			stat_str = _("Lost");
+		} else if (pes.win) {
+			stat_str = _("Won");
+			if (!single_won) {
+				single_won = p;
+			} else {
+				team_won = p->team_number();
+			}
+		}
+		te.set_string(2, stat_str);
+		te.set_string(3, gametimestring(pes.time));
+		sprintf(buf, "%i", pes.points);
+		te.set_string(4, buf);
+	}
+
+	if (local_in_game) {
+		if (local_won) {
+			m_title_area->set_text(_("You won!"));
+		} else {
+			m_title_area->set_text(_("You lost.."));
+		}
+	} else {
+		if (team_won <= 0) {
+			m_title_area->set_text
+				((boost::format("%s won!") % single_won->get_name()).str());
+		} else {
+			m_title_area->set_text
+				((boost::format("Team %i won!") % team_won).str());
+		}
+	}
+	m_players_table->update();
+	m_gametime_value->set_text(gametimestring(m_game->get_gametime()));
+}
+
+void Fullscreen_Menu_GameSummary::player_selection(uint8_t idx)
+{
+
+}
+
+void Fullscreen_Menu_GameSummary::continue_clicked()
+{
+	end_modal(1);
+}
+
+void Fullscreen_Menu_GameSummary::stop_clicked()
+{
+	end_modal(0);
+}
+

=== added file 'src/ui_fsmenu/game_end_summary.h'
--- src/ui_fsmenu/game_end_summary.h	1970-01-01 00:00:00 +0000
+++ src/ui_fsmenu/game_end_summary.h	2013-07-20 12:16:25 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2002-2004, 2006-2008, 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef FULLSCREEN_MENU_GAME_SUMMARY_H
+#define FULLSCREEN_MENU_GAME_SUMMARY_H
+
+#include "base.h"
+
+#include "ui_basic/button.h"
+#include "ui_basic/multilinetextarea.h"
+#include "ui_basic/textarea.h"
+#include "ui_basic/table.h"
+
+namespace Widelands
+{
+	class Game;
+}
+/**
+ * Game summary after a game endif
+ */
+struct Fullscreen_Menu_GameSummary : public Fullscreen_Menu_Base {
+	Fullscreen_Menu_GameSummary(Widelands::Game* game);
+
+private:
+	void fill_data();
+	void player_selection(uint8_t idx);
+	void continue_clicked();
+	void stop_clicked();
+
+	Widelands::Game* m_game;
+	uint32_t    m_fs;
+	std::string m_fn;
+	uint8_t m_butwidth;
+	uint8_t m_butheight;
+	UI::Textarea *  m_title_area;
+	UI::Textarea *  m_gametime_label;
+	UI::Textarea *  m_gametime_value;
+	UI::Button *    m_stop_button;
+	UI::Button *    m_continue_button;
+	UI::Table<uintptr_t const> *     m_players_table;
+};
+
+#endif
+

=== modified file 'src/ui_fsmenu/main.h'
--- src/ui_fsmenu/main.h	2012-02-15 21:25:34 +0000
+++ src/ui_fsmenu/main.h	2013-07-20 12:16:25 +0000
@@ -32,6 +32,7 @@
 struct Fullscreen_Menu_Main : public Fullscreen_Menu_Base {
 	Fullscreen_Menu_Main();
 	enum {
+		mm_summary,
 		mm_playtutorial,
 		mm_singleplayer,
 		mm_multiplayer,

=== added file 'src/wui/game_summary.cc'
--- src/wui/game_summary.cc	1970-01-01 00:00:00 +0000
+++ src/wui/game_summary.cc	2013-07-20 12:16:25 +0000
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2007-2008 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include "game_summary.h"
+
+#include "interactive_gamebase.h"
+#include "interactive_player.h"
+#include "ui_basic/unique_window.h"
+#include "ui_basic/box.h"
+#include "ui_basic/textarea.h"
+#include "ui_basic/table.h"
+#include "ui_basic/button.h"
+#include "ui_fsmenu/game_end_summary.h"
+#include "graphic/graphic.h"
+#include "logic/game.h"
+#include "logic/player.h"
+#include "wlapplication.h"
+#include "timestring.h"
+
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+
+#define PADDING 4
+
+GameSummaryScreen::GameSummaryScreen
+	(Interactive_GameBase * parent, UI::UniqueWindow::Registry * r)
+: UI::UniqueWindow(parent, "game_summary", r, 500, 400, _("Game over")),
+m_game(parent->game())
+{
+	// Init boxes
+	UI::Box * vbox = new UI::Box(this, 0, 0, UI::Box::Vertical);
+	m_title_area = new UI::Textarea(vbox, "", UI::Align_HCenter);
+	vbox->add(m_title_area, UI::Box::AlignCenter);
+	vbox->add_space(PADDING);
+
+	UI::Box * hbox1 = new UI::Box(this, 0, 0, UI::Box::Horizontal);
+	m_players_table = new UI::Table<const uintptr_t>(hbox1, 0, 0, 300, 200);
+	hbox1->add(m_players_table, UI::Box::AlignTop);
+	hbox1->add_space(PADDING);
+
+	UI::Box * infoBox = new UI::Box(hbox1, 0, 0, UI::Box::Vertical);
+	m_gametime_label = new UI::Textarea(infoBox, _("Gametime :"));
+	infoBox->add(m_gametime_label, UI::Box::AlignCenter);
+	m_gametime_value = new UI::Textarea(infoBox);
+	infoBox->add(m_gametime_value, UI::Box::AlignCenter);
+	infoBox->add_space(PADDING);
+	hbox1->add(infoBox, UI::Box::AlignTop);
+	vbox->add(hbox1, UI::Box::AlignLeft);
+	vbox->add_space(PADDING);
+
+	UI::Box * buttonBox = new UI::Box(this, 0, 0, UI::Box::Horizontal);
+	m_continue_button = new UI::Button
+		(buttonBox, "continue_button",
+		0, 0, 100, 32, g_gr->images().get("pics/but0.png"),
+		_("Continue"), _("Continue playing"));
+	buttonBox->add(m_continue_button, UI::Box::AlignRight);
+	buttonBox->add_space(PADDING);
+	m_stop_button = new UI::Button
+		(buttonBox, "stop_button",
+		0, 0, 100, 32, g_gr->images().get("pics/but0.png"),
+		_("Quit"), _("Return to main menu"));
+	buttonBox->add(m_stop_button, UI::Box::AlignRight);
+	vbox->add(buttonBox, UI::Box::AlignBottom);
+	set_center_panel(vbox);
+
+	// Prepare table
+	m_players_table->add_column(150, _("Player"));
+	m_players_table->add_column(50, _("Team"), UI::Align_HCenter);
+	m_players_table->add_column(100, _("Status"), UI::Align_HCenter);
+	m_players_table->add_column(100, _("Time"));
+	m_players_table->add_column(100, _("Score"), UI::Align_Right);
+
+	// Prepare Elements
+	m_title_area->set_textstyle(UI::TextStyle::ui_big());
+
+	// Connections
+	m_continue_button->sigclicked.connect
+		(boost::bind(&GameSummaryScreen::continue_clicked, this));
+	m_stop_button->sigclicked.connect
+		(boost::bind(&GameSummaryScreen::stop_clicked, this));
+	m_players_table->selected.connect
+		(boost::bind(&GameSummaryScreen::player_selection, this, _1));
+
+	// Window
+	center_to_parent();
+	set_can_focus(true);
+	focus();
+	fill_data();
+}
+
+bool GameSummaryScreen::handle_mousepress(Uint8 btn, int32_t mx, int32_t my)
+{
+	// Prevent closing with right click
+	if (btn == SDL_BUTTON_RIGHT)
+		return true;
+
+	return UI::Window::handle_mousepress(btn, mx, my);
+}
+
+void GameSummaryScreen::fill_data()
+{
+	std::vector<Widelands::PlayerEndStatus> players_status
+		= m_game.get_players_end_status();
+	bool local_in_game = false;
+	bool local_won = false;
+	Widelands::Player* single_won = NULL;
+	Widelands::TeamNumber team_won = 0;
+	Interactive_Player* ipl = m_game.get_ipl();
+
+	BOOST_FOREACH(Widelands::PlayerEndStatus pes, players_status) {
+		if (pes.player == ipl->player_number()) {
+			local_in_game = true;
+			local_won = pes.win;
+		}
+		Widelands::Player* p = m_game.get_player(pes.player);
+		UI::Table<uintptr_t>::Entry_Record & te
+			= m_players_table->add(pes.player);
+		// Player name & pic
+		char buf[256];
+		sprintf(buf, "pics/genstats_enable_plr_0%u.png", pes.player);
+		const Image* pic = g_gr->images().get(buf);
+		te.set_picture(0, pic, p->get_name());
+		// Team
+		sprintf(buf, "%i", p->team_number());
+		te.set_string(1, buf);
+		// Status
+		std::string stat_str = _("Resigned");
+		if (pes.lost) {
+			stat_str = _("Lost");
+		} else if (pes.win) {
+			stat_str = _("Won");
+			if (!single_won) {
+				single_won = p;
+			} else {
+				team_won = p->team_number();
+			}
+		}
+		te.set_string(2, stat_str);
+		// Time
+		te.set_string(3, gametimestring(pes.time));
+		// Points
+		sprintf(buf, "%i", pes.points);
+		te.set_string(4, buf);
+	}
+
+	if (local_in_game) {
+		if (local_won) {
+			m_title_area->set_text(_("You won!"));
+		} else {
+			m_title_area->set_text(_("You lost.."));
+		}
+	} else {
+		if (team_won <= 0) {
+			m_title_area->set_text
+				((boost::format("%s won!") % single_won->get_name()).str());
+		} else {
+			m_title_area->set_text
+				((boost::format("Team %i won!") % team_won).str());
+		}
+	}
+	m_players_table->update();
+	m_gametime_value->set_text(gametimestring(m_game.get_gametime()));
+}
+
+void GameSummaryScreen::player_selection(uint8_t idx)
+{
+
+}
+
+void GameSummaryScreen::continue_clicked()
+{
+	die();
+}
+
+void GameSummaryScreen::stop_clicked()
+{
+	Fullscreen_Menu_GameSummary fsm(&m_game);
+	uint32_t code = fsm.run();
+	if (code) {
+		continue_clicked();
+	} else {
+		m_game.get_ipl()->end_modal(0);
+	}
+}
+

=== added file 'src/wui/game_summary.h'
--- src/wui/game_summary.h	1970-01-01 00:00:00 +0000
+++ src/wui/game_summary.h	2013-07-20 12:16:25 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2008 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef GAME_SUMMARY_H
+#define GAME_SUMMARY_H
+
+#include "ui_basic/unique_window.h"
+#include "ui_basic/box.h"
+#include "ui_basic/textarea.h"
+#include "ui_basic/table.h"
+#include "ui_basic/button.h"
+
+#include <boost/signal.hpp>
+
+class Interactive_GameBase;
+namespace Widelands
+{
+struct Game;
+}
+
+/// Shows an ingame summary window on game end
+struct GameSummaryScreen : UI::UniqueWindow {
+	GameSummaryScreen
+		(Interactive_GameBase * parent, UI::UniqueWindow::Registry * r);
+
+	bool handle_mousepress(Uint8 btn, int32_t mx, int32_t my);
+private:
+	void fill_data();
+	void player_selection(uint8_t idx);
+	void stop_clicked();
+	void continue_clicked();
+
+	Widelands::Game & m_game;
+	UI::Textarea *  m_title_area;
+	UI::Textarea *  m_gametime_label;
+	UI::Textarea *  m_gametime_value;
+	UI::Button *    m_continue_button;
+	UI::Button *    m_stop_button;
+	UI::Table<uintptr_t const> *     m_players_table;
+};
+
+#endif

=== modified file 'src/wui/interactive_gamebase.cc'
--- src/wui/interactive_gamebase.cc	2012-12-17 20:01:04 +0000
+++ src/wui/interactive_gamebase.cc	2013-07-20 12:16:25 +0000
@@ -19,6 +19,7 @@
 
 #include "interactive_gamebase.h"
 
+#include "game_summary.h"
 #include "chatoverlay.h"
 #include "profile/profile.h"
 #include "upcast.h"
@@ -97,3 +98,13 @@
 
 	return false;
 }
+
+void Interactive_GameBase::show_game_summary()
+{
+	if (m_game_summary.window) {
+		m_game_summary.window->think();
+		return;
+	}
+	GameSummaryScreen* gsc = new GameSummaryScreen(this, &m_game_summary);
+}
+

=== modified file 'src/wui/interactive_gamebase.h'
--- src/wui/interactive_gamebase.h	2013-02-10 19:36:24 +0000
+++ src/wui/interactive_gamebase.h	2013-07-20 12:16:25 +0000
@@ -79,6 +79,8 @@
 
 	bool try_show_ship_window();
 
+	void show_game_summary();
+
 protected:
 	Game_Main_Menu_Windows m_mainm_windows;
 	ChatProvider           * m_chatProvider;
@@ -90,6 +92,7 @@
 
 	PlayerType m_playertype;
 	UI::UniqueWindow::Registry m_fieldaction;
+	UI::UniqueWindow::Registry m_game_summary;
 };
 
 #endif


Follow ups