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

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