gamemap.cpp

Go to the documentation of this file.
00001 
00005 /***************************************************************************
00006                           gamemap.cpp  -  description
00007                              -------------------
00008     begin                : Tue Oct 24 2000
00009     copyright            : (C) 2000 by Martin Bickel
00010     email                : bickel@asc-hq.org
00011  ***************************************************************************/
00012 
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 <algorithm>
00023 #include <ctime>
00024 #include <cmath>
00025 
00026 #include "global.h"
00027 #include "misc.h"
00028 #include "typen.h"
00029 #include "vehicletype.h"
00030 #include "buildingtype.h"
00031 #include "gamemap.h"
00032 #include "dialog.h"
00033 #include "itemrepository.h"
00034 #include "strtmesg.h"
00035 // #include "graphics/blitter.h"
00036 #include "overviewmapimage.h"
00037 #include "gameeventsystem.h"
00038 #include "spfst.h"
00039 #include "campaignactionrecorder.h"
00040 
00041 #include "packagemanager.h"
00042 #include "tasks/abstracttaskcontainer.h"
00043 
00044 
00045 RandomGenerator::RandomGenerator(int seedValue){
00046 
00047 }
00048 
00049 RandomGenerator::~RandomGenerator(){
00050 
00051 
00052 }
00053 
00054 unsigned int RandomGenerator::getPercentage(){
00055   return getRandomValue(100);
00056 }
00057 
00058 unsigned int RandomGenerator::getRandomValue(int limit) {
00059   return getRandomValue(0, limit); 
00060 }
00061 
00062 unsigned int RandomGenerator::getRandomValue (int lowerLimit, int upperLimit){
00063    if(upperLimit == 0) {
00064         return 1;
00065    }
00066    int random_integer = rand();
00067    random_integer = random_integer % upperLimit;
00068    return (lowerLimit + random_integer);
00069 }
00070 
00071 
00072 
00073 
00074 OverviewMapHolder :: OverviewMapHolder( GameMap& gamemap ) : map(gamemap), initialized(false), secondMapReady(false), completed(false), connected(false), x(0),y(0)
00075 {
00076 }
00077 
00078 void OverviewMapHolder :: connect()
00079 {
00080    if ( !connected ) {
00081       idleEvent.connect ( SigC::slot( *this, &OverviewMapHolder::idleHandler ));
00082       connected = true;
00083    }
00084 }
00085 
00086 
00087 SigC::Signal0<void> OverviewMapHolder::generationComplete;
00088 
00089 bool OverviewMapHolder :: idleHandler( )
00090 {
00091    int t = ticker;
00092    while ( !completed && (t + 5 > ticker ))
00093       drawNextField( true );
00094    return true;
00095 }
00096 
00097 
00098 bool OverviewMapHolder::updateField( const MapCoordinate& pos )
00099 {
00100    SPoint imgpos = OverviewMapImage::map2surface( pos );
00101 
00102    MapField* fld = map.getField( pos );
00103    VisibilityStates visi = fieldVisibility( fld, map.getPlayerView() );
00104    if ( visi == visible_not ) {
00105       OverviewMapImage::fill ( overviewMapImage, imgpos, 0xff545454 );
00106    } else {
00107       if ( fld->building && fieldvisiblenow( fld, map.getPlayerView()) )
00108          OverviewMapImage::fill ( overviewMapImage, imgpos, map.player[fld->building->getOwner()].getColor() );
00109       else {
00110 
00111          int w = fld->getWeather();
00112          fld->typ->getQuickView()->blit( overviewMapImage, imgpos );
00113          for ( MapField::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); ++i )
00114             if ( visi > visible_ago || i->typ->visibleago )
00115                i->getOverviewMapImage( w )->blit( overviewMapImage, imgpos );
00116 
00117          if ( fld->vehicle && fieldvisiblenow( fld, map.getPlayerView()) )
00118             OverviewMapImage::fillCenter ( overviewMapImage, imgpos, map.player[fld->vehicle->getOwner()].getColor() );
00119 
00120          if ( visi == visible_ago )
00121             OverviewMapImage::lighten( overviewMapImage, imgpos, 0.7 ); 
00122 
00123       }
00124 
00125    }
00126    return true;
00127 }
00128 
00129 void OverviewMapHolder::drawNextField( bool signalOnCompletion )
00130 {
00131    if ( !init() )
00132       return;
00133       
00134    if ( x == map.xsize ) {
00135       x = 0;
00136       ++y;
00137    }   
00138    if ( y < map.ysize ) {
00139       if ( !updateField( MapCoordinate(x,y)))
00140          return;
00141       
00142       ++x;
00143    }
00144    if ( y == map.ysize ) {
00145       completed = true;
00146       if ( signalOnCompletion )
00147          generationComplete();
00148 
00149       completedMapImage = overviewMapImage.Duplicate();
00150       secondMapReady = true;
00151    }
00152 }
00153 
00154 Surface OverviewMapHolder::createNewSurface()
00155 {
00156    Surface s;
00157    if ( map.xsize > 0 && map.ysize > 0 ) {
00158       s =  Surface::createSurface( (map.xsize+1) * 6, 4 + map.ysize * 2 , 32, 0 );
00159    }
00160    return s;
00161 }
00162 
00163 bool OverviewMapHolder::init()
00164 {
00165    if ( map.ysize <= 0 || map.xsize <= 0 )
00166       return false;
00167 
00168    if ( !initialized ) {
00169       overviewMapImage = createNewSurface();
00170       initialized = true;
00171    }
00172    return initialized;
00173 }   
00174 
00175 void OverviewMapHolder::resetSize()
00176 {
00177    initialized = false;
00178 }
00179 
00180 
00181 const Surface& OverviewMapHolder::getOverviewMap( bool complete )
00182 {
00183    bool initialized = init();
00184    assert( initialized );
00185    if ( complete )
00186       while ( !completed )
00187          drawNextField( false );
00188 
00189    if(  secondMapReady )
00190       return completedMapImage;
00191    else
00192       return overviewMapImage;
00193 }
00194 
00195 void OverviewMapHolder::startUpdate()
00196 {
00197    completed = false;
00198    x = 0;
00199    y = 0;
00200 }
00201 
00202 void OverviewMapHolder::clear(bool allImages )
00203 {
00204    if ( !initialized )
00205       return;
00206    
00207    overviewMapImage.Fill( Surface::transparent );
00208    if ( allImages ) {
00209       if ( completedMapImage.valid() )
00210          completedMapImage.Fill( Surface::transparent );
00211       secondMapReady = false;
00212    }
00213 
00214    startUpdate();
00215 }
00216 
00217 void OverviewMapHolder::clearmap( GameMap* actmap )
00218 {
00219    if ( actmap )
00220       actmap->overviewMapHolder.clear();
00221 }
00222 
00223 
00224 GameMap :: GameMap ( void )
00225    : actions(this), actionRecorder(NULL), overviewMapHolder( *this ), network(NULL), packageData(NULL)
00226 {
00227    serverMapID = 0;
00228    randomSeed = rand();
00229    dialogsHooked = false;
00230 
00231    eventID = 0;
00232 
00233    state = Normal;
00234 
00235    xsize = 0;
00236    ysize = 0;
00237    field = NULL;
00238 
00239    actplayer = -1;
00240    time.abstime = 0;
00241 
00242    _resourcemode = 0;
00243 
00244    for ( int i = 0; i < 9; ++i ) {
00245       player[i].setParentMap ( this, i );
00246       if ( i == 0 )
00247          player[i].stat = Player::human;
00248       else
00249          player[i].stat = Player::computer;
00250       
00251       player[i].research.chainToMap ( this, i );
00252    }
00253           
00254    levelfinished = 0;
00255 
00256    messageid = 0;
00257 
00258    continueplaying = false;
00259    replayinfo = NULL;
00260    playerView = 0;
00261    lastjournalchange.abstime = 0;
00262    graphicset = 0;
00263    gameparameter_num = 0;
00264    game_parameter = NULL;
00265    mineralResourcesDisplayed = 0;
00266 
00267 
00268 #ifdef WEATHERGENERATOR
00269    weatherSystem  = new WeatherSystem(this, 1, 0.03);
00270 #endif
00271    setgameparameter( cgp_objectsDestroyedByTerrain, 1 );
00272    
00273    
00274    nativeMessageLanguage = "en_US";
00275    
00276    sigMapCreation( *this );
00277 }
00278 
00279 GameMap::Campaign::Campaign()
00280 {
00281    avail = false;
00282    id = 0;
00283    directaccess = true;
00284 }
00285 
00286 void GameMap :: guiHooked()
00287 {
00288    overviewMapHolder.connect();
00289    dialogsHooked = true;
00290 }
00291 
00292 const int tmapversion = 34;
00293 
00294 void GameMap :: read ( tnstream& stream )
00295 {
00296    int version;
00297 
00298    xsize = stream.readWord();
00299    ysize = stream.readWord();
00300 
00301    if ( xsize == 0xfffe  && ysize == 0xfffc ) {
00302      version = stream.readInt();
00303      if ( version > tmapversion )
00304         throw tinvalidversion ( "GameMap", tmapversion, version );
00305 
00306      xsize = stream.readInt();
00307      ysize = stream.readInt();
00308    } else
00309       version = 1;
00310 
00311    stream.readWord(); // xpos
00312    stream.readWord(); // ypos
00313    stream.readInt(); // dummy
00314    field = NULL;
00315 
00316    if ( version <= 13 ) {
00317       char buf[11]; 
00318       stream.readdata ( buf, 11 );
00319       buf[10] = 0;
00320       codeWord = buf;
00321    } else {
00322       codeWord = stream.readString();
00323    }
00324 
00325    if ( version < 2 )
00326       ___loadtitle = stream.readInt();
00327    else
00328       ___loadtitle = true;
00329 
00330    
00331    bool loadCampaign = stream.readInt();
00332    actplayer = stream.readChar();
00333    time.abstime = stream.readInt();   
00334    if(version < 9 || version >= 17){
00335      stream.readChar();
00336      weather.windSpeed = stream.readChar();
00337      weather.windDirection = stream.readChar();
00338    }
00339 
00340    if ( version >= 11 ) 
00341       if ( stream.readInt() != 0x12345678 )
00342          throw ASCmsgException("marker not matched when loading GameMap");
00343    
00344    if ( version >= 32 ) {
00345       int p = stream.readInt();
00346       if ( p ) {
00347          packageData = new PackageData();
00348          packageData->read( stream );
00349          
00350          PackageManager::checkGame( this );
00351          
00352       } else
00353          packageData = NULL;
00354    } else 
00355       packageData = NULL;
00356    
00357       
00358    for ( int j = 0; j < 4; j++ )
00359       stream.readChar(); // was: different wind in different altitudes
00360    for ( int i = 0; i< 12; i++ )
00361       stream.readChar(); // dummy
00362 
00363    _resourcemode = stream.readInt();
00364 
00365    int alliances[8][8];
00366    if ( version <= 10 )
00367       for ( int i = 0; i < 8; i++ )
00368          for ( int j = 0; j < 8; j++ )
00369             alliances[j][i] = stream.readChar();
00370 
00371    int dummy_playername[9];
00372    for ( int i = 0; i< 9; i++ ) {
00373       player[i].existanceAtBeginOfTurn = stream.readChar();
00374       stream.readInt(); // dummy
00375       stream.readInt(); // dummy
00376       if ( version <= 5 )
00377          player[i].research.read_struct ( stream );
00378       else
00379          player[i].research.read ( stream );
00380 
00381       // player[i].ai = (BaseAI*)
00382       stream.readInt() ;
00383       player[i].ai = NULL;
00384       player[i].stat = Player::PlayerStatus ( stream.readChar() );
00385       stream.readChar(); // dummy
00386       dummy_playername[i] = stream.readInt();
00387       player[i].passwordcrc.read ( stream );
00388       player[i].__dissectionsToLoad = stream.readInt();
00389       player[i].__loadunreadmessage = stream.readInt();
00390       player[i].__loadoldmessage = stream.readInt();
00391       player[i].__loadsentmessage = stream.readInt();
00392       if ( version >= 3 )
00393          player[i].ASCversion = stream.readInt();
00394       else
00395          player[i].ASCversion = 0;
00396          
00397       if ( version >= 9 )
00398          player[i].cursorPos.read( stream );
00399          
00400       if ( version >= 11 ) 
00401          player[i].diplomacy.read( stream );
00402       else {
00403          if ( i < 8 ) // no alliances for neutral 'player'
00404             for ( int j = 0; j< 8; ++j ) {
00405                if ( alliances[i][j] == 0 ) 
00406                   player[i].diplomacy.setState( j, PEACE ); 
00407                else
00408                   player[i].diplomacy.setState( j, WAR ); 
00409             }
00410       }
00411       
00412       if ( version >= 12 )
00413          player[i].email = stream.readString();
00414       
00415       if ( version >= 22 )
00416          player[i].read( stream );
00417    }
00418    
00419    if ( version >= 11 ) 
00420       if ( stream.readInt() != 0x12345678 )
00421          throw ASCmsgException("marker not matched when loading GameMap");
00422          
00423 
00424 
00425 
00426    if ( version <= 4 ) {
00428       loadOldEvents = stream.readInt();
00429       stream.readInt(); // int loadeventstocome
00430       stream.readInt(); // int loadeventpassed
00431    }
00432 
00433 
00434    idManager.readData(stream );
00435    
00436    levelfinished = stream.readChar();
00437    
00438    bool alliance_names_not_used_any_more[8];
00439    if ( version <= 9 ) {
00440       ___loadLegacyNetwork  = stream.readInt();
00441       for ( int i = 0; i < 8; i++ )
00442          alliance_names_not_used_any_more[i] = stream.readInt(); // dummy
00443    } else {
00444       ___loadLegacyNetwork = false;
00445       for ( int i = 0; i < 8; i++ )
00446          alliance_names_not_used_any_more[i] = 0;
00447    }
00448 
00449    if ( version <= 12 ) {
00450       for ( int i = 0; i< 8; i++ ) {
00451          stream.readWord(); // cursorpos.position[i].cx = 
00452          stream.readWord(); // cursorpos.position[i].sx = 
00453          stream.readWord(); // cursorpos.position[i].cy = 
00454          stream.readWord(); // cursorpos.position[i].sy = 
00455       }
00456    }
00457 
00458    if ( version <= 9 )
00459       stream.readInt(); // loadtribute
00460       
00461    __loadunsentmessage = stream.readInt();
00462    __loadmessages = stream.readInt();
00463 
00464    messageid = stream.readInt();
00465 
00466    if(  version < 2 ) {
00467       ___loadJournal = stream.readInt();
00468       ___loadNewJournal = stream.readInt();
00469    } else {
00470       ___loadJournal = true;
00471       ___loadNewJournal = true;
00472    }
00473 
00474    int exist_humanplayername[9];
00475    for ( int i = 0; i < 8; i++ )
00476       exist_humanplayername[i] = stream.readInt();
00477    exist_humanplayername[8] = 0;
00478 
00479 
00480    int exist_computerplayername[9];
00481    for ( int i = 0; i < 8; i++ )
00482       exist_computerplayername[i] = stream.readInt();
00483    exist_computerplayername[8] = 0;
00484 
00485    supervisorpasswordcrc.read ( stream );
00486 
00487    if ( version <= 10 )
00488       for ( int i = 0; i < 8; i++ )
00489          stream.readChar(); // alliances_at_beginofturn[i] = 
00490 
00491    stream.readInt(); // was objectcrc = (Object*containercrcs)
00492    bool load_shareview = false;
00493    if ( version <= 10 )
00494       load_shareview = stream.readInt();
00495 
00496    continueplaying = stream.readInt();
00497    __loadreplayinfo =  stream.readInt();
00498    playerView = stream.readInt();
00499    lastjournalchange.abstime = stream.readInt();
00500 
00501    for ( int i = 0; i< 8; i++ )
00502       bi_resource[i].read ( stream );
00503 
00504    int preferredfilenames = stream.readInt();
00505 
00506    bool __loadEllipse = stream.readInt();
00507    graphicset = stream.readInt();
00508    gameparameter_num = stream.readInt();
00509 
00510    stream.readInt(); // dummy
00511    mineralResourcesDisplayed = stream.readInt();
00512    for ( int i = 0; i< 9; i++ )
00513        player[i].queuedEvents = stream.readInt();
00514 
00515    for ( int i = 0; i < 19; i++ )
00516        stream.readInt();
00517 
00518    int _oldgameparameter[8];
00519    for ( int i = 0; i < 8; i++ )
00520        _oldgameparameter[i] = stream.readInt();
00521 
00522    if ( version >= 11 ) 
00523       if ( stream.readInt() != 0x12345678 )
00524          throw ASCmsgException("marker not matched when loading GameMap");
00525 
00527 // Here initmap was called
00529 
00530 
00531 
00532     if ( ___loadtitle )
00533        maptitle = stream.readString();
00534 
00535     if ( loadCampaign ) {
00536        if ( version <= 14 ) {
00537          campaign.id = stream.readWord();
00538          stream.readWord(); // campaign->prevmap 
00539          stream.readChar(); // campaign->player 
00540          campaign.directaccess = stream.readChar();
00541          campaign.avail = true;
00542          for ( int d = 0; d < 21; d++ )
00543             stream.readChar(); // dummy
00544        } else {
00545           campaign.id = stream.readInt();
00546           campaign.directaccess = stream.readChar();
00547           if ( version > 15 )
00548              campaign.avail = stream.readInt();
00549        }
00550     }
00551 
00552     for ( int w=0; w<9 ; w++ ) {
00553        if (dummy_playername[w] )
00554           stream.readString();
00555 
00556        player[w].ai = NULL;
00557 
00558 
00559        if ( exist_humanplayername[w] )
00560           player[w].setName( stream.readString() );
00561 
00562        if ( exist_computerplayername[w] )
00563           stream.readString();
00564 
00565     } /* endfor */
00566 
00567     if ( stream.readInt() )
00568        tribute.read ( stream );
00569 
00570     for ( int aa = 0; aa < 8; aa++ )
00571        if ( alliance_names_not_used_any_more[aa] ) {
00572           char* tempname = NULL;
00573           stream.readpchar ( &tempname );
00574           delete[] tempname;
00575        }
00576 
00577     stream.readInt();
00578 
00579     if ( load_shareview && version <= 10 ) {
00580     
00581       for ( int i = 0; i < 8; i++ )
00582          for ( int j =0; j < 8; j++ ) {
00583             int sv = stream.readChar();
00584             if ( sv )
00585                player[i].diplomacy.setState( j, PEACE_SV );
00586          }      
00587                
00588       stream.readInt();
00589     } 
00590 
00591     if ( preferredfilenames ) {
00592        int p;
00593        int mapname[8];
00594        int mapdescription_not_used_any_more[8];
00595        int savegame[8];
00596        int savegamedescription_not_used_any_more[8];
00597        for ( p = 0; p < 8; p++ )
00598           mapname[p] = stream.readInt();
00599        for ( p = 0; p < 8; p++ )
00600           mapdescription_not_used_any_more[p] = stream.readInt();
00601        for ( p = 0; p < 8; p++ )
00602           savegame[p] = stream.readInt();
00603        for ( p = 0; p < 8; p++ )
00604           savegamedescription_not_used_any_more[p] = stream.readInt();
00605 
00606        for ( int i = 0; i < 8; i++ ) {
00607           if ( mapname[i] )
00608              preferredFileNames.mapname[i] = stream.readString ();
00609 
00610           if ( mapdescription_not_used_any_more[i] )
00611              stream.readString(); // dummy
00612 
00613           if ( savegame[i] )
00614              preferredFileNames.savegame[i] = stream.readString ();
00615 
00616           if ( savegamedescription_not_used_any_more[i] )
00617              stream.readString();
00618        }
00619     }
00620 
00621     if ( __loadEllipse ) {
00622        for ( int i = 0; i < 5; ++i )
00623           stream.readInt();
00624        stream.readFloat();
00625        stream.readInt();
00626     }
00627 
00628     int orggpnum = gameparameter_num;
00629     gameparameter_num = 0;
00630     for ( int gp = 0; gp < 8; gp ++ )
00631        setgameparameter ( GameParameter(gp), _oldgameparameter[gp] );
00632 
00633     for ( int ii = 0 ; ii < orggpnum; ii++ ) {
00634        int gpar = stream.readInt();
00635        setgameparameter ( GameParameter(ii), gpar );
00636     }
00637 
00638     if ( version >= 2 ) {
00639        archivalInformation.author = stream.readString();
00640        archivalInformation.description = stream.readString();
00641        archivalInformation.tags = stream.readString();
00642        archivalInformation.requirements = stream.readString();
00643        archivalInformation.modifytime = stream.readInt();
00644     }
00645 
00646     if ( version >= 4 ) {
00647        int num = stream.readInt();
00648        for ( int ii = 0; ii < num; ++ii )
00649           unitProduction.idsAllowed.push_back ( stream.readInt() );
00650 
00651        for ( int ii = 0; ii < 9; ii++ ) {
00652           int num = stream.readInt( );
00653           for ( int i = 0; i < num; i++ ) {
00654              Player::PlayTime pt;
00655              pt.turn = stream.readInt();
00656              pt.date = stream.readInt();
00657              player[ii].playTime.push_back ( pt );
00658           }
00659        }
00660 
00661     }
00662 
00663     if ( version >= 5 ) {
00664        eventID = stream.readInt();
00665 
00666        int num = stream.readInt();
00667        for ( int i = 0; i< num; ++i ) {
00668           Event* ev = new Event ( *this );
00669           ev->read ( stream );
00670           events.push_back ( ev );
00671        }
00672     }
00673 
00674     if ( version >= 8 )
00675        randomSeed = stream.readInt();
00676        
00677     if ( version >= 12 ) {
00678       bool nw = stream.readInt();
00679       if ( nw ) 
00680          network = GameTransferMechanism::read( stream );         
00681     }
00682     
00683     if ( version >= 25 )
00684        actions.read( stream );
00685     
00686     if ( version >= 30 ) {
00687        nativeMessageLanguage = stream.readString();
00688        int recorder  = stream.readInt();
00689        if ( recorder == 1 ) {
00690           actionRecorder = new CampaignActionLogger( this );
00691           actionRecorder->readData( stream );
00692        } else
00693           actionRecorder = NULL;
00694     }
00695     
00696     if( version >= 31 )
00697        properties.read( stream );
00698     
00699     if ( version >= 33 ) 
00700        tasks->read( stream );
00701     
00702     if ( version >= 34 )
00703        serverMapID = stream.readInt();
00704 
00705 }
00706 
00707 
00708 void GameMap :: write ( tnstream& stream )
00709 {
00710    int i;
00711 
00712    stream.writeWord( 0xfffe );
00713    stream.writeWord( 0xfffc );
00714 
00715    stream.writeInt ( tmapversion );
00716    stream.writeInt( xsize );
00717    stream.writeInt( ysize );
00718 
00719    stream.writeWord( 0 );
00720    stream.writeWord( 0 );
00721    stream.writeInt (1); // dummy
00722    stream.writeString ( codeWord );
00723 
00724    
00725    stream.writeInt( campaign.avail  );
00726    stream.writeChar( actplayer );
00727    stream.writeInt( time.abstime );
00728    
00729    stream.writeChar(0);
00730    stream.writeChar( weather.windSpeed );
00731    stream.writeChar( weather.windDirection );
00732    
00733    stream.writeInt( 0x12345678 );
00734    
00735    stream.writeInt( packageData != NULL );
00736    if ( packageData ) 
00737       packageData->write( stream );
00738    
00739    
00740    for  ( i= 0; i < 4; i++ )
00741       stream.writeChar( 0 );
00742 
00743    for ( i = 0; i< 12; i++ )
00744       stream.writeChar( 0 ); // dummy
00745 
00746    stream.writeInt( _resourcemode );
00747 
00748    for ( i = 0; i< 9; i++ ) {
00749       stream.writeChar( player[i].existanceAtBeginOfTurn );
00750       stream.writeInt( 1 ); // dummy
00751       stream.writeInt( 1 ); // dummy
00752       player[i].research.write ( stream );
00753       stream.writeInt( player[i].ai != NULL );
00754       stream.writeChar( player[i].stat );
00755       stream.writeChar( 0 ); // dummy
00756       stream.writeInt( 0 );
00757       player[i].passwordcrc.write ( stream );
00758       stream.writeInt( !player[i].dissections.empty() );
00759       stream.writeInt( 1 );
00760       stream.writeInt( 1 );
00761       stream.writeInt( 1 );
00762       stream.writeInt ( player[i].ASCversion );
00763       player[i].cursorPos.write( stream );
00764       player[i].diplomacy.write( stream );
00765       stream.writeString ( player[i].email );
00766       player[i].write(stream);
00767    }
00768 
00769    stream.writeInt( 0x12345678 );
00770    
00771    idManager.writeData(stream);
00772    
00773    stream.writeChar( levelfinished );
00774 
00775    stream.writeInt( 1 );
00776    stream.writeInt( !messages.empty() );
00777 
00778    stream.writeInt( messageid );
00779 
00780    for ( i = 0; i < 8; i++ )
00781       stream.writeInt( 1 );
00782 
00783    for ( i = 0; i < 8; i++ )
00784       stream.writeInt( 0 );
00785 
00786    supervisorpasswordcrc.write ( stream );
00787 
00788    stream.writeInt( 0 );
00789 
00790    stream.writeInt( continueplaying );
00791    stream.writeInt( replayinfo != NULL );
00792    stream.writeInt( playerView );
00793    stream.writeInt( lastjournalchange.abstime );
00794 
00795    for ( i = 0; i< 8; i++ )
00796       bi_resource[i].write ( stream );
00797 
00798    stream.writeInt( 1 );
00799    stream.writeInt( 0 ); // was: ellipse
00800    stream.writeInt( graphicset );
00801    stream.writeInt( gameparameter_num );
00802 
00803    stream.writeInt( game_parameter != NULL );
00804    stream.writeInt( mineralResourcesDisplayed );
00805    for ( i = 0; i< 9; i++ )
00806        stream.writeInt( player[i].queuedEvents );
00807 
00808    for ( i = 0; i < 19; i++ )
00809        stream.writeInt( 0 );
00810 
00811    for ( i = 0; i < 8; i++ )
00812        stream.writeInt( getgameparameter(GameParameter(i)) );
00813 
00814 
00815    stream.writeInt( 0x12345678 );
00816 
00817        
00819 // second part
00821 
00822 
00823 
00824    stream.writeString( maptitle );
00825 
00826    if ( campaign.avail ) {
00827       stream.writeInt( campaign.id );
00828       stream.writeChar( campaign.directaccess );
00829       stream.writeInt( campaign.avail );
00830    }
00831 
00832    for (int w=0; w<8 ; w++ ) 
00833       stream.writeString ( player[w].getName() );
00834 
00835    if ( !tribute.empty() ) {
00836        stream.writeInt ( -1 );
00837        tribute.write ( stream );
00838    } else
00839        stream.writeInt ( 0 );
00840 
00841     stream.writeInt ( 0 );
00842 
00843     int p;
00844     for ( p = 0; p < 8; p++ )
00845        stream.writeInt( 1 );
00846 
00847     for ( p = 0; p < 8; p++ )
00848        stream.writeInt( 0 );
00849 
00850     for ( p = 0; p < 8; p++ )
00851        stream.writeInt( 1 );
00852 
00853     for ( p = 0; p < 8; p++ )
00854        stream.writeInt( 0 );
00855 
00856     for ( int k = 0; k < 8; k++ ) {
00857        stream.writeString ( preferredFileNames.mapname[k] );
00858        stream.writeString ( preferredFileNames.savegame[k] );
00859     }
00860 
00861 
00862     for ( int ii = 0 ; ii < gameparameter_num; ii++ )
00863        stream.writeInt ( game_parameter[ii] );
00864 
00865 
00866     stream.writeString ( archivalInformation.author );
00867     stream.writeString ( archivalInformation.description );
00868     stream.writeString ( archivalInformation.tags );
00869     stream.writeString ( archivalInformation.requirements );
00870     stream.writeInt ( (unsigned int) (::time ( &archivalInformation.modifytime )));
00871 
00872 
00873     stream.writeInt( unitProduction.idsAllowed.size() );
00874     for ( int ii = 0; ii < unitProduction.idsAllowed.size(); ++ii )
00875        stream.writeInt ( unitProduction.idsAllowed[ii] );
00876 
00877 
00878     for ( int ii = 0; ii < 9; ii++ ) {
00879        stream.writeInt( player[ii].playTime.size() );
00880        for ( Player::PlayTimeContainer::iterator i = player[ii].playTime.begin(); i != player[ii].playTime.end(); ++i ) {
00881           stream.writeInt( i->turn );
00882           stream.writeInt( (unsigned int) i->date );
00883        }
00884     }
00885 
00886     stream.writeInt( eventID );
00887 
00888     stream.writeInt ( events.size());
00889     for ( Events::iterator i = events.begin(); i != events.end(); ++i )
00890        (*i)->write( stream );
00891 
00892     stream.writeInt( randomSeed );
00893 
00894     if ( network ) {
00895       stream.writeInt( 1 );
00896       network->write( stream );
00897     } else
00898       stream.writeInt( 0 );
00899       
00900     actions.write( stream );
00901     
00902     stream.writeString(nativeMessageLanguage);
00903     
00904     if ( actionRecorder != NULL ) {
00905        stream.writeInt( 1 );
00906        actionRecorder->writeData( stream );
00907     } else
00908        stream.writeInt( 0 );
00909     
00910     properties.write( stream );
00911     
00912    tasks->write( stream );
00913 
00914    stream.writeInt( serverMapID );
00915 }
00916 
00917 
00918 MapCoordinate GameMap::findFirstContainer() const
00919 {
00920    for ( int y = 0; y < ysize; ++y )
00921       for ( int x = 0; x < xsize; ++x )
00922          if ( getField(x,y)->getContainer() )
00923             if ( getField(x,y)->getContainer()->getOwner() == actplayer ) 
00924                return MapCoordinate(x,y);
00925    
00926    return MapCoordinate(0,0);
00927 }
00928 
00929 
00930 MapCoordinate& GameMap::getCursor()
00931 {
00932    #ifdef sgmain
00933    if ( actplayer >= 0 ) {
00934       if ( !player[actplayer].cursorPos.valid() || player[actplayer].cursorPos.x >= xsize || player[actplayer].cursorPos.y >= ysize) 
00935          player[actplayer].cursorPos = findFirstContainer();
00936       
00937       return player[actplayer].cursorPos;
00938    } else
00939       return player[0].cursorPos;
00940 #else
00941    return player[8].cursorPos;
00942    #endif
00943 }
00944 
00945 MapCoordinate GameMap::getCursor() const
00946 {
00947 #ifdef sgmain
00948    if ( actplayer >= 0 ) {
00949       if ( !player[actplayer].cursorPos.valid() || player[actplayer].cursorPos.x >= xsize || player[actplayer].cursorPos.y >= ysize) 
00950          return findFirstContainer();
00951       else
00952          return player[actplayer].cursorPos;
00953    } else
00954       return player[0].cursorPos;
00955 #else
00956       return player[8].cursorPos;
00957 #endif
00958 }
00959 
00960 
00961 void GameMap :: cleartemps( int b, int value )
00962 {
00963   if ( xsize <= 0 || ysize <= 0)
00964      return;
00965 
00966   int l = 0;
00967   for ( int x = 0; x < xsize ; x++)
00968      for ( int y = 0; y <  ysize ; y++) {
00969 
00970          if (b & 1 )
00971            field[l].a.temp = value;
00972          if (b & 2 )
00973            field[l].a.temp2 = value;
00974          if (b & 4 )
00975            field[l].temp3 = value;
00976          if (b & 8 )
00977            field[l].temp4 = value;
00978 
00979          l++;
00980      }
00981 }
00982 
00983 void GameMap :: allocateFields ( int x, int y, TerrainType::Weather* terrain )
00984 {
00985    field = new MapField[x*y];
00986    for ( int i = 0; i < x*y; i++ ) {
00987       if ( terrain ) {
00988          field[i].typ = terrain;
00989          field[i].setparams();
00990       }
00991       field[i].setMap ( this );
00992    }
00993    xsize = x;
00994    ysize = y;
00995    overviewMapHolder.connect();
00996 }
00997 
00998 
00999 void GameMap :: calculateAllObjects ( void )
01000 {
01001    calculateallobjects( this );
01002 }
01003 
01004 MapField*  GameMap :: getField(int x, int y)
01005 {
01006    if ((x < 0) || (y < 0) || (x >= xsize) || (y >= ysize))
01007       return NULL;
01008    else
01009       return (   &field[y * xsize + x] );
01010 }
01011 
01012 const MapField*  GameMap :: getField(int x, int y) const
01013 {
01014    if ((x < 0) || (y < 0) || (x >= xsize) || (y >= ysize))
01015       return NULL;
01016    else
01017       return (   &field[y * xsize + x] );
01018 }
01019 
01020 
01021 MapField*  GameMap :: getField(const MapCoordinate& pos )
01022 {
01023    return getField ( pos.x, pos.y );
01024 }
01025 
01026 int   GameMap :: getPlayerView() const
01027 {
01028 #ifdef karteneditor
01029    return -1;
01030 #else
01031    return playerView;
01032 #endif
01033 }
01034 
01035 
01036 void  GameMap :: setPlayerView( int player )
01037 {
01038    playerView = player;
01039 }
01040 
01041 
01042 
01043 bool GameMap :: isResourceGlobal ( int resource )
01044 {
01045    if ( _resourcemode == 1 ) { // BI-Mode
01046       if ( resource == 1 ) // material
01047          return false;
01048       else
01049          if ( resource == 2 )
01050             return getgameparameter(cgp_globalfuel);
01051          else
01052             return true;
01053    } else {
01054       /*
01055       if ( resource == 0 )
01056          return getgameparameter(cgp_globalenergy);
01057       if ( resource == 1 )
01058          return false;
01059       if ( resource == 2 )
01060          return getgameparameter(cgp_globalfuel);
01061       */
01062       return false;
01063    }
01064 }
01065 
01066 int GameMap :: getgameparameter ( GameParameter num ) const
01067 {
01068   if ( game_parameter && num < gameparameter_num ) {
01069      return game_parameter[num];
01070   } else
01071      if ( num < gameparameternum )
01072         return gameParameterSettings[num].defaultValue;
01073      else
01074         return 0;
01075 }
01076 
01077 void GameMap :: setgameparameter ( GameParameter num, int value )
01078 {
01079    if ( game_parameter ) {
01080      if ( num < gameparameter_num )
01081         game_parameter[num] = value;
01082      else {
01083         int* oldparam = game_parameter;
01084         game_parameter = new int[num+1];
01085         for ( int i = 0; i < gameparameter_num; i++ )
01086            game_parameter[i] = oldparam[i];
01087         for ( int j = gameparameter_num; j < num; j++ )
01088            if ( j < gameparameternum )
01089               game_parameter[j] = gameParameterSettings[j].defaultValue;
01090            else
01091               game_parameter[j] = 0;
01092         game_parameter[num] = value;
01093         gameparameter_num = num + 1;
01094         delete[] oldparam;
01095      }
01096    } else {
01097        game_parameter = new int[num+1];
01098        for ( int j = 0; j < num; j++ )
01099           if ( j < gameparameternum )
01100              game_parameter[j] = gameParameterSettings[j].defaultValue;
01101           else
01102              game_parameter[j] = 0;
01103        game_parameter[num] = value;
01104        gameparameter_num = num + 1;
01105    }
01106 }
01107 
01108 void GameMap :: setupResources ( void )
01109 {
01110    for ( int n = 0; n< 8; n++ ) {
01111       bi_resource[n].energy = 0;
01112       bi_resource[n].material = 0;
01113       bi_resource[n].fuel = 0;
01114 
01115      #ifdef sgmain
01116 
01117       for ( Player::BuildingList::iterator i = player[n].buildingList.begin(); i != player[n].buildingList.end(); i++ )
01118          for ( int r = 0; r < 3; r++ )
01119             if ( isResourceGlobal( r )) {
01120                bi_resource[n].resource(r) += (*i)->actstorage.resource(r);
01121                (*i)->actstorage.resource(r) = 0;
01122             }
01123      #endif
01124    }
01125 }
01126 
01127 
01128 
01129 
01130 int GameMap :: eventpassed( int saveas, int action, int mapid )
01131 {
01132    return eventpassed ( (action << 16) | saveas, mapid );
01133 }
01134 
01135 
01136 
01137 int GameMap :: eventpassed( int id, int mapid )
01138 {
01139    return 0;
01140 }
01141 
01142 
01143 void GameMap:: IDManager :: registerUnitNetworkID( Vehicle* veh )
01144 {
01145    vehicleLookupCache[veh->networkid] = veh;
01146    if ( unitnetworkid < veh->networkid )
01147       unitnetworkid = veh->networkid;
01148 }
01149 
01150 void GameMap:: IDManager :: unregisterUnitNetworkID( Vehicle* veh )
01151 {
01152    VehicleLookupCache::iterator j = vehicleLookupCache.find(veh->networkid);
01153    if ( j != vehicleLookupCache.end() )
01154       vehicleLookupCache.erase(j);
01155 }
01156 
01157 
01158 int GameMap :: IDManager :: getNewNetworkID()
01159 {
01160    ++unitnetworkid;
01161    return unitnetworkid;
01162 }
01163 
01164 void GameMap :: IDManager :: readData ( tnstream& stream )
01165 {
01166    unitnetworkid = stream.readInt();
01167 }
01168 
01169 void GameMap :: IDManager :: writeData ( tnstream& stream ) const
01170 {
01171    stream.writeInt( unitnetworkid );
01172 }
01173 
01174 Vehicle* GameMap :: getUnit ( Vehicle* eht, int nwid )
01175 {
01176    if ( !eht )
01177       return NULL;
01178    else {
01179       if ( eht->networkid == nwid )
01180          return eht;
01181       else
01182          for ( ContainerBase::Cargo::const_iterator i = eht->getCargo().begin(); i != eht->getCargo().end(); ++i )
01183             if ( *i )  {
01184                if ( (*i)->networkid == nwid )
01185                   return *i;
01186                else {
01187                   Vehicle* ld = getUnit ( *i, nwid );
01188                   if ( ld )
01189                      return ld;
01190                }
01191             }
01192       return NULL;
01193    }
01194 }
01195 
01196 
01197 
01198 Vehicle* GameMap :: getUnit ( int nwid, bool consistencyCheck )
01199 {
01200    IDManager::VehicleLookupCache::iterator i = idManager.vehicleLookupCache.find( nwid );
01201    if ( i != idManager.vehicleLookupCache.end() )
01202       return i->second;
01203 
01204 
01205    if ( consistencyCheck ) 
01206       for ( int p = 0; p < 9; p++ )
01207          for ( Player::VehicleList::iterator i = player[p].vehicleList.begin(); i != player[p].vehicleList.end(); i++ )
01208             if ( (*i)->networkid == nwid ) {
01209                displaymessage("warning: id not registered in VehicleLookupCache!",1);
01210                return *i;
01211             }
01212 
01213    return NULL;
01214 }
01215 
01216 const Vehicle* GameMap :: getUnit ( int nwid, bool consistencyCheck ) const
01217 {
01218    IDManager::VehicleLookupCache::const_iterator i = idManager.vehicleLookupCache.find( nwid );
01219    if ( i != idManager.vehicleLookupCache.end() )
01220       return i->second;
01221 
01222 
01223    if ( consistencyCheck ) 
01224       for ( int p = 0; p < 9; p++ )
01225          for ( Player::VehicleList::const_iterator i = player[p].vehicleList.begin(); i != player[p].vehicleList.end(); i++ )
01226             if ( (*i)->networkid == nwid ) {
01227                displaymessage("warning: id not registered in VehicleLookupCache!",1);
01228                return *i;
01229             }
01230 
01231    return NULL;
01232 }
01233 
01234 Vehicle* GameMap :: getUnit ( int x, int y, int nwid )
01235 {
01236    MapField* fld  = getField ( x, y );
01237    if ( !fld )
01238       return NULL;
01239 
01240    if ( fld->vehicle && fld->vehicle->networkid == nwid )
01241          return fld->vehicle;
01242          
01243    if ( fld->getContainer() )
01244       return fld->getContainer()->findUnit( nwid );
01245       
01246    return NULL;
01247      
01248 }
01249 
01250 ContainerBase* GameMap::getContainer ( int nwid )
01251 {
01252    if ( nwid > 0 )
01253       return getUnit(nwid);
01254    else {
01255       int x = (-nwid) & 0xffff;
01256       int y = (-nwid) >> 16;
01257       MapField* fld = getField(x,y);
01258       if ( !fld )
01259          return NULL;
01260 
01261       return fld->building;
01262    }
01263 }
01264 
01265 const ContainerBase* GameMap::getContainer ( int nwid ) const 
01266 {
01267    if ( nwid > 0 )
01268       return getUnit(nwid);
01269    else {
01270       int x = (-nwid) & 0xffff;
01271       int y = (-nwid) >> 16;
01272       const MapField* fld = getField(x,y);
01273       if ( !fld )
01274          return NULL;
01275 
01276       return fld->building;
01277    }
01278 }
01279 
01280 
01281 
01282 void GameMap::beginTurn()
01283 {
01284    if ( !player[actplayer].exist() )
01285       if ( replayinfo )
01286          if ( replayinfo->guidata[actplayer] ) {
01287             delete replayinfo->guidata[actplayer];
01288             replayinfo->guidata[actplayer] = NULL;
01289          }
01290             
01291    for ( Player::VehicleList::const_iterator i = player[actplayer].vehicleList.begin(); i != player[actplayer].vehicleList.end(); i++ )
01292       (*i)->beginTurn();
01293          
01294    if ( player[actplayer].exist() && player[actplayer].stat != Player::off ) 
01295       sigPlayerTurnBegins( player[actplayer] );
01296       
01297 }
01298 
01299 
01300 void GameMap::endTurn()
01301 {
01302 
01303    player[actplayer].ASCversion = getNumericVersion();
01304    Player::PlayTime pt;
01305    pt.turn = time.turn();
01306    ::time ( &pt.date );
01307    player[actplayer].playTime.push_back ( pt );
01308    
01309    sigPlayerTurnEnds( player[actplayer] );
01310    sigPlayerTurnEndsStatic( this, player[actplayer] );
01311          
01312    actions.breakUndo(); // commits all actions to the replay log
01313    
01314    for ( int i = 0; i < 9; ++i )
01315      for ( Player::BuildingList::iterator v = player[i].buildingList.begin(); v != player[i].buildingList.end(); ++v ) {
01316          if ( i == actplayer )
01317             (*v)->endOwnTurn();
01318          (*v)->endAnyTurn();
01319      }
01320 
01321 
01322    Player::VehicleList toRemove;
01323    for ( Player::VehicleList::iterator v = player[actplayer].vehicleList.begin(); v != player[actplayer].vehicleList.end(); ++v ) {
01324       Vehicle* actvehicle = *v;
01325 
01326       // Bei Aenderungen hier auch die Windanzeige dashboard.PAINTWIND aktualisieren !!!
01327 
01328       if (( actvehicle->height >= chtieffliegend )   &&  ( actvehicle->height <= chhochfliegend ) && ( getField(actvehicle->xpos,actvehicle->ypos)->vehicle == actvehicle)) {
01329          if ( getmaxwindspeedforunit ( actvehicle ) < weather.windSpeed*maxwindspeed ){
01330             new Message ( getUnitReference( *v ) + " crashed because of the strong wind", this, 1<<(*v)->getOwner());
01331             toRemove.push_back ( *v );
01332          } else {
01333 
01334             int j = actvehicle->getTank().fuel - UnitHooveringLogic::calcFuelUsage( actvehicle );
01335             if (j < 0) {
01336                new Message ( getUnitReference( *v ) + " crashed due to lack of fuel", this, 1<<(*v)->getOwner());
01337                toRemove.push_back ( *v );
01338             } else {
01339                actvehicle->getResource( actvehicle->getTank().fuel - j, Resources::Fuel, false);
01340             }
01341          }
01342       }
01343 
01344       if ( actvehicle )
01345          actvehicle->endOwnTurn();
01346 
01347    }
01348 
01349    for ( Player::VehicleList::iterator v = toRemove.begin(); v != toRemove.end(); v++ )
01350       delete *v;
01351 
01352    checkunitsforremoval( this );
01353 
01354   for ( int i = 0; i < 9; ++i ) 
01355      for ( Player::VehicleList::iterator v = player[i].vehicleList.begin(); v != player[i].vehicleList.end(); ++v ) 
01356          (*v)->endAnyTurn();
01357 
01358  
01359    if ( replayinfo )
01360       replayinfo->closeLogging();
01361       
01362    processJournal();   
01363 
01364    sigPlayerTurnHasEnded( player[actplayer] );
01365    
01366 }
01367 
01368 
01369 void GameMap::endRound()
01370 {
01371     actplayer = 0;
01372     time.set ( time.turn()+1, 0 );
01373 
01374     for ( int y = 0; y < ysize; ++y )
01375        for ( int x = 0; x < xsize; ++x )
01376            getField(x,y)->endRound( time.turn() );
01377 
01378     for (int i = 0; i <= 7; i++) {
01379        if (player[i].exist() && player[i].stat != Player::off ) {
01380 
01381           for ( Player::VehicleList::iterator j = player[i].vehicleList.begin(); j != player[i].vehicleList.end(); j++ )
01382              (*j)->endRound();
01383 
01384           for ( Player::BuildingList::iterator j = player[i].buildingList.begin(); j != player[i].buildingList.end(); j++ )
01385              (*j)->endRound();
01386           
01387           typedef PointerList<ContainerBase::Work*> BuildingWork;
01388           BuildingWork buildingWork;
01389 
01390           for ( Player::BuildingList::iterator j = player[i].buildingList.begin(); j != player[i].buildingList.end(); j++ ) {
01391              if ( (*j)->getEntry().x == 19 && (*j)->getEntry().y == 72 )
01392                 logMessage("dummy", "dummy");
01393              ContainerBase::Work* w = (*j)->spawnWorkClasses( false );
01394              if ( w ) {
01395                 buildingWork.push_back ( w );
01396                 logMessage("ResourceWork", "Building " + (*j)->getEntry().toString() + " has work to do");
01397              } else
01398                 logMessage("ResourceWork", "Building " + (*j)->getEntry().toString() + " has no work to do");
01399           }
01400 
01401           for ( Player::VehicleList::iterator j = player[i].vehicleList.begin(); j != player[i].vehicleList.end(); j++ ) {
01402              ContainerBase::Work* w = (*j)->spawnWorkClasses( false );
01403              if ( w ) {
01404                 buildingWork.push_back ( w );
01405                 // logMessage("ResourceWork", "Vehicle " + ASCString::toString((*j)->networkid ) + " has work to do");
01406              } 
01407                 // logMessage("ResourceWork", "Vehicle " + ASCString::toString((*j)->networkid ) + " has no work to do");
01408           }
01409           
01410           
01411           bool didSomething;
01412           do {
01413              didSomething = false;
01414              for ( BuildingWork::iterator j = buildingWork.begin(); j != buildingWork.end(); j++ ) {
01415                 if ( ! (*j)->finished() ) 
01416                    if ( (*j)->run() )
01417                       didSomething = true;
01418              }
01419           } while ( didSomething );
01420           doresearch( this, i );
01421        }
01422     }
01423 
01424     int playerMask = 0;
01425     for ( int i = 0; i < getPlayerCount(); ++i )
01426        if ( !getPlayer(i).exist() )
01427           playerMask |= 1 << i;
01428     MapField::resetView(this,playerMask);
01429 
01430     if ( getgameparameter( cgp_objectGrowthMultiplier) > 0 )
01431        objectGrowth();
01432 }
01433 
01434 #include "libs/rand/rand_r.h"
01435 #include "libs/rand/rand_r.c"
01436 
01437 int GameMap::random( int max )
01438 {
01439    return asc_rand_r( &randomSeed ) % max;
01440 }
01441 
01442 void GameMap::objectGrowth()
01443 {
01444    typedef vector< pair<MapField*,int> > NewObjects;
01445    map<MapField*,int> remainingGrowthTime;
01446 
01447    NewObjects newObjects;
01448    for ( int y = 0; y < ysize; ++y )
01449       for ( int x = 0; x < xsize; ++x ) {
01450           MapField* fld = getField( x, y );
01451           for ( MapField::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); ++i)
01452              if ( i->typ->growthRate > 0 )
01453                 for ( int d = 0; d < 6; ++d ) {
01454                    MapField* fld2 = getField ( getNeighbouringFieldCoordinate( MapCoordinate(x,y), d ));
01455                    if ( fld2 ) 
01456                       if ( i->typ->growOnUnits || ((!fld2->vehicle || fld2->vehicle->height >= chtieffliegend) && !fld2->building ))
01457                         if ( fld2->objects.empty() || getgameparameter( cgp_objectGrowOnOtherObjects ) > 0 ) 
01458                            if ( i->remainingGrowthTime > 0 || i->typ->growthDuration <= 0 ) {
01459                               double d = i->typ->growthRate * getgameparameter( cgp_objectGrowthMultiplier) / 100;
01460                               if ( d > 0 ) {
01461                                  if ( d > 0.9 )
01462                                     d = 0.9;
01463 
01464                                  int p = static_cast<int>(std::ceil ( double(1) / d));
01465                                  if ( p > 1 )
01466                                     if ( random ( p ) == 1 )
01467                                        if ( i->typ->fieldModification[fld2->getWeather()].terrainaccess.accessible( fld2->bdt) > 0 ) {
01468                                           newObjects.push_back( make_pair( fld2, i->typ->id ));
01469                                           i->remainingGrowthTime -= 1;
01470                                           remainingGrowthTime[fld2] = i->remainingGrowthTime;
01471                                        }
01472                               }
01473                         }
01474                 }
01475       }
01476 
01477    for ( NewObjects::iterator i = newObjects.begin(); i != newObjects.end(); ++i )
01478       if ( !i->first->checkForObject( getobjecttype_byid( i->second ))) {
01479          if ( i->first->addobject ( getobjecttype_byid( i->second ))) {
01480             Object* o = i->first->checkForObject( getobjecttype_byid( i->second ));
01481             assert(o);
01482             o->remainingGrowthTime = remainingGrowthTime[i->first];
01483          }
01484       }
01485 
01486    checkunitsforremoval( this );
01487 }
01488 
01489 SigC::Signal1<void,GameMap&> GameMap::sigMapDeletion;
01490 SigC::Signal1<void,GameMap&> GameMap::sigMapCreation;
01491 SigC::Signal2<void,GameMap*,Player&> GameMap::sigPlayerTurnEndsStatic;
01492 
01493 GameMap :: ~GameMap ()
01494 {
01495    sigMapDeletion( *this );
01496    state = Destruction;
01497 
01498    if ( field )
01499 
01500       for ( int l=0 ;l < xsize * ysize ; l++ ) {
01501          if ( (field[l].bdt & getTerrainBitType(cbbuildingentry)).any() )
01502             delete field[l].building;
01503 
01504 
01505          Vehicle* aktvehicle = field[l].vehicle;
01506          if ( aktvehicle )
01507             delete aktvehicle;
01508 
01509       } /* endfor */
01510 
01511    int i;
01512    for ( i = 0; i <= 8; i++) {
01513       if ( player[i].ai ) {
01514          delete player[i].ai;
01515          player[i].ai = NULL;
01516       }
01517    }
01518 
01519    if ( replayinfo ) {
01520       delete replayinfo;
01521       replayinfo = NULL;
01522    }
01523 
01524    if ( game_parameter ) {
01525       delete[] game_parameter;
01526       game_parameter = NULL;
01527    }
01528    
01529    if ( network ) {
01530       delete network;
01531       network = NULL;
01532    }   
01533       
01534    if ( actionRecorder ) {
01535       delete actionRecorder;
01536       actionRecorder = NULL;
01537    }
01538 
01539 #ifdef WEATHERGENERATOR
01540    delete weatherSystem;
01541 #endif
01542 
01543    if ( field ) {
01544       delete[] field;
01545       field = NULL;
01546    }
01547 
01548    delete tasks;
01549    tasks = NULL;
01550    
01551 }
01552 
01553 /*
01554 gamemap :: ResourceTribute :: tresourcetribute ( )
01555 {
01556    for ( int a = 0; a < 3; a++ )
01557       for ( int b = 0; b < 8; b++ )
01558          for ( int c = 0; c < 8; c++ ) {
01559             avail.resource[a][b][c] = 0;
01560             paid.resource[a][b][c] = 0;
01561          }
01562 }
01563 */
01564 
01565 bool GameMap :: ResourceTribute :: empty ( )
01566 {
01567    for (int i = 0; i < 8; i++)
01568       for (int j = 0; j < 8; j++)
01569          for (int k = 0; k < 3; k++) {
01570             if ( avail[i][j].resource(k) )
01571                return false;
01572             if ( paid[i][j].resource(k) )
01573                return false;
01574          }
01575 
01576    return true;
01577 }
01578 
01579 const int tributeVersion = 1;  // we are counting backwards, -2 is newer than -1
01580 
01581 void GameMap :: ResourceTribute :: read ( tnstream& stream )
01582 {
01583    int version = stream.readInt();
01584    bool noVersion;
01585 
01586    if ( -version >= tributeVersion ) {
01587       for ( int a = 0; a < 8; ++a )
01588          for ( int b = 0; b < 8; ++b )
01589             payStatusLastTurn[a][b].read( stream );
01590       noVersion = false;
01591    } else
01592       noVersion = true;
01593 
01594 
01595    for ( int a = 0; a < 3; a++ )
01596       for ( int b = 0; b < 8; b++ )
01597          for ( int c = 0; c < 8; c++ ) {
01598              if ( noVersion ) {
01599                 avail[b][c].resource(a) = version;
01600                 noVersion = false;
01601              } else
01602                 avail[b][c].resource(a) = stream.readInt();
01603           }
01604 
01605    for ( int a = 0; a < 3; a++ )
01606       for ( int b = 0; b < 8; b++ )
01607          for ( int c = 0; c < 8; c++ )
01608              paid[b][c].resource(a) = stream.readInt();
01609 }
01610 
01611 void GameMap :: ResourceTribute :: write ( tnstream& stream )
01612 {
01613    stream.writeInt ( -tributeVersion );
01614    for ( int a = 0; a < 8; a++ )
01615       for ( int b = 0; b < 8; b++ )
01616          payStatusLastTurn[a][b].write( stream );
01617 
01618    for ( int a = 0; a < 3; a++ )
01619       for ( int b = 0; b < 8; b++ )
01620          for ( int c = 0; c < 8; c++ )
01621              stream.writeInt ( avail[b][c].resource(a) );
01622 
01623 
01624    for ( int a = 0; a < 3; a++ )
01625       for ( int b = 0; b < 8; b++ )
01626          for ( int c = 0; c < 8; c++ )
01627              stream.writeInt ( paid[b][c].resource(a) );
01628 }
01629 
01630 
01631 
01632 int  GameMap::resize( int top, int bottom, int left, int right )  // positive: larger
01633 {
01634   if ( !top && !bottom && !left && !right )
01635      return 0;
01636 
01637   if ( -(top + bottom) > ysize )
01638      return 1;
01639 
01640   if ( -(left + right) > xsize )
01641      return 2;
01642 
01643   if ( bottom & 1 || top & 1 )
01644      return 3;
01645 
01646 
01647   int ox1, oy1, ox2, oy2;
01648 
01649   if ( top < 0 ) {
01650      for ( int x = 0; x < xsize; x++ )
01651         for ( int y = 0; y < -top; y++ )
01652            getField(x,y)->deleteeverything();
01653 
01654      oy1 = -top;
01655   } else
01656      oy1 = 0;
01657 
01658   if ( bottom < 0 ) {
01659      for ( int x = 0; x < xsize; x++ )
01660         for ( int y = ysize+bottom; y < ysize; y++ )
01661            getField(x,y)->deleteeverything();
01662 
01663      oy2 = ysize + bottom;
01664   } else
01665      oy2 = ysize;
01666    
01667   if ( left < 0 ) {
01668      for ( int x = 0; x < -left; x++ )
01669         for ( int y = 0; y < ysize; y++ )
01670            getField(x,y)->deleteeverything();
01671      ox1 = -left;
01672   } else
01673      ox1 = 0;
01674 
01675   if ( right < 0 ) {
01676      for ( int x = xsize+right; x < xsize; x++ )
01677         for ( int y = 0; y < ysize; y++ )
01678            getField(x,y)->deleteeverything();
01679      ox2 = xsize + right;
01680   } else
01681      ox2 = xsize;
01682 
01683   for (int s = 0; s < 9; s++)
01684      for ( Player::BuildingList::iterator i = player[s].buildingList.begin(); i != player[s].buildingList.end(); i++ )
01685         (*i)->unchainbuildingfromfield();
01686 
01687 
01688   int newx = xsize + left + right;
01689   int newy = ysize + top + bottom;
01690 
01691   MapField* newfield = new MapField [ newx * newy ];
01692   for ( int i = 0; i < newx * newy; i++ )
01693      newfield[i].setMap ( this );
01694 
01695   int x;
01696   for ( x = ox1; x < ox2; x++ )
01697      for ( int y = oy1; y < oy2; y++ ) {
01698         MapField* org = getField ( x, y );
01699         MapField* dst = &newfield[ (x + left) + ( y + top ) * newx];
01700         *dst = *org;
01701      }
01702 
01703   MapField defaultfield;
01704   defaultfield.setMap ( this );
01705   defaultfield.typ = getterraintype_byid ( 30 )->weather[0];
01706 
01707   for ( x = 0; x < left; x++ )
01708      for ( int y = 0; y < newy; y++ )
01709         newfield[ x + y * newx ] = defaultfield;
01710 
01711   for ( x = xsize + left; x < xsize + left + right; x++ )
01712      for ( int y = 0; y < newy; y++ )
01713         newfield[ x + y * newx ] = defaultfield;
01714 
01715 
01716   int y;
01717   for ( y = 0; y < top; y++ )
01718      for ( int x = 0; x < newx; x++ )
01719         newfield[ x + y * newx ] = defaultfield;
01720 
01721   for ( y = ysize + top; y < ysize + top + bottom; y++ )
01722      for ( int x = 0; x < newx; x++ )
01723         newfield[ x + y * newx ] = defaultfield;
01724 
01725   calculateallobjects( this );
01726 
01727   for ( int p = 0; p < newx*newy; p++ )
01728      newfield[p].setparams();
01729 
01730   delete[] field;
01731   field = newfield;
01732   xsize = newx;
01733   ysize = newy;
01734 
01735 
01736   for (int s = 0; s < 9; s++)
01737      for ( Player::BuildingList::iterator i = player[s].buildingList.begin(); i != player[s].buildingList.end(); i++ ) {
01738         MapCoordinate mc = (*i)->getEntry();
01739         mc.x += left;
01740         mc.y += top;
01741         (*i)->chainbuildingtofield ( mc );
01742      }
01743 
01744   for (int s = 0; s < 9; s++)
01745      for ( Player::VehicleList::iterator i = player[s].vehicleList.begin(); i != player[s].vehicleList.end(); i++ ) {
01746         (*i)->xpos += left;
01747         (*i)->ypos += top;
01748      }
01749 
01750 
01751   /*
01752   if (xpos + idisplaymap.getscreenxsize() > xsize)
01753      xpos = xsize - idisplaymap.getscreenxsize() ;
01754   if (ypos + idisplaymap.getscreenysize()  > ysize)
01755      ypos = ysize - idisplaymap.getscreenysize() ;
01756    */
01757 
01758    overviewMapHolder.resetSize();
01759 
01760    if ( left || top ) 
01761       sigCoordinateShift( MapCoodinateVector(left,top));
01762    
01763    return 0;
01764 }
01765 
01766 pterraintype GameMap :: getterraintype_byid ( int id )
01767 {
01768    return terrainTypeRepository.getObject_byID ( id );
01769 }
01770 
01771 ObjectType* GameMap :: getobjecttype_byid ( int id )
01772 {
01773    return objectTypeRepository.getObject_byID ( id );
01774 }
01775 
01776 const ObjectType* GameMap :: getobjecttype_byid ( int id ) const
01777 {
01778    return objectTypeRepository.getObject_byID ( id );
01779 }
01780 
01781 
01782 VehicleType* GameMap :: getvehicletype_byid ( int id )
01783 {
01784    return vehicleTypeRepository.getObject_byID ( id );
01785 }
01786 
01787 const VehicleType* GameMap :: getvehicletype_byid ( int id ) const
01788 {
01789    return vehicleTypeRepository.getObject_byID ( id );
01790 }
01791 
01792 
01793 BuildingType* GameMap :: getbuildingtype_byid ( int id )
01794 {
01795    return buildingTypeRepository.getObject_byID ( id );
01796 }
01797 
01798 const BuildingType* GameMap :: getbuildingtype_byid ( int id ) const
01799 {
01800    return buildingTypeRepository.getObject_byID ( id );
01801 }
01802 
01803 const Technology* GameMap :: gettechnology_byid ( int id )
01804 {
01805    return technologyRepository.getObject_byID ( id );
01806 }
01807 
01808 
01809 pterraintype GameMap :: getterraintype_bypos ( int pos )
01810 {
01811    return terrainTypeRepository.getObject_byPos ( pos );
01812 }
01813 
01814 ObjectType* GameMap :: getobjecttype_bypos ( int pos )
01815 {
01816    return objectTypeRepository.getObject_byPos ( pos );
01817 }
01818 
01819 VehicleType* GameMap :: getvehicletype_bypos ( int pos )
01820 {
01821    return vehicleTypeRepository.getObject_byPos ( pos );
01822 }
01823 
01824 BuildingType* GameMap :: getbuildingtype_bypos ( int pos )
01825 {
01826    return buildingTypeRepository.getObject_byPos ( pos );
01827 }
01828 
01829 const Technology* GameMap :: gettechnology_bypos ( int pos )
01830 {
01831    return technologyRepository.getObject_byPos ( pos );
01832 }
01833 
01834 int GameMap :: getTerrainTypeNum ( )
01835 {
01836    return  terrainTypeRepository.getNum();
01837 }
01838 
01839 int GameMap :: getObjectTypeNum ( )
01840 {
01841    return  objectTypeRepository.getNum();
01842 }
01843 
01844 int GameMap :: getVehicleTypeNum ( )
01845 {
01846    return  vehicleTypeRepository.getNum();
01847 }
01848 
01849 int GameMap :: getBuildingTypeNum ( )
01850 {
01851    return  buildingTypeRepository.getNum();
01852 }
01853 
01854 int GameMap :: getTechnologyNum ( )
01855 {
01856    return  technologyRepository.getNum();
01857 }
01858 
01859 void GameMap::processJournal()
01860 {
01861   if ( !newJournal.empty() ) {
01862      ASCString add = gameJournal;
01863 
01864      char tempstring[100];
01865      char tempstring2[100];
01866      sprintf( tempstring, "#color0# %s ; turn %d #color0##crt##crt#", player[actplayer].getName().c_str(), time.turn() );
01867      sprintf( tempstring2, "#color%d#", getplayercolor ( actplayer ));
01868 
01869      int fnd;
01870      do {
01871         fnd = 0;
01872         if ( !add.empty() ) {
01873            if ( add.find ( '\n', add.length()-1 ) != add.npos ) {
01874               add.erase ( add.length()-1 );
01875               fnd++;
01876            } else
01877              if ( add.length() > 4 )
01878                 if ( add.find ( "#crt#", add.length()-5 ) != add.npos ) {
01879                   add.erase ( add.length()-5 );
01880                   fnd++;
01881                 }
01882         }
01883 
01884      } while ( fnd ); /* enddo */
01885 
01886      add += tempstring2;
01887      add += newJournal;
01888      add += tempstring;
01889 
01890      gameJournal = add;
01891      newJournal.erase();
01892 
01893      lastjournalchange.set ( time.turn(), actplayer );
01894   }
01895  
01896 }
01897 
01898 
01899 void GameMap :: startGame ( )
01900 {
01901    time.set ( 1, 0 );
01902 
01903    for ( int j = 0; j < 8; j++ )
01904       player[j].queuedEvents = 1;
01905 
01906    levelfinished = false;
01907 
01908    for ( int n = 0; n< 8; n++ ) {
01909       bi_resource[n].energy = 0;
01910       bi_resource[n].material = 0;
01911       bi_resource[n].fuel = 0;
01912       player[n].research.setMultiplier( getgameparameter(cgp_researchOutputMultiplier) );
01913    }
01914 
01915    
01916    
01917    #ifndef karteneditor
01918    actplayer = -1;
01919    #else
01920    actplayer = 0;
01921    #endif
01922    
01923    setupResources();
01924    
01925    // calling signal
01926    newRound();
01927 } 
01928 
01929 bool GameMap::UnitProduction::check ( int id )
01930 {
01931    for ( GameMap::UnitProduction::IDsAllowed::iterator i = idsAllowed.begin(); i != idsAllowed.end(); i ++ )
01932       if( *i == id )
01933          return true;
01934 
01935     return false;
01936 }
01937 
01938 VisibilityStates GameMap::getInitialMapVisibility( int player )
01939 {
01940    VisibilityStates c = VisibilityStates( getgameparameter ( cgp_initialMapVisibility ));
01941 
01942    if ( this->player[player].ai ) {
01943       if ( this->player[player].ai->isRunning() ) {
01944          if ( c < this->player[player].ai->getVision() )
01945             c = this->player[player].ai->getVision();
01946       } else
01947          // this is a hack to make the replays of the AI work
01948          if ( c < visible_ago )
01949             c = visible_ago;
01950    }
01951    return c;
01952 }
01953 
01954 void GameMap::setPlayerMode(  Player& p, State s )
01955 {
01956    p.getParentMap()->state = s;
01957 }
01958 
01959 int GameMap::getMemoryFootprint() const
01960 {
01961    int size = sizeof(*this);
01962    if( replayinfo )
01963       for ( int i = 0; i < 8; ++i ) {
01964          if ( replayinfo->guidata[i] )
01965             size += replayinfo->guidata[i]->getMemoryFootprint();
01966          if ( replayinfo->map[i] )
01967             size += replayinfo->map[i]->getMemoryFootprint();
01968       }
01969    return size;
01970 }
01971 
01972 
01973 
01974 void GameMap::operator= ( const GameMap& map )
01975 {
01976   throw ASCmsgException ( "GameMap::operator= undefined");
01977 }
01978 
01979 
01980 void AiThreat :: write ( tnstream& stream )
01981 {
01982    const int version = 1000;
01983    stream.writeInt ( version );
01984    stream.writeInt ( threatTypes );
01985    for ( int i = 0; i < threatTypes; i++ )
01986       stream.writeInt ( threat[i] );
01987 }
01988 
01989 void AiThreat:: read ( tnstream& stream )
01990 {
01991 
01992    int version = stream.readInt();
01993    if ( version == 1000 ) {
01994       threatTypes = stream.readInt();
01995       for ( int i = 0; i < threatTypes; i++ )
01996          threat[i] = stream.readInt();
01997    }
01998 }
01999 
02000 
02001 void AiValue :: write ( tnstream& stream )
02002 {
02003    const int version = 2000;
02004    stream.writeInt ( version );
02005    stream.writeInt ( value );
02006    stream.writeInt ( addedValue );
02007    threat.write ( stream );
02008    stream.writeInt ( valueType );
02009 }
02010 
02011 void AiValue:: read ( tnstream& stream )
02012 {
02013    int version = stream.readInt();
02014    if ( version == 2000 ) {
02015       value = stream.readInt (  );
02016       addedValue= stream.readInt (  );
02017       threat.read ( stream );
02018       valueType = stream.readInt (  );
02019    }
02020 }
02021 
02022 const int aiParamVersion = 3002;
02023 
02024 void AiParameter::write ( tnstream& stream )
02025 {
02026    stream.writeInt ( aiParamVersion );
02027    stream.writeInt ( lastDamage );
02028    stream.writeInt ( damageTime.abstime );
02029    stream.writeInt ( dest.x );
02030    stream.writeInt ( dest.y );
02031    stream.writeInt ( dest.getNumericalHeight() );
02032    stream.writeInt ( dest_nwid );
02033    stream.writeInt ( data );
02034    AiValue::write( stream );
02035    stream.writeInt ( task );
02036    stream.writeInt ( jobPos );
02037    stream.writeInt ( jobs.size() );
02038    for ( int i = 0; i < jobs.size(); i++ )
02039       stream.writeInt( jobs[i] );
02040    stream.writeInt ( resetAfterJobCompletion );
02041 }
02042 
02043 void AiParameter::read ( tnstream& stream )
02044 {
02045    int version = stream.readInt();
02046    if ( version >= 3000 && version <= aiParamVersion ) {
02047       lastDamage = stream.readInt();
02048       damageTime.abstime = stream.readInt();
02049       int x = stream.readInt();
02050       int y = stream.readInt();
02051       int z = stream.readInt();
02052       dest.setnum ( x, y, z );
02053       dest_nwid = stream.readInt();
02054       data = stream.readInt();
02055       AiValue::read( stream );
02056       task = (Task) stream.readInt();
02057       if ( version == 3000 ) {
02058          jobs.clear();
02059          jobs.push_back ( Job( stream.readInt() ));
02060       } else {
02061          jobPos = stream.readInt();
02062          int num = stream.readInt();
02063          jobs.clear();
02064          for ( int i = 0; i < num; i++ )
02065             jobs.push_back ( Job( stream.readInt() ));
02066       }
02067       if ( version >= 3002 )
02068          resetAfterJobCompletion = stream.readInt();
02069       else
02070          resetAfterJobCompletion = false;
02071    }
02072 }
02073 
02074 void AiThreat :: reset ( void )
02075 {
02076    for ( int i = 0; i < aiValueTypeNum; i++ )
02077       threat[i] = 0;
02078 }
02079 
02080 AiParameter :: AiParameter ( Vehicle* _unit ) : AiValue ( getFirstBit( _unit->height ))
02081 {
02082    reset( _unit );
02083 }
02084 
02085 
02086 void AiParameter :: resetTask ( )
02087 {
02088    dest.setnum ( -1, -1, -1 );
02089    dest_nwid = -1;
02090    task = tsk_nothing;
02091 }
02092 
02093 void AiParameter::addJob ( Job j, bool front )
02094 {
02095    if ( front )
02096       jobs.insert ( jobs.begin(), j );
02097    else
02098       jobs.push_back ( j );
02099 }
02100 
02101 void AiParameter::setJob ( const JobList& jobs )
02102 {
02103    this->jobs = jobs;
02104 }
02105 
02106 void AiParameter::setJob ( Job j )
02107 {
02108    int pos = 0;
02109    for ( JobList::iterator i = jobs.begin(); i != jobs.end(); ++i, ++pos )
02110       if ( *i == j ) {
02111          jobPos = pos;
02112          return;
02113       }
02114 
02115    addJob ( j, true );
02116 }
02117 
02118 
02119 bool AiParameter::hasJob ( AiParameter::Job j )
02120 {
02121    return find ( jobs.begin(), jobs.end(), j ) != jobs.end();
02122 }
02123 
02124 void AiParameter :: setNewHeight()
02125 {
02126    AiValue::reset ( getFirstBit( unit->height ) );
02127 }
02128 
02129 
02130 void AiParameter :: reset ( Vehicle* _unit )
02131 {
02132    unit = _unit;
02133    lastDamage = unit->damage;
02134    AiValue::reset ( getFirstBit( _unit->height ) );
02135    data = 0;
02136 
02137    clearJobs();
02138    resetTask();
02139    resetAfterJobCompletion = false;
02140 }
02141 
02142 void AiParameter :: setNextJob()
02143 {
02144    jobPos++;
02145 }
02146 
02147 void AiParameter :: restartJobs()
02148 {
02149    jobPos = 0;
02150 }
02151 
02152 void AiParameter :: clearJobs()
02153 {
02154    jobs.clear();
02155    jobPos = 0;
02156 }
02157 
02158 
02159 
02160 
02161 GameMap :: ReplayInfo :: ReplayInfo ( void )
02162 {
02163    for (int i = 0; i < 8; i++) {
02164       guidata[i] = NULL;
02165       map[i] = NULL;
02166    }
02167    actmemstream = NULL;
02168    stopRecordingActions = 0;
02169 }
02170 
02171 void GameMap :: ReplayInfo :: read ( tnstream& stream )
02172 {
02173    bool loadgui[8];
02174    bool loadmap[8];
02175 
02176    for ( int i = 0; i < 8; i++ )
02177       loadgui[i] = stream.readInt();
02178 
02179    for ( int i = 0; i < 8; i++ )
02180       loadmap[i] = stream.readInt();
02181 
02182    stream.readInt(); // was: actmemstream
02183 
02184    for ( int i = 0; i < 8; i++ ) {
02185       if ( loadgui[i] ) {
02186          guidata[i] = new MemoryStreamStorage;
02187          guidata[i]->readfromstream ( &stream );
02188       } else
02189          guidata[i] = NULL;
02190 
02191       if ( loadmap[i] ) {
02192          map[i] = new MemoryStreamStorage;
02193          map[i]->readfromstream ( &stream );
02194       } else
02195          map[i] = NULL;
02196    }
02197 
02198    actmemstream = NULL;
02199 }
02200 
02201 void GameMap :: ReplayInfo :: write ( tnstream& stream )
02202 {
02203    for ( int i = 0; i < 8; i++ )
02204       stream.writeInt ( guidata[i] != NULL );
02205 
02206    for ( int i = 0; i < 8; i++ )
02207       stream.writeInt ( map[i] != NULL );
02208 
02209    stream.writeInt ( actmemstream != NULL );
02210 
02211    for ( int i = 0; i < 8; i++ ) {
02212       // printf("GameMap :: ReplayInfo :: write  i=%d\n", i );
02213       if ( guidata[i] )
02214          guidata[i]->writetostream ( &stream );
02215 
02216       if ( map[i] )
02217          map[i]->writetostream ( &stream );
02218    }
02219 }
02220 
02221 void GameMap :: ReplayInfo :: closeLogging()
02222 {
02223    if ( actmemstream ) {
02224       delete actmemstream;
02225       actmemstream = NULL;
02226    }
02227 }
02228 
02229 GameMap :: ReplayInfo :: ~ReplayInfo ( )
02230 {
02231    for (int i = 0; i < 8; i++)  {
02232       if ( guidata[i] ) {
02233          delete guidata[i];
02234          guidata[i] = NULL;
02235       }
02236       if ( map[i] ) {
02237          delete map[i];
02238          map[i] = NULL;
02239       }
02240   }
02241   if ( actmemstream ) {
02242      delete actmemstream ;
02243      actmemstream = NULL;
02244   }
02245 }
02246 
02247 GameParameterSettings gameParameterSettings[gameparameternum ] = {
02248       {  "LifetimeTrack",                      1,                    1,   maxint,             true,   false,   "lifetime of tracks"},//       cgp_fahrspur                        
02249       {  "LifetimeBrokenIce",                  2,                    1,   maxint,             true,   false,   "freezing time of icebreaker fairway"},   //       cgp_eis,                            
02250       {  "MoveFromInaccessibleFields",         1,                    0,   1,                  true,   false,    "move vehicles from unaccessible fields"},   //       cgp_movefrominvalidfields,          
02251       {  "BuildingConstructionFactorMaterial", 100,                  0,   maxint,             true,   false,   "building construction material factor (percent)"},   //       cgp_building_material_factor,
02252       {  "BuildingConstructionFactorEnergy",   100,                  0,   maxint,             true,   false,   "building construction fuel factor (percent)"},   //       cgp_building_fuel_factor,
02253       {  "ForbidBuildingConstruction",         0,                    0,   1,                  true,   false,   "forbid construction of buildings"},   //       cgp_forbid_building_construction,
02254       {  "LimitUnitProductionByUnit",          0,                    0,   2,                  true,   false,   "limit construction of units by other units"},   //       cgp_forbid_unitunit_construction,   
02255       {  "Bi3Training",                        0,                    0,   maxunitexperience,  true,   false,   "use BI3 style training factor "},   //       cgp_bi3_training,                   
02256       {  "MaxMinesOnField",                    1,                    0,   maxint,             true,   false,   "maximum number of mines on a single field"},   //       cgp_maxminesonfield,                
02257       {  "LifetimeAntipersonnelMine",          0,                    0,   maxint,             true,   false,   "lifetime of antipersonnel mine"},   //       cgp_antipersonnelmine_lifetime,     
02258       {  "LifetimeAntiTankMine",               0,                    0,   maxint,             true,   false,   "lifetime of antitank mine"},   //       cgp_antitankmine_lifetime,          
02259       {  "LifetimeAntiSubMine",                0,                    0,   maxint,             true,   false,   "lifetime of antisub mine"},   //       cgp_mooredmine_lifetime,            
02260       {  "LifetimeAntiShipMine",               0,                    0,   maxint,             true,   false,   "lifetime of antiship mine"},   //       cgp_floatingmine_lifetime,          
02261       {  "BuildingArmorFactor",                100,                  1,   maxint,             true,   false,   "building armor factor (percent)"},   //       cgp_buildingarmor,                  
02262       {  "MaxBuildingRepair",                  100,                  0,   100,                true,   false,   "max building damage repair / turn"},   //       cgp_maxbuildingrepair,              
02263       {  "BuildingRepairCostIncrease",         100,                  1,   maxint,             true,   false,   "building repair cost increase (percent)"},   //       cgp_buildingrepairfactor,           
02264       {  "GlobalFuel",                         1,                    0,   1,                  true,   false,   "fuel globally available (BI Resource Mode)"},   //       cgp_globalfuel,                     
02265       {  "MaxTrainingExperience",              maxunitexperience,    0,   maxunitexperience,  true,   false,   "maximum experience that can be gained by training"},   //       cgp_maxtrainingexperience,          
02266       {  "InitialMapVisibility",               0,                    0,   2,                  true,   false,   "initial map visibility"},   //       cgp_initialMapVisibility,           
02267       {  "AttackPower",                        40,                   1,   100,                true,   false,   "attack power (EXPERIMENTAL!)"},   //       cgp_attackPower,                    
02268       {  "JammingAmplifier",                   100,                  0,   1000,               true,   false,   "jamming amplifier (EXPERIMENTAL!)"},   //       cgp_jammingAmplifier,               
02269       {  "JammingSlope",                       10,                   0,   100,                true,   false,   "jamming slope (EXPERIMENTAL!)"},   //       cgp_jammingSlope,                   
02270       {  "SupervisorMapSave",                  0,                    0,   1,                  false,  false,   "The Supervisor may save a game as new map (spying!!!)"},  //       cgp_superVisorCanSaveMap,           
02271       {  "ObjectsDestroyedByTerrain",          1,                    0,   1,                  true,   false,   "objects can be destroyed by terrain"},   //       cgp_objectsDestroyedByTerrain,      
02272       {  "TrainingIncrement",                  2,                    1,   maxunitexperience,  true,   false,   "training centers: training increment"},   //       cgp_trainingIncrement,              
02273       {  "ExperienceEffectDivisorAttack",      1,                    1,   10,                 false,  false,   "experience effect divisor for attack"},  //       gp_experienceDivisorAttack
02274       {  "DisableDirectView",                  1,                    0,   1,                  false,  false,   "disable direct View"},  //       cgp_disableDirectView
02275       {  "DisableUnitTrade",                   0,                    0,   1,                  false,  false,   "disable transfering units/buildings to other players"},  //       cgp_disableUnitTransfer
02276       {  "ExperienceEffectDivisorDefense",     1,                    1,   10,                 false,  false,   "experience effect divisor for defense"},  //       cgp_experienceDivisorDefense
02277       {  "DebugGameEvents",                    0,                    0,   2,                  true,   false,   "debug game events"},  //       cgp_debugEvents
02278       {  "ObjectGrowthRate",                   0,                    0,   maxint,             true,   false,   "Object growth rate (percentage)" },  //       cgp_objectGrowthMultiplier
02279       {  "ObjectsGrowOnOtherObjects",          1,                    0,   1,                  false,  false,   "Objects can grow on fields with other objects"  },  //       cgp_objectGrowOnOtherObjects
02280       {  "ResearchOutputMultiplier",           1,                    1,   maxint,             false,  false,   "Multiplies the research output of all labs"  },  //       cgp_researchOutputMultiplier
02281       {  "ProduceOnlyResearchedStuffInternally", 0,                  0,   1,                  true,   false,   "Produce only researched stuff internally" },
02282       {  "ProduceOnlyResearchedStuffExternally", 1,                  0,   1,                  true,   false,   "Produce only researched stuff externally" }
02283 };
02284 

Generated on Mon May 21 01:26:33 2012 for Advanced Strategic Command by  doxygen 1.5.1