00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sstream>
00022 #include <pgimage.h>
00023 #include <pglistbox.h>
00024 #include <pglistboxitem.h>
00025
00026 #include "newgame.h"
00027 #include "editmapparam.h"
00028 #include "alliancesetup.h"
00029 #include "playersetup.h"
00030 #include "fileselector.h"
00031 #include "emailsetup.h"
00032 #include "../loaders.h"
00033 #include "../gamemap.h"
00034 #include "../paradialog.h"
00035 #include "../turncontrol.h"
00036 #include "../viewcalculation.h"
00037 #include "../networkinterface.h"
00038 #include "../spfst.h"
00039 #include "../spfst-legacy.h"
00040 #include "../windowing.h"
00041 #include "../controls.h"
00042 #include "../sg.h"
00043 #include "../gamedlg.h"
00044 #include "../network/simple_file_transfer.h"
00045 #include "../network/pbem-server.h"
00046 #include "../textfile_evaluation.h"
00047 #include "../textfileparser.h"
00048 #include "../widgets/textrenderer.h"
00049 #include "../mapdisplayinterface.h"
00050 #include "../campaignactionrecorder.h"
00051
00052 class GameParameterEditorWidget;
00053
00054 const int pageCount = 11;
00055
00056 class Campaign {
00057 public:
00058 ASCString name;
00059 ASCString description;
00060 ASCString file;
00061
00062 void runTextIO ( PropertyContainer& pc ) {
00063 pc.addString ( "name", name);
00064 pc.addString ( "description", description );
00065 pc.addString ( "file", file );
00066 }
00067 };
00068
00069 class StartMultiplayerGame: public ConfigurableWindow {
00070 private:
00071 bool startButton;
00072 bool success;
00073 GameMap* newMap;
00074
00075 enum Pages { ModeSelection = 1, FilenameSelection, PlayerSetup, EmailSetup, AllianceSetup, MapParameterEditor, MultiPlayerOptions, PasswordSearch, PBEMServerSetup, CampaignChooser };
00076 Pages page;
00077
00078 enum Mode { NewCampaign, ContinueCampaign, Skirmish, Hotseat, PBEM, PBP, PBEM_Server };
00079 int mode;
00080
00081 static const char* buttonLabels[];
00082
00083 ASCString filename;
00084 ASCString PBEMfilename;
00085 bool replay;
00086 bool supervisorEnabled;
00087 Password supervisorPassword;
00088
00089 GameParameterEditorWidget* mapParameterEditor;
00090 PG_Widget* mapParameterEditorParent;
00091
00092 AllianceSetupWidget* allianceSetup;
00093 PG_Widget* allianceSetupParent;
00094 DirectAllianceSetupStrategy directAllianceSetupStrategy;
00095
00096 PlayerSetupWidget* playerSetup;
00097 PG_Widget* playerSetupParent;
00098
00099 EmailSetupWidget* emailSetup;
00100 PG_Widget* emailSetupParent;
00101
00102 bool nextPage(PG_Button* button = NULL);
00103 void showPage();
00104 bool checkPlayerStat();
00105
00106 ASCString getDefaultPBEM_Filename();
00107 void setupNetwork();
00108
00109 PBEMServer* pbemserver;
00110
00111 void loadPBEMServerDefaults();
00112
00113 typedef deallocating_vector<Campaign*> Campaigns;
00114 Campaigns campaigns;
00115 void loadCampaigns();
00116 Campaign* getSelectedCampaign();
00117 bool campaignSelected();
00118
00119 void fileNameSelected( const ASCString& filename )
00120 {
00121 this->filename = filename;
00122 if ( startButton )
00123 start();
00124 else
00125 nextPage();
00126 };
00127
00128 void fileNameMarked( const ASCString& filename )
00129 {
00130 this->filename = filename;
00131 };
00132
00133 bool quickstart()
00134 {
00135 if ( Apply() )
00136 start();
00137 return true;
00138 }
00139
00140
00141 void showSupervisorWidgets()
00142 {
00143 if ( page == MultiPlayerOptions ) {
00144 if ( supervisorEnabled )
00145 show( "SuperVisor" );
00146 else
00147 hide( "SuperVisor" );
00148 }
00149 }
00150
00151 bool togglesupervisor( bool on )
00152 {
00153 supervisorEnabled = on;
00154 showSupervisorWidgets();
00155 return true;
00156 }
00157
00158 void showButtons( bool start, bool quickstart, bool next )
00159 {
00160 startButton = start;
00161
00162 assert ( start != next );
00163 assert ( !(start && quickstart) );
00164
00165 if ( next )
00166 show("next");
00167 else
00168 hide("next");
00169
00170 if ( quickstart )
00171 show("quickstart");
00172 else
00173 hide("quickstart");
00174
00175 if ( start )
00176 show("start");
00177 else
00178 hide("start");
00179 };
00180
00181
00182 GameMap* searchForMap( const ASCString& password );
00183
00184 protected:
00185 void userHandler( const ASCString& label, PropertyReadingContainer& pc, PG_Widget* parent, WidgetParameters widgetParams );
00186 bool start();
00187 bool Apply();
00188
00189 bool eventKeyDown(const SDL_KeyboardEvent *key){
00190 if(key->keysym.sym == SDLK_ESCAPE) {
00191 if ( page <= 2 )
00192 QuitModal();
00193 return true;
00194 }
00195 return false;
00196 }
00197
00198 public:
00199 StartMultiplayerGame(PG_MessageObject* c);
00200 ~StartMultiplayerGame();
00201
00202 bool getSuccess()
00203 {
00204 return success;
00205 }
00206
00207 };
00208
00209 const char* StartMultiplayerGame::buttonLabels[8] = {
00210 "NewCampaign",
00211 "ContinueCampaign",
00212 "SinglePlayer",
00213 "Hotseat",
00214 "PBEM",
00215 "PBP",
00216 "PBEMServer",
00217 NULL
00218 };
00219
00220
00221 StartMultiplayerGame::StartMultiplayerGame(PG_MessageObject* c): ConfigurableWindow( NULL, PG_Rect::null, "newmultiplayergame", false ), startButton(false), success(false), newMap(NULL), page(ModeSelection), mode ( 0 ), replay(true), supervisorEnabled(false),
00222 mapParameterEditor(NULL), mapParameterEditorParent(NULL),
00223 allianceSetup(NULL), allianceSetupParent(NULL),
00224 playerSetup(NULL), playerSetupParent(NULL),
00225 emailSetup(NULL), emailSetupParent(NULL),
00226 pbemserver(NULL)
00227 {
00228 setup();
00229 sigClose.connect( SigC::slot( *this, &StartMultiplayerGame::QuitModal ));
00230
00231 PG_RadioButton* b1 = dynamic_cast<PG_RadioButton*>(FindChild(buttonLabels[0], true ));
00232 if ( b1 )
00233 b1->SetPressed();
00234
00235 PG_Button* next = dynamic_cast<PG_Button*>(FindChild("next", true ));
00236 if ( next )
00237 next->sigClick.connect( SigC::slot( *this, &StartMultiplayerGame::nextPage ));
00238
00239 PG_Button* start = dynamic_cast<PG_Button*>(FindChild("start", true ));
00240 if ( start )
00241 start->sigClick.connect( SigC::slot( *this, &StartMultiplayerGame::start ));
00242
00243 PG_Button* qstart = dynamic_cast<PG_Button*>(FindChild("quickstart", true ));
00244 if ( qstart )
00245 qstart->sigClick.connect( SigC::slot( *this, &StartMultiplayerGame::quickstart ));
00246
00247 PG_CheckButton* supervisor = dynamic_cast<PG_CheckButton*>(FindChild("SupervisorOn", true ));
00248 if ( supervisor ) {
00249 if ( supervisorEnabled )
00250 supervisor->SetPressed();
00251 else
00252 supervisor->SetUnpressed();
00253 supervisor->sigClick.connect( SigC::slot( *this, &StartMultiplayerGame::togglesupervisor ));
00254 }
00255
00256 PG_LineEdit* s1 = dynamic_cast<PG_LineEdit*>( FindChild( "SupervisorPlain", true ));
00257 if ( s1 )
00258 s1->SetPassHidden ('*');
00259
00260
00261 PG_CheckButton* cb = dynamic_cast<PG_CheckButton*>( FindChild( "Replay", true ));
00262 if ( cb ) {
00263 if ( replay )
00264 cb->SetPressed( );
00265 else
00266 cb->SetUnpressed();
00267 }
00268
00269 showPage();
00270 showButtons(false,false,true);
00271
00272 loadPBEMServerDefaults();
00273 loadCampaigns();
00274 }
00275
00276
00277 StartMultiplayerGame::~StartMultiplayerGame()
00278 {
00279 if ( newMap )
00280 delete newMap;
00281
00282 if ( pbemserver )
00283 delete pbemserver;
00284 }
00285
00286 bool StartMultiplayerGame::campaignSelected()
00287 {
00288
00289 TextRenderer* text = dynamic_cast<TextRenderer*>( FindChild( "CampaignDescription", true ));
00290 if ( text ) {
00291 Campaign* c = getSelectedCampaign();
00292 if ( c )
00293 text->SetText( c->description );
00294 }
00295 return true;
00296 }
00297
00298 void StartMultiplayerGame::loadCampaigns()
00299 {
00300 PG_ListBox* list = dynamic_cast<PG_ListBox*>( FindChild( "CampaignList", true ));
00301 if ( !list )
00302 return;
00303
00304 list->sigSelectItem.connect( SigC::slot( *this, &StartMultiplayerGame::campaignSelected ));
00305
00306
00307 tfindfile ff ( "*.asccampaign" );
00308 tfindfile::FileInfo fi;
00309 while ( ff.getnextname( fi) ) {
00310 try {
00311 tnfilestream f ( fi.name, tnstream::reading );
00312 TextFormatParser parser(&f);
00313
00314 PropertyReadingContainer prc ( "campaign", parser.run());
00315 Campaign* c = new Campaign();
00316 c->runTextIO(prc);
00317
00318 campaigns.push_back ( c );
00319
00320 if ( list )
00321 new PG_ListBoxItem( list, 20, c->name );
00322
00323 } catch ( ParsingError pe ) {
00324 errorMessage( pe.getMessage( ));
00325 }
00326 }
00327 }
00328
00329
00330 Campaign* StartMultiplayerGame::getSelectedCampaign()
00331 {
00332 PG_ListBox* list = dynamic_cast<PG_ListBox*>( FindChild( "CampaignList", true ));
00333
00334 if ( list )
00335 for ( int i = 0; i < list->GetWidgetCount(); ++i ) {
00336 PG_ListBoxBaseItem* bi = dynamic_cast<PG_ListBoxBaseItem*>(list->FindWidget(i));
00337 if ( bi && bi->IsSelected() )
00338 for ( Campaigns::iterator i = campaigns.begin(); i != campaigns.end(); ++i )
00339 if ( (*i)->name == bi->GetText() )
00340 return *i;
00341 }
00342
00343
00344 return NULL;
00345 }
00346
00347
00348 bool StartMultiplayerGame::Apply()
00349 {
00350 switch ( page ) {
00351 case FilenameSelection: {
00352 if ( !filename.empty() )
00353 if ( exist( filename )) {
00354 delete newMap;
00355 newMap = mapLoadingExceptionChecker( filename, MapLoadingFunction( tmaploaders::loadmap ));
00356 if ( newMap ) {
00357 if ( mode != NewCampaign && mode != ContinueCampaign )
00358 newMap->campaign.avail = false;
00359 else
00360 replay = false;
00361
00362 if ( mode == Skirmish )
00363 replay = false;
00364
00365 if ( checkPlayerStat() )
00366 return true;
00367 else {
00368 delete newMap;
00369 newMap = NULL;
00370 return false;
00371 }
00372 }
00373 }
00374
00375 }
00376 break;
00377 case PlayerSetup:
00378 if ( playerSetup->Valid() ) {
00379 playerSetup->Apply();
00380 return true;
00381 }
00382 break;
00383 case EmailSetup:
00384 emailSetup->Apply();
00385 return true;
00386
00387 case AllianceSetup:
00388 allianceSetup->Apply();
00389 return true;
00390
00391 case MapParameterEditor:
00392 if ( mapParameterEditor->Valid() ) {
00393 mapParameterEditor->Apply();
00394 return true;
00395 }
00396 break;
00397 case MultiPlayerOptions:
00398 {
00399 PG_CheckButton* cb = dynamic_cast<PG_CheckButton*>( FindChild( "Replay", true ));
00400 if ( cb )
00401 replay = cb->GetPressed();
00402
00403 PG_LineEdit* le = dynamic_cast<PG_LineEdit*>( FindChild( "Filename", true ));
00404 if ( le && !le->GetText().empty() )
00405 PBEMfilename = le->GetText();
00406
00407 if ( supervisorEnabled ) {
00408 PG_LineEdit* s1 = dynamic_cast<PG_LineEdit*>( FindChild( "SupervisorPlain", true ));
00409 PG_LineEdit* s2 = dynamic_cast<PG_LineEdit*>( FindChild( "SupervisorEnc", true ));
00410
00411 if ( s1 && s2 && !s1->GetText().empty() && !s2->GetText().empty()) {
00412 Password pwd;
00413 pwd.setUnencoded( s1->GetText() );
00414
00415 Password pwd2;
00416 pwd2.setEncoded( s2->GetText() );
00417 if ( pwd != pwd2 ) {
00418 warningMessage ( "Passwords don't match!");
00419 return false;
00420 }
00421 }
00422
00423 if ( s1 && !s1->GetText().empty() )
00424 supervisorPassword.setUnencoded( s1->GetText() );
00425
00426 if ( s2 && !s2->GetText().empty() )
00427 supervisorPassword.setEncoded( s2->GetText() );
00428 }
00429 return true;
00430 }
00431 break;
00432 case PBEMServerSetup:
00433 {
00434 if ( !pbemserver )
00435 pbemserver = new PBEMServer();
00436
00437
00438
00439
00440
00441 PG_LineEdit* le = dynamic_cast<PG_LineEdit*>( FindChild( "Server", true ));
00442 if ( le && !le->GetText().empty() )
00443 pbemserver->setServerAddress ( le->GetText());
00444
00445 }
00446 return true;
00447 case PasswordSearch: {
00448 PG_LineEdit* pw = dynamic_cast<PG_LineEdit*>( FindChild( "MapPassword", true ));
00449 if ( pw ) {
00450 if ( pw->GetText().empty() ) {
00451 errorMessage("please enter a password");
00452 return false;
00453 }
00454
00455 GameMap* map = searchForMap( pw->GetText() );
00456 if ( !map ) {
00457 errorMessage("No map found");
00458 return false;
00459 }
00460 newMap = map;
00461 replay = false;
00462
00463 return true;
00464 }
00465
00466 }
00467 break;
00468
00469 case CampaignChooser: {
00470 Campaign* c =getSelectedCampaign();
00471 if ( c ) {
00472 if ( c->file.empty() )
00473 return false;
00474
00475 tfindfile ff ( c->file );
00476 if ( ff.getFoundFileNum() < 1 )
00477 return false;
00478
00479 if ( ff.getFoundFileNum() == 1 ) {
00480 tfindfile::FileInfo fi;
00481 if ( !ff.getnextname( fi) )
00482 return false;
00483
00484 filename = fi.name;
00485 replay = false;
00486 return true;
00487 } else {
00488 filename = selectFile( c->file, true );
00489 if ( filename.empty() ) {
00490 return false;
00491 } else {
00492 replay = false;
00493 return true;
00494 }
00495 }
00496 } else
00497 return false;
00498 }
00499
00500 default:
00501 break;
00502 }
00503
00504 return false;
00505 }
00506
00507 GameMap* StartMultiplayerGame::searchForMap( const ASCString& password )
00508 {
00509 StatusMessageWindowHolder smw = MessagingHub::Instance().infoMessageWindow( "please wait, searching for map...");
00510
00511 tfindfile ff ( mapextension );
00512 string filename = ff.getnextname();
00513 while( !filename.empty() ) {
00514 try {
00515 tmaploaders loader;
00516 GameMap* map = loader.loadmap( filename );
00517 if ( map->codeWord == password )
00518 return map;
00519 else
00520 delete map;
00521 }
00522 catch ( ASCexception ) {
00523 }
00524
00525 filename = ff.getnextname();
00526 }
00527 return NULL;
00528 }
00529
00530 bool StartMultiplayerGame::nextPage(PG_Button* button)
00531 {
00532 int oldpage = page;
00533 switch ( page ) {
00534 case ModeSelection: {
00535 int i = 0;
00536 while ( buttonLabels[i] ) {
00537 PG_RadioButton* b = dynamic_cast<PG_RadioButton*>(FindChild(buttonLabels[i], true ));
00538 if ( b && b->GetPressed() ) {
00539 mode = i;
00540 break;
00541 }
00542 ++i;
00543 }
00544 if ( mode == ContinueCampaign )
00545 page = PasswordSearch;
00546 else
00547 if ( mode == NewCampaign )
00548 page = CampaignChooser;
00549 else
00550 page = FilenameSelection;
00551 }
00552 break;
00553
00554 case FilenameSelection:
00555 if ( Apply() )
00556 page = PlayerSetup;
00557 break;
00558 case PlayerSetup:
00559 if ( Apply() ) {
00560 if ( mode == PBEM || mode == PBP || mode == PBEM_Server )
00561 page = EmailSetup;
00562 else
00563 page = AllianceSetup;
00564 }
00565 break;
00566 case EmailSetup:
00567 if ( Apply() ) {
00568 if ( mode == PBEM_Server )
00569 page = PBEMServerSetup;
00570 else
00571 page = AllianceSetup;
00572 }
00573 break;
00574
00575 case PBEMServerSetup:
00576 if ( Apply() ) {
00577 page = AllianceSetup;
00578 }
00579 break;
00580
00581 case AllianceSetup:
00582 if ( Apply() )
00583 page = MapParameterEditor;
00584 break;
00585
00586 case MapParameterEditor:
00587 if ( Apply() )
00588 page = MultiPlayerOptions;
00589 break;
00590
00591 default:
00592 break;
00593 }
00594
00595 if ( oldpage != page ) {
00596 if ( page == PlayerSetup && playerSetupParent ) {
00597 delete playerSetup;
00598 if ( mode == Skirmish )
00599 playerSetup = new PlayerSetupWidget( newMap, PlayerSetupWidget::AllEditableSinglePlayer, playerSetupParent, PG_Rect( 0, 0, playerSetupParent->Width(), playerSetupParent->Height() ));
00600 else
00601 playerSetup = new PlayerSetupWidget( newMap, PlayerSetupWidget::AllEditable, playerSetupParent, PG_Rect( 0, 0, playerSetupParent->Width(), playerSetupParent->Height() ));
00602 }
00603
00604 if ( page == AllianceSetup && allianceSetupParent ) {
00605 delete allianceSetup;
00606 allianceSetup = new AllianceSetupWidget( newMap, &directAllianceSetupStrategy, true, allianceSetupParent, PG_Rect( 0, 0, allianceSetupParent->Width(), allianceSetupParent->Height() ));
00607 }
00608
00609 if ( page == MapParameterEditor && mapParameterEditorParent ) {
00610 if ( mode == PBP )
00611 newMap->setgameparameter(cgp_superVisorCanSaveMap,1);
00612 delete mapParameterEditor;
00613 mapParameterEditor = new GameParameterEditorWidget( newMap, mapParameterEditorParent, PG_Rect( 0, 0, mapParameterEditorParent->Width(), mapParameterEditorParent->Height() ));
00614 }
00615
00616 if ( page == EmailSetup && emailSetupParent ) {
00617 delete emailSetup;
00618 emailSetup = new EmailSetupWidget( newMap, -1, emailSetupParent, PG_Rect( 0, 0, emailSetupParent->Width(), emailSetupParent->Height() ));
00619 }
00620
00621 if ( page == MultiPlayerOptions ) {
00622 PG_LineEdit* le = dynamic_cast<PG_LineEdit*>( FindChild( "Filename", true ));
00623 PBEMfilename = getDefaultPBEM_Filename();
00624 if ( le )
00625 le->SetText( PBEMfilename );
00626 }
00627
00628 showPage();
00629 return true;
00630 } else
00631 return false;
00632 }
00633
00634 void StartMultiplayerGame::loadPBEMServerDefaults()
00635 {
00636 if ( !pbemserver )
00637 pbemserver = new PBEMServer();
00638
00639
00640
00641
00642 PG_LineEdit* le = dynamic_cast<PG_LineEdit*>( FindChild( "Server", true ));
00643 if ( le )
00644 le->SetText( PBEMServer::getDefaultServerAddress() );
00645
00646 }
00647
00648
00649 void StartMultiplayerGame::showPage()
00650 {
00651 for ( int i = 0; i < pageCount; ++i ) {
00652 ASCString name = "Page" + ASCString::toString(i);
00653 if ( page == i )
00654 show( name );
00655 else
00656 hide( name );
00657 }
00658 showSupervisorWidgets();
00659
00660 switch ( page ) {
00661 case CampaignChooser:
00662 showButtons(true,false,false);
00663 break;
00664
00665 case FilenameSelection:
00666 if ( mode == NewCampaign || mode == ContinueCampaign )
00667 showButtons(true,false,false);
00668 else
00669 showButtons(false,true,true);
00670 break;
00671
00672 case MapParameterEditor:
00673 if ( mode != Hotseat && mode != PBEM )
00674 showButtons(true,false,false);
00675 else
00676 showButtons(false,true,true);
00677 break;
00678 case MultiPlayerOptions:
00679 showButtons(true,false,false);
00680 break;
00681 case PasswordSearch:
00682 showButtons(true,false,false);
00683 break;
00684
00685 default:
00686 break;
00687 }
00688 }
00689
00690
00691
00692 void StartMultiplayerGame::userHandler( const ASCString& label, PropertyReadingContainer& pc, PG_Widget* parent, WidgetParameters widgetParams )
00693 {
00694 if ( label == "FileList" ) {
00695 FileSelectionItemFactory* factory = new FileSelectionItemFactory( mapextension );
00696 factory->filenameSelectedKeyb.connect ( SigC::slot( *this, &StartMultiplayerGame::fileNameSelected ));
00697 factory->filenameSelectedMouse.connect ( SigC::slot( *this, &StartMultiplayerGame::fileNameMarked ));
00698 factory->filenameMarked.connect ( SigC::slot( *this, &StartMultiplayerGame::fileNameMarked ));
00699 new ItemSelectorWidget( parent, PG_Rect(0, 0, parent->Width(), parent->Height()), factory );
00700 }
00701
00702 if ( label == "PlayerSetup" )
00703 playerSetupParent = parent;
00704
00705 if ( label == "AllianceSetup" )
00706 allianceSetupParent = parent;
00707
00708 if ( label == "GameParameters" )
00709 mapParameterEditorParent = parent;
00710
00711 if ( label == "EmailSetup" )
00712 emailSetupParent = parent;
00713
00714 }
00715
00716 bool StartMultiplayerGame::checkPlayerStat()
00717 {
00718 ASCString msg;
00719 if ( mode == NewCampaign || mode == ContinueCampaign ) {
00720 bool humanFound = false;
00721 for ( int i = 0; i < newMap->getPlayerCount(); ++i )
00722 if ( newMap->player[i].exist() )
00723 if ( newMap->player[i].stat == Player::human )
00724 humanFound = true;
00725
00726 if ( !humanFound ) {
00727 warningMessage("no human players on map!");
00728 return false;
00729 }
00730 return true;
00731 }
00732
00733 if ( mode == Skirmish ) {
00734 bool humanFound = false;
00735 for ( int i = 0; i < newMap->getPlayerCount(); ++i )
00736 if ( newMap->player[i].exist() )
00737 if ( newMap->player[i].stat == Player::human || newMap->player[i].stat == Player::supervisor ) {
00738 if ( humanFound ) {
00739 newMap->player[i].stat = Player::computer;
00740 msg += newMap->player[i].getName() + " has been switch to AI\n";
00741 } else
00742 humanFound = true;
00743 }
00744 if ( !humanFound )
00745 for ( int i = 0; i < newMap->getPlayerCount(); ++i )
00746 if ( newMap->player[i].exist() )
00747 if ( newMap->player[i].stat == Player::computer ) {
00748 newMap->player[i].stat = Player::human;
00749 msg += newMap->player[i].getName() + " has been switch to human\n";
00750 humanFound = true;
00751 break;
00752 }
00753
00754 bool aiFound = false;
00755 for ( int i = 0; i < newMap->getPlayerCount(); ++i )
00756 if ( newMap->player[i].exist() )
00757 if ( newMap->player[i].stat == Player::computer )
00758 aiFound = true;
00759
00760 if ( !aiFound )
00761 for ( int i = 0; i < newMap->getPlayerCount(); ++i )
00762 if ( newMap->player[i].exist() )
00763 if ( newMap->player[i].stat == Player::off ) {
00764 newMap->player[i].stat = Player::computer;
00765 msg += newMap->player[i].getName() + " has been switch to AI\n";
00766 aiFound = true;
00767 break;
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777 }
00778
00779 if ( mode == PBEM || mode == Hotseat ) {
00780 int humanNum = 0;
00781 for ( int i = 0; i < newMap->getPlayerCount(); ++i )
00782 if ( newMap->player[i].exist() )
00783 if ( newMap->player[i].stat == Player::human || newMap->player[i].stat == Player::supervisor )
00784 ++humanNum;
00785
00786 if ( humanNum <= 1 )
00787 for ( int i = 0; i < newMap->getPlayerCount(); ++i )
00788 if ( newMap->player[i].exist() )
00789 if ( newMap->player[i].stat == Player::computer || newMap->player[i].stat == Player::off ) {
00790 newMap->player[i].stat = Player::human;
00791 msg += newMap->player[i].getName() + " has been switched to human\n";
00792 ++humanNum;
00793 }
00794
00795
00796 if ( humanNum <= 1 ) {
00797 MessagingHub::Instance().error("Not enough players on map for multiplayer game!");
00798 return false;
00799 }
00800 }
00801
00802 if ( mode == PBP ) {
00803 newMap->player[0].stat = Player::supervisor;
00804
00805 int humanNum = 0;
00806 for ( int i = 1; i < newMap->getPlayerCount(); ++i )
00807 if ( newMap->player[i].exist() )
00808 if ( newMap->player[i].stat == Player::human || newMap->player[i].stat == Player::supervisor )
00809 ++humanNum;
00810
00811 if ( humanNum < 1 )
00812 for ( int i = 1; i < newMap->getPlayerCount(); ++i )
00813 if ( newMap->player[i].exist() )
00814 if ( newMap->player[i].stat == Player::computer || newMap->player[i].stat == Player::off ) {
00815 newMap->player[i].stat = Player::human;
00816 msg += newMap->player[i].getName() + " has been switched to human\n";
00817 ++humanNum;
00818 }
00819 }
00820
00821
00822
00823 return true;
00824 }
00825
00826 ASCString StartMultiplayerGame::getDefaultPBEM_Filename()
00827 {
00828 ASCString filename = newMap->preferredFileNames.mapname[0];
00829 if( filename.empty() )
00830 filename = "game";
00831
00832 if ( filename.find( '.') != ASCString::npos )
00833 filename.erase( filename.find( '.'));
00834
00835 filename += "-$p-$t";
00836
00837 return filename;
00838 }
00839
00840
00841 void StartMultiplayerGame::setupNetwork()
00842 {
00843 if ( mode == PBP || mode == PBEM ) {
00844 if ( newMap && (!newMap->network || newMap->network->getMechanismID() != FileTransfer::mechanismID()) ) {
00845
00846 delete newMap->network;
00847
00848 FileTransfer* ft = new FileTransfer();
00849 newMap->network = ft;
00850
00851 if ( !PBEMfilename.empty() )
00852 ft->setup( PBEMfilename );
00853 else
00854 ft->setup( getDefaultPBEM_Filename() );
00855 }
00856 } else
00857 if ( mode == PBEM_Server ) {
00858 if ( newMap ) {
00859 delete newMap->network;
00860 newMap->network = pbemserver;
00861
00862 pbemserver = NULL;
00863 }
00864 }
00865 }
00866
00867
00868 bool StartMultiplayerGame::start()
00869 {
00870 if ( !Apply() )
00871 return false;
00872
00873 if ( !newMap )
00874 newMap = mapLoadingExceptionChecker( filename, MapLoadingFunction( tmaploaders::loadmap ));
00875
00876 if ( !newMap )
00877 return false;
00878
00879
00880
00881
00882 if ( replay )
00883 newMap->replayinfo = new GameMap::ReplayInfo;
00884 else
00885 if ( newMap->replayinfo ) {
00886 delete newMap->replayinfo;
00887 newMap->replayinfo = NULL;
00888 }
00889
00890 if ( supervisorEnabled )
00891 newMap->supervisorpasswordcrc = supervisorPassword;
00892
00893
00894 setupNetwork();
00895
00896 delete actmap;
00897 actmap = newMap;
00898 newMap = NULL;
00899 QuitModal();
00900 Hide();
00901 computeview( actmap );
00902 hookGuiToMap(actmap);
00903
00904 next_turn( actmap, NextTurnStrategy_AskUser(), &getDefaultMapDisplay() );
00905 displaymap();
00906 updateFieldInfo();
00907 success = true;
00908
00909 if ( mode == PBP || mode == PBEM )
00910 sendGameParameterAsMail ( actmap );
00911
00912 if ( (mode == NewCampaign || mode == ContinueCampaign) && CGameOptions::Instance()->recordCampaignMaps )
00913 actmap->actionRecorder = new CampaignActionLogger( actmap );
00914
00915
00916 return true;
00917 }
00918
00919
00920
00921 bool startMultiplayerGame()
00922 {
00923 bool res = false;
00924 try {
00925 StartMultiplayerGame smg(NULL);
00926 smg.Show();
00927 smg.RunModal();
00928 res = smg.getSuccess();
00929 smg.Hide();
00930 }
00931 catch ( ShutDownMap sdm ) {
00932 warningMessage("No players found on map");
00933 throw sdm;
00934 }
00935
00936
00937
00938
00939
00940 return res;
00941 }
00942
00943