00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "turncontrol.h"
00029 #include "gamemap.h"
00030 #include "mapdisplay.h"
00031 #include "gameoptions.h"
00032 #include "dialogs/pwd_dlg.h"
00033 #include "controls.h"
00034 #include "spfst.h"
00035 #include "dlg_box.h"
00036 #include "ai/ai.h"
00037 #include "dialog.h"
00038 #include "strtmesg.h"
00039 #include "loaders.h"
00040 #include "cannedmessages.h"
00041 #include "viewcalculation.h"
00042 #include "network/simple_file_transfer.h"
00043 #include "dialogs/fileselector.h"
00044
00045 bool authenticateUser ( GameMap* actmap, int forcepasswordchecking = 0, bool allowCancel = true, bool lockView = true, bool throwOnFailure = false )
00046 {
00047 for ( int p = 0; p < 8; p++ )
00048 actmap->player[p].existanceAtBeginOfTurn = actmap->player[p].exist() && actmap->player[p].stat != Player::off;
00049
00050 int humannum = 0;
00051 for ( int i = 0; i < 8; i++ )
00052 if ( actmap->player[i].exist() )
00053 if ( actmap->player[i].isHuman() )
00054 humannum++;
00055
00056 if ( humannum > 1 || forcepasswordchecking > 0 ) {
00057 MapDisplayPG::LockDisplay ld ( !lockView );
00058
00059 bool firstRound = actmap->time.turn() == 1;
00060 bool specifyPassword = firstRound && actmap->player[actmap->actplayer].passwordcrc.empty();
00061
00062
00063 if ( (!actmap->player[actmap->actplayer].passwordcrc.empty() && actmap->player[actmap->actplayer].passwordcrc != CGameOptions::Instance()->getDefaultPassword() )
00064 || firstRound ) {
00065 if ( forcepasswordchecking < 0 ) {
00066 delete actmap;
00067 actmap = NULL;
00068 throw NoMapLoaded();
00069 } else {
00070 bool stat;
00071 actmap->setPlayerView ( actmap->actplayer );
00072 do {
00073 stat = enterpassword ( actmap->player[actmap->actplayer].passwordcrc, specifyPassword, allowCancel );
00074 if ( !stat ) {
00075 if ( throwOnFailure ) {
00076 delete actmap;
00077 throw NoMapLoaded();
00078 } else
00079 return false;
00080 }
00081 } while ( actmap->player[actmap->actplayer].passwordcrc.empty() && stat && viewtextquery ( 910, "warning", "~e~nter password", "~c~ontinue without password" ) == 0 );
00082 }
00083 } else {
00084 infoMessage("next player is " + actmap->player[actmap->actplayer].getName() );
00085 actmap->setPlayerView ( actmap->actplayer );
00086 }
00087 actmap->overviewMapHolder.clear( true );
00088 } else
00089 actmap->overviewMapHolder.clear( true );
00090
00091 moveparams.movestatus = 0;
00092
00093 actmap->setPlayerView ( actmap->actplayer );
00094
00095 return true;
00096
00097 }
00098
00099
00100
00101
00102 void runai( GameMap* actmap, int playerView )
00103 {
00104 MapDisplayPG::CursorHiding cusorHiding;
00105 actmap->setPlayerView ( playerView );
00106
00107 computeview( actmap );
00108
00109 if ( !actmap->player[ actmap->actplayer ].ai )
00110 actmap->player[ actmap->actplayer ].ai = new AI ( actmap, actmap->actplayer );
00111
00112 actmap->player[ actmap->actplayer ].ai->run();
00113 updateFieldInfo();
00114 }
00115
00116
00117 int findNextPlayer( const GameMap* actmap )
00118 {
00119 int p = actmap->actplayer;
00120 bool found = false;
00121 int loop = 0;
00122 do {
00123 ++p;
00124 if ( p >= actmap->getPlayerCount()) {
00125 p = 0;
00126 ++loop;
00127 if ( loop >= 3 )
00128 throw ShutDownMap();
00129 }
00130
00131
00132 if ( actmap->player[p].exist() )
00133 if ( actmap->player[p].stat != Player::off )
00134 found = true;
00135
00136 } while ( !found );
00137 return p;
00138 }
00139
00140
00142 void clearReplays( GameMap* actmap )
00143 {
00144 if ( actmap->replayinfo )
00145 for ( int i = 0; i < actmap->getPlayerCount(); ++i )
00146 if ( !actmap->player[i].exist() )
00147 if ( actmap->replayinfo->map[i] && actmap->replayinfo->guidata[i] ) {
00148 delete actmap->replayinfo->map[i];
00149 actmap->replayinfo->map[i] = NULL;
00150
00151 delete actmap->replayinfo->guidata[i];
00152 actmap->replayinfo->guidata[i] = NULL;
00153 }
00154 }
00155
00156
00157 void iterateToNextPlayer( GameMap* actmap, bool saveNetwork, int lastPlayer, int lastTurn )
00158 {
00159 int loop = 0;
00160 bool closeLoop = false;
00161
00162 clearReplays( actmap );
00163
00164 do {
00165
00166
00167 int currentPlayer= actmap->actplayer;
00168
00169 int nextPlayer = findNextPlayer( actmap );
00170
00171 if ( nextPlayer <= currentPlayer ) {
00172 actmap->endRound();
00173 ++loop;
00174 }
00175
00176 if ( loop > 2 ) {
00177 displaymessage("no human players found !", 1 );
00178 delete actmap;
00179 actmap = NULL;
00180 throw NoMapLoaded();
00181 }
00182
00183
00184 actmap->actplayer = nextPlayer;
00185
00186 if ( actmap->player[nextPlayer].stat == Player::computer ) {
00187 actmap->beginTurn();
00188 runai( actmap, lastPlayer );
00189 actmap->endTurn();
00190 }
00191
00192 if ( actmap->player[nextPlayer].stat == Player::suspended ) {
00193 actmap->beginTurn();
00194 actmap->endTurn();
00195 }
00196
00197 if ( actmap->player[nextPlayer].stat == Player::human || actmap->player[nextPlayer].stat == Player::supervisor ) {
00198 if ( actmap->network && lastPlayer >= 0 && saveNetwork ) {
00199 actmap->network->send( actmap, lastPlayer, lastTurn );
00200 delete actmap;
00201 actmap = NULL;
00202 throw NoMapLoaded();
00203 } else
00204 closeLoop = true;
00205 }
00206 } while ( !closeLoop );
00207
00208 }
00209
00210 void next_turn ( int playerView )
00211 {
00212 int lastPlayer = actmap->actplayer;
00213 int lastTurn = actmap->time.turn();
00214
00215 if ( lastPlayer >= 0 )
00216 actmap->endTurn();
00217
00218 int pv;
00219 if ( playerView == -2 ) {
00220 if ( actmap->time.turn() <= 0 || actmap->actplayer < 0 )
00221 pv = -1;
00222 else
00223 if ( actmap->player[actmap->actplayer].stat != Player::human )
00224 pv = -1;
00225 else
00226 pv = actmap->actplayer;
00227 } else
00228 pv = playerView;
00229
00230
00231 if ( findNextPlayer( actmap ) == lastPlayer ) {
00232 if ( !actmap->continueplaying ) {
00233 viewtext2(904);
00234 if (choice_dlg("Do you want to continue playing ?","~y~es","~n~o") == 2) {
00235 delete actmap;
00236 actmap = NULL;
00237 throw NoMapLoaded();
00238 } else {
00239 actmap->continueplaying = true;
00240 if ( actmap->replayinfo ) {
00241 delete actmap->replayinfo;
00242 actmap->replayinfo = NULL;
00243 }
00244 }
00245 }
00246 }
00247
00248
00249 iterateToNextPlayer( actmap, true, lastPlayer, lastTurn );
00250
00251 actmap->setPlayerView ( -1 );
00252
00253 if ( !authenticateUser( actmap, 0, false, true, true )) {
00254 delete actmap;
00255 throw NoMapLoaded();
00256 }
00257
00258 actmap->beginTurn();
00259 actmap->setPlayerView ( actmap->actplayer );
00260 actmap->overviewMapHolder.clear();
00261 actmap->sigPlayerUserInteractionBegins( actmap->player[actmap->actplayer] );
00262 }
00263
00264
00265 void skipTurn( GameMap* gamemap )
00266 {
00267 if ( gamemap->actplayer >= 0 ) {
00268 gamemap->beginTurn();
00269 gamemap->endTurn();
00270 }
00271 iterateToNextPlayer( gamemap, false, -1, -1 );
00272 }
00273
00274 void checkUsedASCVersions ( Player& currentPlayer )
00275 {
00276 for ( int i = 0; i < 8; i++ )
00277 if ( actmap->player[i].exist() )
00278 if ( actmap->actplayer != i )
00279 if ( actmap->player[i].ASCversion > 0 )
00280 if ( (actmap->player[i].ASCversion & 0xffffff00) > getNumericVersion() ) {
00281 new Message ( ASCString("Player ") + actmap->player[i].getName()
00282 + " is using a newer version of ASC. \n"
00283 "Please check www.asc-hq.org for updates.\n\n"
00284 "Please do NOT report any problems with this version of ASC until "
00285 "you have confirmed that they are also present in the latest "
00286 "version of ASC.", actmap, 1<<actmap->actplayer );
00287 return;
00288 }
00289
00290 }
00291
00292
00293
00294
00295 bool continuenetworkgame ( bool mostRecent )
00296 {
00297 ASCString filename;
00298 if ( !mostRecent ) {
00299 filename = selectFile( ASCString("*") + tournamentextension + ";*.asc", true );
00300 } else {
00301 int datefound = 0;
00302
00303 for ( int w = 0; w < 2; ++w) {
00304
00305 ASCString wildcard;
00306 if ( w == 0 )
00307 wildcard = ASCString("*") + tournamentextension;
00308 else
00309 wildcard = "*.asc";
00310
00311 tfindfile ff ( wildcard );
00312
00313 tfindfile::FileInfo fi;
00314 while ( ff.getnextname( fi ))
00315 if ( fi.date > datefound ) {
00316 datefound = fi.date;
00317 filename = fi.name;
00318 }
00319 }
00320 }
00321
00322 if ( filename.empty() )
00323 return false;
00324
00325 StatusMessageWindowHolder smw = MessagingHub::Instance().infoMessageWindow( "loading " + filename );
00326
00327 return continuenetworkgame( filename );
00328 }
00329
00330 bool continuenetworkgame ( const ASCString& filename )
00331 {
00332 FileTransfer ft;
00333 auto_ptr<GameMap> newMap ( mapLoadingExceptionChecker( filename, MapLoadingFunction( &ft, &FileTransfer::loadPBEMFile )));
00334 if ( !newMap.get() )
00335 return false;
00336
00337 if ( !authenticateUser( newMap.get() , 0, true, false ))
00338 return false;
00339
00340 delete actmap;
00341 actmap = newMap.release();
00342
00343 computeview( actmap );
00344 actmap->beginTurn();
00345 actmap->setPlayerView ( actmap->actplayer );
00346 return true;
00347 }
00348
00349
00350
00351 void checkforvictory ( bool hasTurnControl )
00352 {
00353 if ( !actmap->continueplaying ) {
00354 int plnum = 0;
00355 for ( int i = 0; i < 8; i++ )
00356 if ( !actmap->player[i].exist() && actmap->player[i].existanceAtBeginOfTurn ) {
00357 int to = 0;
00358 for ( int j = 0; j < 8; j++ )
00359 if ( j != i )
00360 to |= 1 << j;
00361
00362
00363 if ( !actmap->campaign.avail ) {
00364 char txt[1000];
00365 const char* sp = getmessage( 10010 );
00366
00367 sprintf ( txt, sp, actmap->player[i].getName().c_str() );
00368 new Message ( txt, actmap, to );
00369 }
00370
00371 actmap->player[i].existanceAtBeginOfTurn = false;
00372
00373 if ( i == actmap->actplayer ) {
00374 if ( actmap->getPlayerView() == i && actmap->getPlayer(i).stat == Player::human )
00375 displaymessage ( getmessage ( 10011 ),1 );
00376
00377 int humannum=0;
00378 for ( int j = 0; j < 8; j++ )
00379 if (actmap->player[j].exist() && actmap->player[j].stat == Player::human )
00380 humannum++;
00381
00382 if ( hasTurnControl ) {
00383 if ( humannum )
00384 next_turn();
00385 else {
00386 delete actmap;
00387 actmap = NULL;
00388 throw NoMapLoaded();
00389 }
00390 }
00391 }
00392 } else
00393 plnum++;
00394
00395 if ( plnum <= 1 ) {
00396 if ( actmap->player[actmap->actplayer].ai && actmap->player[actmap->actplayer].ai->isRunning() ) {
00397 displaymessage("You lost!",1);
00398 } else {
00399 displaymessage("Congratulations!\nYou won!",1);
00400 if (choice_dlg("Do you want to continue playing ?","~y~es","~n~o") == 2) {
00401 delete actmap;
00402 actmap = NULL;
00403 throw NoMapLoaded();
00404 } else {
00405 actmap->continueplaying = 1;
00406 if ( actmap->replayinfo ) {
00407 delete actmap->replayinfo;
00408 actmap->replayinfo = 0;
00409 }
00410 }
00411 }
00412 }
00413 }
00414 }
00415