00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00044
00045
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},
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
00091
00092
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 );
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];
00423 int MissPos;
00424 int MapPos ;
00425 int ShopPos;
00426 int ACTNPos;
00427 Uint16 DFNum ;
00428 int DFPos[32] ;
00429 int DFLength[32];
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;
00447 char PlayType;
00448 char Recs2Win;
00449 char Stuff2[3];
00450 char Landscape;
00451 TAllianzen Allianz;
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;
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 ;
00505 Uint16 Prior;
00506 Uint16 Owner;
00507 Uint16 Stuff66[7];
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
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
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
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 }
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
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
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
01007 o->weatherPicture[0].bi3pic[0] = Line[X];
01008
01009
01010
01011
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
01033
01034
01035
01036
01037
01038
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
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
01085
01086 for ( int I = 0; I < SHOPHead.Num ; I++ ) {
01087 MissFile->readdata2 ( FileShop );
01088 if ( FileShop.ID == 1) {
01089 if (FileShop.a.ShopType == 32) {
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
01208
01209
01210
01211
01212 found = 255;
01213 } else
01214 found = 254;
01215 }
01216 }
01217
01218 if ( fld->building ) {
01219
01220
01221 const char* shopStr = GetStr( ShopNum + 2,16);
01222 if ( shopStr )
01223 fld->building->name = shopStr;
01224
01225
01226
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
01301
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
01340
01341
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
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
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 );
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
01464 fseek(fp, 0, SEEK_END);
01465 unsigned long txtsize=ftell(fp);
01466 fseek(fp, 0, SEEK_SET);
01467
01468
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
01478
01479 if ( fread(&txtsize, 4, 1, fp) != 1 )
01480 throw treadafterend( filename );
01481
01482 unsigned long outptr=0;
01483 txtbuffer=(char *)realloc(txtbuffer, txtsize+10000);
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500 while (outptr<txtsize)
01501 {
01502 char code=0;
01503 char inbuf[16];
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
01518 txtbuffer[outptr]=inbuf[inptr];
01519 outptr++; inptr++;
01520 } else {
01521
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
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
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
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
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
01611
01612
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 }
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 }
01633 catch ( ASCexception ) {
01634 strcat ( missing, "\nA fatal error occured" );
01635 error = true;
01636 }
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