initial commit, lordsawar source, slightly modified
[lordsawar] / src / gui / driver.cpp
1 //  Copyright (C) 2007, 2008, Ole Laursen
2 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 //
4 //  This program is free software; you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation; either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU Library General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
17 //  02110-1301, USA.
18
19 #include <assert.h>
20 #include <sigc++/functors/mem_fun.h>
21 #include <sigc++/bind.h>
22 #include <errno.h>
23 #include <string.h>
24
25 #include "driver.h"
26
27 #include <iostream>
28 #include "error-utils.h"
29 #include "main.h"
30 #include "splash-window.h"
31 #include "game-window.h"
32 #include "game-lobby-dialog.h"
33 #include "defs.h"
34 #include "GraphicsCache.h"
35 #include "GameScenario.h"
36 #include "CreateScenario.h"
37 #include "counter.h"
38 #include "shieldsetlist.h"
39 #include "File.h"
40 #include "armysetlist.h"
41 #include "playerlist.h"
42 #include "player.h"
43 #include "citylist.h"
44 #include "xmlhelper.h"
45 #include "Configuration.h"
46 #include "ucompose.hpp"
47 #include "sound.h"
48 #include "timed-message-dialog.h"
49 #include "game-preferences-dialog.h"
50
51 #include "game-client.h"
52 #include "pbm-game-client.h"
53 #include "game-server.h"
54 #include "pbm-game-server.h"
55 #include "NextTurnHotseat.h"
56 #include "NextTurnPbm.h"
57 #include "NextTurnNetworked.h"
58 #include "pbm/pbm.h"
59 #include "recently-played-game-list.h"
60 #include "Backpack.h"
61 #include "Item.h"
62 #include "city.h"
63 #include "FogMap.h"
64 #include "history.h"
65 #include "game.h"
66 #include "stacklist.h"
67 #include "smallmap.h"
68 #include "new-random-map-dialog.h"
69
70 Driver::Driver(std::string load_filename)
71 {
72     game_window = NULL;
73     game_lobby_dialog = NULL;
74     splash_window = NULL;
75     download_window = NULL;
76   game_scenario_downloaded = "";
77     splash_window = new SplashWindow;
78     splash_window->new_game_requested.connect(
79         sigc::mem_fun(*this, &Driver::on_new_game_requested));
80     splash_window->new_hosted_network_game_requested.connect(
81         sigc::mem_fun(*this, &Driver::on_new_hosted_network_game_requested));
82     splash_window->new_remote_network_game_requested.connect(
83         sigc::mem_fun(*this, &Driver::on_new_remote_network_game_requested));
84     splash_window->new_pbm_game_requested.connect(
85         sigc::mem_fun(*this, &Driver::on_new_pbm_game_requested));
86     splash_window->load_requested.connect(
87         sigc::mem_fun(*this, &Driver::on_load_requested));
88     splash_window->quit_requested.connect(
89         sigc::mem_fun(*this, &Driver::on_quit_requested));
90
91     d_load_filename = load_filename;
92
93     //here are the command-line options that don't bring up the splash screen:
94     if (Main::instance().start_stress_test) 
95       {
96         Sound::deleteInstance();
97         stress_test();
98         exit(0);
99       }
100     if (Main::instance().start_robots != 0) 
101       {
102         run();
103         return;
104       }
105     splash_window->show();
106     //here are the ones that do
107     run();
108 }
109
110 void Driver::run()
111 {
112   if (Main::instance().start_test_scenario) 
113     {
114       // quick load a test scenario
115       GameParameters g;
116       GameParameters::Player p;
117       p.type = GameParameters::Player::HUMAN;
118       p.id = 0;
119       p.name = "Mr. Test";
120       g.players.push_back(p);
121       p.type = GameParameters::Player::EASY;
122       p.id = 1;
123       p.name = "Evil";
124       g.players.push_back(p);
125       for (unsigned int i = 2; i < MAX_PLAYERS; i++)
126         {
127           p.type = GameParameters::Player::OFF;
128           p.id = i;
129           p.name = "";
130           g.players.push_back(p);
131         }
132       g.map.width = 125;
133       g.map.height = 125;
134       g.map.grass = 78;
135       g.map.water = 7;
136       g.map.swamp = 2;
137       g.map.forest = 3;
138       g.map.hills = 5;
139       g.map.mountains = 5;
140       g.map.cities = 20;
141       g.map.ruins = 25;
142       g.map_path = "";
143       g.play_with_quests = GameParameters::NO_QUESTING;
144       g.hidden_map = false;
145       g.neutral_cities = GameParameters::STRONG;
146       g.razing_cities = GameParameters::ALWAYS;
147       g.diplomacy = false;
148       g.random_turns = false;
149       g.quick_start = GameParameters::NO_QUICK_START;
150       g.intense_combat = false;
151       g.military_advisor = false;
152       g.army_theme = "default";
153       g.tile_theme = "default";
154       g.shield_theme = "default";
155       g.city_theme = "default";
156       g.process_armies = GameParameters::PROCESS_ARMIES_AT_PLAYERS_TURN;
157       g.difficulty = GameScenario::calculate_difficulty_rating(g);
158       g.cities_can_produce_allies = false;
159       g.cusp_of_war = false;
160       g.see_opponents_stacks = true;
161       g.see_opponents_production = true;
162       on_new_game_requested(g);
163     }
164   else if (Main::instance().turn_filename != "") 
165     {
166       PbmGameClient *pbm_game_client = PbmGameClient::getInstance();
167       GameScenario *game_scenario = load_game(d_load_filename);
168       if (game_scenario == NULL)
169         return;
170       //now apply the actions in the turn file
171       bool broken;
172
173       //if the active player isn't a network player than don't do anything
174       if (Playerlist::getActiveplayer()->getType() != Player::NETWORKED)
175         return;
176       //load the file, and decode them as we go.
177       XML_Helper helper(Main::instance().turn_filename, std::ios::in, 
178                         Configuration::s_zipfiles);
179       NextTurnPbm *nextTurn;
180       nextTurn = new NextTurnPbm(game_scenario->getTurnmode(),
181                               game_scenario->s_random_turns);
182       broken = pbm_game_client->loadWithHelper (helper, 
183                                                 Playerlist::getActiveplayer());
184       helper.close();
185       if (!broken)
186         {
187           game_scenario->saveGame(d_load_filename);
188           if (Playerlist::getActiveplayer()->getType() != Player::NETWORKED)
189             {
190               if (splash_window)
191                 splash_window->hide();
192
193               init_game_window();
194               game_window->show();
195               game_window->load_game(game_scenario, nextTurn);
196             }
197         }
198     }
199   else if (Main::instance().start_robots != 0) 
200     {
201       Sound::deleteInstance();
202       lordsawaromatic("127.0.0.1", LORDSAWAR_PORT, Player::AI_FAST,
203                       Main::instance().start_robots);
204     }
205   else
206     {
207       splash_window->show();
208       if (d_load_filename.empty() == false)
209         {
210           GameParameters g;
211           g.map_path = d_load_filename;
212           size_t found = d_load_filename.find(".map");
213           if (found != std::string::npos)
214             {
215               GamePreferencesDialog d(d_load_filename, GameScenario::HOTSEAT);
216               d.set_parent_window(*splash_window->get_window());
217               d.game_started.connect(sigc::mem_fun
218                                      (*this, &Driver::on_new_game_requested));
219               d.run();
220             }
221           else
222             {
223               found = d_load_filename.find(".sav");
224               if (found != std::string::npos)
225                 on_load_requested(d_load_filename);
226               else
227                 on_new_game_requested(g);
228             }
229         }
230     }
231   return;
232 }
233
234 Driver::~Driver()
235 {
236   if (game_window)
237     delete game_window;
238   if (game_lobby_dialog)
239     delete game_lobby_dialog;
240   if (splash_window)
241     delete splash_window;
242   if (download_window)
243     delete download_window;
244 }
245
246 void Driver::on_hosted_player_sat_down(Player *player)
247 {
248   guint32 id = player->getId();
249   GameServer *game_server = GameServer::getInstance();
250   game_server->sit_down(player);
251   player_replaced.emit(Playerlist::getInstance()->getPlayer(id));
252 }
253
254 void Driver::on_hosted_player_stood_up(Player *player)
255 {
256   guint32 id = player->getId();
257   GameServer *game_server = GameServer::getInstance();
258   game_server->stand_up(player);
259   player_replaced.emit(Playerlist::getInstance()->getPlayer(id));
260 }
261
262 void Driver::on_hosted_player_chat(std::string message)
263 {
264   GameServer *game_server = GameServer::getInstance();
265   game_server->chat(message);
266 }
267
268 void Driver::on_client_player_sat_down(Player *player)
269 {
270   GameClient *game_client = GameClient::getInstance();
271   game_client->sit_down(player);
272 }
273
274 void Driver::on_client_player_stood_up(Player *player)
275 {
276   GameClient *game_client = GameClient::getInstance();
277   game_client->stand_up(player);
278 }
279
280 void Driver::on_client_player_chat(std::string message)
281 {
282   GameClient *game_client = GameClient::getInstance();
283   game_client->chat(message);
284 }
285
286 GameScenario *Driver::create_new_scenario(GameParameters &g, GameScenario::PlayMode m)
287 {
288   bool update_uuid = false;
289   if (g.map_path.empty()) 
290     {
291       // construct new random scenario if we're not going to load the game
292       std::string path = 
293         NewRandomMapDialog::create_and_dump_scenario("random.map", g, NULL);
294       g.map_path = path;
295     }
296   else
297     update_uuid = true;
298
299   bool broken = false;
300                                                  
301   GameScenario* game_scenario = new GameScenario(g.map_path, broken);
302
303   GameScenarioOptions::s_see_opponents_stacks = g.see_opponents_stacks;
304   GameScenarioOptions::s_see_opponents_production = g.see_opponents_production;
305   GameScenarioOptions::s_play_with_quests = g.play_with_quests;
306   GameScenarioOptions::s_hidden_map = g.hidden_map;
307   GameScenarioOptions::s_diplomacy = g.diplomacy;
308   GameScenarioOptions::s_cusp_of_war = g.cusp_of_war;
309   GameScenarioOptions::s_neutral_cities = g.neutral_cities;
310   GameScenarioOptions::s_razing_cities = g.razing_cities;
311   GameScenarioOptions::s_intense_combat = g.intense_combat;
312   GameScenarioOptions::s_military_advisor = g.military_advisor;
313   GameScenarioOptions::s_random_turns = g.random_turns;
314
315   if (broken)
316     return NULL;
317
318   game_scenario->setName(g.name);
319   game_scenario->setPlayMode(m);
320
321   if (game_scenario->getRound() == 0)
322     {
323       if (update_uuid)
324         game_scenario->setNewRandomId();
325
326       Playerlist::getInstance()->syncPlayers(g.players);
327
328       game_scenario->initialize(g);
329     }
330   return game_scenario;
331 }
332
333 void Driver::on_new_hosted_network_game_requested(GameParameters g, int port,
334                                                   std::string nick)
335 {
336     if (splash_window)
337         splash_window->hide();
338
339     GameScenario *game_scenario = 
340       create_new_scenario(g, GameScenario::NETWORKED);
341
342     if (game_scenario == NULL)
343       {
344         TimedMessageDialog dialog(*splash_window->get_window(),
345                                   _("Corrupted saved game file."), 0);
346         dialog.run();
347         dialog.hide();
348         return;
349       }
350
351   GameServer *game_server = GameServer::getInstance();
352   game_server->start(game_scenario, port, nick);
353   NextTurnNetworked *next_turn = new NextTurnNetworked(game_scenario->getTurnmode(), game_scenario->s_random_turns);
354   if (game_scenario->s_random_turns == true)
355     next_turn->snextRound.connect (sigc::mem_fun(GameServer::getInstance(), 
356                                                  &GameServer::sendTurnOrder));
357   next_turn->snextPlayerUnavailable.connect(sigc::mem_fun(this, &Driver::on_player_unavailable));
358   if (game_lobby_dialog)
359     delete game_lobby_dialog;
360   game_lobby_dialog = new GameLobbyDialog(game_scenario, next_turn, 
361                                               game_server, true);
362   game_server->round_begins.connect(sigc::mem_fun(next_turn, &NextTurnNetworked::start));
363   Playerlist::getInstance()->splayerDead.connect
364     (sigc::mem_fun(GameServer::getInstance(), &GameServer::sendKillPlayer));
365   game_lobby_dialog->set_parent_window(*splash_window->get_window());
366   game_lobby_dialog->player_sat_down.connect
367     (sigc::mem_fun(this, &Driver::on_hosted_player_sat_down));
368   game_lobby_dialog->player_stood_up.connect
369     (sigc::mem_fun(this, &Driver::on_hosted_player_stood_up));
370   game_lobby_dialog->message_sent.connect
371     (sigc::mem_fun(this, &Driver::on_hosted_player_chat));
372   game_lobby_dialog->start_network_game.connect
373     (sigc::mem_fun(this, &Driver::start_network_game_requested));
374   game_lobby_dialog->show();
375   bool response = game_lobby_dialog->run();
376   game_lobby_dialog->hide();
377     
378   if (response == false)
379     {
380       GameServer::deleteInstance();
381       delete game_scenario;
382       if (splash_window)
383         splash_window->show();
384     }
385 }
386
387   
388 void Driver::on_server_went_away()
389 {
390   heartbeat_conn.disconnect();
391   if (game_lobby_dialog)
392     game_lobby_dialog->hide();
393   if (download_window)
394     download_window->hide();
395   if (splash_window)
396     splash_window->show();
397   GameClient::deleteInstance();
398   TimedMessageDialog dialog(*splash_window->get_window(), 
399                             _("Server went away."), 0);
400   dialog.run();
401   dialog.hide();
402 }
403
404 void Driver::on_client_could_not_connect()
405 {
406   heartbeat_conn.disconnect();
407   if (game_lobby_dialog)
408     game_lobby_dialog->hide();
409   if (download_window)
410     download_window->hide();
411   if (splash_window)
412     splash_window->show();
413   GameClient::deleteInstance();
414   TimedMessageDialog dialog(*splash_window->get_window(), 
415                             _("Could not connect."), 0);
416   dialog.run();
417   dialog.hide();
418 }
419
420 void Driver::on_new_remote_network_game_requested(std::string host, unsigned short port, std::string nick)
421 {
422   if (splash_window)
423     splash_window->hide();
424   GameClient *game_client = GameClient::getInstance();
425   game_client->game_scenario_received.connect
426     (sigc::mem_fun(this, &Driver::on_game_scenario_downloaded));
427   game_client->client_disconnected.connect
428     (sigc::mem_fun(this, &Driver::on_server_went_away));
429   game_client->client_could_not_connect.connect
430     (sigc::mem_fun(this, &Driver::on_client_could_not_connect));
431   game_scenario_received.connect
432     (sigc::mem_fun(this, &Driver::on_game_scenario_received));
433   if (download_window)
434     delete download_window;
435   download_window = new NewNetworkGameDownloadWindow();
436   download_window->pulse();
437   game_client->start(host, port, nick);
438   heartbeat_conn = Glib::signal_timeout().connect
439     (bind_return(sigc::mem_fun(*this, &Driver::heartbeat), true), 1 * 1000);
440
441 }
442
443 void Driver::heartbeat()
444 {
445   static bool already_done = false;
446   if (already_done)
447     return;
448   if (game_scenario_downloaded == "")
449     {
450       if (download_window)
451         download_window->pulse();
452       return;
453     }
454   
455   game_scenario_received.emit(game_scenario_downloaded);
456   already_done = true;
457 }
458
459 void Driver::on_game_scenario_received(std::string path)
460 {
461   heartbeat_conn.disconnect();
462   if (download_window)
463     download_window->hide();
464   GameScenario *game_scenario = load_game(path);
465   GameClient *game_client = GameClient::getInstance();
466   std::string host = game_client->getHost();
467   guint32 port = game_client->getPort();
468   RecentlyPlayedGameList::getInstance()->addNetworkedEntry(game_scenario, host, port);
469   RecentlyPlayedGameList::getInstance()->saveToFile(File::getSavePath() + "/recently-played.xml");
470
471   NextTurnNetworked *next_turn = new NextTurnNetworked(game_scenario->getTurnmode(), game_scenario->s_random_turns);
472   next_turn->snextPlayerUnavailable.connect(sigc::mem_fun(this, &Driver::on_player_unavailable));
473   game_client->round_begins.connect(sigc::mem_fun(next_turn, &NextTurnNetworked::start));
474   if (game_lobby_dialog)
475     delete game_lobby_dialog;
476   game_lobby_dialog = new GameLobbyDialog(game_scenario, next_turn, 
477                                               GameClient::getInstance(), false);
478   game_lobby_dialog->set_parent_window(*splash_window->get_window());
479   game_lobby_dialog->player_sat_down.connect
480     (sigc::mem_fun(this, &Driver::on_client_player_sat_down));
481   game_lobby_dialog->player_stood_up.connect
482     (sigc::mem_fun(this, &Driver::on_client_player_stood_up));
483   game_lobby_dialog->message_sent.connect
484     (sigc::mem_fun(this, &Driver::on_client_player_chat));
485   game_lobby_dialog->start_network_game.connect
486     (sigc::mem_fun(this, &Driver::start_network_game_requested));
487   game_lobby_dialog->show();
488   bool response = game_lobby_dialog->run();
489   game_lobby_dialog->hide();
490
491   if (response == false)
492     {
493       if (splash_window)
494         splash_window->show();
495     
496       GameClient::deleteInstance();
497       delete game_scenario;
498     }
499 }
500 void Driver::on_game_scenario_downloaded(std::string path)
501 {
502   game_scenario_downloaded = path;
503   //emitting the signal doesn't work.
504   //it stops the game client from doing more processing.
505   //how can i bring up the game lobby dialog with this scenario?
506   //...without stopping the game client from getting more messages
507 }
508
509 void Driver::on_new_game_requested(GameParameters g)
510 {
511     GameScenario *game_scenario = create_new_scenario(g, GameScenario::HOTSEAT);
512
513     if (game_scenario == NULL)
514       {
515         TimedMessageDialog dialog(*splash_window->get_window(),
516                                   _("Corrupted saved game file."), 0);
517         dialog.run();
518         dialog.hide();
519         splash_window->show();
520         return;
521       }
522
523     std::list<std::string> e, w;
524     if (g.map_path != "" && game_scenario->validate(e, w) == false)
525       {
526         TimedMessageDialog dialog
527           (*splash_window->get_window(), 
528            _("Invalid map file.\n" 
529              "Please validate it in the scenario editor."), 0);
530         std::list<std::string>::iterator it = e.begin();
531         for (; it != e.end(); it++)
532           {
533             printf ("error: %s\n", (*it).c_str());
534           }
535         dialog.run();
536         dialog.hide();
537         splash_window->show();
538         return;
539       }
540
541     if (splash_window)
542         splash_window->hide();
543
544     NextTurn *next_turn = new NextTurnHotseat(game_scenario->getTurnmode(),
545                                               game_scenario->s_random_turns);
546     init_game_window();
547     
548     game_window->show();
549     game_window->new_game(game_scenario, next_turn);
550 }
551
552 void Driver::on_load_requested(std::string filename)
553 {
554     if (splash_window)
555         splash_window->hide();
556
557     GameScenario *game_scenario = load_game(filename);
558     if (game_scenario == NULL)
559       {
560         splash_window->show();
561         return;
562       }
563
564     init_game_window();
565     
566     game_window->show();
567     if (game_scenario->getPlayMode() == GameScenario::HOTSEAT)
568       game_window->load_game
569         (game_scenario, new NextTurnHotseat(game_scenario->getTurnmode(),
570                                             game_scenario->s_random_turns));
571     else if (game_scenario->getPlayMode() == GameScenario::PLAY_BY_MAIL)
572       {
573         PbmGameServer::getInstance()->start();
574         game_window->load_game
575           (game_scenario, new NextTurnPbm(game_scenario->getTurnmode(),
576                                           game_scenario->s_random_turns));
577       }
578     else if (game_scenario->getPlayMode() == GameScenario::NETWORKED)
579       game_window->load_game
580         (game_scenario, new NextTurnNetworked(game_scenario->getTurnmode(),
581                                               game_scenario->s_random_turns));
582 }
583
584 void Driver::on_quit_requested()
585 {
586     if (splash_window)
587         splash_window->hide();
588     
589     if (game_window)
590         game_window->hide();
591
592     Main::instance().stop_main_loop();
593 }
594
595 void Driver::on_game_ended()
596 {
597   if (game_window)
598     {
599       game_window->hide();
600     }
601   GameClient::deleteInstance();
602   PbmGameClient::deleteInstance();
603   GameServer::deleteInstance();
604   PbmGameServer::deleteInstance();
605
606   GraphicsCache::deleteInstance();
607
608   splash_window->show();
609 }
610
611 void Driver::init_game_window()
612 {
613   if (game_window)
614     delete game_window;
615     game_window = new GameWindow;
616
617     game_window->game_ended.connect(
618         sigc::mem_fun(*this, &Driver::on_game_ended));
619     game_window->show_lobby.connect(
620         sigc::mem_fun(*this, &Driver::on_show_lobby_requested));
621     game_window->quit_requested.connect(
622         sigc::mem_fun(*this, &Driver::on_quit_requested));
623
624     //make the width+height suitable for the screen size.
625     Glib::RefPtr<Gdk::Screen> screen = Gdk::Display::get_default()->get_default_screen();
626     guint32 screen_height = screen->get_height();
627     guint32 height = 450;
628     if (screen_height <= 600)
629       height = 400;
630         height = 400;
631     guint32 width = (int)((float)height * 1.42223);
632 //    game_window->init(width, height);
633         game_window->init(800, 480);
634
635 }
636
637 GameScenario *Driver::load_game(std::string file_path)
638 {
639     bool broken = false;
640     GameScenario* game_scenario = new GameScenario(file_path, broken);
641
642     if (broken)
643       {
644         TimedMessageDialog dialog(*splash_window->get_window(),
645                                   _("Corrupted saved game file."), 0);
646         dialog.run();
647         dialog.hide();
648         return NULL;
649       }
650     return game_scenario;
651 }
652
653 void Driver::on_new_pbm_game_requested(GameParameters g)
654 {
655   std::string filename;
656   std::string temp_filename = File::getSavePath() + "pbmtmp.sav";
657       
658   GameScenario *game_scenario = 
659     create_new_scenario(g, GameScenario::PLAY_BY_MAIL);
660   if (game_scenario == NULL)
661     {
662       TimedMessageDialog dialog(*splash_window->get_window(),
663                                 _("Corrupted saved game file."), 0);
664         dialog.run();
665         dialog.hide();
666       return;
667     }
668   game_scenario->saveGame(temp_filename);
669   std::string player_name = Playerlist::getActiveplayer()->getName();
670   delete game_scenario;
671   pbm play_by_mail;
672   play_by_mail.init(temp_filename);
673
674   Gtk::FileChooserDialog chooser(*splash_window->get_window(), _("Save the scenario and mail it to the first player"),
675                                  Gtk::FILE_CHOOSER_ACTION_SAVE);
676   Gtk::FileFilter sav_filter;
677   sav_filter.add_pattern("*.sav");
678   chooser.set_filter(sav_filter);
679   chooser.set_current_folder(Glib::get_home_dir());
680
681   chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
682   chooser.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
683   chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
684
685   chooser.show_all();
686   int res = chooser.run();
687   chooser.hide();
688
689   if (res == Gtk::RESPONSE_ACCEPT)
690     {
691       std::string filename = chooser.get_filename();
692
693       remove (filename.c_str());
694       if (rename(temp_filename.c_str(), filename.c_str()))
695         {
696           char* err = strerror(errno);
697           std::cerr <<_("Error while trying to rename the temporary file to ")
698             << filename << "\n";
699           std::cerr <<_("Error: ") <<err <<std::endl;
700         }
701     }
702   Glib::ustring s = String::ucompose(_("Now send the saved-game file to %1"),
703                                      player_name);
704   TimedMessageDialog dialog(*splash_window->get_window(), s, 0);
705   dialog.run();
706   dialog.hide();
707   return;
708 }
709
710 void Driver::stressTestNextRound()
711 {
712   static time_t prev_round_start = time(NULL);
713   static int count = 1;
714   /*
715   if (count == 1)
716     {
717       FILE * fileptr = fopen("/tmp/crapola.csv", "w");
718       fclose(fileptr);
719     }
720     */
721   count++;
722   time_t now = time(NULL);
723   printf ("starting round %d!\n", count);
724   /*
725   FILE * fileptr = fopen("/tmp/crapola.csv", "a");
726   int total_fights = Playerlist::getInstance()->countFightsThisTurn();
727   int total_moves = Playerlist::getInstance()->countMovesThisTurn();
728   fprintf(fileptr, "%d, %d, %d, %d, %d, %d, %d, %d", count, 
729           now - prev_round_start,
730           Stacklist::getNoOfStacks(), 
731           Stacklist::getNoOfArmies(), 
732           total_fights,
733           total_moves,
734           Citylist::getInstance()->countCities(Playerlist::getInstance()->getNeutral()), 
735           Playerlist::getInstance()->countPlayersAlive());
736   if (Playerlist::getInstance()->countPlayersAlive() == 2)
737     {
738       Playerlist *pl = Playerlist::getInstance();
739       for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
740         {
741           if ((*it)->isDead() == true)
742             continue;
743           if ((*it) == pl->getNeutral())
744             continue;
745           fprintf(fileptr,", %d (%d)", Citylist::getInstance()->countCities(*it), (*it)->getHeroes().size() + (*it)->countAllies());
746         }
747     }
748   fprintf(fileptr,"\n");
749   fclose(fileptr);
750   */
751       
752   prev_round_start = now;
753   sleep (1);
754 }
755
756 void Driver::stress_test()
757 {
758
759   // quick load a test scenario
760   GameParameters g;
761   GameParameters::Player p;
762   for (unsigned int i = 0; i < MAX_PLAYERS; i++)
763     {
764       p.type = GameParameters::Player::HARD;
765       p.id = i;
766       switch (p.id)
767         {
768         case 0: p.name = "one"; break;
769         case 1: p.name = "two"; break;
770         case 2: p.name = "three"; break;
771         case 3: p.name = "four"; break;
772         case 4: p.name = "five"; break;
773         case 5: p.name = "six"; break;
774         case 6: p.name = "seven"; break;
775         case 7: p.name = "eight"; break;
776         }
777       g.players.push_back(p);
778     }
779   g.map.width = MAP_SIZE_NORMAL_WIDTH;
780   g.map.height = MAP_SIZE_NORMAL_HEIGHT;
781   g.map.grass = 78;
782   g.map.water = 7;
783   g.map.swamp = 2;
784   g.map.forest = 3;
785   g.map.hills = 5;
786   g.map.mountains = 5;
787   g.map.cities = 40;
788   g.map.ruins = 15;
789   g.map.temples = 1;
790   g.map.signposts = 10;
791   g.map_path = "";
792   g.play_with_quests = GameParameters::ONE_QUEST_PER_PLAYER;
793   g.hidden_map = false;
794   g.neutral_cities = GameParameters::STRONG;
795   g.razing_cities = GameParameters::ALWAYS;
796   g.diplomacy = false;
797   g.random_turns = false;
798   g.quick_start = GameParameters::NO_QUICK_START;
799   g.intense_combat = false;
800   g.military_advisor = false;
801   g.army_theme = "default";
802   g.tile_theme = "default";
803   g.shield_theme = "default";
804   g.city_theme = "default";
805   g.process_armies = GameParameters::PROCESS_ARMIES_AT_PLAYERS_TURN;
806   g.difficulty = GameScenario::calculate_difficulty_rating(g);
807   g.cities_can_produce_allies = false;
808   g.cusp_of_war = false;
809   g.see_opponents_stacks = true;
810   g.see_opponents_production = true;
811       
812   bool broken = false;
813   std::string path;
814   path = NewRandomMapDialog::create_and_dump_scenario("random.map", g, NULL);
815   g.map_path = path;
816
817   GameScenario* game_scenario = new GameScenario(g.map_path, broken);
818
819   if (broken)
820     return;
821
822   NextTurnHotseat *nextTurn;
823   nextTurn = new NextTurnHotseat(game_scenario->getTurnmode(),
824                                  game_scenario->s_random_turns);
825     
826   nextTurn->snextRound.connect
827     (sigc::mem_fun(this, &Driver::stressTestNextRound));
828   if (game_scenario->getRound() == 0)
829     {
830       Playerlist::getInstance()->syncPlayers(g.players);
831       game_scenario->initialize(g);
832     }
833
834   //this is a bit unfortunate... we have to instantiate images just to get stack positions into the stack tiles.  is there a better way?
835   /*/
836   GameMap::getInstance()->getTileset()->instantiateImages();
837   GameMap::getInstance()->getShieldset()->instantiateImages();
838   GameMap::getInstance()->getCityset()->instantiateImages();
839   guint32 armyset = Playerlist::getInstance()->getNeutral()->getArmyset();
840   Armysetlist::getInstance()->getArmyset(armyset)->instantiateImages();
841   */
842   Game game(game_scenario, nextTurn);
843   game.get_smallmap().set_slide_speed(0);
844   Configuration::s_displaySpeedDelay = 0;
845   time_t start = time(NULL);
846   nextTurn->start();
847   //next turn and game_Scenario get deleted inside game.
848   size_t mins = (time(NULL) - start) / 60;
849   printf("duration: %d mins, turns: %d\n", mins, game_scenario->getRound());
850
851 }
852         
853 void Driver::lordsawaromatic(std::string host, unsigned short port, Player::Type type, int num_players)
854 {
855   GameClient *game_client = GameClient::getInstance();
856   game_client->game_scenario_received.connect
857     (sigc::mem_fun(this, &Driver::on_game_scenario_downloaded));
858   game_client->client_disconnected.connect
859     (sigc::mem_fun(this, &Driver::on_server_went_away));
860   game_client->client_could_not_connect.connect
861     (sigc::mem_fun(this, &Driver::on_client_could_not_connect));
862   game_scenario_received.connect
863     (sigc::mem_fun(this, &Driver::on_game_scenario_received_for_robots));
864   game_client->setNickname("lordsawaromatic");
865   game_client->start(host, port, "lordsawaromatic");
866   heartbeat_conn = Glib::signal_timeout().connect
867     (bind_return(sigc::mem_fun(*this, &Driver::heartbeat), true), 1 * 1000);
868   robot_player_type = type;
869   number_of_robots = num_players;
870 }
871
872 void Driver::on_game_scenario_received_for_robots(std::string path)
873 {
874   heartbeat_conn.disconnect();
875   GameScenario *game_scenario = load_game(path);
876   NextTurnNetworked *next_turn = new NextTurnNetworked(game_scenario->getTurnmode(), game_scenario->s_random_turns);
877   GameClient::getInstance()->round_begins.connect(sigc::mem_fun(next_turn, &NextTurnNetworked::start));
878   Playerlist *pl = Playerlist::getInstance();
879
880   unsigned int count = 0;
881   for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
882     {
883       if (count >= number_of_robots && number_of_robots > 0)
884         break;
885       if ((*it)->getType() == Player::NETWORKED)
886         {
887           on_client_player_sat_down(*it);
888           count++;
889         }
890     }
891
892   pl->turnHumansInto(robot_player_type, number_of_robots);
893
894   for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
895     if (Player::Type((*it)->getType()) == robot_player_type)
896       {
897         GameClient::getInstance()->listenForLocalEvents(*it);
898       }
899
900   //end turn signals are listened to by next_turn, that are fired by the game client decoder
901
902   next_turn->start();
903 }
904
905 void Driver::on_show_lobby_requested()
906 {
907   if (game_lobby_dialog)
908     game_lobby_dialog->show();
909 }
910     
911 void Driver::start_network_game_requested(GameScenario *game_scenario, NextTurnNetworked *next_turn)
912 {
913   if (game_window)
914     {
915   
916       Player *active = Playerlist::getActiveplayer();
917       if (active->getType() == Player::NETWORKED)
918         game_window->show();
919       else
920         {
921           if (active->hasAlreadyInitializedTurn())
922             game_window->show();
923           else
924             game_window->continue_network_game (next_turn);
925         }
926     }
927   else
928     {
929       init_game_window();
930       player_replaced.connect
931         (sigc::mem_fun(game_window, &GameWindow::on_player_replaced));
932       game_window->show();
933
934       game_window->new_network_game (game_scenario, next_turn);
935     }
936 }
937   
938 void Driver::on_player_unavailable(Player *p)
939 {
940   game_lobby_dialog->player_is_unavailable(p);
941   on_show_lobby_requested();
942 }