Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

turncontrol.cpp

Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00009     Copyright (C) 1994-2005  Martin Bickel  and  Marc Schellenberger
00010 
00011     This program is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     This program is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU General Public License for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with this program; see the file COPYING. If not, write to the 
00023     Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00024     Boston, MA  02111-1307  USA
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       // bool askForPassword = false;
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 );  // the idle handler of enterpassword starts generating the overview map, so we need to have the correct view prior to enterpassword
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 ); /* enddo */
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 ); /* enddo */
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 ); // Message "player has been terminated"
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 

Generated on Tue Jun 24 01:27:53 2008 for Advanced Strategic Command by  doxygen 1.4.2