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

resourcenet.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           resourcenet.cpp  -  description
00003                              -------------------
00004     begin                : Tue Jan 28 2001
00005     copyright            : (C) 2001 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00013 /***************************************************************************
00014  *                                                                         *
00015  *   This program is free software; you can redistribute it and/or modify  *
00016  *   it under the terms of the GNU General Public License as published by  *
00017  *   the Free Software Foundation; either version 2 of the License, or     *
00018  *   (at your option) any later version.                                   *
00019  *                                                                         *
00020  ***************************************************************************/
00021 
00022 #include "typen.h"
00023 #include "vehicletype.h"
00024 #include "buildingtype.h"
00025 #include "spfst.h"
00026 #include "resourcenet.h"
00027 #include "mapalgorithms.h"
00028 #include "dlg_box.h"
00029 #include "dialog.h"
00030 #include "cannedmessages.h"
00031 
00032 SigC::Signal0<void> tributeTransferred;
00033 
00034 void MapNetwork :: searchfield ( int x, int y, int dir )
00035 {
00036   int s;
00037 
00038    tfield* fld = actmap->getField ( x, y );
00039    if ( !fld )
00040       return;
00041 
00042    int arr[sidenum]; 
00043 
00044    do { 
00045 
00046       if ( fld->a.temp )
00047          return;
00048 
00049       #ifdef netdebug
00050       cursor.gotoxy ( a, b );
00051       displaymap();
00052       #endif
00053 
00054       if ( fld->building ) { 
00055          searchbuilding ( x, y );
00056          return;
00057       }
00058 
00059       fld->a.temp = 1;
00060 
00061       int d = fieldavail( x, y );
00062       if ( d <= 0 )
00063          return;
00064 
00065       searchvehicle ( x, y );
00066 
00067       int olddir = dir + sidenum/2; 
00068       while (olddir >= sidenum ) 
00069          olddir -= sidenum; 
00070 
00071          int r = 0; 
00072          for (s = 0; s < sidenum; s++) { 
00073             if ( (d & (1 << s))  &&  ( s != olddir )) {
00074                arr[ r ] = s; 
00075                r++;
00076             } 
00077          } 
00078 
00079 
00080          if (r > 1) {      // Kreuzungsstelle 
00081             for ( s = 0; s < r; s++) { 
00082                int nx = x;
00083                int ny = y;
00084                getnextfield ( nx, ny, arr[s] );
00085                searchfield( nx, ny, arr[s] );
00086                if ( searchfinished() )
00087                   return ;
00088             } 
00089             return;
00090          } else  
00091             if ( r == 1 ) {
00092                dir = arr[0];
00093                getnextfield ( x, y, dir );
00094                fld = actmap->getField( x, y ); 
00095                if ( !fld )
00096                   return;
00097             } else
00098                return;
00099    }  while ( 1 ); 
00100 
00101 }
00102 
00103 void MapNetwork :: searchvehicle ( int x, int y )
00104 {
00105    if ( pass == 2 ) {
00106       tfield* newfield = actmap->getField ( x, y );
00107       if ( newfield )
00108          if ( !newfield->a.temp2 )
00109            if ( newfield->vehicle ) {
00110               checkvehicle ( newfield->vehicle );
00111               newfield->a.temp2 = 1;
00112            }
00113    }
00114 }
00115 
00116 
00117 void MapNetwork :: searchbuilding ( int x, int y )
00118 {
00119    Building* bld = actmap->getField( x, y )->building;
00120    if ( !bld )
00121       return;
00122 
00123    tfield* entry = bld->getEntryField();
00124    if ( entry->a.temp )
00125       return;
00126 
00127    if ( pass == 1 )
00128       checkbuilding( bld );
00129 
00130    entry->a.temp = 1;
00131 
00132    if ( !searchfinished() ) 
00133       for( int i = 0; i < 4; i++ )
00134          for ( int j = 0; j < 6; j++ ) {
00135             MapCoordinate mc = bld->getFieldCoordinates ( BuildingType::LocalCoordinate(i, j) );
00136             tfield* fld2 = actmap->getField ( mc );
00137             if ( fld2 && fld2->building == bld )
00138                for ( int d = 0; d < sidenum; d++ ) {
00139                   int xp2 = mc.x;
00140                   int yp2 = mc.y;
00141                   getnextfield ( xp2, yp2, d );
00142                   tfield* newfield = actmap->getField ( xp2, yp2 );
00143                   if ( newfield && newfield->building != bld  && !newfield->a.temp )
00144                      searchfield ( xp2, yp2, d );
00145 
00146                   searchvehicle ( xp2, yp2 );
00147 
00148                } /* endfor */
00149          }
00150 }
00151 
00152 
00153 int MapNetwork :: instancesrunning = 0;
00154 
00155 MapNetwork :: MapNetwork ( GameMap* gamemap, int checkInstances ) : actmap ( gamemap )
00156 {
00157    if ( checkInstances ) {
00158       if ( instancesrunning )
00159          displaymessage(" fatal error at MapNetwork; there are other running instances ", 2 );
00160    } 
00161    // else displaymessage("warning: Mapnetwork instance check disabled !", 1 );
00162 // this could be resolved by using the different bits of field->a.temp 
00163 
00164    instancesrunning++;
00165    pass = 1;
00166 }
00167 
00168 
00169 MapNetwork :: ~MapNetwork ()
00170 { 
00171    instancesrunning--;
00172 }
00173 
00174 
00175 
00176 void MapNetwork :: searchAllVehiclesNextToBuildings ( int player )
00177 {
00178    pass++;
00179    for ( Player::VehicleList::iterator j = actmap->player[player].vehicleList.begin(); j != actmap->player[player].vehicleList.end(); j++ ) {
00180       MapCoordinate3D mc = (*j)->getPosition();
00181       for ( int s = 0; s < sidenum; s++ ) {
00182          tfield* fld = actmap->getField ( getNeighbouringFieldCoordinate ( mc, s ));
00183          if ( fld ) {
00184             Building* bld = fld->building;
00185             if ( bld && bld->color == (*j)->color ) {
00186                tfield* fld2 = actmap->getField( (*j)->getPosition());
00187                if ( !fld2->a.temp2 ) {
00188                   fld2->a.temp2 = 1;
00189                   checkvehicle ( *j );
00190                }
00191             }
00192          }
00193       }
00194    }
00195 }
00196 
00197 void MapNetwork :: start ( int x, int y )
00198 {
00199    if ( globalsearch() == 2 ) {
00200       for ( int i = 0; i < 8; i++ )
00201          if ( actmap->player[i].exist() ) {
00202 
00203             for ( Player::BuildingList::iterator j = actmap->player[i].buildingList.begin(); j != actmap->player[i].buildingList.end(); j++ )
00204                checkbuilding(*j);
00205 
00206             // if ( !searchfinished() )
00207             actmap->cleartemps(7);
00208             searchAllVehiclesNextToBuildings ( i );
00209             actmap->cleartemps(7);
00210 
00211          }
00212    } else 
00213       if ( globalsearch() == 1 ) {
00214          actmap->cleartemps(7);
00215          startposition.x = x;
00216          startposition.y = y;
00217          searchfield ( x, y, -1 );
00218          actmap->cleartemps(7);
00219          if ( !searchfinished() ) {
00220             pass++;
00221             startposition.x = x;
00222             startposition.y = y;
00223             searchfield ( x, y, -1 );
00224             actmap->cleartemps(7);
00225          }
00226       } else  
00227          if ( globalsearch() == 0 ) {
00228             tfield* fld = actmap->getField ( x, y );
00229             if ( fld ) {
00230                if ( fld->building ) {
00231                   if ( pass == 1 )
00232                      checkbuilding( fld->building );
00233                } else
00234                   if ( fld->vehicle )
00235 
00236                      if ( pass == 2 )
00237                         checkvehicle ( fld->vehicle );
00238             }
00239          }
00240 }
00241 
00242 
00243 
00244 int ResourceNet :: fieldavail ( int x, int y )
00245 {
00246     tfield* fld = actmap->getField ( x, y );
00247 /*    Object* o = fld->checkforobject ( pipelineobject ) ; 
00248     if ( o )
00249        return o->dir;
00250     else */
00251 
00252     if ( fld ) {
00253        TerrainBits tb = getTerrainBitType(cbpipeline);
00254        assert( resourcetype >= 0 );
00255        
00256        if ( resourcetype == 0)
00257          tb |= getTerrainBitType(cbpowerline);
00258 
00259        if ( (fld->bdt & tb).any() ) {
00260           int d = 0;
00261           for ( int i = 0; i < sidenum; i++ ) {
00262              int xp = x;
00263              int yp = y;
00264              getnextfield ( xp, yp , i );
00265              tfield* fld2 = actmap->getField ( xp, yp );
00266              if ( fld2 )
00267                 if ( (fld2->bdt & tb).any() ||  fld2->building )
00268                    d |= ( 1 << i );
00269           }
00270           return d;
00271 
00272        } else
00273           return 0;
00274     }
00275     return 0;
00276 
00277 }
00278 
00279 
00280 int StaticResourceNet :: getresource ( int x, int y, int resource, int _need, int _queryonly, int _player, int _scope )
00281 {
00282    if ( actmap->isResourceGlobal ( resource ))
00283       scope = 3;
00284    else
00285       scope = _scope;
00286 
00287    player = _player;
00288    resourcetype = resource;
00289    got = 0;
00290    need = _need;
00291    queryonly = _queryonly;
00292 
00293    if (scope == 3 && player == 8 )     // neutral player has no map-wide pool
00294       scope = 0;
00295 
00296    start ( x , y );
00297    return got;
00298 }
00299 
00300 
00301 int StaticResourceNet :: searchfinished ( void )
00302 {
00303    return got >= need;
00304 }
00305 
00306 
00307 
00308 
00309 
00310 GetResource :: GetResource ( GameMap* gamemap, int scope )
00311              : StaticResourceNet ( gamemap, scope )
00312 {
00313    memset ( tributegot, 0, sizeof ( tributegot ));
00314 }
00315 
00316 
00317 void GetResource :: checkvehicle ( Vehicle* v )
00318 {
00319    if ( v->color/8 == player && resourcetype == 0 )
00320       got += v->getResource( need-got, Resources::Energy, queryonly, 1, player );
00321 }
00322 
00323 
00324 void GetResource :: checkbuilding ( Building* b )
00325 {
00326    if ( b->color/8 == player ) {
00327       if ((b->netcontrol & (cnet_stopenergyoutput << resourcetype)) == 0) {
00328          int toget = need-got;
00329          if ( b->actstorage.resource( resourcetype ) < 0 ) {
00330             displaymessage("map corruption detected; building %s storage for %d/%d is negative!",1,resourceNames[resourcetype],b->getEntry().x, b->getEntry().y );
00331             b->actstorage.resource( resourcetype ) = 0;
00332          }
00333 
00334 
00335          if ( b->actstorage.resource( resourcetype ) < toget )
00336             toget = b->actstorage.resource( resourcetype );
00337 
00338          if ( !queryonly )
00339             b->actstorage.resource( resourcetype ) -= toget;
00340          got += toget;
00341       }
00342    } else
00343       if ( b->color/8 < 8 ) { // no neutral buildings
00344 
00345          // Codeguard reports "Pointer arithmetic in invalid memory". Whats wrong here ?
00346          // Resources tttt = actmap->tribute.avail[ b->color / 8 ][ player ];
00347          int gettable = actmap->tribute.avail[ b->color / 8 ][ player ].resource(resourcetype) - tributegot[ resourcetype ][ b->color / 8];
00348          if ( gettable > 0 ) {
00349             int toget = need-got;
00350             if ( toget > gettable )
00351                toget = gettable;
00352 
00353             // int found = b->getResource( toget, resourcetype, queryonly );
00354             int found = b->actstorage.resource(resourcetype);
00355             if ( toget < found )
00356                found = toget;
00357 
00358             if ( !queryonly )
00359                b->actstorage.resource(resourcetype) -= found;
00360 
00361             tributegot[ resourcetype ][ b->color / 8] += found;
00362 
00363             if ( !queryonly ) {
00364                actmap->tribute.avail[ b->color / 8 ][ player ].resource( resourcetype ) -= found;
00365                actmap->tribute.paid [ player ][ b->color / 8 ].resource( resourcetype ) += found;
00366                if ( found )
00367                   tributeTransferred();
00368             }
00369 
00370             got += found;
00371          }
00372       }
00373 }
00374 
00375 void GetResource :: start ( int x, int y )
00376 {
00377    if ( scope == 3 ) {
00378       got = need;
00379       if ( got > actmap->bi_resource[player].resource( resourcetype ) )
00380          got = actmap->bi_resource[player].resource( resourcetype );
00381 
00382       if ( !queryonly )
00383          actmap->bi_resource[player].resource( resourcetype ) -= got;
00384 
00385       if ( resourcetype == 0 )
00386          searchAllVehiclesNextToBuildings ( player );
00387 
00388    } else
00389       MapNetwork :: start ( x, y );
00390 }
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 void PutResource :: checkbuilding ( Building* b )
00400 {
00401    if ( b->color/8 == player ) {
00402       if ((b->netcontrol & (cnet_stopenergyinput << resourcetype)) == 0) {
00403          int tostore = need-got;
00404 
00405          if ( b->actstorage.resource( resourcetype ) < 0 ) {
00406             displaymessage("map corruption detected; building %s storage for %d/%d is negative!",1,resourceNames[resourcetype],b->getEntry().x, b->getEntry().y );
00407             b->actstorage.resource( resourcetype ) = 0;
00408          }
00409          
00410          if ( b->getStorageCapacity().resource( resourcetype ) - b->actstorage.resource( resourcetype ) < tostore )
00411             tostore = b->getStorageCapacity().resource( resourcetype ) - b->actstorage.resource( resourcetype );
00412       
00413          if ( !queryonly )
00414             b->actstorage.resource( resourcetype ) += tostore;
00415          got += tostore;
00416       }
00417    }
00418 }
00419 
00420 
00421 void PutResource :: start ( int x, int y )
00422 {
00423    if ( scope == 3 ) {
00424 
00425       got = need;
00426       if ( got > maxint - actmap->bi_resource[player].resource( resourcetype ) )
00427          got = maxint - actmap->bi_resource[player].resource( resourcetype );
00428 
00429       if ( !queryonly )
00430          actmap->bi_resource[player].resource( resourcetype ) += got;
00431 
00432    } else
00433       MapNetwork :: start ( x, y );
00434 }
00435 
00436 
00437 
00438 
00439 
00440 void PutTribute :: checkbuilding ( Building* b )
00441 {
00442    if ( b->color/8 == targplayer ) {
00443       if ((b->netcontrol & (cnet_stopenergyinput << resourcetype)) == 0) {
00444          int tostore = need-got;
00445          if ( b->getStorageCapacity().resource( resourcetype ) - b->actstorage.resource( resourcetype ) < tostore )
00446             tostore = b->getStorageCapacity().resource( resourcetype ) - b->actstorage.resource( resourcetype );
00447       
00448          if ( !queryonly ) {
00449             b->actstorage.resource( resourcetype ) += tostore;
00450             actmap->tribute.avail[ player ][ targplayer ].resource( resourcetype ) -= tostore;
00451             actmap->tribute.paid [ targplayer ][ player ].resource( resourcetype ) += tostore;
00452          }
00453          got += tostore;
00454       }
00455    }
00456 }
00457 
00458 
00459 void PutTribute :: start ( int x, int y )
00460 {
00461    int pl = targplayer;
00462    if ( pl == -1 )
00463       targplayer = 0;
00464 
00465    do {
00466       if ( targplayer != player )
00467          if ( actmap->player[targplayer].exist() ) {
00468             need = actmap->tribute.avail[ player ][ targplayer ].resource( resourcetype );
00469             if ( need > 0 ) {
00470                if ( scope == 3 ) {
00471 
00472                   got = need;
00473                   if ( got > maxint - actmap->bi_resource[targplayer].resource( resourcetype ) )
00474                      got = maxint - actmap->bi_resource[targplayer].resource( resourcetype );
00475 
00476                   if ( got > actmap->bi_resource[player].resource( resourcetype ) )
00477                      got = actmap->bi_resource[player].resource( resourcetype );
00478 
00479                   if ( !queryonly ) {
00480                      actmap->bi_resource[targplayer].resource( resourcetype ) += got;
00481                      actmap->bi_resource[player].resource( resourcetype ) -= got;
00482 
00483                      actmap->tribute.avail[ player ][ targplayer ].resource( resourcetype ) -= got;
00484                      actmap->tribute.paid [ targplayer ][ player ].resource( resourcetype ) += got;
00485                   }
00486 
00487                } else {
00488                   int avail = startbuilding->getResource ( need, resourcetype, 1, 0 );
00489                   if ( need > avail )
00490                      need = avail;
00491                   MapNetwork :: start ( x, y );
00492                   if ( !queryonly ) {
00493                      startbuilding->getResource ( got, resourcetype, queryonly, 0, startbuilding->getOwner() ); 
00494                      // printf(" building at %d/%d had %d, pushed %d\n", x, y, avail, got );
00495                   }
00496 
00497                }
00498             }
00499          }
00500       targplayer++;
00501    } while ( targplayer < 8  && pl == -1 );
00502 }
00503 
00504 int PutTribute :: puttribute ( Building* start, int resource, int _queryonly, int _forplayer, int _fromplayer, int _scope )
00505 {
00506    startbuilding = start;
00507    targplayer = _forplayer;
00508    return getresource ( startbuilding->getEntry().x, startbuilding->getEntry().y, resource, 0, _queryonly, _fromplayer, _scope );
00509 }
00510 
00511 
00512 void transfer_all_outstanding_tribute ( Player& player )
00513 {
00514 
00515    int targplayer = player.getPosition();
00516    GameMap* actmap = player.getParentMap();
00517    
00518    if ( actmap->player[targplayer].exist() ) {
00519       ASCString text;
00520 
00521       for ( int player = 0; player < 8; player++ ) {
00522          if ( targplayer != player )
00523             if ( actmap->player[player].exist() ) {
00524                int topay[3];
00525                int got[3];
00526                for ( int resourcetype = 0; resourcetype < 3; resourcetype++ ) {
00527                   got[ resourcetype ] = actmap->tribute.paid[ targplayer ][ player ].resource( resourcetype ) - actmap->tribute.payStatusLastTurn[ targplayer ][ player ].resource( resourcetype );
00528                   topay[ resourcetype ] = actmap->tribute.avail[ player ][ targplayer ].resource( resourcetype ) + got[ resourcetype ];
00529 
00530                   if ( !actmap->isResourceGlobal (resourcetype) ) {
00531                      for ( Player::BuildingList::iterator j = actmap->player[player].buildingList.begin(); j != actmap->player[player].buildingList.end() &&  topay[resourcetype] > got[resourcetype] ; j++ ) {
00532                         PutTribute pt ( actmap );
00533                         got[resourcetype] += pt.puttribute ( *j, resourcetype, 0, targplayer, player, 1 );
00534                      }
00535                   } else {
00536                      int i;
00537                      if ( actmap->bi_resource[ player ].resource(resourcetype) < topay[resourcetype] )
00538                         i = actmap->bi_resource[ player ].resource(resourcetype);
00539                      else
00540                         i = topay[resourcetype];
00541                      got [resourcetype ] += i;
00542                      actmap->bi_resource[ player ].resource(resourcetype) -= i;
00543                      actmap->bi_resource[ targplayer ].resource(resourcetype) += i;
00544 
00545                      actmap->tribute.avail[ player ][ targplayer ].resource( resourcetype ) -= got[resourcetype];
00546                      actmap->tribute.paid[ targplayer ][ player ].resource( resourcetype ) += got[resourcetype];
00547                   }
00548                }
00549                actmap->tribute.payStatusLastTurn[ targplayer ][ player ] = actmap->tribute.paid[ targplayer ][ player ];
00550                if ( topay[0] || topay[1] || topay[2] || got[0] || got[1] || got[2]) {
00551                   Resources tp ( topay[0], topay[1], topay[2] );
00552                   Resources gt ( got[0],   got[1],   got[2]   );
00553 
00554                   ASCString topayStr = tp.toString();
00555 
00556                   ASCString gotStr;
00557                   if ( gt == tp )
00558                      gotStr = "all";
00559                   else {
00560                      gotStr = gt.toString();
00561                      if ( gotStr.empty() )
00562                         gotStr = "nothing";
00563                   }
00564 
00565                   ASCString msg;
00566                   msg.format ( getmessage( 10020 ) , actmap->player[player].getName().c_str(), topayStr.c_str(), gotStr.c_str() );
00567 
00568                   text += msg;
00569 
00570 
00571                   // next message, this time for the providing player
00572 
00573                   if ( got[0] || got[1] || got[2] ) {
00574                      msg = "";
00575                      gotStr = gt.toString();
00576                      msg.format ( getmessage( 10021 ) , gotStr.c_str(), actmap->player[targplayer].getName().c_str());
00577                      new Message ( msg, actmap, 1 << player );
00578                   }
00579 
00580 
00581                }
00582 
00583                if ( got[0] || got[1] || got[2] )
00584                  tributeTransferred();
00585 
00586             }
00587       }
00588       if ( !text.empty() )
00589          new Message ( text, actmap, 1 << targplayer );
00590 
00591    }
00592 }
00593 
00594 
00595 void GetResourceCapacity :: checkbuilding ( Building* b )
00596 {
00597    if ( b->color/8 == player ) {
00598       if ((b->netcontrol & (cnet_stopenergyinput << resourcetype)) == 0) {
00599          int t = b->getStorageCapacity().resource( resourcetype );
00600          if ( t > maxint - got )
00601             got = maxint;
00602          else
00603             got += t;
00604       }
00605    }
00606 }
00607 
00608 
00609 void GetResourceCapacity :: start ( int x, int y )
00610 {
00611    if ( scope == 3 ) {
00612       got = maxint;
00613    } else
00614       MapNetwork :: start ( x, y );
00615 }
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 int ResourceChangeNet :: getresource ( int x, int y, int resource, int _player, int _scope )
00627 {
00628    if ( (_scope > 0)  &&  (actmap->isResourceGlobal ( resource )) )
00629       scope = 2;
00630    else
00631       scope = _scope;
00632 
00633    player = _player;
00634    resourcetype = resource;
00635    got = 0;
00636    start ( x , y );
00637    return got;
00638 }
00639 
00640 
00641 
00642 
00643 void GetResourcePlus :: checkvehicle ( Vehicle* v )
00644 {/*
00645    if ( resourcetype == 0 )
00646       if ( v->getGeneratorStatus() )
00647          got += v->typ->tank.energy;
00648          */
00649 }
00650 
00651 
00652 void GetResourcePlus :: checkbuilding ( Building* bld )
00653 {
00654    if ( bld->color/8 == player )
00655       got += bld->getResourcePlus().resource( resourcetype );
00656 }
00657 
00658 
00659 
00660 
00661 
00662 void GetResourceUsage :: checkbuilding ( Building* b )
00663 {
00664    if ( b->color/8 == player ) 
00665       got += b->getResourceUsage().resource( resourcetype );
00666 }
00667 
00668 
00669 
00670 bool compareMapResources( GameMap* currentMap, GameMap* replaymap, int player, ASCString* log )
00671 {
00672    ASCString s;
00673    bool diff  = false;
00674    for ( int r = 0; r < 3; ++r ) {
00675       if ( currentMap->isResourceGlobal( r )) {
00676          if ( currentMap->bi_resource[player].resource(r) != replaymap->bi_resource[player].resource(r) ) {
00677             diff = true;
00678             if ( log ) {
00679                s.format ( "Global resource mismatch: %d %s available after replay, but %d available in actual map\n", replaymap-> bi_resource[player].resource(r), resourceNames[r], currentMap->bi_resource[player].resource(r) );
00680                *log += s;
00681             }
00682          }
00683       } else {
00684          GetConnectedBuildings::BuildingContainer cb;
00685          for ( Player::BuildingList::iterator b = currentMap->player[player].buildingList.begin(); b != currentMap->player[player].buildingList.end(); ++b ) {
00686             Building* b1 = *b;
00687             ContainerBase* b2 = replaymap->getContainer( b1->getIdentification() );
00688             if ( !b1 || !b2 ) {
00689                if ( log ) {
00690                   s.format ( "Building missing! \n");
00691                   *log += s;
00692                }
00693             } else {
00694                if ( find ( cb.begin(), cb.end(), b1 ) == cb.end()) {
00695                   int ab1 = b1->getResource( maxint, r, true, 1, player );
00696                   int ab2 = b2->getResource( maxint, r, true, 1, player);
00697                   if ( ab1 != ab2 ) {
00698                      diff = true;
00699                      if ( log ) {
00700                         s.format ( "Building (%d,%d) resource mismatch: %d %s available after replay, but %d available in actual map\n", b1->getPosition().x, b1->getPosition().y, ab1, resourceNames[r], ab2 );
00701                         *log += s;
00702                      }
00703                   }
00704                   cb.push_back ( b1 );
00705                   GetConnectedBuildings::BuildingContainer cbl;
00706                   GetConnectedBuildings gcb ( cbl, b1->getMap(), r );
00707                   gcb.start ( b1->getPosition().x, b1->getPosition().y );
00708                   cb.insert ( cb.end(), cbl.begin(), cbl.end() );
00709                }
00710             }
00711          }
00712       }
00713       for ( Player::VehicleList::iterator v = currentMap->player[player].vehicleList.begin(); v != currentMap->player[player].vehicleList.end(); ++v ) {
00714          Vehicle* v1 = *v;
00715          Vehicle* v2 = replaymap->getUnit( v1->networkid );
00716          if ( !v1 || !v2 ) {
00717             if ( log ) {
00718                s.format ( "Vehicle missing! \n");
00719                *log += s;
00720             }
00721          } else {
00722             if ( v1->typ != v2->typ ) {
00723                diff = true;
00724                if ( log ) {
00725                   s.format ( "Vehicles with NWID %d don't have matching type, probably production inconsistency. (%s <-> %s)\n", v1->networkid, v1->typ->getName().c_str(), v2->typ->getName().c_str() );
00726                   *log += s;
00727                }
00728             } else {
00729                int av1 = v1->getResource( maxint, r, true, 1, player );
00730                int av2 = v2->getResource( maxint, r, true, 1, player );
00731                if ( av1 != av2 ) {
00732                   diff = true;
00733                   if ( log ) {
00734                      s.format ( "Vehicle %s (%d,%d) resource mismatch: %d %s available after replay, but %d available in actual map\n", v1->typ->getName().c_str(), v1->getPosition().x, v1->getPosition().y, av2, resourceNames[r], av1 );
00735                      *log += s;
00736                   }
00737                }
00738                
00739                if ( v1->damage != v2->damage ) {
00740                   diff = true;
00741                   if ( log ) {
00742                      s.format ( "Vehicle (%d,%d) damage mismatch: %d after replay, but %d in actual map\n", v1->getPosition().x, v1->getPosition().y, v2->damage, v1->damage );
00743                      *log += s;
00744                   }
00745                }
00746             }
00747          }
00748       }
00749 
00750    }
00751    if ( currentMap->player[player].vehicleList.size() != replaymap->player[player].vehicleList.size() ) {
00752       diff = true;
00753       if ( log ) {
00754          s.format ( "The number of units differ. Replay: %d ; actual map: %d", replaymap->player[player].vehicleList.size(), currentMap->player[player].vehicleList.size());
00755          *log += s;
00756 
00757          GameMap* more;
00758          GameMap* less;
00759          if ( currentMap->player[player].vehicleList.size() > replaymap->player[player].vehicleList.size() ) {
00760             more = currentMap;
00761             less = replaymap;
00762          } else {
00763             more = replaymap;
00764             less = currentMap;
00765          }
00766 
00767          for ( Player::VehicleList::iterator i = more->player[player].vehicleList.begin(); i != more->player[player].vehicleList.end(); ++i )
00768             if ( !less->getUnit( (*i)->networkid )) {
00769                s.format( "Type: %s at %d/%d\n", (*i)->getName().c_str(), (*i)->getPosition().x, (*i)->getPosition().y );
00770                *log += s;
00771             }
00772       }
00773    }
00774 
00775    if ( currentMap->player[player].buildingList.size() != replaymap->player[player].buildingList.size() ) {
00776       diff = true;
00777       if ( log ) {
00778          s.format ( "The number of buildings differ. Replay: %d ; actual map: %d", replaymap->player[player].buildingList.size(), currentMap->player[player].buildingList.size());
00779          *log += s;
00780       }
00781    }
00782 
00783    if ( currentMap->player[player].research.progress != replaymap->player[player].research.progress ) {
00784       diff = true;
00785       if ( log ) {
00786          s.format ( "Research points mismatch! Replay: %d ; actual map: %d", replaymap->player[player].research.progress, currentMap->player[player].research.progress);
00787          *log += s;
00788       }
00789    }
00790 
00791    sort ( currentMap->player[player].research.developedTechnologies.begin(), currentMap->player[player].research.developedTechnologies.end() );
00792    sort ( replaymap->player[player].research.developedTechnologies.begin(), replaymap->player[player].research.developedTechnologies.end() );
00793    if ( replaymap->player[player].research.developedTechnologies.size() != currentMap->player[player].research.developedTechnologies.size() ) {
00794       diff = true;
00795       if ( log ) {
00796          s.format ( "Number of developed technologies differ !\n" );
00797          *log += s;
00798       }
00799    } else {
00800       for ( int i = 0; i < replaymap->player[player].research.developedTechnologies.size(); ++i )
00801          if ( replaymap->player[player].research.developedTechnologies[i] != currentMap->player[player].research.developedTechnologies[i] ) {
00802          diff = true;
00803          if ( log ) {
00804             s.format ( "Different technologies developed !\n" );
00805             *log += s;
00806          }
00807          }
00808    }
00809 
00810    for ( Player::BuildingList::iterator b = currentMap->player[player].buildingList.begin(); b != currentMap->player[player].buildingList.end(); ++b ) {
00811       Building* b1 = *b;
00812       Building* b2 = dynamic_cast<Building*>(replaymap->getContainer( b1->getIdentification() ));
00813       if ( !b1 || !b2 ) {
00814          if ( log ) {
00815             s.format ( "Building missing! \n");
00816             *log += s;
00817          }
00818       } else {
00819          bool mismatch = false;
00820          for ( int i = 0; i < b1->getProduction().size(); ++i )
00821             if ( b1->getProduction()[i] ) {
00822                bool found = false;
00823                for ( int j = 0; j < b2->getProduction().size(); ++j)
00824                   if ( b2->getProduction()[j] == b1->getProduction()[i] )
00825                      found = true;
00826                if ( !found)
00827                   mismatch = true;
00828             }
00829 
00830             for ( int j = 0; j < b2->getProduction().size(); ++j )
00831                if ( b2->getProduction()[j] ) {
00832                   bool found = false;
00833                   for ( int i = 0; i < b1->getProduction().size(); ++i)
00834                      if ( b1->getProduction()[i] == b2->getProduction()[j] )
00835                         found = true;
00836                   if ( !found)
00837                      mismatch = true;
00838                }
00839 
00840                if ( mismatch ) {
00841                   diff = true;
00842                   if ( log ) {
00843                      s.format ( "Building (%d,%d) production line mismatch !\n", b1->getPosition().x, b1->getPosition().y );
00844                      *log += s;
00845                   }
00846                }
00847       }
00848    }
00849 
00850    return diff;
00851 }
00852 

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