loadbi3.cpp

Go to the documentation of this file.
00001 
00005 /*
00006     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00007     Copyright (C) 1994-2010 Martin Bickel  and  Marc Schellenberger
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with this program; see the file COPYING. If not, write to the 
00021     Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00022     Boston, MA  02111-1307  USA
00023 */
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <cstring>
00028 
00029 #include "loadbi3.h"
00030 #include "typen.h"
00031 #include "buildingtype.h"
00032 #include "vehicletype.h"
00033 #include "misc.h"
00034 #include "gameoptions.h"
00035 #include "graphicset.h"
00036 #include "spfst.h"
00037 #include "spfst-legacy.h"
00038 #include "loaders.h"
00039 #include "dialog.h"
00040 #include "itemrepository.h"
00041 #include "textfile_evaluation.h"
00042 
00043 /*#ifdef convert/er
00044   #error The small editors should not need to use LoadBi3
00045   #endif*/
00046 
00047 
00048 #pragma pack(1)
00049 
00050 
00051 
00052 class timporterror : public ASCexception {};
00053 
00054 
00055 int battleisleversion = -1;
00056 
00057 const int LIBFilesAnz  = 11;
00058 
00059 struct  TLIBFiles {
00060       const char*  Name;
00061       int FirstRecO;
00062       int RecSize;
00063       int DataInRecOfs;
00064       int DataSize;
00065       int Anzahl;
00066   };
00067  TLIBFiles LIBFiles [ LIBFilesAnz ] = 
00068       {{"part000.lib",  0xC, 0x240,   0, 0x240, 1335},
00069       {"unit000.lib",  0x4, 0x240,   0, 0x240, 128},   // 128 f?r BI3   // 118 f?r BI2 Scenery
00070       {"layr000.lib",  0x4, 0x240,   0, 0x240, 24},
00071       {"layr001.lib",  0x4, 0x240,   0, 0x240, 24},
00072       {"layr002.lib",  0x4, 0x240,   0, 0x240, 24},
00073       {"layr003.lib",  0x4, 0x240,   0, 0x240, 24},
00074       {"layr004.lib",  0x4, 0x240,   0, 0x240, 24},
00075       {"layr005.lib",  0x4, 0x240,   0, 0x240, 24},
00076       {"layr006.lib",  0x4, 0x240,   0, 0x240, 24},
00077       {"curs000.lib",  0xC, 0x25E,0x1A, 0x240, 12},
00078       {"palt000.lib",  0xC, 0x300,   0, 0x300, 4 } ,
00079       } ;
00080       
00081 
00082 int libs_to_load = 9;
00083 
00084 
00085 void checkbi3dir ( void )
00086 {
00087    if ( CGameOptions::Instance()->BI3directory.empty() ) {
00088       readgameoptions();
00089       /*
00090       if ( !gameoptions.bi3.dir.getName() ) {
00091          gameoptions.bi3.dir = new char [300];
00092          gameoptions.bi3.dir[0] = 0;
00093       }
00094       */
00095    }
00096 
00097    bool notfound;
00098    do {
00099       notfound = false;
00100       
00101       ASCString filename;
00102 
00103       for ( int i = 0; i < libs_to_load ; i++ ) {
00104          filename =  CGameOptions::Instance()->BI3directory + LIBFiles[i].Name ;
00105          
00106          if ( !exist ( filename ) ) {
00107             filename = CGameOptions::Instance()->BI3directory + "LIB" + pathdelimitterstring + LIBFiles[i].Name;
00108             if ( !exist ( filename ) ) {
00109                printf("Battle Isle file %s not found !\n", filename.c_str() );
00110                notfound = true;
00111             }
00112          }
00113       }
00114      if ( notfound ) {
00115             char bi3path[10000];
00116             printf("Enter Battle Isle directory:\n" );
00117             if ( !scanf ( "%s", bi3path ) )
00118                bi3path[0] = 0;
00119 
00120             CGameOptions::Instance()->BI3directory = bi3path;
00121             appendbackslash ( CGameOptions::Instance()->BI3directory );
00122             CGameOptions::Instance()->setChanged();
00123      }
00124    } while ( notfound ); /* enddo */
00125    battleisleversion = 3;
00126 }
00127 
00128 
00129 ASCString getbi3path ( void )
00130 {
00131    return CGameOptions::Instance()->BI3directory;
00132 }
00133 
00134 
00136 class Bi3MapTranslationTable {
00137     public:
00139        vector< pair<int,int> > terraintranslation;
00140 
00141        struct Terrain2id {
00142            int BIpic;
00143            int terrainid;
00144            int weather;
00145            void read ( tnstream& stream ) {
00146                int version = stream.readInt();
00147                if ( version != 1 )
00148                   throw tinvalidversion( stream.getDeviceName(), 1, version );
00149                BIpic = stream.readInt();
00150                terrainid = stream.readInt();
00151                weather = stream.readInt();
00152            };
00153 
00154            void write ( tnstream& stream ) const {
00155                stream.writeInt( 1 );
00156                stream.writeInt( BIpic );
00157                stream.writeInt( terrainid );
00158                stream.writeInt( weather );
00159            };
00160        };
00164        vector< Terrain2id > terrain2idTranslation;
00165 
00166 
00167        struct Terraincombixlat {
00168                    int bigraph;
00169                    int terrainid;
00170                    int terrainweather;
00171                    int objectid;
00172                    void read ( tnstream& stream ) {
00173                       stream.readInt();
00174                       bigraph = stream.readInt();
00175                       terrainid = stream.readInt();
00176                       terrainweather = stream.readInt();
00177                       objectid = stream.readInt();
00178                    };
00179 
00180                    void write ( tnstream& stream ) const {
00181                       stream.writeInt( 1 );
00182                       stream.writeInt( bigraph );
00183                       stream.writeInt( terrainid );
00184                       stream.writeInt( terrainweather );
00185                       stream.writeInt( objectid );
00186                    };
00187 
00188             };
00190         vector<Terraincombixlat> terraincombixlat;
00191 
00192 
00193         struct Objecttranslataion {
00194            int BIpic;
00195            int objects[4];
00196            int terrainID;
00197            int terrainWeather;
00198            void read ( tnstream& stream ) {
00199                stream.readInt();
00200                BIpic = stream.readInt();
00201                for ( int i = 0; i< 4; ++i )
00202                   objects[i] = stream.readInt();
00203                terrainID = stream.readInt();
00204                terrainWeather = stream.readInt();
00205            };
00206 
00207            void write ( tnstream& stream ) const {
00208                stream.writeInt( 1 );
00209                stream.writeInt( BIpic );
00210                for ( int i = 0; i< 4; ++i )
00211                    stream.writeInt( objects[i] );
00212                stream.writeInt( terrainID );
00213                stream.writeInt( terrainWeather );
00214            };
00215         };
00216 
00220         vector<Objecttranslataion> objecttranslate ;
00221 
00225         vector< pair<int,int> > object2IDtranslate;
00226 
00227         void runTextIO ( PropertyContainer& pc );
00228 
00229         void read ( tnstream& stream );
00230         void write ( tnstream& stream ) const;
00231         ASCString filename, location;
00232 };
00233 
00234 
00235 void Bi3MapTranslationTable :: read ( tnstream& stream )
00236 {
00237    int version = stream.readInt();
00238    readClassContainer( terraintranslation, stream );
00239    readClassContainer( terrain2idTranslation, stream );
00240    readClassContainer( terraincombixlat, stream );
00241    readClassContainer( objecttranslate, stream );
00242    readClassContainer( object2IDtranslate, stream );
00243    if ( version >= 2 ) {
00244       filename = stream.readString();
00245       location = stream.readString();
00246    }
00247 
00248 }
00249 
00250 
00251 
00252 void Bi3MapTranslationTable :: write ( tnstream& stream ) const
00253 {
00254    stream.writeInt ( 2 );
00255    writeClassContainer ( terraintranslation, stream );
00256    writeClassContainer ( terrain2idTranslation, stream );
00257    writeClassContainer ( terraincombixlat, stream );
00258    writeClassContainer ( objecttranslate, stream );
00259    writeClassContainer ( object2IDtranslate, stream );
00260    stream.writeString( filename );
00261    stream.writeString( location );
00262 }
00263 
00264 
00265 void Bi3MapTranslationTable :: runTextIO ( PropertyContainer& pc )
00266 {
00267    vector<int> _terraintranslation;
00268    pc.addIntegerArray ( "TerrainTranslation", _terraintranslation );
00269 
00270    vector<int> _terrain2idtrans;
00271    pc.addIntegerArray ( "Terrain2IDTranslation", _terrain2idtrans );
00272 
00273    vector<int> _terrainobjtranslation;
00274    pc.addIntegerArray ( "TerrainObjTranslation", _terrainobjtranslation );
00275 
00276    vector<int> _objecttranslation;
00277    if ( pc.find( "ObjectTranslation" ))
00278       pc.addIntegerArray ( "ObjectTranslation", _objecttranslation );
00279 
00280    vector<int> _object2IDtranslation;
00281    pc.addIntegerArray ( "Object2IDTranslation", _object2IDtranslation );
00282 
00283    vector<int> object3translation;
00284    if ( pc.find( "Object3Translation" ))
00285       pc.addIntegerArray ( "Object3Translation", object3translation );
00286 
00287 
00288    if ( _terraintranslation.size() % 2 )
00289       fatalError ( "Bi3 map translation : terraintranslation - Invalid number of entries ");
00290    terraintranslation.clear();
00291    for ( int i = 0; i < _terraintranslation.size()/2; i++ )
00292       terraintranslation.push_back ( make_pair( _terraintranslation[i*2], _terraintranslation[i*2+1] ));
00293 
00294 
00295    if ( _terrain2idtrans.size() % 3 )
00296       fatalError ( "Bi3 map translation : terrain2idTranslation - Invalid number of entries ");
00297    terrain2idTranslation.clear();
00298    for ( int i = 0; i < _terrain2idtrans.size()/3; i++ ) {
00299       Terrain2id t2i;
00300       t2i.BIpic = _terrain2idtrans[i*3];
00301       t2i.terrainid = _terrain2idtrans[i*3+1];
00302       t2i.weather = _terrain2idtrans[i*3+2];
00303       terrain2idTranslation.push_back ( t2i );
00304    }
00305 
00306    if ( _terrainobjtranslation.size() % 4 )
00307       fatalError ( "Bi3 map translation : terrainobjtranslation - Invalid number of entries ");
00308    terraincombixlat.clear();
00309    for ( int i = 0; i < _terrainobjtranslation.size()/4; i++ ) {
00310        Terraincombixlat tcx;
00311        tcx.bigraph = _terrainobjtranslation[i*4];
00312        tcx.terrainid = _terrainobjtranslation[i*4+1];
00313        tcx.terrainweather = _terrainobjtranslation[i*4+2];
00314        tcx.objectid = _terrainobjtranslation[i*4+3];
00315        terraincombixlat.push_back ( tcx );
00316    }
00317 
00318    if ( _objecttranslation.size() % 5 )
00319       fatalError ( "Bi3 map translation : objecttranslation - Invalid number of entries ");
00320    objecttranslate.clear();
00321    for ( int i = 0; i < _objecttranslation.size()/5; i++ ) {
00322       Objecttranslataion ot;
00323       ot.BIpic = _objecttranslation[i*5];
00324       for ( int j = 0; j < 4; j++ )
00325          ot.objects[j] = _objecttranslation[i*5 + 1 + j];
00326       ot.terrainID = -1;
00327       ot.terrainWeather = 0;
00328 
00329       objecttranslate.push_back ( ot );
00330    }
00331 
00332 
00333    if ( object3translation.size() % 7 )
00334       fatalError ( "Bi3 map translation : object3translation - Invalid number of entries ");
00335    for ( int i = 0; i < object3translation.size()/7; i++ ) {
00336       Objecttranslataion ot;
00337       ot.BIpic = object3translation[i*7];
00338       for ( int j = 0; j < 4; j++ )
00339          ot.objects[j] = object3translation[i*7 + 1 + j];
00340       ot.terrainID = object3translation[i*7 + 5];
00341       ot.terrainWeather = object3translation[i*7 + 6];
00342 
00343       objecttranslate.push_back ( ot );
00344    }
00345 
00346 
00347    if ( _object2IDtranslation.size() % 2 )
00348       fatalError ( "Bi3 map translation : object2IDtranslation - Invalid number of entries ");
00349    object2IDtranslate.clear();
00350    for ( int i = 0; i < _object2IDtranslation.size()/2; i++ )
00351       object2IDtranslate.push_back ( make_pair ( _object2IDtranslation[i*2], _object2IDtranslation[i*2+1] ));
00352 }
00353 
00354 
00355 
00356 
00357 PointerVector<Bi3MapTranslationTable*> bi3ImportTables;
00358 
00359 Bi3MapTranslationTable* findTable( const ASCString& filename ) {
00360    for ( PointerVector<Bi3MapTranslationTable*>::iterator i = bi3ImportTables.begin(); i != bi3ImportTables.end(); ++i )
00361       if ( (*i)->filename == filename )
00362          return *i;
00363    return NULL;
00364 }
00365 
00366 vector<ASCString> getBI3ImportTables()
00367 {
00368    vector<ASCString> list;
00369    for ( PointerVector<Bi3MapTranslationTable*>::iterator i = bi3ImportTables.begin(); i != bi3ImportTables.end(); ++i )
00370       list.push_back ( (*i)->filename );
00371    return list;
00372 }
00373 
00374 
00375 void BI3TranslationTableLoader::read ( tnstream& stream )
00376 {
00377    stream.readInt();
00378    readPointerContainer ( bi3ImportTables, stream );
00379 }
00380 
00381 void BI3TranslationTableLoader::write ( tnstream& stream )
00382 {
00383    stream.writeInt( 1 );
00384    writePointerContainer ( bi3ImportTables, stream );
00385 }
00386 
00387 
00388 ASCString BI3TranslationTableLoader::getTypeName()
00389 {
00390    return "bi3maptranslation";
00391 }
00392 
00393 void BI3TranslationTableLoader::readTextFiles( PropertyReadingContainer& prc, const ASCString& fileName, const ASCString& location )
00394 {
00395    Bi3MapTranslationTable* bmtt = new Bi3MapTranslationTable;
00396    bmtt->runTextIO ( prc );
00397    bmtt->filename = fileName;
00398    bmtt->location = location;
00399    bi3ImportTables.push_back ( bmtt );
00400 }
00401 
00402 
00403 const int fuelfactor = 120;
00404 const int materialfactor = 390;
00405 const int energyfactor = 390;
00406 
00407 
00408 
00409 
00410       const char* HeadID = "MSSN";
00411       const char* ACTNID = "ACTN";
00412       const char* SHOPID = "SHOP";
00413       const char* MAPID  = "MAP\0";
00414       const char* MISSID = "MISS";
00415 
00416 
00417 
00418 class tloadBImap {
00419        Bi3MapTranslationTable* translationTable;
00420      
00421        struct THeader {
00422          char ID[4];                            // { 'MSSN' }
00423          int MissPos;
00424          int MapPos ;
00425          int ShopPos;
00426          int ACTNPos;
00427          Uint16 DFNum ;
00428          int DFPos[32] ;                     // { Pos nach DFXX }
00429          int DFLength[32];                   // { +4B von DFXX }
00430        };
00431 
00432        struct TACTN {
00433          char ID[4];
00434          Uint16 XSize, YSize;
00435        };
00436 
00437        typedef Uint16 TStdProdRec[64];
00438        typedef char TAllianzen[6];
00439 
00440 
00441        struct TMISSPart {
00442            char ID[4];
00443            Uint16 Stuff1 [3];
00444            Uint16 NextMiss;
00445            char StartWeather;
00446            char WhoPlays;           // { jeder Mensch/Computer ein Bit }
00447            char PlayType;           // { jeder Computer ein Bit }
00448            char Recs2Win;           // { Wieviel Gewinnrecords aus map erf llt werden m ssen, damit man gewinnt (f r jeden player gleich) }
00449            char Stuff2[3];
00450            char Landscape;
00451            TAllianzen Allianz;      // { Wer mit wem }
00452            Uint16 Stuff3[65];
00453            TStdProdRec StdProd;
00454            Uint16 Stuff4[24];
00455        };
00456           
00457        struct TMAPHead {
00458               char ID[4];
00459        };
00460           
00461        struct TFileMap { 
00462               Uint16 What1;
00463               Uint16 Round, Move;
00464               char Player, What2;
00465               Uint16 Stuff2;
00466               Uint16 Zero1;
00467               Uint16 Nr1;
00468               Uint16 Nr2;
00469               Uint16 Nr3;
00470               Uint16 Zero2[11];
00471        };
00472           
00473        struct TSHOPHead {
00474               char ID[4];
00475               Uint16 Num;
00476        };
00477           
00478        typedef int TVehContent[8];
00479        typedef TVehContent *PVehContent;
00480           
00481           union TShopContent {
00482              Uint16 XY[4][4];
00483              Uint16 All[16];
00484              TVehContent Veh;
00485           };
00486        typedef TShopContent *PShopContent;
00487          
00488        typedef Uint16 TProduceRec[4];
00489 
00490        struct TFileShop {
00491          Uint16 ID;
00492          Uint16 Pos1;
00493          union  {
00494             struct {
00495                Uint16 ShopType;
00496                Uint16 Stuff06;  // { Zero }
00497                Uint16 Name;
00498                Uint16 Pos2;
00499                Uint16 E, M;
00500                char EP, MP ;
00501                TShopContent Content;
00502                Uint16 ShopType2;
00503                TProduceRec Produce;
00504                Uint16 Stuff60 ; // { Zero }
00505                Uint16 Prior;
00506                Uint16 Owner;
00507                Uint16 Stuff66[7];  // { Zero }
00508             } a;
00509             struct {
00510                 char Zero2[6];
00511                 Uint16 W0A;
00512                 char Zero3[6];
00513                 Uint16 W48;
00514                 Uint16 W4A;
00515                 char Zero4[2];
00516                 Uint16 W4E;
00517             } b;
00518             char raw[76];
00519          };
00520        };
00521 
00522        dynamic_array<char*> names;
00523        int namenum;
00524        bool fakemap;
00525 
00526      protected:
00527         int xoffset, yoffset;
00528         TerrainType::Weather* defaultterraintype;
00529      public:
00530        void LoadFromFile( const char* path, const char* AFileName, TerrainType::Weather* trrn, string* errorOutput );
00531        tloadBImap ( Bi3MapTranslationTable* _translationTable ) : translationTable ( _translationTable ) {
00532           xoffset = 0;
00533           yoffset = 0;
00534           fakemap = false;
00535        };
00536 
00537        void ____fakeMap____ ( void ) { fakemap = true; };
00538        virtual ~tloadBImap() {};
00539      private:
00540 
00541        tn_file_buf_stream* MissFile;
00542        THeader Header;
00543 
00544        struct TTextItem {
00545            int a;
00546            int b;
00547            char name[1000];
00548        };
00549 
00550        dynamic_array<TTextItem> ShopNameList;
00551        void LoadTXTFile ( char* filename );
00552 //       int TPWMtextfile;
00553 
00554        void ReadMISSPart(void);
00555        void ReadACTNPart(void);
00556        void ReadSHOPPart(void);
00557        void ReadShopNames( char *txtdata, unsigned long txtsize );
00558        Vehicle* getunit ( int typ, int col );
00559        VehicleType* getvehicletype ( int typ );
00560        char* GetStr ( int a, int b );
00561        int convcol ( int c );
00562 
00563        TMISSPart OrgMissRec;
00564        void GetTXTName ( const char* path, const char* filename, char* buf );
00565 
00566       protected:
00567         char* missing;
00568         virtual void preparemap ( int x, int y  ) = 0;
00569         virtual MapField* getfield ( int x, int y );
00570 
00571 };
00572 
00573 class ImportBiMap : public tloadBImap {
00574          protected:
00575            virtual void preparemap ( int x, int y  );
00576          public:
00577            ImportBiMap ( Bi3MapTranslationTable* _translationTable ) : tloadBImap (  _translationTable ) {};
00578 };
00579 
00580 class InsertBiMap : public tloadBImap {
00581          protected:
00582            virtual void preparemap ( int x, int y  );
00583            virtual MapField* getfield ( int x, int y );
00584          public:
00585            InsertBiMap ( int x, int y, Bi3MapTranslationTable* _translationTable ) : tloadBImap (  _translationTable ) {
00586              xoffset = x; 
00587              yoffset = y;
00588            };
00589 };
00590 
00591 
00592 MapField* tloadBImap :: getfield ( int x, int y )
00593 {
00594    return ::getfield ( x, y );
00595 }
00596 
00597 MapField* InsertBiMap :: getfield ( int x, int y )
00598 {
00599    return ::getfield ( xoffset + x, yoffset + y );
00600 }
00601 
00602 
00603 void  tloadBImap ::  ReadMISSPart(void)
00604 { 
00605 
00606   MissFile->seek ( Header.MissPos );
00607 
00608   MissFile->readdata2 ( OrgMissRec ); 
00609   if ( strncmp ( OrgMissRec.ID, MISSID, 4)  ) {
00610      strcat ( missing, "\nFatal error: No Battle Isle mission; invalid MissID\n"  );
00611      throw timporterror (); 
00612   }
00613 
00614 /*
00615   int I; 
00616   StdProd = OrgMissRec.StdProd; 
00617   for (I = 0; I <= 63; I++) 
00618       StdProd[I] = StdProd[I] & 0x03; 
00619 
00620   PlayerType = OrgMissRec.PlayType & 0x3F; 
00621   Allianz = OrgMissRec.Allianz; 
00622   for (I = 0; I <= 5; I++) 
00623      Allianz[I] = Allianz[I] & 0x3F; 
00624   Recs2Win = OrgMissRec.Recs2Win;
00625   StartWeather = OrgMissRec.StartWeather; 
00626   if ( StartWeather < 0  ||  StartWeather > 4 )
00627      StartWeather = 0; 
00628   NextMiss = OrgMissRec.NextMiss; 
00629   Landscape = OrgMissRec.Landscape; 
00630 */
00631 } 
00632 
00633 int tloadBImap :: convcol ( int c )
00634 {
00635    int cl = getFirstBit ( c );
00636    if ( cl == 6 )
00637       return 8;
00638    else
00639      if ( cl < 2 )
00640         cl = 1 - cl;
00641    return cl;
00642 }
00643 
00644   
00645 const int bi3unitnum = 74;
00646 int translateunits[ bi3unitnum ][2] = { {1201,26}, {1270,26}, {1202,13}, {1200,6}, {1203,-1},
00647                                         {1204,16}, {1205,17}, {1206,4}, {1207,65}, {1208,-1},
00648                                         {1209,7},  {1210,66}, {1211,2}, {1212,3},  {1213,17},
00649                                         {1214,51}, {1215,17}, {1216,2}, {1217,10}, {1218,11},
00650                                         {1219,16}, {1220,61}, {1221,49},{1222,56}, {1276,-1},
00651                                         {1223,25}, {1224,72}, {1225,57},{1226,58}, {1227,7},
00652                                         {1228,59}, {1241,9},  {1242,22},{1244,19}, {1243,29},
00653                                         {1245,55}, {1246,19}, {1271,21},{1247,52}, {1248,31},
00654                                         {1251,15}, {1252,15}, {1256,39},{1257,42}, {1258,47},
00655                                         {1259,14}, {1260,36}, {1261,34},{1262,47}, {1263,37},
00656                                         {1264,38}, {1265,5},  {1229,18},{1277,-1}, {1249,-1},
00657                                         {1230,1},  {1231,66}, {1266, 5},{1232,64}, {1233,-1},
00658                                         {1234,4},  {1235,4},  {1267,35},{1250,29}};
00659 
00660 
00661 VehicleType*  tloadBImap :: getvehicletype ( int tp )
00662 {
00663    for ( int j = 0; j < vehicleTypeRepository.getNum(); j++ ) {
00664       VehicleType* tnk = vehicleTypeRepository.getObject_byPos ( j );
00665       if ( tnk )
00666          if ( tnk->bipicture > 0 )
00667             if ( tnk->bipicture == 1340 + tp * 2 )
00668                   return tnk;
00669    }
00670 
00671 
00672    if ( tp < bi3unitnum )
00673       for ( int i = 0; i < 2; i++ )
00674          if ( translateunits[tp][i] > 0 ) {
00675             VehicleType* tnk = vehicleTypeRepository.getObject_byID ( translateunits[tp][i] );
00676             if ( tnk )
00677                return tnk;
00678          }
00679    return NULL;
00680 }
00681 
00682 Vehicle* tloadBImap :: getunit ( int tp, int col )
00683 {
00684    if ( tp != 0xffff && tp != 0xff && col != 0xff ) {
00685       VehicleType* vt = getvehicletype ( tp );
00686       if ( vt ) {
00687          Vehicle* eht = new Vehicle ( vt, actmap, col );
00688          eht->fillMagically();
00689          return eht;
00690       }
00691    }
00692 
00693    return NULL;
00694 }
00695 
00696 void         generatemap( TerrainType::Weather*   bt,
00697                           int                xsize,
00698                           int                ysize)
00699 {
00700    delete actmap;
00701    actmap = new GameMap;
00702    for (int k = 1; k < 8; k++)
00703       actmap->player[k].stat = Player::computer;
00704 
00705    actmap->maptitle = "new map";
00706 
00707    actmap->allocateFields(xsize, ysize);
00708 
00709    if ( actmap->field== NULL)
00710       displaymessage ( "Could not generate map !! \nProbably out of enough memory !",2);
00711 
00712    for ( int l = 0; l < xsize*ysize; l++ ) {
00713       actmap->field[l].typ = bt;
00714       actmap->field[l].setparams();
00715       actmap->field[l].setMap( actmap );
00716    }
00717 
00718    actmap->_resourcemode = 1;
00719 }
00720 
00721 
00722 void ImportBiMap :: preparemap ( int x, int y  )
00723 {
00724     generatemap ( defaultterraintype, x, y ); 
00725     actmap->setgameparameter( cgp_movefrominvalidfields, 1);
00726     actmap->setgameparameter( cgp_forbid_building_construction, 1);
00727 }
00728 
00729 void InsertBiMap :: preparemap ( int x, int y  )
00730 {
00731    if ( yoffset & 1 ) {
00732       yoffset--;
00733       strcat ( missing, "y position for map insertion must be even; current position decreased\n");
00734    }
00735    int xp = xoffset;
00736    int yp = yoffset;
00737    if ( xp + x > actmap->xsize ) {
00738       int dx = xp + x - actmap->xsize;
00739       strcat ( missing, "map had to be resized in X direction\n");
00740       int r = actmap->resize ( 0, 0, 0, dx );
00741       if ( r ) {
00742          strcat ( missing, "Resizing failed !!\n");
00743          throw timporterror();
00744       }
00745    }
00746    if ( yp + y > actmap->ysize ) {
00747       int dy = yp + y - actmap->ysize;
00748       strcat ( missing, "map had to be resized in Y direction\n");
00749       int r = actmap->resize ( 0, dy, 0, 0 );
00750       if ( r ) {
00751          strcat ( missing, "Resizing failed !!\n");
00752          throw timporterror();
00753       }
00754    }
00755 
00756    for ( int b = 0; b < y; b++ )
00757       for ( int a = 0; a < x; a++ )
00758          getfield ( a, b ) -> deleteeverything();
00759 }
00760 
00761 void  stu_height ( Vehicle* vehicle )
00762 {
00763    char l;
00764    MapField* fld = getfield ( vehicle->xpos, vehicle->ypos );
00765 
00766    vehicle->height = chfahrend;
00767 
00768    for (l=chsatellit; l> chfahrend ;  ) {
00769       if (vehicle->typ->height & l )
00770          vehicle->height = l;
00771       l>>=1;
00772    } /* endfor */
00773 
00774    for (l=chtiefgetaucht; l<= chschwimmend ;  ) {
00775       if (vehicle->typ->height & l )
00776         if (vehicle->typ->terrainaccess.accessible (  fld->bdt ) > 0 )
00777            vehicle->height = l;
00778       l<<=1;
00779    }
00780 
00781    if (vehicle->typ->height & chfahrend)
00782       if (vehicle->typ->terrainaccess.accessible ( fld->bdt ) > 0 )
00783          vehicle->height = chfahrend;
00784 
00785    vehicle->setMovement ( vehicle->typ->movement[getFirstBit( vehicle->height )] );
00786 }
00787 
00788 
00789 void        tloadBImap ::   ReadACTNPart(void)
00790 { 
00791     struct {
00792        int X, Y;
00793     } Size;
00794 
00795     TACTN        ACTNHead; 
00796   
00797     MissFile->seek ( Header.ACTNPos );
00798     MissFile->readdata2( ACTNHead ); 
00799     if ( strncmp ( ACTNHead.ID ,ACTNID,4 )) {
00800        strcat ( missing, "\nFatal error: No Battle Isle mission; invalid ACTNID\n"  );
00801        throw timporterror (); 
00802     }
00803 
00804     Size.X = ACTNHead.XSize;
00805     Size.Y = ACTNHead.YSize;
00806     if ( Size.Y & 1 )
00807        Size.Y++;
00808 
00809     preparemap ( Size.X / 2, Size.Y * 2 );
00810 
00811     for ( int i = 0; i < 6; i++ )
00812        if ( OrgMissRec.WhoPlays & (1<< i))
00813           actmap->player[ convcol ( 1 << i) ].stat = Player::PlayerStatus( (OrgMissRec.PlayType>>i) & 1);
00814        else
00815           actmap->player[convcol ( 1 << i) ].stat = Player::off;
00816 
00817     /*  Terrain  */ 
00818     int Y, X;
00819 
00820     int missnum = 0;
00821     dynamic_array<int> miss;
00822 
00823     Uint16*         Line = new Uint16[Size.X]; 
00824 
00825     for (Y = 0; Y < Size.Y ; Y++) { 
00826       MissFile->readdata( Line, Size.X * 2); 
00827       for (X = 0; X < Size.X ; X++) {
00828          for ( int tr = 0; tr < translationTable->terraintranslation.size(); tr++ )
00829             if ( Line[X] == translationTable->terraintranslation[tr].first )
00830                Line[X] = translationTable->terraintranslation[tr].second;
00831          int found = 0;
00832          MapField* fld = getfield ( X / 2, Y * 2 + (X & 1) );
00833          fld->tempw = Line[X];
00834          fld->temp3 = 0;
00835 
00836 
00837          for ( int i = 0; i < translationTable->terrain2idTranslation.size(); i++ ) {
00838             if ( Line[X] == translationTable->terrain2idTranslation[i].BIpic ) {
00839                 pterraintype trrn = terrainTypeRepository.getObject_byID ( translationTable->terrain2idTranslation[i].terrainid );
00840                 int w = translationTable->terrain2idTranslation[i].weather;
00841                 if ( trrn )
00842                   if ( trrn->weather[w] ) {
00843                      fld->typ = trrn->weather[w];
00844                      fld->setparams();
00845                      found = 1;
00846                   }
00847             }
00848          }
00849 
00850          if ( !found )
00851             for ( int j = 0; j < translationTable->terraincombixlat.size(); j++ )
00852                if ( Line[X] == translationTable->terraincombixlat[j].bigraph ) {
00853                   pterraintype trrn = terrainTypeRepository.getObject_byID ( translationTable->terraincombixlat[j].terrainid );
00854                   if ( trrn ) {
00855                      fld->typ = trrn->weather[translationTable->terraincombixlat[j].terrainweather];
00856                      ObjectType* obj = NULL;
00857                      if ( translationTable->terraincombixlat[j].objectid > 0 )
00858                         obj = objectTypeRepository.getObject_byID ( translationTable->terraincombixlat[j].objectid );
00859                      if ( obj )
00860                         fld->addobject ( obj, -1, 1 );
00861                      fld->setparams();
00862                      found = 1;
00863                   }
00864                }
00865 
00866          if ( !found )
00867             for ( int i = 0; i < terrainTypeRepository.getNum(); i++ ) {
00868                pterraintype trrn = terrainTypeRepository.getObject_byPos ( i );
00869                if ( trrn )
00870                   for ( int j = 0; j < cwettertypennum; j++ )
00871                      if ( trrn->weather[j] )
00872                         if ( trrn->weather[j]->bi_pict == Line[X] ) {
00873                            fld->typ = trrn->weather[j];
00874                            fld->setparams();
00875                            found = 1;
00876                         }
00877             }
00878 
00879 
00880          if ( !found ) {
00881             int fnd = 0;
00882             for ( int k = 0; k < missnum; k++ )
00883                if ( miss[k] == Line[X] )
00884                   fnd = 1;
00885 
00886             if ( !fnd )
00887                miss[missnum++] = Line[X];
00888 
00889          }
00890       }
00891     }
00892 
00893     if ( missnum ) {
00894        strcat ( missing, "The following terrain fields could not be found: " );
00895        for ( int k = 0; k < missnum; k++ ) {
00896           strcat ( missing, strrr ( miss[k] ));
00897           strcat ( missing, ", ");
00898        }
00899        strcat ( missing, "\n\n");
00900     }
00901 
00902 
00903 
00904     missnum = 0;
00905 
00906     //  Objekte  
00907     for (Y = 0; Y < Size.Y ; Y++) { 
00908       MissFile->readdata( Line, Size.X * 2 ); 
00909       
00910       for (X = 0; X < Size.X ; X++) {
00911          int found = 0;
00912          int newx = X / 2;
00913          int newy = Y * 2 + (X & 1);
00914 
00915          if ( Line[X] != 0xffff )
00916             getfield ( newx, newy )->tempw = Line[X];
00917 
00918 
00919          int xl = 0;
00920          int xlt[5];
00921          int trrID = -1;
00922          int trrWeather = 0;
00923          xlt[0] = Line[X];
00924          for ( int b = 0; b < translationTable->objecttranslate.size(); b++ )
00925              if ( translationTable->objecttranslate[b].BIpic == Line[X] ) {
00926                 for ( int c = 1; c < 5; c++ )
00927                    if ( translationTable->objecttranslate[b].objects[c] != -1 )
00928                       xlt[xl++] = translationTable->objecttranslate[b].objects[c];
00929                 trrID = translationTable->objecttranslate[b].terrainID;
00930                 trrWeather = translationTable->objecttranslate[b].terrainWeather;
00931              }
00932          if ( xl == 0 ) {
00933             for ( int c = 0; c < translationTable->terraintranslation.size(); c++ )
00934                 if ( translationTable->terraintranslation[c].first == Line[X] )
00935                    xlt[xl++] = translationTable->terraintranslation[c].second;
00936 
00937             if ( xl == 0 )
00938                xl = 1;
00939          }
00940 
00941          for ( int m = 0; m < xl; m++ ) {
00942             int found_without_force = 0;
00943             for ( int pass = 0; pass < 2 && !found_without_force; pass++ ) {
00944                for ( int i = 0; i < translationTable->object2IDtranslate.size(); i++ )
00945                   if ( xlt[m] == translationTable->object2IDtranslate[i].first )  {
00946                      ObjectType* obj = objectTypeRepository.getObject_byID ( translationTable->object2IDtranslate[i].second );
00947                      if ( obj ) {
00948                         MapField* fld = getfield ( newx, newy );
00949                         if ( pass == 1 || obj->getFieldModification(fld->getWeather()).terrainaccess.accessible ( fld->bdt )) {
00950                            fld -> addobject ( obj, 0, true );
00951                            found |= 1;
00952                            if ( pass == 0 )
00953                              found_without_force = 1;
00954                         }
00955                      }
00956                }
00957 
00958                if ( !(found & 1) )
00959                   for ( int i = 0; i < objectTypeRepository.getNum(); i++ ) {
00960                      ObjectType* obj = objectTypeRepository.getObject_byPos ( i );
00961                      if ( obj )
00962                         for ( int ww = 0; ww < cwettertypennum; ww++ )
00963                            if ( obj->weather.test(ww) )
00964                               for ( unsigned int j = 0; j < obj->weatherPicture[ww].images.size(); j++ )
00965                                  if ( obj->weatherPicture[ww].bi3pic[j] == xlt[m]  && !(found & 2)  && !( GraphicSetManager::Instance().getMode(xlt[m]) & 256) ) {
00966                                     MapField* fld = getfield ( newx, newy );
00967                                     if ( pass == 1 || obj->getFieldModification(fld->getWeather()).terrainaccess.accessible ( fld->bdt )) {
00968                                        fld -> addobject ( obj, 0, true );
00969                                        found |= 1;
00970                                        if ( pass == 0 )
00971                                          found_without_force = 1;
00972                                     }
00973                                  }
00974                   }
00975             }
00976          }
00977 
00978          if ( trrID >= 0 ) {
00979             pterraintype trrn = terrainTypeRepository.getObject_byID ( trrID );
00980             if ( trrn ) {
00981                if ( !trrn->weather[trrWeather] )
00982                   trrWeather = 0;
00983 
00984                if ( trrn->weather[trrWeather] ) {
00985                   MapField* fld = getfield ( newx, newy );
00986                   fld->typ = trrn->weather[trrWeather];
00987                   fld->setparams();
00988                }
00989             }
00990          }
00991 
00992 
00993          if ( !found  && Line[X] != 0xffff ) {
00994             if ( fakemap ) {
00995                ObjectType* o = new ObjectType;
00996                *o = *objectTypeRepository.getObject_byID ( 44 );
00997                int id = 1000000;
00998                while ( objectTypeRepository.getObject_byID ( id ))
00999                  id++;
01000 
01001                o->id = id;
01002                o->weather = 1;
01003 
01004                o->weatherPicture[0].resize(1);
01005 
01006                // loadbi3pict_double ( Line[X], &o->weatherPicture[0].images[0] );
01007                o->weatherPicture[0].bi3pic[0] = Line[X];
01008 
01009                // addobjecttype ( o );
01010 
01011                // getfield ( newx, newy )->addobject ( o, 0, true );
01012 
01013             } else {
01014 
01015                getfield ( newx, newy )->temp3 = 1;
01016 
01017                int fnd = 0;
01018                for ( int k = 0; k < missnum; k++ )
01019                   if ( miss[k] == Line[X] )
01020                      fnd = 1;
01021 
01022                if ( !fnd )
01023                   if ( Line[X] < 44  || Line[X] > 88 )
01024                      miss[missnum++] = Line[X];
01025             }
01026             
01027          }
01028       }
01029       
01030     } 
01031 /*
01032     if ( missnum ) {
01033        strcat ( missing, "The following objects could not be found: " );
01034        for ( int k = 0; k < missnum; k++ ) {
01035           strcat ( missing, strrr ( miss[k] ));
01036           strcat ( missing, ", ");
01037        }
01038        strcat ( missing, "\n\n");
01039     }
01040 */
01041 
01042     for (Y = 0; Y < Size.Y ; Y++) { 
01043       MissFile->readdata ( Line, Size.X * 2 ); 
01044       for (X = 0; X < Size.X ; X++) {
01045          int tp = Line[X] & 255;
01046          int cl = convcol(Line[X] >> 8);
01047          Vehicle* eht = getunit ( tp, cl );
01048          if ( eht ) {
01049             MapField* fld = getfield ( X / 2, Y * 2 + (X & 1) );
01050             fld->vehicle = eht;
01051             fld->vehicle->xpos = xoffset + X / 2;
01052             fld->vehicle->ypos = yoffset + Y * 2 + (X & 1);
01053             stu_height ( fld->vehicle );
01054          }
01055       }
01056     } 
01057     delete[] Line;
01058 } 
01059  
01060 struct blds {
01061   BuildingType* bld;
01062   int pictnum;
01063   int terrainmatch;
01064   int objectmatch;
01065 } ;
01066 
01067 
01068 void       tloadBImap :: ReadSHOPPart( void )
01069 { 
01070    TSHOPHead    SHOPHead;
01071    TFileShop    FileShop;
01072 //   PVehContent  PVC; 
01073  
01074    int firstmissingbuilding = 1;
01075  
01076    MissFile->seek ( Header.ShopPos );
01077    MissFile->readdata2 ( SHOPHead ); 
01078    if ( strncmp ( SHOPHead.ID, SHOPID, 4 )) {
01079       strcat ( missing, "\nFatal error: No Battle Isle mission; invalid ShopID\n"  );
01080       throw timporterror (); 
01081    }
01082 
01083    int ShopNum = 0; 
01084  //  int VehContNum = 0;
01085  //   int AINum = 0;
01086    for ( int I = 0; I < SHOPHead.Num ; I++ ) {
01087       MissFile->readdata2 ( FileShop );
01088       if ( FileShop.ID == 1) {   //  wenn kein ki punkt  
01089         if (FileShop.a.ShopType == 32) {   //  Vehicle  
01090            int IsVehCont = false; 
01091            for ( int J = 0; J < 8; J++ ) 
01092               if ( FileShop.a.Content.Veh[J] != 0xFFFF ) 
01093                  IsVehCont = true; 
01094            if ( IsVehCont ) {
01095               int Y = FileShop.Pos1 / 64;
01096               int X = FileShop.Pos1 % 64;
01097               MapField* fld = getfield ( X / 2, Y * 2 + (X & 1) );
01098               if ( fld->vehicle ) 
01099                  for ( int j = 0; j < 8; j++ ) 
01100                     if ( FileShop.a.Content.Veh[j] >= 0 ) {
01101                        Vehicle* eht = getunit ( FileShop.a.Content.Veh[j], fld->vehicle->color/8 );
01102                        if ( eht ) {
01103                           eht->xpos = xoffset + X / 2;
01104                           eht->ypos = yoffset + Y * 2 + (X & 1);
01105                           fld->vehicle->addToCargo( eht );
01106                        }
01107                     }
01108 
01109            } 
01110         }
01111        
01112         else {
01113            int Y = FileShop.Pos1 / 64;
01114            int X = FileShop.Pos1 % 64;
01115            int newx = X / 2;
01116            int newy = Y * 2 + (X & 1);
01117             
01118            MapField* fld = getfield ( newx, newy );
01119 
01120            dynamic_array<blds> bldlist;
01121            int bldlistnum = 0;
01122 
01123            for ( int i = 0; i < buildingTypeRepository.getNum(); i++ ) {
01124                BuildingType* bld  = buildingTypeRepository.getObject_byPos ( i );
01125                if ( bld )
01126                   for ( int w = 0; w < cwettertypennum; w++ ) 
01127                      for ( int p = 0; p < maxbuildingpicnum; p++ ) 
01128                            if ( bld->getBIPicture(bld->entry, w, p) == fld->tempw ) {
01129                               bldlist[ bldlistnum ].bld = bld;
01130                               int cnt = 0;
01131                               int terrainmatch = 0;
01132                               int objmatch = 0;
01133                               bool fail = false;
01134                               for ( int m = 0; m < 4; m++ )
01135                                  for ( int n = 0; n < 6; n++ )
01136                                     if ( bld->fieldExists( BuildingType::LocalCoordinate(m , n) ) ) {
01137                                        MapCoordinate pos = bld->getFieldCoordinate ( MapCoordinate(newx, newy), BuildingType::LocalCoordinate(m, n) );
01138                                        MapField* fld2 = getfield ( pos.x, pos.y );
01139                                        if ( !fld2 )
01140                                           fail = true;
01141                                        else {
01142                                           if ( bld->terrainaccess.accessible ( fld2->bdt ) > 0 )
01143                                              terrainmatch++;
01144                                           if ( bld->getBIPicture( BuildingType::LocalCoordinate(m,n), w, p) == fld2->tempw )
01145                                              objmatch++;
01146                                        }
01147                                        cnt++;
01148                                     }
01149                               if ( !fail ) {
01150                                  bldlist[ bldlistnum ].pictnum = cnt;
01151                                  bldlist[ bldlistnum ].terrainmatch = terrainmatch;
01152                                  bldlist[ bldlistnum ].objectmatch = objmatch;
01153 
01154                                  bldlistnum++;
01155                               }
01156 
01157                            }
01158            }
01159 
01160            int found = 0;
01161            if ( bldlistnum ) {
01162               for ( int j = 0; j < bldlistnum-1;  )
01163                  if ( ( bldlist[ j ].objectmatch < bldlist[ j+1 ].objectmatch ) ||
01164                       ( bldlist[ j ].objectmatch == bldlist[ j+1 ].objectmatch && bldlist[ j ].terrainmatch < bldlist[ j+1 ].terrainmatch) ) {
01165                     blds tmp = bldlist[ j ];
01166                     bldlist[ j ] = bldlist[ j+1 ];
01167                     bldlist[ j+1 ] = tmp;
01168                     if ( j > 0 )
01169                        j--;
01170                  } else
01171                    j++;
01172 
01173               int actpos = 0;
01174               while ( !found && actpos < bldlistnum ) {
01175                   BuildingType* bld = bldlist[actpos].bld;
01176                   for ( int w = 0; w < cwettertypennum; w++ ) 
01177                      for ( int p = 0; p < maxbuildingpicnum; p++ )  
01178                          if ( !found ) {
01179                             int match = 1;
01180                             for ( int m = 0; m < 4; m++ )
01181                                for ( int n = 0; n < 6; n++ )
01182                                   if ( bld->fieldExists( BuildingType::LocalCoordinate(m , n) ) ) 
01183                                      if ( bld->getPicture( BuildingType::LocalCoordinate(m , n), w, p ).valid() ) {
01184                                         MapCoordinate pos = bld->getFieldCoordinate ( MapCoordinate(newx, newy), BuildingType::LocalCoordinate(m, n) );
01185                                         MapField* fld2 = getfield ( pos.x, pos.y );
01186                                         if ( fld2->tempw != bld->getBIPicture( BuildingType::LocalCoordinate(m , n), w, p ))
01187                                            match = 0;
01188                                      }
01189                             if ( match )
01190                                found = 1;
01191                          }
01192                   actpos++;
01193               }
01194               actpos--;
01195 
01196               if ( found ) {
01197                  putbuilding ( actmap, MapCoordinate(xoffset + newx, yoffset + newy), 0, bldlist[actpos].bld, bldlist[actpos].bld->construction_steps - 1, 1 );
01198                  if ( fld->building ) {
01199                     
01200                     for ( int m = 0; m < 4; m++ )
01201                        for ( int n = 0; n < 6; n++ )
01202                           if ( fld->building->getPicture( BuildingType::LocalCoordinate(m , n) ).valid() ) {
01203                              fld->building->getField ( BuildingType::LocalCoordinate(m, n) )->temp3 = 0;
01204                           }
01205 
01206                        /*
01207                              if ( field->object )
01208                                 for ( int o = 0; o < field->object->objnum; o++ )
01209                                    field->removeobject ( field->object->object[o]->typ );
01210                           }
01211                      */
01212                      found = 255;
01213                  } else
01214                      found = 254;
01215               } 
01216            } 
01217 
01218            if ( fld->building ) {
01219 
01220 //              if ( battleisleversion == 3 )
01221               const char* shopStr = GetStr( ShopNum + 2,16);
01222               if ( shopStr )
01223                  fld->building->name = shopStr;   /*  bi3 macht das so  */ 
01224               /*
01225               else
01226                  ArrShop.NameStr = GetStr(FileShop.Name, 16);    //  bi2 wahrscheinlich so
01227                  */
01228               int newcol = convcol ( FileShop.a.Owner );
01229               if ( newcol != fld->building->color/8 )
01230                  fld->building->convert ( newcol );
01231 
01232               for ( int j = 0; j < 16; j++ ) {
01233                  Vehicle* eht = getunit ( FileShop.a.Content.All[j], fld->building->color/8 );
01234                  if ( eht ) {
01235                     fld->building->addToCargo( eht );
01236                     eht->xpos = newx;
01237                     eht->ypos = newy;
01238                  }
01239               }
01240 
01241               int prodnum = 0;
01242               for ( int k= 0; k < 4; k++ ) {
01243                  VehicleType* vt = getvehicletype ( FileShop.a.Produce[k] );
01244                  if ( vt ) {
01245                     int fnd = 0;
01246                     for ( int l = 0; l < prodnum; l++ )
01247                        if ( fld->building->getProduction()[l] == vt )
01248                           fnd++;
01249 
01250                     if ( !fnd )
01251                        if ( fld->building->typ->vehicleFit( vt ))
01252                           fld->building->addProductionLine( vt );
01253                  }
01254               }
01255               for ( int l = 0; l < 64; l++ )
01256                  if ( OrgMissRec.StdProd[l] & 3 ) {
01257                     VehicleType* vt = getvehicletype ( l );
01258                     if ( vt ) {
01259                        int fnd = 0;
01260                        for ( int l = 0; l < prodnum; l++ )
01261                           if ( fld->building->getProduction()[l] == vt )
01262                              fnd++;
01263                        if ( !fnd )
01264                            if ( fld->building->typ->vehicleFit( vt ))
01265                               fld->building->addProductionLine( vt );
01266                     }
01267                  }
01268               fld->building->bi_resourceplus.energy = energyfactor * FileShop.a.EP;
01269               fld->building->bi_resourceplus.material = materialfactor * FileShop.a.MP;
01270               fld->building->bi_resourceplus.fuel = fuelfactor * FileShop.a.EP;
01271 
01272               fld->building->actstorage.energy = energyfactor * FileShop.a.E;
01273               fld->building->actstorage.material = materialfactor * FileShop.a.M;
01274               fld->building->actstorage.fuel = fuelfactor * FileShop.a.E;
01275 
01276            } else {
01277                  if ( found == 254 ) {
01278                     char tmp[100];
01279                     int obj = fld->tempw;
01280                     sprintf( tmp, "The building at position %d / %d using pic #%d could not be set\n", newx, newy, obj );
01281                     strcat ( missing, tmp );
01282                  } else {
01283                     if ( firstmissingbuilding ) {
01284                        strcat ( missing, "The buildings at the following coordinates could not be found:\n " );
01285                        firstmissingbuilding = 0;
01286                     }
01287                     char tmp[100];
01288                     int obj = fld->tempw;
01289                     sprintf( tmp, "%d / %d using pic #%d\n", newx, newy, obj );
01290                     strcat ( missing, tmp );
01291                  }
01292 
01293            }
01294            ShopNum++;
01295 
01296         }
01297       } 
01298       
01299    } 
01300 //   if ( TPWMtextfile ) 
01301 //      strcat ( missing, "\nThe names of the buildings could not be read because the text file is TPWM encoded. Please decode it first if you want to keep the names of the shops !\n");
01302    
01303 
01304    int missnum = 0;
01305    dynamic_array<int> miss;
01306 
01307    for ( int y = 0; y < actmap->ysize; y++ )
01308       for ( int x = 0; x < actmap->xsize; x++ ) 
01309          if ( ::getfield(x,y)->temp3 ) {
01310             int m = ::getfield(x,y)->tempw;
01311             if ( m > 0 && m != 0xffff ) {
01312                int fnd = 0;
01313                for ( int k = 0; k < missnum; k++ )
01314                   if ( miss[k] == m )
01315                      fnd = 1;
01316 
01317                if ( !fnd )
01318                   miss[missnum++] = m;
01319                
01320             }
01321          }
01322       
01323      
01324    if ( missnum ) {
01325       strcat ( missing, "The following objects could not be found: " );
01326       for ( int k = 0; k < missnum; k++ ) {
01327          strcat ( missing, strrr ( miss[k] ));
01328          strcat ( missing, ", ");
01329       }
01330       strcat ( missing, "\n\n");
01331    }
01332 
01333 
01334 } 
01335 
01336 
01337 char* tloadBImap :: GetStr( int a, int b )
01338 {
01339 //   if ( TPWMtextfile )
01340 //      return NULL;
01341 //   else
01342       for ( int i = 0; i <= ShopNameList.getlength(); i++ )
01343          if ( ShopNameList[i].a == a && ShopNameList[i].b == b )
01344             return strdup ( ShopNameList[i].name );
01345 
01346    return NULL;
01347 }
01348 
01349 /* TPTC: TOCONV.PAS(303): Warning: Nested function, tok=SplitName 
01350     
01351 Boolean      SplitName(char *       S,
01352                        char *       Name,
01353                        Uint16 *       R1,
01354                        Uint16 *       R2)
01355       { 
01356         Integer      Code; 
01357       
01358         Result = false; 
01359         strcpy(S,Trim(S)); 
01360         if (strcmp(S,"") != 0) { 
01361           if (S[0] != '#') return;
01362           val(copy(S,2,4),R1,&Code); 
01363           if (Code != 0) return;
01364           if (S[5] != ':') return;
01365           val(copy(S,7,4),R2,&Code); 
01366           if (Code != 0) return;
01367           if (S[10] != '{') return;
01368           if (S[strlen(S)-1] != '}') return;
01369           strcpy(S,copy(S,12,strlen(S) - 12)); 
01370   //           Delete(S, 1, 11);
01371   //        Delete(S, Length(S), 1); 
01372           strcpy(Name,S); 
01373           sbld(Result,"%b",true); 
01374         } 
01375       } 
01376 
01377 */    
01378 
01379 
01380 void    tloadBImap :: ReadShopNames( char* databuf, unsigned long datasize )
01381 { 
01382    unsigned long dptr=0;
01383    char buf[ 1000];
01384    int c;      
01385    do {
01386       do {
01387          c = databuf[dptr++];
01388       } while ( c != '#' && dptr<datasize );
01389       if ( c == '#' ) {
01390          int i;
01391          for ( i = 0; i < 4; i++ ) {
01392             c = databuf[dptr++];
01393             if ( c < '0' || c > '9' )
01394                return;
01395 
01396             buf[i] = c;
01397          }
01398          buf[4] = 0;
01399          int a1 = atoi ( buf );
01400          if ( databuf[dptr++] != ':' )
01401             return;
01402 
01403          for ( i = 0; i < 4; i++ ) {
01404             c = databuf[dptr++];
01405             if ( c < '0' || c > '9' )
01406                return;
01407 
01408             buf[i] = c;
01409          }
01410          buf[4] = 0;
01411          int a2 = atoi ( buf );
01412 
01413          if ( databuf[dptr++] != '{' )
01414             return;
01415 
01416          i = 0;
01417          do {
01418             c = databuf[dptr++];
01419             buf[i++] = c;
01420          } while ( c != '}' && dptr<datasize ); /* enddo */
01421 
01422          if ( c == '}' ) {
01423             buf[i-1] = 0;
01424             int pos = ShopNameList.getlength()+1;
01425             ShopNameList[pos].a = a1;
01426             ShopNameList[pos].b = a2;
01427             strcpy ( ShopNameList[pos].name , buf );
01428          }
01429       }
01430    } while ( dptr<datasize );
01431 } 
01432 
01433 
01434 void tloadBImap :: GetTXTName ( const char* path, const char* filename, char* buf )
01435 {
01436     strcpy ( buf, path );
01437     strcat ( buf, "ger" );
01438     strcat ( buf, pathdelimitterstring );
01439     strcat ( buf, filename );
01440     strcpy ( &buf[ strlen ( buf ) - 3], "txt" );
01441     if ( exist ( buf )) 
01442        return;
01443 
01444     strcpy ( buf, path );
01445     strcat ( buf, "eng" );
01446     strcat ( buf, pathdelimitterstring );
01447     strcat ( buf, filename );
01448     strcpy ( &buf[ strlen ( buf ) - 3], "txt" );
01449     if ( exist ( buf ))
01450        return;
01451 
01452     buf[0] = 0;
01453     return;
01454 }
01455   
01456 void tloadBImap :: LoadTXTFile ( char* filename )
01457 {
01458 
01459    FILE* fp = fopen ( filename, "rb" );
01460    if ( !fp )
01461       return;
01462 
01463    // get file size
01464    fseek(fp, 0, SEEK_END);
01465    unsigned long txtsize=ftell(fp);
01466    fseek(fp, 0, SEEK_SET);
01467 
01468    // databuffer which holds the textdata 
01469    char *txtbuffer=(char *)malloc(txtsize+10000);
01470    memset(txtbuffer, 0, txtsize+10000);
01471 
01472    char buf[1000];
01473    if ( fread ( buf, 1, 4, fp ) != 4)
01474       throw treadafterend( filename );
01475    
01476    if ( strncmp ( buf, "TPWM",4) == 0  ) {
01477       // The file is compressed.
01478 //      unsigned long tpwmsize=txtsize; // store the size of the compressed file.
01479       if ( fread(&txtsize, 4, 1, fp) != 1 ) // this is the uncompressed size.
01480          throw treadafterend( filename );
01481       
01482       unsigned long outptr=0;
01483       txtbuffer=(char *)realloc(txtbuffer, txtsize+10000);
01484 
01485       // the tpwm algorithm is quite simple:
01486       // you have datablocks containing 1 codebyte and 8 values.
01487       // the codebyte determines whether to copy a single char or
01488       // to repeat a previous block. Each bit in the codebyte marks
01489       // the meaning (and size) of one value. The MSB is linked to the 
01490       // first value and the LSB to the last one.
01491       // A cleared bit means: the value is 1 byte sized and gets copied directly.
01492       // A set bit means: the value is a 2 byte pair and is interpreted as follows:
01493       // The lower nibble (bits 0-3) in the 1st byte is the length of the block +3 
01494       // (thus giving a min. block length of 3 and a max. of 18) and the second byte
01495       // plus the high nibble of the first byte shifted left by 4 bits is an offset
01496       // in reverse direction into the already decompressed data (thus giving a range
01497       // from offset to offset-4095.
01498       // or simply look at the code. could be easier to understand ;-)
01499       
01500       while (outptr<txtsize)
01501       {
01502          char code=0;
01503          char inbuf[16]; // worst case buffer usage is 8*2
01504          memset(inbuf,0,16);
01505          int inptr=0;
01506          if ( fread(&code, 1, 1, fp) != 1 )
01507             throw treadafterend( filename );
01508          char bitsset=((code>>7)&1)+((code>>6)&1)+((code>>5)&1)+((code>>4)&1)+((code>>3)&1)+((code>>2)&1)+((code>>1)&1)+((code>>0)&1);
01509          
01510          int toread = min(8+bitsset, int(txtsize-outptr));
01511          fread(&inbuf, toread, 1, fp);
01512    
01513          for (int i=0; (i<8)&&(outptr<txtsize); i++)
01514          {
01515             if ((code&(0x80>>i))==0)
01516             {
01517                // straight copy
01518                txtbuffer[outptr]=inbuf[inptr];
01519                outptr++; inptr++;
01520             } else {
01521                // repeat
01522                char d0,d1;
01523                d0=inbuf[inptr]; inptr++;
01524                d1=inbuf[inptr]; inptr++;
01525                int blklen=(d0&0xf)+3;
01526                int blkofs=((d0&0xf0)<<4)+d1;
01527                for (int j=0; (j<blklen)&&(outptr<txtsize); j++)
01528                {
01529                   txtbuffer[outptr]=txtbuffer[outptr-blkofs];
01530                   outptr++;
01531                }
01532             }
01533          }         
01534       }
01535    } else {
01536       // The file is uncompressed.
01537       if ( fread(txtbuffer, txtsize, 1, fp) != 1 )
01538          throw treadafterend( filename );
01539    }
01540 
01541     txtbuffer[txtsize]=0;
01542 
01543    fclose ( fp );
01544 
01545    ReadShopNames( txtbuffer, txtsize );
01546 
01547    free(txtbuffer);
01548 
01549    /*
01550    LevelDescription:= GetStr(0, 0);
01551       LevelName:= GetStr(1, 24);
01552 
01553       P:= Pos('|', LevelDescription);
01554       if (Length(LevelDescription)> 0) and (P<> 0) then begin
01555         SavePlayerNames:= true;
01556         S:= Copy(LevelDescription, P, Length(LevelDescription)-P+1);
01557         Delete(LevelDescription, P, Length(LevelDescription)-P+1);
01558         Delete(S, 1, 1);
01559         for I:= 0 to 6 do begin
01560           P:= Pos('|', S);
01561           if P= 0 then P:= Length(S)+ 1;
01562           FPlayers[I].Name:= Copy(S, 1, P-1);
01563           Delete(S, 1, P);
01564           P:= Pos('|', S);
01565           if P= 0 then P:= Length(S)+ 1;
01566           try
01567             FPlayers[I].Color:= StrToInt(Copy(S, 1, P-1));
01568           except
01569             FPlayers[I].Color:= 0;
01570           end;
01571           Delete(S, 1, P);
01572         end;
01573       end else
01574         SavePlayerNames:= false;
01575    */
01576 }
01577 
01578 void tloadBImap :: LoadFromFile( const char* path, const char* AFileName, TerrainType::Weather* trrn, string* errorOutput )
01579 {
01580    defaultterraintype = trrn;
01581    char temp[4000];
01582    missing = temp;
01583    missing[0] = 0;
01584    namenum = 0;
01585 //   PShopNameItem PSNI;
01586 
01587     char TXTName[1000];
01588     bool error = false;
01589     try {
01590        GetTXTName( path, AFileName, TXTName );
01591    
01592        LoadTXTFile(TXTName);
01593    
01594        char completefilename[1000];
01595        strcpy ( completefilename, path );
01596        strcat ( completefilename, "mis" );
01597        strcat ( completefilename, pathdelimitterstring );
01598        strcat ( completefilename, AFileName );
01599        tn_file_buf_stream stream ( completefilename, tnstream::reading );
01600        MissFile = &stream;
01601        MissFile->readdata2( Header );
01602        if ( strncmp ( Header.ID, HeadID, 4 )) {
01603           strcat ( missing, "\nFatal error: No Battle Isle mission; invalid HeadID\n"  );
01604           throw timporterror (); 
01605        }
01606        ReadMISSPart();
01607        ReadACTNPart();
01608        ReadSHOPPart();
01609        /*
01610        ReadMAPPart();
01611        LoadDFs();
01612        UnPackDF(AktDFNum);
01613        */
01614 
01615        if ( GetStr ( 1, 24 ) )
01616           actmap->maptitle = GetStr ( 1, 24 );
01617        else
01618           actmap->maptitle.erase();
01619 
01620        if ( actmap->maptitle.empty() )
01621           actmap->maptitle = "imported BI map";
01622 
01623     } /* endtry */
01624     catch ( treadafterend ) {
01625        throw;
01626     }
01627     catch ( tfileerror err ) {
01628        strcat ( missing, "\nA fatal error occured while accessing the file " );
01629        strcat ( missing, err.getFileName().c_str() );
01630        strcat ( missing, "\n" );
01631        error = true;
01632     } /* endcatch */
01633     catch ( ASCexception ) {
01634        strcat ( missing, "\nA fatal error occured" );
01635        error = true;
01636     } /* endcatch */
01637 
01638     if ( !error )
01639        calculateallobjects( actmap );
01640     if ( missing[0] ) {
01641       if ( errorOutput )
01642          (*errorOutput)=missing;
01643       else {
01644          tviewanytext vat;
01645          vat.init ( "warning", missing );
01646          vat.run();
01647          vat.done();
01648       }
01649     }
01650 
01651 }
01652 
01653 
01654 ASCString defaultImportTranslationTable;
01655 
01656 void setDefaultBI3ImportTranslationTable( const ASCString& filename )
01657 {
01658    defaultImportTranslationTable = filename;
01659 }
01660 
01661 
01662 
01663 void importbattleislemap ( const ASCString& path, const ASCString& mapfilename, TerrainType::Weather* trrn, const ASCString& importTable, ASCString* errorOutput, bool fakemap  )
01664 {
01665     GameMap* oldmap = actmap;
01666     actmap = NULL;
01667     GraphicSetManager::Instance().setActive(1);
01668     try {
01669        ImportBiMap lbim ( findTable(importTable) );
01670        if ( fakemap )
01671           lbim.____fakeMap____();
01672        lbim.LoadFromFile ( path.c_str(), mapfilename.c_str(), trrn, errorOutput );
01673        actmap->_resourcemode = 1;
01674        actmap->cleartemps ( 7 );
01675     }
01676     catch ( ASCexception ) {
01677        delete actmap;
01678        actmap = oldmap;
01679        throw;
01680     }
01681     delete oldmap;
01682 }
01683 
01684 
01685 void insertbattleislemap ( int x, int y, const ASCString& path, const ASCString& mapfilename, const ASCString& importTable  )
01686 {
01687     GraphicSetManager::Instance().setActive ( 1 );
01688     InsertBiMap lbim ( x, y, findTable(importTable) );
01689     lbim.LoadFromFile ( path.c_str(), mapfilename.c_str(), NULL, NULL );
01690     actmap->_resourcemode = 1;
01691     actmap->cleartemps ( 7 );
01692 }
01693 
01694 
01695 #pragma pack()
01696 

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