loaders.cpp

Go to the documentation of this file.
00001 
00008 /*
00009     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00010     Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; see the file COPYING. If not, write to the
00024     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00025     Boston, MA  02111-1307  USA
00026 */
00027 
00028 #include <algorithm>
00029 #include <cstring>
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032 
00033 #include "typen.h"
00034 #include "misc.h"
00035 #include "buildingtype.h"
00036 #include "vehicletype.h"
00037 #include "spfst.h"
00038 #include "loaders.h"
00039 #include "dlg_box.h"
00040 #include "dlg_box.h"
00041 #include "dialog.h"
00042 #include "sgstream.h"
00043 #include "attack.h"
00044 #include "errors.h"
00045 #include "strtmesg.h"
00046 #include "textfileparser.h"
00047 #include "itemrepository.h"
00048 #include "prehistoricevents.h"
00049 #include "gamemap.h"
00050 #include "gameeventsystem.h"
00051 #include "graphicset.h"
00052 #include "gameoptions.h"
00053 #include "lua/luarunner.h"
00054 #include "lua/luastate.h"
00055 #include "packagemanager.h"
00056 #include "i18n.h"
00057 #include "mapimageexport.h"
00058 
00059 #ifdef sgmain
00060 # include "ai/ai.h"
00061 #endif
00062 
00063 
00064 
00065 const int actsavegameversion  = 0xff63;
00066 const int minsavegameversion  = 0xff31;
00067 const int actmapversion       = 0xfe51;
00068 const int minmapversion       = 0xfe24;
00069 const int actnetworkversion   = 0x0032;
00070 const int minnetworkversion   = 0x0004;
00071 const int actreplayversion    = 0x0003;
00072 const int minreplayversion    = 0x0001;
00073 
00074 
00075 const int fileterminator = 0xa01a;
00076 
00077 
00078 const char* savegameextension = "*.sav";
00079 const char* mapextension = "*.map";
00080 const char* tournamentextension = ".ascpbm";
00081 
00082 bool suppressMapTriggerExecution = true;
00083 
00084 void         seteventtriggers( GameMap* actmap )
00085 {
00086    if ( !suppressMapTriggerExecution )
00087       for ( GameMap::Events::iterator i = actmap->events.begin(); i != actmap->events.end(); ++i )
00088          (*i)->arm();
00089 
00090    for ( int i = 0; i < 8; i++ )
00091       actmap->player[i].queuedEvents = 1;
00092 }
00093 
00094 
00095 
00096 #define csm_typid32 1      /*  b1  */
00097 #define csm_direction 2    /*  b1  */
00098 #define csm_vehicle 4      /*  b1  */
00099 #define csm_building 8     /*  b1  */
00100 #define csm_height 32      /*  b1  */
00101 #define csm_cnt2 64        /*  b1  */
00102 #define csm_b3 128         /*  b1  */
00103 
00104 #define csm_material 1     /*  b3  */
00105 #define csm_fuel 2         /*  b3  */
00106 #define csm_visible 4      /*  b3  */
00107 #define csm_weather 16     /*  b3  */
00108 #define csm_object 64      /*  b3  */
00109 #define csm_b4 128         /* b3 */
00110 
00111 #define csm_resources  1     /* b4 */
00112 #define csm_connection 2     // b4
00113 #define csm_newobject  4     // b4
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 /**************************************************************/
00122 /*     sezierungen schreiben / lesen                         */
00123 /**************************************************************/
00124 
00125 
00126 void   tspfldloaders::readdissections ( void )
00127 {
00128    for (int i = 0; i < 8; i ++ ) {
00129       if ( spfld->player[ i ].__dissectionsToLoad ) {
00130          int k;
00131          do {
00132             Player::Dissection du;
00133             stream->readInt(); // dummy;
00134             stream->readInt(); // dummy;
00135 
00136             du.orgpoints = stream->readInt();
00137             du.points    = stream->readInt();
00138             du.num       = stream->readInt();
00139 
00140             k = stream->readInt();
00141 
00142             int j = stream->readInt();
00143             du.fzt = vehicleTypeRepository.getObject_byID ( j );
00144             if ( !du.fzt )
00145                throw InvalidID ( "vehicle", j );
00146 
00147             j = stream->readInt();
00148             du.tech = technologyRepository.getObject_byID  ( j );
00149             if ( !du.tech )
00150                throw InvalidID ( "technology", j );
00151 
00152             spfld->player[ i ].dissections.push_back ( du );
00153          } while ( k );
00154       }
00155    } /* endfor */
00156 }
00157 
00158 void   tspfldloaders::writedissections ( void )
00159 {
00160    for (int i = 0; i < 8; i ++ ) {
00161       Player::DissectionContainer::iterator di = spfld->player[i].dissections.begin();
00162       while ( di != spfld->player[i].dissections.end() ) {
00163          stream->writeInt ( 1 ); // dummy
00164          stream->writeInt ( 1 ); // dummy
00165          stream->writeInt ( di->orgpoints );
00166          stream->writeInt ( di->points );
00167          stream->writeInt ( di->num );
00168 
00169          di++;
00170          if ( di != spfld->player[i].dissections.end() )
00171             stream->writeInt ( 1 );
00172          else
00173             stream->writeInt ( 0 );
00174 
00175          stream->writeInt ( di->fzt->id );
00176          stream->writeInt ( di->tech->id );
00177       }
00178    }
00179 }
00180 
00181 
00182 
00183 /**************************************************************/
00184 /*        Messages  schreiben / lesen                         */
00185 /**************************************************************/
00186 
00187 const int messageVersion = 0xabcdf1;
00188 const int messageMinVersion = 0xabcdef;
00189 
00190 void      tspfldloaders:: writemessages ( void )
00191 {
00192    stream->writeInt ( messageVersion );
00193 
00194    int id = 0;
00195    for ( MessageContainer::iterator mi = spfld->messages.begin(); mi != spfld->messages.end();  ) {
00196       id++;
00197       (*mi)->id = id;
00198 
00199       stream->writeInt ( (*mi)->from );
00200       stream->writeInt ( (*mi)->to );
00201       stream->writeInt ( (*mi)->cc );
00202       stream->writeInt ( (unsigned int) (*mi)->time );
00203       stream->writeInt ( 1 );
00204       stream->writeInt ( (*mi)->id );
00205       stream->writeInt ( (*mi)->gametime.turn() );
00206       stream->writeInt ( (*mi)->gametime.move() );
00207       stream->writeInt( (*mi)->reminder );
00208 
00209 
00210       ASCString& t = (*mi)->text;
00211 
00212       mi++;
00213       stream->writeInt ( mi != spfld->messages.end() ? 1 : 0 );
00214 
00215       stream->writeString ( t );
00216    }
00217 
00218    for ( int i = 0; i < 8; i++ )
00219       writemessagelist ( spfld->player[ i ].oldmessage );
00220 
00221    for ( int i = 0; i < 8; i++ )
00222       writemessagelist ( spfld->player[ i ].unreadmessage );
00223 
00224    for ( int i = 0; i < 8; i++ )
00225       writemessagelist ( spfld->player[ i ].sentmessage );
00226 
00227    writemessagelist ( spfld->unsentmessage );
00228 
00229    stream->writeInt ( messageVersion );
00230 
00231    stream->writeString ( spfld->gameJournal );
00232    stream->writeString ( spfld->newJournal );
00233 }
00234 
00235 
00236 void      tspfldloaders:: writemessagelist( MessagePntrContainer& lst )
00237 {
00238    for ( MessagePntrContainer::iterator i = lst.begin(); i != lst.end(); i++ )
00239       stream->writeInt ( (*i)->id );
00240    stream->writeInt ( 0 );
00241 }
00242 
00243 
00244 /*
00245 class MessageIDequals : public unary_function<Message*,bool>{
00246       int id;
00247    public:
00248       MessageIDequals ( int _id ) { id == _id; };
00249       bool operator() ( const Message* m ) { return m->id == id; };
00250 };
00251 */
00252 
00253 void      tspfldloaders:: readmessagelist( MessagePntrContainer& lst )
00254 {
00255    int i = stream->readInt();
00256 
00257    while ( i ) {
00258       // MessageContainer::iterator mi = find ( spfld->messages.begin(), spfld->messages.end(), MessageIDequals ( i ));
00259       MessageContainer::iterator mi = spfld->messages.end();
00260       for ( MessageContainer::iterator mi2 = spfld->messages.begin(); mi2 != spfld->messages.end(); mi2++ )
00261          if ( (*mi2)->id == i )
00262             mi = mi2;
00263 
00264       if ( mi == spfld->messages.end())
00265          warningMessage( "message list corrupted !\nplease report this bug!\nthe game will continue, but some messages will probably be missing\nand other instabilities may occur.");
00266       lst.push_back ( *mi );
00267       i = stream->readInt();
00268    }
00269 }
00270 
00271 
00272 void      tspfldloaders:: readmessages ( void )
00273 {
00274    int magic = stream->readInt();
00275    assertOrThrow( magic >= messageMinVersion  && magic <= messageVersion );
00276 
00277    while ( spfld->__loadmessages ) {
00278       Message* msg = new Message ( spfld );
00279 
00280       msg->from    = stream->readInt();
00281       msg->to      = stream->readInt();
00282       if ( magic >= 0xabcdf0 )
00283          msg->cc      = stream->readInt();
00284       else
00285          msg->cc = 0;
00286 
00287       msg->time    = stream->readInt();
00288       bool msgtext = stream->readInt();
00289       msg->id      = stream->readInt();
00290       int t = stream->readInt();
00291       int m = stream->readInt();
00292       msg->gametime.set ( t, m );
00293 
00294       if ( magic >= 0xabcdf1 )
00295          msg->reminder = stream->readInt();
00296       else
00297          msg->reminder = false;
00298 
00299       spfld->__loadmessages = stream->readInt();
00300 
00301       if ( msgtext )
00302          msg->text = stream->readString( true );
00303 
00304    }
00305 
00306    for ( int i = 0; i < 8; i++ )
00307       if ( spfld->player[ i ].__loadoldmessage )
00308          readmessagelist ( spfld->player[ i ].oldmessage );
00309 
00310    for ( int i = 0; i < 8; i++ )
00311       if ( spfld->player[ i ].__loadunreadmessage )
00312          readmessagelist ( spfld->player[ i ].unreadmessage );
00313 
00314    for ( int i = 0; i < 8; i++ )
00315       if ( spfld->player[ i ].__loadsentmessage )
00316          readmessagelist ( spfld->player[ i ].sentmessage );
00317 
00318    if ( spfld->__loadunsentmessage )
00319       readmessagelist ( spfld->unsentmessage );
00320 
00321    stream->readInt(); // magic
00322 
00323    if ( spfld->___loadJournal )
00324       spfld->gameJournal = stream->readString();
00325 
00326    if (  spfld->___loadNewJournal )
00327       spfld->newJournal = stream->readString();
00328 }
00329 
00330 
00331 
00332 
00333 
00334 
00335 void   tspfldloaders::readoldevents ( void )
00336 {
00337    if ( spfld->loadOldEvents ) {
00338       int  num = stream->readInt();
00339       while ( num ) {
00340          for ( int i = 0; i < num; i++ )
00341             stream->readInt();
00342          for ( int i = 0; i < num; i++ )
00343             stream->readInt();
00344 
00345          num  = stream->readInt();
00346       }
00347    }
00348 }
00349 
00350 void checkForUniqueUnitIDs( GameMap* gamemap )
00351 {
00352    map<int,int> units;
00353    for ( int p = 0; p < gamemap->getPlayerCount(); ++p )
00354       for ( Player::VehicleList::iterator i = gamemap->getPlayer(p).vehicleList.begin(); i != gamemap->getPlayer(p).vehicleList.end(); ++i )
00355          if ( units[(*i)->networkid]++ > 0 ) {
00356             warningMessage("unit with duplicate network ids: " + ASCString::toString( (*i)->networkid ) + "\nThis will lead to replay errors during the next turn." );
00357             (*i)->networkid = gamemap->idManager.getNewNetworkID();;
00358          }
00359 }
00360 
00361 /**************************************************************/
00362 /*     map schreiben / lesen / initialisieren          */
00363 /**************************************************************/
00364 
00365 void    tspfldloaders::writemap ( void )
00366 {
00367    checkForUniqueUnitIDs( spfld );
00368    if ( !spfld )
00369       displaymessage ( "tspfldloaders::writemap  ; no map to write ! ",2);
00370 
00371    spfld->write ( *stream );
00372 }
00373 
00374 
00375 void     tmaploaders::initmap ( void )
00376 {
00377    spfld->game_parameter = NULL;
00378 }
00379 
00380 
00381 void     tgameloaders::initmap ( void )
00382 {
00383    spfld->game_parameter = NULL;
00384 }
00385 
00386 
00387 void     tspfldloaders::readmap ( void )
00388 {
00389    spfld = new GameMap;
00390 
00391    spfld->read ( *stream );
00392 }
00393 
00394 
00395 
00396 void tgameloaders :: writeAI ( )
00397 {
00398 #ifdef sgmain
00399    int a = 0;
00400    for ( int i = 0; i< 8; i++ )
00401       if ( spfld->player[i].ai )
00402          a += 1 << i;
00403 
00404    stream->writeInt ( a );
00405 
00406    for ( int i = 0; i < 8; i++ )
00407       if ( spfld->player[i].ai )
00408          spfld->player[i].ai->write( *stream );
00409 #else
00410    stream->writeInt(0);
00411 #endif
00412 }
00413 
00414 void tgameloaders :: readAI ( )
00415 {
00416 #ifdef sgmain
00417    int a = stream->readInt();
00418    for ( int i = 0; i< 8; i++ )
00419       if ( a & ( 1 << i ) ) {
00420          AI* ai = new AI ( spfld, i );
00421          ai->read ( *stream );
00422          spfld->player[i].ai = ai;
00423       } else {
00424          spfld->player[i].ai = NULL;
00425       }
00426 #else
00427    for ( int i = 0; i< 9; i++ )
00428       spfld->player[i].ai = NULL;
00429 #endif
00430 }
00431 
00432 
00433 /**************************************************************/
00434 /*     Network schreiben / lesen                             */
00435 /**************************************************************/
00436 
00437 extern void readLegacyNetworkData ( tnstream& stream );
00438 
00439 
00440 void        tspfldloaders::readLegacyNetwork ( void )
00441 {
00442    if ( spfld->___loadLegacyNetwork )
00443       readLegacyNetworkData( *stream );
00444 }
00445 
00446 
00447 
00448 
00449 /**************************************************************/
00450 /*     fielder schreiben / lesen                              */
00451 /**************************************************************/
00452 
00453 const int objectstreamversion = 4;
00454 
00455 void   tspfldloaders::writefields ( void )
00456 {
00457    int l = 0;
00458    int cnt1 = spfld->xsize * spfld->ysize;
00459    int cnt2;
00460 
00461    do {
00462       cnt2 = 0;
00463       MapField* fld = &spfld->field[l];
00464       /*
00465 
00466       RLE encoding not supported any more, since tfield is becomming too complex
00467 
00468       if (l + 2 < cnt1) {
00469          l2 = l + 1;
00470          fld2 = &spfld->field[l2];
00471        asfasfdasfd
00472          while ((l2 + 2 < cnt1) && ( memcmp(fld2, fld, sizeof(*fld2)) == 0) ) {
00473             cnt2++;
00474             l2++;
00475             fld2 = &spfld->field[l2];
00476          }
00477       }
00478       */
00479 
00480 
00481       char b1 = 0;
00482       char b3 = 0;
00483       char b4 = 0;
00484 
00485       if (fld->typ->terraintype->id > 255)
00486          b1 |= csm_typid32;
00487       if (fld->vehicle != NULL)
00488          b1 |= csm_vehicle;
00489       if ( (fld->bdt & getTerrainBitType( cbbuildingentry )).any() )
00490          b1 |= csm_building;
00491 
00492 
00493       if (cnt2 > 0)
00494          b1 |= csm_cnt2;
00495 
00496       if (fld->material > 0)
00497          b3 |= csm_material;
00498       if (fld->fuel > 0)
00499          b3 |= csm_fuel;
00500 
00501       if (fld->typ != fld->typ->terraintype->weather[0])
00502          b3 |= csm_weather;
00503       if (fld->visible)
00504          b3 |= csm_visible;
00505       if ( !fld->objects.empty() || !fld->mines.empty() )
00506          b4 |= csm_newobject;
00507 
00508       if ( fld->resourceview )
00509          b4 |= csm_resources;
00510 
00511       if ( fld->connection )
00512          b4 |= csm_connection;
00513 
00514       if ( b4 )
00515          b3 |= csm_b4;
00516 
00517       if ( b3 )
00518          b1 |= csm_b3;
00519 
00520       stream->writeChar( b1 );
00521 
00522       if (b1 & csm_b3 )
00523          stream->writeChar ( b3 );
00524 
00525       if (b3 & csm_b4 )
00526          stream->writeChar ( b4 );
00527 
00528       if (b1 & csm_cnt2 )
00529          stream->writeInt ( cnt2 );
00530 
00531       if (b3 & csm_weather ) {
00532          int k = 1;
00533          while ( fld->typ != fld->typ->terraintype->weather[k]    &&   k < cwettertypennum ) {
00534             k++;
00535          } /* endwhile */
00536 
00537          if ( k == cwettertypennum ) {
00538             k = 0;
00539             displaymessage ( "invalid terrain ( weather not found ) at position %d \n",1,l );
00540          }
00541          stream->writeInt ( k );
00542       }
00543 
00544       if (b1 & csm_typid32 )
00545          stream->writeInt ( fld->typ->terraintype->id );
00546       else
00547          stream->writeChar ( fld->typ->terraintype->id );
00548 
00549       if (b1 & csm_vehicle )
00550          fld->vehicle->write ( *stream );
00551 
00552 
00553       if (b1 & csm_building )
00554          fld->building->write ( *stream );
00555 
00556       if (b3 & csm_material )
00557          stream->writeChar ( fld->material );
00558 
00559       if (b3 & csm_fuel )
00560          stream->writeChar ( fld->fuel );
00561 
00562       if (b3 & csm_visible )
00563          stream->writeWord ( fld->visible );
00564 
00565       if ( b4 & csm_newobject ) {
00566          stream->writeInt ( objectstreamversion );
00567 
00568          stream->writeInt ( fld->mines.size() );
00569          for ( MapField::MineContainer::iterator m = fld->mines.begin(); m != fld->mines.end(); m++  ) {
00570             stream->writeInt ( m->type );
00571             stream->writeInt ( m->strength );
00572             stream->writeInt ( m->lifetimer );
00573             stream->writeInt ( m->player );
00574             stream->writeInt ( m->identifier );
00575          }
00576 
00577          stream->writeInt ( fld->objects.size() );
00578 
00579          for ( MapField::ObjectContainer::iterator o = fld->objects.begin(); o != fld->objects.end(); o++  ) {
00580             stream->writeInt ( 1 ); // was: pointer to type
00581             stream->writeInt ( o->damage );
00582             stream->writeInt ( o->dir );
00583             stream->writeInt ( o->lifetimer );
00584             for ( int i = 0; i < 4; i++ )
00585                stream->writeInt ( 0 );  // dummy
00586             stream->writeInt ( o->typ->id );
00587             stream->writeInt( o->remainingGrowthTime );
00588          }
00589       }
00590 
00591       if (b4 & csm_resources ) {
00592          stream->writeChar ( fld->resourceview->visible );
00593          for ( int i = 0; i < 8; i++ )
00594             stream->writeChar ( fld->resourceview->fuelvisible[i] );
00595          for ( int i = 0; i < 8; i++ )
00596             stream->writeChar ( fld->resourceview->materialvisible[i] );
00597       }
00598 
00599       if ( b4 & csm_connection )
00600          stream->writeInt ( fld->connection );
00601 
00602       l += 1 + cnt2;
00603    }  while (l < cnt1);
00604 }
00605 
00606 
00607 
00608 
00609 
00610 void tspfldloaders::readfields ( void )
00611 {
00612    int cnt2 = 0;
00613    int cnt1 = spfld->xsize * spfld->ysize;
00614 
00615    assertOrThrow( cnt1 > 0 );
00616    assertOrThrow( spfld->xsize > 0 );
00617    assertOrThrow( spfld->ysize > 0 );
00618 
00619    spfld->allocateFields ( spfld->xsize , spfld->ysize );
00620 
00621    if (spfld->field == NULL)
00622       displaymessage ( "Could not allocate memory for map ",2);
00623 
00624    int l = 0;
00625    MapField* lfld = NULL;
00626 
00627    do {
00628       MapField* fld2;
00629 
00630       if (cnt2 == 0) {
00631 
00632          fld2 = & spfld->field[l];
00633 
00634          fld2->bdt.setInt ( 0 , 0 );
00635 
00636          char b1, b3, b4;
00637          b1 = stream->readChar();
00638 
00639          if (b1 & csm_b3 )
00640             b3 = stream->readChar();
00641          else
00642             b3 = 0;
00643 
00644          if (b3 & csm_b4 )
00645             b4 = stream->readChar();
00646          else
00647             b4 = 0;
00648 
00649          if (b1 & csm_cnt2 )
00650             cnt2 = stream->readInt();
00651          else
00652             cnt2 = 0;
00653 
00654          int weather;
00655          if (b3 & csm_weather )
00656             weather = stream->readInt();
00657          else
00658             weather = 0;
00659 
00660          assertOrThrow( weather >= 0 && weather < cwettertypennum );
00661 
00662          int k;
00663 
00664          if (b1 & csm_typid32 )
00665             k = stream->readInt();
00666          else
00667             k = stream->readChar();
00668 
00669          pterraintype trn = terrainTypeRepository.getObject_byID ( k );
00670          if ( !trn )
00671             throw InvalidID ( "terrain", k );
00672 
00673          fld2->typ = trn->weather[weather];
00674          if ( !fld2->typ ) {
00675             fld2->typ = trn->weather[0];
00676             if ( !fld2->typ )
00677                throw InvalidID ( "terrain", k );
00678          }
00679 
00680          if (b1 & csm_direction )
00681             stream->readChar();  // fld2->direction = 0;
00682 
00683 
00684          if (b1 & csm_vehicle ) {
00685             fld2->vehicle = Vehicle::newFromStream ( spfld, *stream );
00686             fld2->vehicle->setnewposition ( l%spfld->xsize, l/spfld->xsize );
00687          }
00688 
00689          if (b1 & csm_building ) {
00690             fld2->building = Building::newFromStream ( spfld, *stream );
00691             fld2->bdt |= getTerrainBitType(cbbuildingentry);
00692          }
00693 
00694          if (b3 & csm_material)
00695             fld2->material = stream->readChar();
00696          else
00697             fld2->material = 0;
00698 
00699          if (b3 & csm_fuel)
00700             fld2->fuel = stream->readChar();
00701          else
00702             fld2->fuel = 0;
00703 
00704          if (b3 & csm_visible)
00705             fld2->visible = stream->readWord();
00706          else
00707             fld2->visible = 0;
00708 
00709          bool tempobjects[16];
00710          int  tempobjectNum = 0;
00711 
00712          if (b3 & csm_object ) {
00713 
00714             char minetype = stream->readChar();
00715             char minestrength = stream->readChar();
00716             if ( minetype >> 4 ) {
00717                Mine m( MineTypes((minetype >> 1) & 7), minestrength, minetype >> 4, spfld );
00718                fld2->mines.push_back ( m );
00719             }
00720 
00721             tempobjectNum = stream->readInt();
00722 
00723             for ( int i = 0; i < 16; i++ )
00724                tempobjects[i] = stream->readInt();
00725          }
00726 
00727          int objectversion = 1;
00728          if ( b4 & csm_newobject ) {
00729             objectversion = stream->readInt();
00730 
00731             if ( objectversion < 1 || objectversion > objectstreamversion )
00732                throw tinvalidversion ( "object", objectstreamversion, objectversion );
00733 
00734             int minenum = stream->readInt();
00735 
00736             for ( int i = 0; i < minenum; i++ ) {
00737                MineTypes type = MineTypes(stream->readInt());
00738                int strength = stream->readInt();
00739                int minetime = stream->readInt();
00740                int player = stream->readInt();
00741                if ( player < 0 || player > 7 )
00742                   player = 0;
00743 
00744                assertOrThrow( strength >= 0 );
00745                assertOrThrow( type > 0 && type <= 4 );
00746 
00747                int id;
00748                if ( objectversion >= 4 )
00749                   id = stream->readInt();
00750                else
00751                   id = spfld->idManager.getNewNetworkID();
00752 
00753                Mine m ( type, strength, player, spfld, id );
00754                if ( objectversion == 1 ) {
00755                   int endtime = minetime;
00756                   int lifetime = spfld->getgameparameter( GameParameter(cgp_antipersonnelmine_lifetime + m.type - 1));
00757                   if ( lifetime > 0  &&  endtime > 0 )
00758                      m.lifetimer = endtime - spfld->time.turn() + spfld->getgameparameter( GameParameter(cgp_antipersonnelmine_lifetime + m.type - 1));
00759                   else if ( lifetime > 0 )
00760                      m.lifetimer = lifetime;
00761                   else
00762                      m.lifetimer = -1;
00763                } else
00764                   m.lifetimer = minetime;
00765                fld2->mines.push_back ( m );
00766             }
00767 
00768             tempobjectNum = stream->readInt();
00769          }
00770 
00771          if ( (b3 & csm_object) || (b4 & csm_newobject )) {
00772             for ( int n = 0; n < tempobjectNum; n++ ) {
00773                Object o;
00774                stream->readInt(); // was: type
00775                o.damage = stream->readInt();
00776                assertOrThrow( o.damage >= 0 );
00777                o.dir = stream->readInt();
00778                if ( objectversion >= 2 )
00779                   o.lifetimer = stream->readInt();
00780                else
00781                   stream->readInt();
00782 
00783                for ( int i = 0; i < 4; i++ )
00784                   stream->readInt(); // dummy
00785 
00786                int id = stream->readInt();
00787                o.typ = objectTypeRepository.getObject_byID ( id );
00788 
00789                if ( !o.typ )
00790                   throw InvalidID ( "object", id );
00791 
00792                if ( objectversion >= 3 )
00793                   o.remainingGrowthTime = stream->readInt();
00794 
00795                if ( objectversion == 1 )
00796                   o.lifetimer = o.typ->lifetime;
00797 
00798 
00799                fld2->objects.push_back ( o );
00800             }
00801             fld2->sortobjects();
00802          }
00803 
00804          if (b4 & csm_resources ) {
00805             fld2->resourceview = new MapField::Resourceview;
00806             fld2->resourceview->visible = stream->readChar();
00807             for ( int i = 0; i < 8; i++ )
00808                fld2->resourceview->fuelvisible[i] = stream->readChar();
00809             for ( int i = 0; i < 8; i++ )
00810                fld2->resourceview->materialvisible[i] = stream->readChar();
00811          }
00812 
00813          if ( b4 & csm_connection )
00814             fld2->connection = stream->readInt();
00815 
00816          if (b1 & csm_cnt2 )
00817             lfld = fld2;
00818 
00819       } else {
00820          spfld->field[l].typ = lfld->typ;
00821          spfld->field[l].fuel = lfld->material;
00822          spfld->field[l].visible = lfld->visible;
00823          spfld->field[l].tempw = 0;
00824          spfld->field[l].connection = lfld->connection;
00825          for ( int i = 0; i < 8; i++ )
00826             spfld->field[l].view[i] = lfld->view[i];
00827          cnt2--;
00828       }
00829       l++ ;
00830    }  while (l < cnt1);
00831 
00832    spfld->overviewMapHolder.connect();
00833 
00834 }
00835 
00836 
00837 
00838 /**************************************************************/
00839 /*     Chain Items                                           */
00840 /**************************************************************/
00841 
00842 void   tspfldloaders::chainitems ( GameMap* actmap )
00843 {
00844    int i = 0;
00845    for (int y = 0; y < actmap->ysize; y++)
00846       for (int x = 0; x < actmap->xsize; x++) {
00847          MapField* fld = &actmap->field[i];
00848          fld->setparams();
00849          i++;
00850       }
00851 }
00852 
00853 
00854 
00855 /**************************************************************/
00856 /*     Set Player Existencies                                */
00857 /**************************************************************/
00858 
00859 SigC::Signal1<void,GameMap*> tspfldloaders::mapLoaded;
00860 
00861 
00862 tspfldloaders::tspfldloaders ( void )
00863 {
00864    spfld = NULL;
00865 }
00866 
00867 
00868 tspfldloaders::~tspfldloaders ( void )
00869 {
00870    delete spfld;
00871    spfld = NULL;
00872 }
00873 
00874 
00875 
00876 
00877 
00878 
00879 
00880 
00881 
00882 
00883 
00884 
00885 
00886 
00887 
00888 
00889 
00890 
00891 int          tmaploaders::savemap( const ASCString& name, GameMap* gamemap )
00892 {
00893 #ifdef logging
00894    logtofile ( "loaders / tmaploaders::savemap / started " );
00895 #endif
00896 
00897    tnfilestream filestream ( name, tnstream::writing );
00898 
00899    stream = &filestream;
00900 
00901    spfld = gamemap;
00902 
00903 
00904    /********************************************************************************/
00905    /*   Stream initialisieren, Dateiinfo schreiben , map schreiben          */
00906    /********************************************************************************/
00907    {
00908       stream->writepchar ( getFullVersionString() );  // description is not used any more
00909       stream->writeWord ( fileterminator );
00910       stream->writeInt ( actmapversion  );
00911 
00912       writemap ( );
00913    }
00914 
00915    writefields ();
00916 #ifdef WEATHERGENERATOR
00917    spfld->weatherSystem->write(filestream);
00918 #endif
00919    stream->writeInt ( actmapversion );
00920 
00921    spfld = NULL;
00922 
00923    return 0;
00924 }
00925 
00926 
00927 
00928 void weatherSystemRequired()
00929 {
00930    throw ASCmsgException( "This file can not be loaded, since it contains data of the discontinued weather generator");
00931 }
00932 
00933 
00934 GameMap* tmaploaders::_loadmap( const ASCString& name )
00935 {
00936    displayLogMessage ( 4, "loading map %s ... ", name.c_str() );
00937 
00938    tnfilestream filestream ( name, tnstream::reading);
00939 
00940    stream = &filestream;
00941 
00942    char* description = NULL;
00943 
00944    stream->readpchar ( &description );
00945    delete[] description;
00946 
00947    int w = stream->readWord();
00948 
00949    if ( w != fileterminator )
00950       throw tinvalidversion ( name, fileterminator, w );
00951 
00952 
00953    int version = stream->readInt();
00954 
00955    if ( version > actmapversion || version < minmapversion )
00956       throw tinvalidversion ( name, actmapversion, version );
00957 
00958 
00959    displayLogMessage ( 8, "map, ");
00960    readmap ();
00961 
00962    if ( version <= 0xfe27 ) {
00963       displayLogMessage ( 8, "eventsToCome, ");
00964       readOldEventLists ( stream, false, spfld );
00965    }
00966 
00967    displayLogMessage ( 8, "fields, ");
00968    readfields ();
00969 
00970 
00971    if(version == 0xfe50)
00972       weatherSystemRequired();
00973 
00974    version = stream->readInt();
00975    if (version > actmapversion || version < minmapversion )
00976       throw tinvalidversion ( name, actmapversion, version );
00977 
00978 
00979    displayLogMessage ( 8, "chainItems, ");
00980    chainitems ( spfld );
00981 
00982    for ( int sp = spfld->getPlayerCount()-1; sp >= 0; sp--)
00983       if ( spfld->player[sp].exist() )
00984          spfld->actplayer = sp;
00985 
00986    displayLogMessage ( 8, "setEventTriggers, ");
00987    seteventtriggers( spfld );
00988 
00989    displayLogMessage ( 8, "calculateallobjects ");
00990    calculateallobjects( spfld );
00991 
00992 
00993    displayLogMessage ( 8, "init for playing, ");
00994 
00995    spfld->time.set ( 1, 0 );
00996    spfld->levelfinished = false;
00997    spfld->preferredFileNames.mapname[0] = name ;
00998    checkForUniqueUnitIDs( spfld );
00999    spfld->startGame();
01000 
01001    displayLogMessage ( 4, "done\n");
01002 
01003    GameMap* m  = spfld;
01004    spfld = NULL;
01005 
01006    mapLoaded( m );
01007 
01008    return m;
01009 }
01010 
01011 
01012 GameMap* eventLocalizationMap = NULL;
01013 
01014 
01015 
01016 void loadLocalizedMessageFile( GameMap* map, const ASCString& filename )
01017 {
01018    eventLocalizationMap = map;
01019 
01020    LuaState state;
01021    LuaRunner runner( state );
01022    runner.runFile( filename );
01023    if ( !runner.getErrors().empty() )
01024       errorMessage( runner.getErrors() );
01025 
01026    eventLocalizationMap = NULL;
01027 }
01028 
01029 void loadLocalizedMessages( GameMap* map, const ASCString& name )
01030 {
01031    Locale locale;
01032    ASCString filename = locale.getLocalizedFile( name );
01033    if( !filename.empty() && exist( filename ) )
01034       loadLocalizedMessageFile( map, filename );
01035 
01036 }
01037 
01038 GameMap* tmaploaders::loadmap ( const ASCString& name )
01039 {
01040    tmaploaders gl;
01041    GameMap* map = gl._loadmap ( name );
01042 #ifdef sgmain
01043    loadLocalizedMessages( map, name );
01044 #endif
01045    return map;
01046 }
01047 
01048 
01049 
01050 
01051 
01052 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
01053   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
01054   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  */
01055 
01056 
01057 
01058 
01059 void   tsavegameloaders::savegame( tnstream* strm, GameMap* gamemap, bool writeReplays )
01060 {
01061    PackageManager::storeData( gamemap );
01062 
01063    stream = strm;
01064    spfld = gamemap;
01065 
01066    stream->writepchar( getFullVersionString() );
01067    stream->writeWord( fileterminator );
01068 
01069    stream->writeInt( actsavegameversion );
01070 
01071    //An Image of the Map will now be saved to the file.
01072    writemaptostream( spfld , 100, 100, *stream);
01073    
01074    stream->writeString( gamemap->maptitle );
01075    stream->writeString( gamemap->getCurrentPlayer().getName() );
01076    stream->writeInt( gamemap->time.turn() );
01077 
01078    writemap ();
01079 
01080    writemessages();
01081 
01082    writefields ( );
01083 
01084    writedissections();
01085 
01086    if ( writeReplays && spfld->replayinfo ) {
01087       stream->writeInt( 1 );
01088       spfld->replayinfo->write(*stream);
01089    } else
01090       stream->writeInt( 0 );
01091 
01092    writeAI();
01093 
01094 
01095 
01096    stream->writeInt( actsavegameversion );
01097 
01098    spfld = NULL;
01099 }
01100 
01101 
01102 void tsavegameloaders::savegame( GameMap* gamemap, const ASCString& name)
01103 {
01104    tnfilestream filestream ( name, tnstream::writing );
01105    savegame ( &filestream, gamemap, true );
01106 }
01107 
01108 GameFileInformation tsavegameloaders::loadMapimageFromFile( const ASCString& filename )
01109 {
01110    GameFileInformation gfi;
01111    try {
01112       tnfilestream stream( filename, tnstream::reading );
01113 
01114       stream.readString(); // was: description
01115 
01116       int w = stream.readWord();
01117 
01118       if ( w != fileterminator )
01119          throw tinvalidversion ( stream.getDeviceName(), fileterminator, w );
01120 
01121       int version = stream.readInt();
01122       
01123       if ( version >= 0xff63 ) {
01124          gfi.image =  loadmapfromstream( stream );
01125          gfi.maptitle = stream.readString();
01126          gfi.playername = stream.readString();
01127          gfi.turn = stream.readInt();
01128       }
01129    } catch(...) {
01130    }
01131    return gfi;
01132 }
01133 
01134 GameMap* tsavegameloaders::loadGameFromFile( const ASCString& filename )
01135 {
01136    tnfilestream filestream( filename, tnstream::reading );
01137    tsavegameloaders gl;
01138    return gl.loadgame( &filestream );
01139 }
01140 
01141 GameMap*          tsavegameloaders::loadgame( tnstream* strm )
01142 {
01143    stream = strm;
01144 
01145    stream->readString(); // was: description
01146 
01147    int w = stream->readWord();
01148 
01149    if ( w != fileterminator )
01150       throw tinvalidversion ( strm->getDeviceName(), fileterminator, w );
01151 
01152    int version = stream->readInt();
01153 
01154    if (version > actsavegameversion || version < minsavegameversion )
01155       throw tinvalidversion ( strm->getDeviceName(), actsavegameversion, version );
01156 
01157    if ( version >= 0xff62 ) {
01158       // ignoring the map image
01159       loadmapfromstream( *stream );
01160    }
01161    
01162    if ( version >= 0xff63 ) {
01163       // ignoring the map information
01164       stream->readString();   
01165       stream->readString();   
01166       stream->readInt();
01167    }
01168 
01169    readmap ();
01170 
01171    readLegacyNetwork ();
01172 
01173    if  ( version <= 0xff39 )
01174       for ( int i = 0; i < 8; i++ )
01175          spfld->player[i].research.read_techs ( *stream );
01176 
01177    readmessages();
01178 
01179    if ( version <= 0xff37 ) {
01180       readOldEventLists ( stream, true, spfld );
01181       readoldevents ();
01182    }
01183 
01184    readfields ( );
01185 
01186    if(version == 0xff60)
01187       weatherSystemRequired();
01188 
01189    readdissections();
01190 
01191    bool loadReplay = true;
01192    if ( version >= 0xff35 )
01193       if ( !stream->readInt() )
01194          loadReplay = false;
01195 
01196    if ( loadReplay ) {
01197       spfld->replayinfo = new GameMap::ReplayInfo;
01198       spfld->replayinfo->read ( *stream );
01199    } else
01200       spfld->replayinfo = NULL;
01201 
01202 
01203    if ( version >= 0xff34 )
01204       readAI ();
01205 
01206    version = stream->readInt();
01207    if (version > actsavegameversion || version < minsavegameversion )
01208       throw tinvalidversion ( strm->getDeviceName(), actsavegameversion, version );
01209 
01210    chainitems ( spfld );
01211 
01212    seteventtriggers( spfld );
01213 
01214    calculateallobjects( spfld );
01215    checkForUniqueUnitIDs( spfld );
01216 
01217    mapLoaded( spfld );
01218 
01219 
01220    GameMap* s = spfld;
01221    spfld = NULL;  // to avoid that is is deleted by the destructor of tsavegameloaders
01222    return s;
01223 }
01224 
01225 
01226 
01227 /*****************************************************************************************************/
01228 /*   Netzwerk                                                                                       */
01229 /*****************************************************************************************************/
01230 
01231 
01232 
01233 
01234 int          tnetworkloaders::savenwgame( tnstream* strm, const GameMap* gamemap )
01235 {
01236 
01237    PackageManager::storeData( gamemap );
01238 
01239    spfld = const_cast<GameMap*>(gamemap); // yes, this is bad, but spfld can't be made constant because it is also used for loading
01240 
01241    stream = strm;
01242 
01243    stream->writepchar ( getFullVersionString() );  // description is not used any more
01244    stream->writeWord ( fileterminator );
01245 
01246    stream->writeInt ( actnetworkversion );
01247 
01248    writemap ();
01249 
01250    writemessages();
01251 
01252    stream->writeInt ( actnetworkversion );
01253 
01254    writefields ( );
01255 
01256    writedissections();
01257 
01258    if ( spfld->replayinfo )
01259       spfld->replayinfo->write ( *stream );
01260 
01261    // the AI must be the last data of the file
01262    writeAI();
01263 
01264    stream->writeInt ( actnetworkversion );
01265 
01266    spfld = NULL;
01267 
01268    return 0;
01269 }
01270 
01271 
01272 
01273 
01274 
01275 GameMap*  tnetworkloaders::loadnwgame( tnstream* strm )
01276 {
01277    const char* name = "network game";
01278 
01279    stream = strm;
01280 
01281 
01282    char* description = NULL;
01283    stream->readpchar ( &description );
01284    delete[] description;
01285 
01286    int w = stream->readWord();
01287 
01288    if ( w != fileterminator )
01289       throw tinvalidversion ( name, fileterminator, (int) w );
01290 
01291 
01292    int version = stream->readInt();
01293 
01294    if (version > actnetworkversion || version < minnetworkversion )
01295       throw tinvalidversion ( name, actnetworkversion, version );
01296 
01297    readmap ();
01298 
01299    if ( version <= 0x11 )
01300       for ( int i = 0; i < 8; i++ )
01301          spfld->player[i].research.read_techs ( *stream );
01302 
01303 
01304    //NEW SaveData Weather
01305    if(version == 0x0030)
01306       weatherSystemRequired();
01307 
01308    /*if(version > 0xfe28){  //Vielleicht minus 1
01309      actmap->weatherSystem->read(*stream);
01310    }*/
01311    readmessages();
01312    readLegacyNetwork ();
01313 
01314    version = stream->readInt();
01315 
01316    if (version > actnetworkversion || version < minnetworkversion )
01317       throw tinvalidversion ( name, actnetworkversion, version );
01318 
01319 
01320 
01321    if ( version < 10 ) {
01322       readOldEventLists ( stream, true, spfld );
01323       readoldevents    ();
01324    }
01325 
01326    readfields ( );
01327 
01328    readdissections();
01329 
01330    if ( spfld->__loadreplayinfo ) {
01331       spfld->replayinfo = new GameMap::ReplayInfo;
01332       spfld->replayinfo->read ( *stream );
01333    }
01334 
01335    if ( version > 8 )
01336       readAI();
01337 
01338 #ifdef sgmain
01339    version = stream->readInt();
01340    if (version > actnetworkversion || version < minnetworkversion )
01341       throw tinvalidversion ( name, actnetworkversion, version );
01342 #endif
01343 
01344    chainitems ( spfld );
01345 
01346    seteventtriggers( spfld );
01347 
01348    calculateallobjects( spfld );
01349 
01350    checkForUniqueUnitIDs( spfld );
01351 
01352    spfld->levelfinished = false;
01353 
01354    // there was a bug that made the ammo amount underflow
01355    for ( int i = 0; i < 8; ++i)
01356       for ( Player::BuildingList::iterator b = spfld->player[i].buildingList.begin(); b != spfld->player[i].buildingList.end(); ++b )
01357          for ( int a = 0; a < waffenanzahl; ++a )
01358             if ( (*b)->ammo[a] > 32000 ) {
01359                ASCString s;
01360                s.format( "Player %s had %d ammo of type %s in the building at %d/%d", spfld->player[i].getName().c_str(), (*b)->ammo[a], cwaffentypen[a], (*b)->getEntry().x, (*b)->getEntry().y );
01361                new Message( s, spfld, 1 );
01362                (*b)->ammo[a] = 0;
01363             }
01364 
01365 
01366 
01367    GameMap* spfldcopy = spfld;
01368    spfld = NULL;
01369 
01370    mapLoaded( spfldcopy );
01371 
01372 
01373    return spfldcopy;
01374 
01375 }
01376 
01377 
01378 
01379 
01380 
01381 
01382 ASCString getLuaQuote( bool open, int n )
01383 {
01384    ASCString s =  open? "[[" : "]]";
01385    for ( int i =0; i < n; ++i )
01386       s.insert(1, "=" );
01387    return s;
01388 }
01389 
01390 ASCString luaQuote( const ASCString& text )
01391 {
01392    int count = 0;
01393    while( text.find_first_of( getLuaQuote( true,  count )) != ASCString::npos ||
01394           text.find_first_of( getLuaQuote( false, count )) != ASCString::npos )
01395       ++count;
01396 
01397    return getLuaQuote( true, count) + text + getLuaQuote( false, count );
01398 }
01399 
01400 void writeMessageFile( GameMap* gamemap, tnstream& stream )
01401 {
01402    stream.writeString( "map = asc.getLoadingMap() \n", false);
01403    for ( GameMap::Events::const_iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i ) {
01404       ASCString s = (*i)->action->getLocalizationString();
01405       if ( !s.empty() )  {
01406          stream.writeString ( "--- ===== Event " + ASCString::toString((*i)->id) + "  ======= \n", false );
01407          stream.writeString ( "message = " + luaQuote( s ) + "\n", false );
01408          stream.writeString ( "asc.setLocalizedEventMessage( map, " + ASCString::toString((*i)->id) + ", message )\n\n", false);
01409       }
01410    }
01411 
01412    for ( int p = 0; p <= gamemap->getPlayerCount(); ++p ) {
01413       Player& player = gamemap->getPlayer(p);
01414       for ( Player::BuildingList::const_iterator b = player.buildingList.begin(); b != player.buildingList.end(); ++b ) {
01415          if ( !(*b)->name.empty() ) {
01416             stream.writeString ( "--- ===== Building " + ASCString::toString((*b)->getIdentification()) + "  ======= \n", false );
01417             ASCString f;
01418             f.format( "asc.setLocalizedContainerName( map, asc.MapCoordinate( %d, %d ), %s ) \n", (*b)->getPosition().x, (*b)->getPosition().y, +  luaQuote( (*b)->name ).c_str() );
01419             stream.writeString (  f, false  );
01420          }
01421       }
01422    }
01423 }
01424 
01425 
01426 
01427 void  savemap( const ASCString& name, GameMap* gamemap )
01428 {
01429 
01430 #ifdef logging
01431    logtofile ( "loaders / savemap / started " );
01432 #endif
01433 
01434    try {
01435       tmaploaders gl;
01436       gl.savemap ( name, gamemap );
01437 
01438 
01439       if ( CGameOptions::Instance()->saveEventMessagesExternal && gamemap->nativeMessageLanguage.length() ) {
01440          tn_file_buf_stream messages ( name + "." + gamemap->nativeMessageLanguage, tnstream::writing );
01441          writeMessageFile( gamemap, messages );
01442       }
01443 
01444    } /* endtry */
01445 
01446    catch ( tfileerror err ) {
01447       displaymessage( "file error writing map to filename %s ", 1, err.getFileName().c_str() );
01448    } /* endcatch */
01449    catch ( ASCexception ) {
01450       displaymessage( "error writing map ", 1 );
01451    } /* endcatch */
01452 
01453 }
01454 
01455 void  savegame( const ASCString& name, GameMap* gamemap)
01456 {
01457    try {
01458       tsavegameloaders gl;
01459       gl.savegame ( gamemap, name);
01460    } catch ( tfileerror err) {
01461       displaymessage( "error writing map to filename %s ", 1, err.getFileName().c_str() );
01462    } /* endcatch */
01463    catch ( ASCexception ) {
01464       displaymessage( "error writing map ", 1 );
01465    } /* endcatch */
01466 }
01467 
01468 
01469 void  savereplay( GameMap* gamemap, int num )
01470 {
01471    try {
01472       if ( !gamemap->replayinfo )
01473          fatalError ( "treplayloaders :: savereplay   ;   No replay activated !");
01474 
01475       if ( gamemap->replayinfo->map[num] ) {
01476          delete gamemap->replayinfo->map[num];
01477          gamemap->replayinfo->map[num] = NULL;
01478       }
01479 
01480       gamemap->replayinfo->map[num] = new MemoryStreamStorage;
01481       MemoryStream memstream ( gamemap->replayinfo->map[num], tnstream::writing );
01482 
01483       memstream.writeInt( actreplayversion );
01484 
01485       tsavegameloaders sgl;
01486       sgl.savegame ( &memstream, gamemap, false );
01487 
01488       memstream.writeInt ( actreplayversion );
01489    } catch ( ASCexception ) {
01490       displaymessage( "error saving replay information", 1 );
01491    } /* endcatch */
01492 }
01493 
01494 GameMap*  loadreplay( MemoryStreamStorage* streambuf )
01495 {
01496    GameMap* replaymap = NULL;
01497 
01498    try {
01499       const char* name = "memorystream actmap->replayinfo";
01500       MemoryStream memstream ( streambuf, tnstream::reading );
01501 
01502       int version = memstream.readInt();
01503       if (version > actreplayversion || version < minreplayversion )
01504          throw tinvalidversion ( name, actreplayversion, version );
01505 
01506       tsavegameloaders sgl;
01507       replaymap = sgl.loadgame ( &memstream );
01508 
01509       version = memstream.readInt();
01510       if (version > actreplayversion || version < minreplayversion ) {
01511          delete replaymap;
01512          throw tinvalidversion ( name, actreplayversion, version );
01513       }
01514 
01515    } catch ( InvalidID err ) {
01516       displaymessage( err.getMessage().c_str(), 1 );
01517       replaymap = NULL;
01518    } /* endcatch */
01519    catch ( tinvalidversion err ) {
01520       displaymessage( err.getMessage().c_str(), 1 );
01521       replaymap = NULL;
01522    } /* endcatch */
01523    catch ( tfileerror err) {
01524       displaymessage( "error reading map filename %s ", 1, err.getFileName().c_str() );
01525       replaymap = NULL;
01526    } /* endcatch */
01527    catch ( ASCexception ) {
01528       displaymessage( "error loading replay", 1 );
01529       replaymap = NULL;
01530    } /* endcatch */
01531 
01532    return replaymap;
01533 }
01534 
01535 
01536 
01537 
01538 GameMap* mapLoadingExceptionChecker( const ASCString& filename, MapLoadingFunction loader )
01539 {
01540    GameMap* m = NULL;
01541    try {
01542       m = loader( filename );
01543    } catch ( InvalidID err ) {
01544       displaymessage( err.getMessage().c_str(), 1 );
01545       return NULL;
01546    } /* endcatch */
01547    catch ( tinvalidversion err ) {
01548       displaymessage( err.getMessage().c_str(), 1 );
01549       return NULL;
01550    } /* endcatch */
01551    catch ( StreamCompressionError err ) {
01552       displaymessage( "The file %s is corrupted.\nPlease obtain a new copy of that file", 1, filename.c_str() );
01553       return NULL;
01554    } catch ( tfileerror err) {
01555       displaymessage( "error reading map filename %s ", 1, err.getFileName().c_str() );
01556       return NULL;
01557    } /* endcatch */
01558    catch ( ASCmsgException msg ) {
01559       displaymessage( "error loading file\n" + msg.getMessage() , 1 );
01560       return NULL;
01561    } /* endcatch */
01562    catch ( ASCexception ) {
01563       displaymessage( "error loading file", 1 );
01564       return NULL;
01565    } /* endcatch */
01566 
01567    return m;
01568 }
01569 
01570 
01571 
01572 
01573 
01574 
01575 
01576 
01577 
01578 bool validatemapfile ( const ASCString& filename )
01579 {
01580 
01581    char* description = NULL;
01582 
01583    try {
01584 
01585       tnfilestream stream ( filename, tnstream::reading );
01586       stream.readpchar ( &description, 200 );
01587       if ( description ) {
01588          delete[]  description ;
01589          description = NULL;
01590       }
01591 
01592       int w = stream.readWord();
01593       if ( w != fileterminator )
01594          throw tinvalidversion ( filename, fileterminator, (int) w );
01595 
01596       int version = stream.readInt();
01597 
01598       if (version > actmapversion || version < minmapversion )
01599          throw tinvalidversion ( filename, actmapversion, version );
01600 
01601    } /* endtry */
01602 
01603    catch ( ... ) {
01604       return false;
01605    } /* endcatch */
01606 
01607    return true;
01608 }
01609 
01610 
01611 
01612 
01613 
01614 bool validateemlfile ( const ASCString& filename )
01615 {
01616    char* description = NULL;
01617 
01618    try {
01619 
01620       tnfilestream stream ( filename, tnstream::reading );
01621       stream.readpchar ( &description, 200 );
01622       if ( description ) {
01623          delete[]  description ;
01624          description = NULL;
01625       }
01626 
01627       int w = stream.readWord();
01628       if ( w != fileterminator )
01629          throw tinvalidversion ( filename, fileterminator, (int) w );
01630 
01631       int version = stream.readInt();
01632 
01633       if (version > actnetworkversion || version < minnetworkversion )
01634          throw tinvalidversion ( filename, actnetworkversion, version );
01635 
01636    } /* endtry */
01637 
01638    catch ( ASCexception ) {
01639       return false;
01640    } /* endcatch */
01641 
01642 
01643    return true;
01644 }
01645 
01646 
01647 bool validatesavfile ( const ASCString& filename )
01648 {
01649 
01650    char* description = NULL;
01651 
01652    try {
01653 
01654       tnfilestream stream ( filename, tnstream::reading );
01655       stream.readpchar ( &description, 200 );
01656       if ( description ) {
01657          delete[]  description ;
01658          description = NULL;
01659       }
01660 
01661       int w = stream.readWord();
01662       if ( w != fileterminator )
01663          throw tinvalidversion ( filename, fileterminator, w );
01664 
01665       int version = stream.readInt();
01666       if (version > actsavegameversion || version < minsavegameversion )
01667          throw tinvalidversion ( filename, actsavegameversion, version );
01668 
01669    } /* endtry */
01670 
01671    catch ( ASCexception ) {
01672       return false;
01673    } /* endcatch */
01674 
01675    return true;
01676 }
01677 
01678 
01679 
01680 
01681 MapConinuationInfo findNextCampaignMap( int id  )
01682 {
01683    MapConinuationInfo mi;
01684 
01685    tfindfile ff ( mapextension );
01686 
01687    ASCString filename = ff.getnextname();
01688    while( !filename.empty() ) {
01689 
01690       try {
01691          tnfilestream filestream ( filename, tnstream::reading );
01692          tmaploaders spfldloader;
01693          spfldloader.stream = &filestream;
01694 
01695          CharBuf description;
01696 
01697          spfldloader.stream->readpchar ( &description.buf );
01698 
01699          int w = spfldloader.stream->readWord();
01700 
01701          if ( w != fileterminator )
01702             throw tinvalidversion ( filename.c_str(), w, fileterminator );
01703 
01704          int version =  spfldloader.stream->readInt();
01705 
01706          if (version > actmapversion || version < minmapversion )
01707             throw tinvalidversion ( filename.c_str(), version, actmapversion );
01708 
01709          spfldloader.readmap ();
01710 
01711          if ( spfldloader.spfld->campaign.avail && spfldloader.spfld->campaign.id == id ) {
01712             mi.title = spfldloader.spfld->maptitle;
01713             mi.codeword = spfldloader.spfld->codeWord;
01714             mi.filename = filename;
01715             return mi;
01716          }
01717       } catch ( ... ) {
01718       } /* endcatch */
01719 
01720       filename = ff.getnextname();
01721    }
01722 
01723    return mi;
01724 }
01725 
01726 

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