00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00036 #include "overviewmapimage.h"
00037 #include "gameeventsystem.h"
00038 #include "spfst.h"
00039
00040
00041 RandomGenerator::RandomGenerator(int seedValue){
00042
00043 }
00044
00045 RandomGenerator::~RandomGenerator(){
00046
00047
00048 }
00049
00050 unsigned int RandomGenerator::getPercentage(){
00051 return getRandomValue(100);
00052 }
00053
00054 unsigned int RandomGenerator::getRandomValue(int limit) {
00055 return getRandomValue(0, limit);
00056 }
00057
00058 unsigned int RandomGenerator::getRandomValue (int lowerLimit, int upperLimit){
00059 if(upperLimit == 0) {
00060 return 1;
00061 }
00062 int random_integer = rand();
00063 random_integer = random_integer % upperLimit;
00064 return (lowerLimit + random_integer);
00065 }
00066
00067
00068
00069
00070 OverviewMapHolder :: OverviewMapHolder( GameMap& gamemap ) : map(gamemap), initialized(false), secondMapReady(false), completed(false), connected(false), x(0),y(0)
00071 {
00072 }
00073
00074 void OverviewMapHolder :: connect()
00075 {
00076 if ( !connected ) {
00077 idleEvent.connect ( SigC::slot( *this, &OverviewMapHolder::idleHandler ));
00078 connected = true;
00079 }
00080 }
00081
00082
00083 SigC::Signal0<void> OverviewMapHolder::generationComplete;
00084
00085 bool OverviewMapHolder :: idleHandler( )
00086 {
00087 int t = ticker;
00088 while ( !completed && (t + 5 > ticker ))
00089 drawNextField( true );
00090 return true;
00091 }
00092
00093
00094 bool OverviewMapHolder::updateField( const MapCoordinate& pos )
00095 {
00096 SPoint imgpos = OverviewMapImage::map2surface( pos );
00097
00098 tfield* fld = map.getField( pos );
00099 VisibilityStates visi = fieldVisibility( fld, map.getPlayerView(), &map );
00100 if ( visi == visible_not ) {
00101 OverviewMapImage::fill ( overviewMapImage, imgpos, 0xff545454 );
00102 } else {
00103 if ( fld->building && fieldvisiblenow( fld, map.getPlayerView(), &map) )
00104 OverviewMapImage::fill ( overviewMapImage, imgpos, map.player[fld->building->getOwner()].getColor() );
00105 else {
00106
00107 int w = fld->getweather();
00108 fld->typ->getQuickView()->blit( overviewMapImage, imgpos );
00109 for ( tfield::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); ++i )
00110 if ( visi > visible_ago || i->typ->visibleago )
00111 i->getOverviewMapImage( w )->blit( overviewMapImage, imgpos );
00112
00113 if ( fld->vehicle && fieldvisiblenow( fld, map.getPlayerView()) )
00114 OverviewMapImage::fillCenter ( overviewMapImage, imgpos, map.player[fld->vehicle->getOwner()].getColor() );
00115
00116 if ( visi == visible_ago )
00117 OverviewMapImage::lighten( overviewMapImage, imgpos, 0.7 );
00118
00119 }
00120
00121 }
00122 return true;
00123 }
00124
00125 void OverviewMapHolder::drawNextField( bool signalOnCompletion )
00126 {
00127 if ( !init() )
00128 return;
00129
00130 if ( x == map.xsize ) {
00131 x = 0;
00132 ++y;
00133 }
00134 if ( y < map.ysize ) {
00135 if ( !updateField( MapCoordinate(x,y)))
00136 return;
00137
00138 ++x;
00139 }
00140 if ( y == map.ysize ) {
00141 completed = true;
00142 if ( signalOnCompletion )
00143 generationComplete();
00144
00145 completedMapImage = overviewMapImage.Duplicate();
00146 secondMapReady = true;
00147 }
00148 }
00149
00150 Surface OverviewMapHolder::createNewSurface()
00151 {
00152 Surface s;
00153 if ( map.xsize > 0 && map.ysize > 0 ) {
00154 s = Surface::createSurface( (map.xsize+1) * 6, 4 + map.ysize * 2 , 32, 0 );
00155 }
00156 return s;
00157 }
00158
00159 bool OverviewMapHolder::init()
00160 {
00161 if ( map.ysize <= 0 || map.xsize <= 0 )
00162 return false;
00163
00164 if ( !initialized ) {
00165 overviewMapImage = createNewSurface();
00166 initialized = true;
00167 }
00168 return initialized;
00169 }
00170
00171 void OverviewMapHolder::resetSize()
00172 {
00173 initialized = false;
00174 }
00175
00176
00177 const Surface& OverviewMapHolder::getOverviewMap( bool complete )
00178 {
00179 bool initialized = init();
00180 assert( initialized );
00181 if ( complete )
00182 while ( !completed )
00183 drawNextField( false );
00184
00185 if( secondMapReady )
00186 return completedMapImage;
00187 else
00188 return overviewMapImage;
00189 }
00190
00191 void OverviewMapHolder::startUpdate()
00192 {
00193 completed = false;
00194 x = 0;
00195 y = 0;
00196 }
00197
00198 void OverviewMapHolder::clear(bool allImages )
00199 {
00200 if ( !initialized )
00201 return;
00202
00203 overviewMapImage.Fill( Surface::transparent );
00204 if ( allImages ) {
00205 if ( completedMapImage.valid() )
00206 completedMapImage.Fill( Surface::transparent );
00207 secondMapReady = false;
00208 }
00209
00210 startUpdate();
00211 }
00212
00213 void OverviewMapHolder::clearmap( GameMap* actmap )
00214 {
00215 if ( actmap )
00216 actmap->overviewMapHolder.clear();
00217 }
00218
00219
00220 GameMap :: GameMap ( void )
00221 : overviewMapHolder( *this ), network(NULL)
00222 {
00223 randomSeed = rand();
00224 dialogsHooked = false;
00225
00226 eventID = 0;
00227
00228 state = Normal;
00229
00230 int i;
00231
00232 xsize = 0;
00233 ysize = 0;
00234 field = NULL;
00235
00236 actplayer = -1;
00237 time.abstime = 0;
00238
00239 _resourcemode = 0;
00240
00241 for ( i = 0; i < 9; ++i ) {
00242 player[i].setParentMap ( this, i );
00243 if ( i == 0 )
00244 player[i].stat = Player::human;
00245 else
00246 player[i].stat = Player::computer;
00247
00248 player[i].research.chainToMap ( this, i );
00249 }
00250
00251 unitnetworkid = 0;
00252
00253 levelfinished = 0;
00254
00255 messageid = 0;
00256
00257 continueplaying = false;
00258 replayinfo = NULL;
00259 playerView = 0;
00260 lastjournalchange.abstime = 0;
00261 graphicset = 0;
00262 gameparameter_num = 0;
00263 game_parameter = NULL;
00264 mineralResourcesDisplayed = 0;
00265
00266
00267
00268
00269
00270 #ifdef WEATHERGENERATOR
00271 weatherSystem = new WeatherSystem(this, 1, 0.03);
00272 #endif
00273 setgameparameter( cgp_objectsDestroyedByTerrain, 1 );
00274 }
00275
00276 GameMap::Campaign::Campaign()
00277 {
00278 avail = false;
00279 id = 0;
00280 directaccess = true;
00281 }
00282
00283 void GameMap :: guiHooked()
00284 {
00285 overviewMapHolder.connect();
00286 dialogsHooked = true;
00287 }
00288
00289 const int tmapversion = 22;
00290
00291 void GameMap :: read ( tnstream& stream )
00292 {
00293 int version;
00294 int i;
00295
00296 xsize = stream.readWord();
00297 ysize = stream.readWord();
00298
00299 if ( xsize == 0xfffe && ysize == 0xfffc ) {
00300 version = stream.readInt();
00301 if ( version > tmapversion )
00302 throw tinvalidversion ( "GameMap", tmapversion, version );
00303
00304 xsize = stream.readInt();
00305 ysize = stream.readInt();
00306 } else
00307 version = 1;
00308
00309 stream.readWord();
00310 stream.readWord();
00311 stream.readInt();
00312 field = NULL;
00313
00314 if ( version <= 13 ) {
00315 char buf[11];
00316 stream.readdata ( buf, 11 );
00317 buf[10] = 0;
00318 codeWord = buf;
00319 } else {
00320 codeWord = stream.readString();
00321 }
00322
00323 if ( version < 2 )
00324 ___loadtitle = stream.readInt();
00325 else
00326 ___loadtitle = true;
00327
00328 bool loadCampaign = stream.readInt();
00329 actplayer = stream.readChar();
00330 time.abstime = stream.readInt();
00331 if(version < 9 || version >= 17){
00332 stream.readChar();
00333 weather.windSpeed = stream.readChar();
00334 weather.windDirection = stream.readChar();
00335 }
00336
00337 if ( version >= 11 )
00338 if ( stream.readInt() != 0x12345678 )
00339 throw ASCmsgException("marker not matched when loading GameMap");
00340
00341
00342 for ( int j = 0; j < 4; j++ )
00343 stream.readChar();
00344 for ( i = 0; i< 12; i++ )
00345 stream.readChar();
00346
00347 _resourcemode = stream.readInt();
00348
00349 int alliances[8][8];
00350 if ( version <= 10 )
00351 for ( i = 0; i < 8; i++ )
00352 for ( int j = 0; j < 8; j++ )
00353 alliances[j][i] = stream.readChar();
00354
00355 int dummy_playername[9];
00356 for ( i = 0; i< 9; i++ ) {
00357 player[i].existanceAtBeginOfTurn = stream.readChar();
00358 stream.readInt();
00359 stream.readInt();
00360 if ( version <= 5 )
00361 player[i].research.read_struct ( stream );
00362 else
00363 player[i].research.read ( stream );
00364
00365 player[i].ai = (BaseAI*)stream.readInt() ;
00366 player[i].stat = Player::PlayerStatus ( stream.readChar() );
00367 stream.readChar();
00368 dummy_playername[i] = stream.readInt();
00369 player[i].passwordcrc.read ( stream );
00370 player[i].__dissectionsToLoad = stream.readInt();
00371 player[i].__loadunreadmessage = stream.readInt();
00372 player[i].__loadoldmessage = stream.readInt();
00373 player[i].__loadsentmessage = stream.readInt();
00374 if ( version >= 3 )
00375 player[i].ASCversion = stream.readInt();
00376 else
00377 player[i].ASCversion = 0;
00378
00379 if ( version >= 9 )
00380 player[i].cursorPos.read( stream );
00381
00382 if ( version >= 11 )
00383 player[i].diplomacy.read( stream );
00384 else {
00385 if ( i < 8 )
00386 for ( int j = 0; j< 8; ++j ) {
00387 if ( alliances[i][j] == 0 )
00388 player[i].diplomacy.setState( j, PEACE, false );
00389 else
00390 player[i].diplomacy.setState( j, WAR, false );
00391 }
00392 }
00393
00394 if ( version >= 12 )
00395 player[i].email = stream.readString();
00396
00397 if ( version >= 22 )
00398 player[i].read( stream );
00399 }
00400
00401 if ( version >= 11 )
00402 if ( stream.readInt() != 0x12345678 )
00403 throw ASCmsgException("marker not matched when loading GameMap");
00404
00405
00406
00407
00408 if ( version <= 4 ) {
00410 loadOldEvents = stream.readInt();
00411 stream.readInt();
00412 stream.readInt();
00413 }
00414
00415
00416 unitnetworkid = stream.readInt();
00417 levelfinished = stream.readChar();
00418
00419 bool alliance_names_not_used_any_more[8];
00420 if ( version <= 9 ) {
00421 ___loadLegacyNetwork = stream.readInt();
00422 for ( i = 0; i < 8; i++ )
00423 alliance_names_not_used_any_more[i] = stream.readInt();
00424 } else {
00425 ___loadLegacyNetwork = false;
00426 for ( i = 0; i < 8; i++ )
00427 alliance_names_not_used_any_more[i] = 0;
00428 }
00429
00430 if ( version <= 12 ) {
00431 for ( i = 0; i< 8; i++ ) {
00432 stream.readWord();
00433 stream.readWord();
00434 stream.readWord();
00435 stream.readWord();
00436 }
00437 }
00438
00439 if ( version <= 9 )
00440 stream.readInt();
00441
00442 __loadunsentmessage = stream.readInt();
00443 __loadmessages = stream.readInt();
00444
00445 messageid = stream.readInt();
00446
00447 if( version < 2 ) {
00448 ___loadJournal = stream.readInt();
00449 ___loadNewJournal = stream.readInt();
00450 } else {
00451 ___loadJournal = true;
00452 ___loadNewJournal = true;
00453 }
00454
00455 int exist_humanplayername[9];
00456 for ( i = 0; i < 8; i++ )
00457 exist_humanplayername[i] = stream.readInt();
00458 exist_humanplayername[8] = 0;
00459
00460
00461 int exist_computerplayername[9];
00462 for ( i = 0; i < 8; i++ )
00463 exist_computerplayername[i] = stream.readInt();
00464 exist_computerplayername[8] = 0;
00465
00466 supervisorpasswordcrc.read ( stream );
00467
00468 if ( version <= 10 )
00469 for ( i = 0; i < 8; i++ )
00470 stream.readChar();
00471
00472 stream.readInt();
00473 bool load_shareview = false;
00474 if ( version <= 10 )
00475 load_shareview = stream.readInt();
00476
00477 continueplaying = stream.readInt();
00478 __loadreplayinfo = stream.readInt();
00479 playerView = stream.readInt();
00480 lastjournalchange.abstime = stream.readInt();
00481
00482 for ( i = 0; i< 8; i++ )
00483 bi_resource[i].read ( stream );
00484
00485 int preferredfilenames = stream.readInt();
00486
00487 bool __loadEllipse = stream.readInt();
00488 graphicset = stream.readInt();
00489 gameparameter_num = stream.readInt();
00490
00491 stream.readInt();
00492 mineralResourcesDisplayed = stream.readInt();
00493 for ( i = 0; i< 9; i++ )
00494 player[i].queuedEvents = stream.readInt();
00495
00496 for ( i = 0; i < 19; i++ )
00497 stream.readInt();
00498
00499 int _oldgameparameter[8];
00500 for ( i = 0; i < 8; i++ )
00501 _oldgameparameter[i] = stream.readInt();
00502
00503 if ( version >= 11 )
00504 if ( stream.readInt() != 0x12345678 )
00505 throw ASCmsgException("marker not matched when loading GameMap");
00506
00508
00510
00511
00512
00513 if ( ___loadtitle )
00514 maptitle = stream.readString();
00515
00516 if ( loadCampaign ) {
00517 if ( version <= 14 ) {
00518 campaign.id = stream.readWord();
00519 stream.readWord();
00520 stream.readChar();
00521 campaign.directaccess = stream.readChar();
00522 campaign.avail = true;
00523 for ( int d = 0; d < 21; d++ )
00524 stream.readChar();
00525 } else {
00526 campaign.id = stream.readInt();
00527 campaign.directaccess = stream.readChar();
00528 if ( version > 15 )
00529 campaign.avail = stream.readInt();
00530 }
00531 }
00532
00533 for ( int w=0; w<9 ; w++ ) {
00534 if (dummy_playername[w] )
00535 stream.readString();
00536
00537 player[w].ai = NULL;
00538
00539
00540 if ( exist_humanplayername[w] )
00541 player[w].setName( stream.readString() );
00542
00543 if ( exist_computerplayername[w] )
00544 stream.readString();
00545
00546 }
00547
00548 if ( stream.readInt() )
00549 tribute.read ( stream );
00550
00551 for ( int aa = 0; aa < 8; aa++ )
00552 if ( alliance_names_not_used_any_more[aa] ) {
00553 char* tempname = NULL;
00554 stream.readpchar ( &tempname );
00555 delete[] tempname;
00556 }
00557
00558 stream.readInt();
00559
00560 if ( load_shareview && version <= 10 ) {
00561
00562 for ( int i = 0; i < 8; i++ )
00563 for ( int j =0; j < 8; j++ ) {
00564 int sv = stream.readChar();
00565 if ( sv )
00566 player[i].diplomacy.setState( j, PEACE_SV, false );
00567 }
00568
00569 stream.readInt();
00570 }
00571
00572 if ( preferredfilenames ) {
00573 int p;
00574 int mapname[8];
00575 int mapdescription_not_used_any_more[8];
00576 int savegame[8];
00577 int savegamedescription_not_used_any_more[8];
00578 for ( p = 0; p < 8; p++ )
00579 mapname[p] = stream.readInt();
00580 for ( p = 0; p < 8; p++ )
00581 mapdescription_not_used_any_more[p] = stream.readInt();
00582 for ( p = 0; p < 8; p++ )
00583 savegame[p] = stream.readInt();
00584 for ( p = 0; p < 8; p++ )
00585 savegamedescription_not_used_any_more[p] = stream.readInt();
00586
00587 for ( int i = 0; i < 8; i++ ) {
00588 if ( mapname[i] )
00589 preferredFileNames.mapname[i] = stream.readString ();
00590
00591 if ( mapdescription_not_used_any_more[i] )
00592 stream.readString();
00593
00594 if ( savegame[i] )
00595 preferredFileNames.savegame[i] = stream.readString ();
00596
00597 if ( savegamedescription_not_used_any_more[i] )
00598 stream.readString();
00599 }
00600 }
00601
00602 if ( __loadEllipse ) {
00603 for ( int i = 0; i < 5; ++i )
00604 stream.readInt();
00605 stream.readFloat();
00606 stream.readInt();
00607 }
00608
00609 int orggpnum = gameparameter_num;
00610 gameparameter_num = 0;
00611 for ( int gp = 0; gp < 8; gp ++ )
00612 setgameparameter ( GameParameter(gp), _oldgameparameter[gp] );
00613
00614 for ( int ii = 0 ; ii < orggpnum; ii++ ) {
00615 int gpar = stream.readInt();
00616 setgameparameter ( GameParameter(ii), gpar );
00617 }
00618
00619 if ( version >= 2 ) {
00620 archivalInformation.author = stream.readString();
00621 archivalInformation.description = stream.readString();
00622 archivalInformation.tags = stream.readString();
00623 archivalInformation.requirements = stream.readString();
00624 archivalInformation.modifytime = stream.readInt();
00625 }
00626
00627 if ( version >= 4 ) {
00628 int num = stream.readInt();
00629 for ( int ii = 0; ii < num; ++ii )
00630 unitProduction.idsAllowed.push_back ( stream.readInt() );
00631
00632 for ( int ii = 0; ii < 9; ii++ ) {
00633 int num = stream.readInt( );
00634 for ( int i = 0; i < num; i++ ) {
00635 Player::PlayTime pt;
00636 pt.turn = stream.readInt();
00637 pt.date = stream.readInt();
00638 player[ii].playTime.push_back ( pt );
00639 }
00640 }
00641
00642 }
00643
00644 if ( version >= 5 ) {
00645 eventID = stream.readInt();
00646
00647 int num = stream.readInt();
00648 for ( int i = 0; i< num; ++i ) {
00649 Event* ev = new Event ( *this );
00650 ev->read ( stream );
00651 events.push_back ( ev );
00652 }
00653 }
00654
00655 if ( version >= 8 )
00656 randomSeed = stream.readInt();
00657
00658 if ( version >= 12 ) {
00659 bool nw = stream.readInt();
00660 if ( nw )
00661 network = GameTransferMechanism::read( stream );
00662 }
00663 }
00664
00665
00666 void GameMap :: write ( tnstream& stream )
00667 {
00668 int i;
00669
00670 stream.writeWord( 0xfffe );
00671 stream.writeWord( 0xfffc );
00672
00673 stream.writeInt ( tmapversion );
00674 stream.writeInt( xsize );
00675 stream.writeInt( ysize );
00676
00677 stream.writeWord( 0 );
00678 stream.writeWord( 0 );
00679 stream.writeInt (1);
00680 stream.writeString ( codeWord );
00681
00682
00683
00684 stream.writeInt( campaign.avail );
00685 stream.writeChar( actplayer );
00686 stream.writeInt( time.abstime );
00687
00688 stream.writeChar(0);
00689 stream.writeChar( weather.windSpeed );
00690 stream.writeChar( weather.windDirection );
00691
00692 stream.writeInt( 0x12345678 );
00693
00694 for ( i= 0; i < 4; i++ )
00695 stream.writeChar( 0 );
00696
00697 for ( i = 0; i< 12; i++ )
00698 stream.writeChar( 0 );
00699
00700 stream.writeInt( _resourcemode );
00701
00702 for ( i = 0; i< 9; i++ ) {
00703 stream.writeChar( player[i].existanceAtBeginOfTurn );
00704 stream.writeInt( 1 );
00705 stream.writeInt( 1 );
00706 player[i].research.write ( stream );
00707 stream.writeInt( player[i].ai != NULL );
00708 stream.writeChar( player[i].stat );
00709 stream.writeChar( 0 );
00710 stream.writeInt( 0 );
00711 player[i].passwordcrc.write ( stream );
00712 stream.writeInt( !player[i].dissections.empty() );
00713 stream.writeInt( 1 );
00714 stream.writeInt( 1 );
00715 stream.writeInt( 1 );
00716 stream.writeInt ( player[i].ASCversion );
00717 player[i].cursorPos.write( stream );
00718 player[i].diplomacy.write( stream );
00719 stream.writeString ( player[i].email );
00720 player[i].write(stream);
00721 }
00722
00723 stream.writeInt( 0x12345678 );
00724
00725 stream.writeInt( unitnetworkid );
00726 stream.writeChar( levelfinished );
00727
00728 stream.writeInt( 1 );
00729 stream.writeInt( !messages.empty() );
00730
00731 stream.writeInt( messageid );
00732
00733 for ( i = 0; i < 8; i++ )
00734 stream.writeInt( 1 );
00735
00736 for ( i = 0; i < 8; i++ )
00737 stream.writeInt( 0 );
00738
00739 supervisorpasswordcrc.write ( stream );
00740
00741 stream.writeInt( 0 );
00742
00743 stream.writeInt( continueplaying );
00744 stream.writeInt( replayinfo != NULL );
00745 stream.writeInt( playerView );
00746 stream.writeInt( lastjournalchange.abstime );
00747
00748 for ( i = 0; i< 8; i++ )
00749 bi_resource[i].write ( stream );
00750
00751 stream.writeInt( 1 );
00752 stream.writeInt( 0 );
00753 stream.writeInt( graphicset );
00754 stream.writeInt( gameparameter_num );
00755
00756 stream.writeInt( game_parameter != NULL );
00757 stream.writeInt( mineralResourcesDisplayed );
00758 for ( i = 0; i< 9; i++ )
00759 stream.writeInt( player[i].queuedEvents );
00760
00761 for ( i = 0; i < 19; i++ )
00762 stream.writeInt( 0 );
00763
00764 for ( i = 0; i < 8; i++ )
00765 stream.writeInt( getgameparameter(GameParameter(i)) );
00766
00767
00768 stream.writeInt( 0x12345678 );
00769
00770
00772
00774
00775
00776
00777 stream.writeString( maptitle );
00778
00779 if ( campaign.avail ) {
00780 stream.writeInt( campaign.id );
00781 stream.writeChar( campaign.directaccess );
00782 stream.writeInt( campaign.avail );
00783 }
00784
00785 for (int w=0; w<8 ; w++ )
00786 stream.writeString ( player[w].getName() );
00787
00788 if ( !tribute.empty() ) {
00789 stream.writeInt ( -1 );
00790 tribute.write ( stream );
00791 } else
00792 stream.writeInt ( 0 );
00793
00794 stream.writeInt ( 0 );
00795
00796 int p;
00797 for ( p = 0; p < 8; p++ )
00798 stream.writeInt( 1 );
00799
00800 for ( p = 0; p < 8; p++ )
00801 stream.writeInt( 0 );
00802
00803 for ( p = 0; p < 8; p++ )
00804 stream.writeInt( 1 );
00805
00806 for ( p = 0; p < 8; p++ )
00807 stream.writeInt( 0 );
00808
00809 for ( int k = 0; k < 8; k++ ) {
00810 stream.writeString ( preferredFileNames.mapname[k] );
00811 stream.writeString ( preferredFileNames.savegame[k] );
00812 }
00813
00814
00815 for ( int ii = 0 ; ii < gameparameter_num; ii++ )
00816 stream.writeInt ( game_parameter[ii] );
00817
00818
00819 stream.writeString ( archivalInformation.author );
00820 stream.writeString ( archivalInformation.description );
00821 stream.writeString ( archivalInformation.tags );
00822 stream.writeString ( archivalInformation.requirements );
00823 stream.writeInt ( (unsigned int) (::time ( &archivalInformation.modifytime )));
00824
00825
00826 stream.writeInt( unitProduction.idsAllowed.size() );
00827 for ( int ii = 0; ii < unitProduction.idsAllowed.size(); ++ii )
00828 stream.writeInt ( unitProduction.idsAllowed[ii] );
00829
00830
00831 for ( int ii = 0; ii < 9; ii++ ) {
00832 stream.writeInt( player[ii].playTime.size() );
00833 for ( Player::PlayTimeContainer::iterator i = player[ii].playTime.begin(); i != player[ii].playTime.end(); ++i ) {
00834 stream.writeInt( i->turn );
00835 stream.writeInt( (unsigned int) i->date );
00836 }
00837 }
00838
00839 stream.writeInt( eventID );
00840
00841 stream.writeInt ( events.size());
00842 for ( Events::iterator i = events.begin(); i != events.end(); ++i )
00843 (*i)->write( stream );
00844
00845 stream.writeInt( randomSeed );
00846
00847 if ( network ) {
00848 stream.writeInt( 1 );
00849 network->write( stream );
00850 } else
00851 stream.writeInt( 0 );
00852 }
00853
00854
00855
00856
00857 MapCoordinate& GameMap::getCursor()
00858 {
00859 #ifdef sgmain
00860 if ( actplayer >= 0 ) {
00861 if ( !player[actplayer].cursorPos.valid() ) {
00862 bool found = false;
00863 for ( int y = 0; y < ysize && !found; ++y )
00864 for ( int x = 0; x < xsize && !found; ++x )
00865 if ( getField(x,y)->getContainer() )
00866 if ( getField(x,y)->getContainer()->getOwner() == actplayer ) {
00867 player[actplayer].cursorPos = getField(x,y)->getContainer()->getPosition();
00868 found = true;
00869 }
00870 }
00871 return player[actplayer].cursorPos;
00872 } else
00873 return player[0].cursorPos;
00874 #else
00875 return player[8].cursorPos;
00876 #endif
00877 }
00878
00879
00880 void GameMap :: cleartemps( int b, int value )
00881 {
00882 if ( xsize <= 0 || ysize <= 0)
00883 return;
00884
00885 int l = 0;
00886 for ( int x = 0; x < xsize ; x++)
00887 for ( int y = 0; y < ysize ; y++) {
00888
00889 if (b & 1 )
00890 field[l].a.temp = value;
00891 if (b & 2 )
00892 field[l].a.temp2 = value;
00893 if (b & 4 )
00894 field[l].temp3 = value;
00895 if (b & 8 )
00896 field[l].temp4 = value;
00897
00898 l++;
00899 }
00900 }
00901
00902 void GameMap :: allocateFields ( int x, int y, TerrainType::Weather* terrain )
00903 {
00904 field = new tfield[x*y];
00905 for ( int i = 0; i < x*y; i++ ) {
00906 if ( terrain ) {
00907 field[i].typ = terrain;
00908 field[i].setparams();
00909 }
00910 field[i].setMap ( this );
00911 }
00912 xsize = x;
00913 ysize = y;
00914 overviewMapHolder.connect();
00915 }
00916
00917
00918 void GameMap :: calculateAllObjects ( void )
00919 {
00920 calculateallobjects();
00921 }
00922
00923 tfield* GameMap :: getField(int x, int y)
00924 {
00925 if ((x < 0) || (y < 0) || (x >= xsize) || (y >= ysize))
00926 return NULL;
00927 else
00928 return ( &field[y * xsize + x] );
00929 }
00930
00931 tfield* GameMap :: getField(const MapCoordinate& pos )
00932 {
00933 return getField ( pos.x, pos.y );
00934 }
00935
00936 int GameMap :: getPlayerView() const
00937 {
00938 #ifdef karteneditor
00939 return -1;
00940 #else
00941 return playerView;
00942 #endif
00943 }
00944
00945
00946 void GameMap :: setPlayerView( int player )
00947 {
00948 playerView = player;
00949 }
00950
00951
00952
00953 bool GameMap :: isResourceGlobal ( int resource )
00954 {
00955 if ( _resourcemode == 1 ) {
00956 if ( resource == 1 )
00957 return false;
00958 else
00959 if ( resource == 2 )
00960 return getgameparameter(cgp_globalfuel);
00961 else
00962 return true;
00963 } else {
00964
00965
00966
00967
00968
00969
00970
00971
00972 return false;
00973 }
00974 }
00975
00976 int GameMap :: getgameparameter ( GameParameter num ) const
00977 {
00978 if ( game_parameter && num < gameparameter_num ) {
00979 return game_parameter[num];
00980 } else
00981 if ( num < gameparameternum )
00982 return gameParameterSettings[num].defaultValue;
00983 else
00984 return 0;
00985 }
00986
00987 void GameMap :: setgameparameter ( GameParameter num, int value )
00988 {
00989 if ( game_parameter ) {
00990 if ( num < gameparameter_num )
00991 game_parameter[num] = value;
00992 else {
00993 int* oldparam = game_parameter;
00994 game_parameter = new int[num+1];
00995 for ( int i = 0; i < gameparameter_num; i++ )
00996 game_parameter[i] = oldparam[i];
00997 for ( int j = gameparameter_num; j < num; j++ )
00998 if ( j < gameparameternum )
00999 game_parameter[j] = gameParameterSettings[j].defaultValue;
01000 else
01001 game_parameter[j] = 0;
01002 game_parameter[num] = value;
01003 gameparameter_num = num + 1;
01004 delete[] oldparam;
01005 }
01006 } else {
01007 game_parameter = new int[num+1];
01008 for ( int j = 0; j < num; j++ )
01009 if ( j < gameparameternum )
01010 game_parameter[j] = gameParameterSettings[j].defaultValue;
01011 else
01012 game_parameter[j] = 0;
01013 game_parameter[num] = value;
01014 gameparameter_num = num + 1;
01015 }
01016 }
01017
01018 void GameMap :: setupResources ( void )
01019 {
01020 for ( int n = 0; n< 8; n++ ) {
01021 bi_resource[n].energy = 0;
01022 bi_resource[n].material = 0;
01023 bi_resource[n].fuel = 0;
01024
01025 #ifdef sgmain
01026
01027 for ( Player::BuildingList::iterator i = player[n].buildingList.begin(); i != player[n].buildingList.end(); i++ )
01028 for ( int r = 0; r < 3; r++ )
01029 if ( isResourceGlobal( r )) {
01030 bi_resource[n].resource(r) += (*i)->actstorage.resource(r);
01031 (*i)->actstorage.resource(r) = 0;
01032 }
01033 #endif
01034 }
01035 }
01036
01037
01038
01039
01040 int GameMap :: eventpassed( int saveas, int action, int mapid )
01041 {
01042 return eventpassed ( (action << 16) | saveas, mapid );
01043 }
01044
01045
01046
01047 int GameMap :: eventpassed( int id, int mapid )
01048 {
01049 return 0;
01050 }
01051
01052
01053 void GameMap::registerUnitNetworkID( Vehicle* veh )
01054 {
01055 vehicleLookupCache[veh->networkid] = veh;
01056 if ( unitnetworkid < veh->networkid )
01057 unitnetworkid = veh->networkid;
01058 }
01059
01060 void GameMap::unregisterUnitNetworkID( Vehicle* veh )
01061 {
01062 VehicleLookupCache::iterator j = vehicleLookupCache.find(veh->networkid);
01063 if ( j != vehicleLookupCache.end() )
01064 vehicleLookupCache.erase(j);
01065 }
01066
01067
01068 int GameMap :: getNewNetworkID()
01069 {
01070 ++unitnetworkid;
01071 return unitnetworkid;
01072 }
01073
01074 Vehicle* GameMap :: getUnit ( Vehicle* eht, int nwid )
01075 {
01076 if ( !eht )
01077 return NULL;
01078 else {
01079 if ( eht->networkid == nwid )
01080 return eht;
01081 else
01082 for ( ContainerBase::Cargo::const_iterator i = eht->getCargo().begin(); i != eht->getCargo().end(); ++i )
01083 if ( *i ) {
01084 if ( (*i)->networkid == nwid )
01085 return *i;
01086 else {
01087 Vehicle* ld = getUnit ( *i, nwid );
01088 if ( ld )
01089 return ld;
01090 }
01091 }
01092 return NULL;
01093 }
01094 }
01095
01096 Vehicle* GameMap :: getUnit ( int nwid, bool consistencyCheck )
01097 {
01098 VehicleLookupCache::iterator i = vehicleLookupCache.find( nwid );
01099 if ( i != vehicleLookupCache.end() )
01100 return i->second;
01101
01102
01103 if ( consistencyCheck )
01104 for ( int p = 0; p < 9; p++ )
01105 for ( Player::VehicleList::iterator i = player[p].vehicleList.begin(); i != player[p].vehicleList.end(); i++ )
01106 if ( (*i)->networkid == nwid ) {
01107 displaymessage("warning: id not registered in VehicleLookupCache!",1);
01108 return *i;
01109 }
01110
01111 return NULL;
01112 }
01113
01114
01115 Vehicle* GameMap :: getUnit ( int x, int y, int nwid )
01116 {
01117 tfield* fld = getField ( x, y );
01118 if ( !fld )
01119 return NULL;
01120
01121 if ( fld->vehicle && fld->vehicle->networkid == nwid )
01122 return fld->vehicle;
01123
01124 if ( fld->getContainer() )
01125 return fld->getContainer()->findUnit( nwid );
01126
01127 return NULL;
01128
01129 }
01130
01131 ContainerBase* GameMap::getContainer ( int nwid )
01132 {
01133 if ( nwid > 0 )
01134 return getUnit(nwid);
01135 else {
01136 int x = (-nwid) & 0xffff;
01137 int y = (-nwid) >> 16;
01138 tfield* fld = getfield(x,y);
01139 if ( !fld )
01140 return NULL;
01141
01142 return fld->building;
01143 }
01144 }
01145
01146
01147
01148 void GameMap::beginTurn()
01149 {
01150 if ( !player[actplayer].exist() )
01151 if ( replayinfo )
01152 if ( replayinfo->guidata[actplayer] ) {
01153 delete replayinfo->guidata[actplayer];
01154 replayinfo->guidata[actplayer] = NULL;
01155 }
01156
01157 if ( player[actplayer].exist() && player[actplayer].stat != Player::off ) {
01158 sigPlayerTurnBegins( player[actplayer] );
01159
01160
01161
01162
01163 }
01164 }
01165
01166
01167 void GameMap::endTurn()
01168 {
01169 player[actplayer].ASCversion = getNumericVersion();
01170 Player::PlayTime pt;
01171 pt.turn = time.turn();
01172 ::time ( &pt.date );
01173 player[actplayer].playTime.push_back ( pt );
01174
01175 sigPlayerTurnEnds( player[actplayer] );
01176
01177 for ( int i = 0; i < 9; ++i )
01178 for ( Player::BuildingList::iterator v = player[i].buildingList.begin(); v != player[i].buildingList.end(); ++v ) {
01179 if ( i == actplayer )
01180 (*v)->endOwnTurn();
01181 (*v)->endAnyTurn();
01182 }
01183
01184
01185 Player::VehicleList toRemove;
01186 for ( Player::VehicleList::iterator v = player[actplayer].vehicleList.begin(); v != player[actplayer].vehicleList.end(); ++v ) {
01187 Vehicle* actvehicle = *v;
01188
01189
01190
01191 if (( actvehicle->height >= chtieffliegend ) && ( actvehicle->height <= chhochfliegend ) && ( getfield(actvehicle->xpos,actvehicle->ypos)->vehicle == actvehicle)) {
01192 if ( getmaxwindspeedforunit ( actvehicle ) < weather.windSpeed*maxwindspeed ){
01193 new Message ( getUnitReference( *v ) + " crashed because of the strong wind", this, 1<<(*v)->getOwner());
01194 toRemove.push_back ( *v );
01195 } else {
01196
01197 int j = actvehicle->getTank().fuel - UnitHooveringLogic::calcFuelUsage( actvehicle );
01198 if (j < 0) {
01199 new Message ( getUnitReference( *v ) + " crashed due to lack of fuel", this, 1<<(*v)->getOwner());
01200 toRemove.push_back ( *v );
01201
01202 } else {
01203
01204 actvehicle->getResource( actvehicle->getTank().fuel - j, Resources::Fuel, false);
01205 }
01206 }
01207 }
01208
01209 if ( actvehicle )
01210 actvehicle->endOwnTurn();
01211
01212 }
01213
01214 for ( Player::VehicleList::iterator v = toRemove.begin(); v != toRemove.end(); v++ )
01215 delete *v;
01216
01217 checkunitsforremoval();
01218
01219 for ( int i = 0; i < 9; ++i )
01220 for ( Player::VehicleList::iterator v = player[i].vehicleList.begin(); v != player[i].vehicleList.end(); ++v )
01221 (*v)->endAnyTurn();
01222
01223
01224 if ( replayinfo )
01225 replayinfo->closeLogging();
01226
01227 processJournal();
01228
01229 sigPlayerTurnHasEnded( player[actplayer] );
01230
01231 }
01232
01233
01234 void GameMap::endRound()
01235 {
01236 actplayer = 0;
01237 time.set ( time.turn()+1, 0 );
01238
01239 for ( int y = 0; y < ysize; ++y )
01240 for ( int x = 0; x < xsize; ++x )
01241 getField(x,y)->endRound( time.turn() );
01242
01243 for (int i = 0; i <= 7; i++) {
01244 if (player[i].exist() && player[i].stat != Player::off ) {
01245
01246 for ( Player::VehicleList::iterator j = player[i].vehicleList.begin(); j != player[i].vehicleList.end(); j++ )
01247 (*j)->endRound();
01248
01249 for ( Player::BuildingList::iterator j = player[i].buildingList.begin(); j != player[i].buildingList.end(); j++ )
01250 (*j)->endRound();
01251
01252 typedef PointerList<ContainerBase::Work*> BuildingWork;
01253 BuildingWork buildingWork;
01254
01255 for ( Player::BuildingList::iterator j = player[i].buildingList.begin(); j != player[i].buildingList.end(); j++ ) {
01256 ContainerBase::Work* w = (*j)->spawnWorkClasses( false );
01257 if ( w )
01258 buildingWork.push_back ( w );
01259 }
01260
01261 for ( Player::VehicleList::iterator j = player[i].vehicleList.begin(); j != player[i].vehicleList.end(); j++ ) {
01262 ContainerBase::Work* w = (*j)->spawnWorkClasses( false );
01263 if ( w )
01264 buildingWork.push_back ( w );
01265 }
01266
01267
01268 bool didSomething;
01269 do {
01270 didSomething = false;
01271 for ( BuildingWork::iterator j = buildingWork.begin(); j != buildingWork.end(); j++ )
01272 if ( ! (*j)->finished() )
01273
01274 if ( (*j)->run() )
01275 didSomething = true;
01276
01277 } while ( didSomething );
01278 doresearch( this, i );
01279 }
01280 }
01281
01282 int playerMask = 0;
01283 for ( int i = 0; i < getPlayerCount(); ++i )
01284 if ( !getPlayer(i).exist() )
01285 playerMask |= 1 << i;
01286 tfield::resetView(this,playerMask);
01287
01288 if ( getgameparameter( cgp_objectGrowthMultiplier) > 0 )
01289 objectGrowth();
01290 }
01291
01292 #include "libs/rand/rand_r.h"
01293 #include "libs/rand/rand_r.c"
01294
01295 int GameMap::random( int max )
01296 {
01297 return asc_rand_r( &randomSeed ) % max;
01298 }
01299
01300 void GameMap::objectGrowth()
01301 {
01302 typedef vector< pair<tfield*,int> > NewObjects;
01303 map<tfield*,int> remainingGrowthTime;
01304
01305 NewObjects newObjects;
01306 for ( int y = 0; y < ysize; ++y )
01307 for ( int x = 0; x < xsize; ++x ) {
01308 tfield* fld = getField( x, y );
01309 for ( tfield::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); ++i)
01310 if ( i->typ->growthRate > 0 && i->remainingGrowthTime != 0 )
01311 for ( int d = 0; d < 6; ++d ) {
01312 tfield* fld2 = getField ( getNeighbouringFieldCoordinate( MapCoordinate(x,y), d ));
01313 if ( fld2 )
01314 if ( i->typ->growOnUnits || ((!fld2->vehicle || fld2->vehicle->height >= chtieffliegend) && !fld2->building ))
01315 if ( fld2->objects.empty() || getgameparameter( cgp_objectGrowOnOtherObjects ) > 0 ) {
01316 double d = i->typ->growthRate * getgameparameter( cgp_objectGrowthMultiplier) / 100;
01317 if ( d > 0 ) {
01318 if ( d > 0.9 )
01319 d = 0.9;
01320
01321 int p = static_cast<int>(std::ceil ( double(1) / d));
01322 if ( p > 1 )
01323 if ( random ( p ) == 1 )
01324 if ( i->typ->fieldModification[fld2->getweather()].terrainaccess.accessible( fld2->bdt) > 0 ) {
01325 newObjects.push_back( make_pair( fld2, i->typ->id ));
01326 i->remainingGrowthTime -= 1;
01327 remainingGrowthTime[fld2] = i->remainingGrowthTime;
01328 }
01329 }
01330 }
01331 }
01332 }
01333
01334 for ( NewObjects::iterator i = newObjects.begin(); i != newObjects.end(); ++i )
01335 if ( !i->first->checkforobject( getobjecttype_byid( i->second ))) {
01336 if ( i->first->addobject ( getobjecttype_byid( i->second ))) {
01337 Object* o = i->first->checkforobject( getobjecttype_byid( i->second ));
01338 assert(o);
01339 o->remainingGrowthTime = remainingGrowthTime[i->first];
01340 }
01341 }
01342 }
01343
01344 SigC::Signal1<void,GameMap&> GameMap::sigMapDeletion;
01345
01346 GameMap :: ~GameMap ()
01347 {
01348 sigMapDeletion( *this );
01349 state = Destruction;
01350
01351 if ( field )
01352
01353 for ( int l=0 ;l < xsize * ysize ; l++ ) {
01354 if ( (field[l].bdt & getTerrainBitType(cbbuildingentry)).any() )
01355 delete field[l].building;
01356
01357
01358 Vehicle* aktvehicle = field[l].vehicle;
01359 if ( aktvehicle )
01360 delete aktvehicle;
01361
01362 }
01363
01364 int i;
01365 for ( i = 0; i <= 8; i++) {
01366 if ( player[i].ai ) {
01367 delete player[i].ai;
01368 player[i].ai = NULL;
01369 }
01370 }
01371
01372 if ( replayinfo ) {
01373 delete replayinfo;
01374 replayinfo = NULL;
01375 }
01376
01377 if ( game_parameter ) {
01378 delete[] game_parameter;
01379 game_parameter = NULL;
01380 }
01381
01382 if ( network ) {
01383 delete network;
01384 network = NULL;
01385 }
01386
01387
01388 #ifdef WEATHERGENERATOR
01389 delete weatherSystem;
01390 #endif
01391
01392 if ( field ) {
01393 delete[] field;
01394 field = NULL;
01395 }
01396
01397 if ( actmap == this )
01398 actmap = NULL;
01399
01400 }
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414 bool GameMap :: ResourceTribute :: empty ( )
01415 {
01416 for (int i = 0; i < 8; i++)
01417 for (int j = 0; j < 8; j++)
01418 for (int k = 0; k < 3; k++) {
01419 if ( avail[i][j].resource(k) )
01420 return false;
01421 if ( paid[i][j].resource(k) )
01422 return false;
01423 }
01424
01425 return true;
01426 }
01427
01428 const int tributeVersion = 1;
01429
01430 void GameMap :: ResourceTribute :: read ( tnstream& stream )
01431 {
01432 int version = stream.readInt();
01433 bool noVersion;
01434
01435 if ( -version >= tributeVersion ) {
01436 for ( int a = 0; a < 8; ++a )
01437 for ( int b = 0; b < 8; ++b )
01438 payStatusLastTurn[a][b].read( stream );
01439 noVersion = false;
01440 } else
01441 noVersion = true;
01442
01443
01444 for ( int a = 0; a < 3; a++ )
01445 for ( int b = 0; b < 8; b++ )
01446 for ( int c = 0; c < 8; c++ ) {
01447 if ( noVersion ) {
01448 avail[b][c].resource(a) = version;
01449 noVersion = false;
01450 } else
01451 avail[b][c].resource(a) = stream.readInt();
01452 }
01453
01454 for ( int a = 0; a < 3; a++ )
01455 for ( int b = 0; b < 8; b++ )
01456 for ( int c = 0; c < 8; c++ )
01457 paid[b][c].resource(a) = stream.readInt();
01458 }
01459
01460 void GameMap :: ResourceTribute :: write ( tnstream& stream )
01461 {
01462 stream.writeInt ( -tributeVersion );
01463 for ( int a = 0; a < 8; a++ )
01464 for ( int b = 0; b < 8; b++ )
01465 payStatusLastTurn[a][b].write( stream );
01466
01467 for ( int a = 0; a < 3; a++ )
01468 for ( int b = 0; b < 8; b++ )
01469 for ( int c = 0; c < 8; c++ )
01470 stream.writeInt ( avail[b][c].resource(a) );
01471
01472
01473 for ( int a = 0; a < 3; a++ )
01474 for ( int b = 0; b < 8; b++ )
01475 for ( int c = 0; c < 8; c++ )
01476 stream.writeInt ( paid[b][c].resource(a) );
01477 }
01478
01479
01480
01481 int GameMap::resize( int top, int bottom, int left, int right )
01482 {
01483 if ( !top && !bottom && !left && !right )
01484 return 0;
01485
01486 if ( -(top + bottom) > ysize )
01487 return 1;
01488
01489 if ( -(left + right) > xsize )
01490 return 2;
01491
01492 if ( bottom & 1 || top & 1 )
01493 return 3;
01494
01495
01496 int ox1, oy1, ox2, oy2;
01497
01498 if ( top < 0 ) {
01499 for ( int x = 0; x < xsize; x++ )
01500 for ( int y = 0; y < -top; y++ )
01501 getField(x,y)->deleteeverything();
01502
01503 oy1 = -top;
01504 } else
01505 oy1 = 0;
01506
01507 if ( bottom < 0 ) {
01508 for ( int x = 0; x < xsize; x++ )
01509 for ( int y = ysize+bottom; y < ysize; y++ )
01510 getField(x,y)->deleteeverything();
01511
01512 oy2 = ysize + bottom;
01513 } else
01514 oy2 = ysize;
01515
01516 if ( left < 0 ) {
01517 for ( int x = 0; x < -left; x++ )
01518 for ( int y = 0; y < ysize; y++ )
01519 getField(x,y)->deleteeverything();
01520 ox1 = -left;
01521 } else
01522 ox1 = 0;
01523
01524 if ( right < 0 ) {
01525 for ( int x = xsize+right; x < xsize; x++ )
01526 for ( int y = 0; y < ysize; y++ )
01527 getField(x,y)->deleteeverything();
01528 ox2 = xsize + right;
01529 } else
01530 ox2 = xsize;
01531
01532 for (int s = 0; s < 9; s++)
01533 for ( Player::BuildingList::iterator i = player[s].buildingList.begin(); i != player[s].buildingList.end(); i++ )
01534 (*i)->unchainbuildingfromfield();
01535
01536
01537 int newx = xsize + left + right;
01538 int newy = ysize + top + bottom;
01539
01540 tfield* newfield = new tfield [ newx * newy ];
01541 for ( int i = 0; i < newx * newy; i++ )
01542 newfield[i].setMap ( this );
01543
01544 int x;
01545 for ( x = ox1; x < ox2; x++ )
01546 for ( int y = oy1; y < oy2; y++ ) {
01547 tfield* org = getField ( x, y );
01548 tfield* dst = &newfield[ (x + left) + ( y + top ) * newx];
01549 *dst = *org;
01550 }
01551
01552 tfield defaultfield;
01553 defaultfield.setMap ( this );
01554 defaultfield.typ = getterraintype_byid ( 30 )->weather[0];
01555
01556 for ( x = 0; x < left; x++ )
01557 for ( int y = 0; y < newy; y++ )
01558 newfield[ x + y * newx ] = defaultfield;
01559
01560 for ( x = xsize + left; x < xsize + left + right; x++ )
01561 for ( int y = 0; y < newy; y++ )
01562 newfield[ x + y * newx ] = defaultfield;
01563
01564
01565 int y;
01566 for ( y = 0; y < top; y++ )
01567 for ( int x = 0; x < newx; x++ )
01568 newfield[ x + y * newx ] = defaultfield;
01569
01570 for ( y = ysize + top; y < ysize + top + bottom; y++ )
01571