Advanced Strategic Command
loadbi3.cpp
Go to the documentation of this file.
1 
5 /*
6  This file is part of Advanced Strategic Command; http://www.asc-hq.de
7  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; see the file COPYING. If not, write to the
21  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22  Boston, MA 02111-1307 USA
23 */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <cstring>
28 
29 #include "loadbi3.h"
30 #include "typen.h"
31 #include "buildingtype.h"
32 #include "vehicletype.h"
33 #include "misc.h"
34 #include "gameoptions.h"
35 #include "graphicset.h"
36 #include "spfst.h"
37 #include "spfst-legacy.h"
38 #include "loaders.h"
39 #include "dialog.h"
40 #include "itemrepository.h"
41 #include "textfile_evaluation.h"
42 
43 /*#ifdef convert/er
44  #error The small editors should not need to use LoadBi3
45  #endif*/
46 
47 
48 #pragma pack(1)
49 
50 
51 
52 class timporterror : public ASCexception {};
53 
54 
56 
57 const int LIBFilesAnz = 11;
58 
59 struct TLIBFiles {
60  const char* Name;
61  int FirstRecO;
62  int RecSize;
64  int DataSize;
65  int Anzahl;
66  };
68  {{"part000.lib", 0xC, 0x240, 0, 0x240, 1335},
69  {"unit000.lib", 0x4, 0x240, 0, 0x240, 128}, // 128 f?r BI3 // 118 f?r BI2 Scenery
70  {"layr000.lib", 0x4, 0x240, 0, 0x240, 24},
71  {"layr001.lib", 0x4, 0x240, 0, 0x240, 24},
72  {"layr002.lib", 0x4, 0x240, 0, 0x240, 24},
73  {"layr003.lib", 0x4, 0x240, 0, 0x240, 24},
74  {"layr004.lib", 0x4, 0x240, 0, 0x240, 24},
75  {"layr005.lib", 0x4, 0x240, 0, 0x240, 24},
76  {"layr006.lib", 0x4, 0x240, 0, 0x240, 24},
77  {"curs000.lib", 0xC, 0x25E,0x1A, 0x240, 12},
78  {"palt000.lib", 0xC, 0x300, 0, 0x300, 4 } ,
79  } ;
80 
81 
82 int libs_to_load = 9;
83 
84 
85 void checkbi3dir ( void )
86 {
87  if ( CGameOptions::Instance()->BI3directory.empty() ) {
89  /*
90  if ( !gameoptions.bi3.dir.getName() ) {
91  gameoptions.bi3.dir = new char [300];
92  gameoptions.bi3.dir[0] = 0;
93  }
94  */
95  }
96 
97  bool notfound;
98  do {
99  notfound = false;
100 
101  ASCString filename;
102 
103  for ( int i = 0; i < libs_to_load ; i++ ) {
104  filename = CGameOptions::Instance()->BI3directory + LIBFiles[i].Name ;
105 
106  if ( !exist ( filename ) ) {
107  filename = CGameOptions::Instance()->BI3directory + "LIB" + pathdelimitterstring + LIBFiles[i].Name;
108  if ( !exist ( filename ) ) {
109  printf("Battle Isle file %s not found !\n", filename.c_str() );
110  notfound = true;
111  }
112  }
113  }
114  if ( notfound ) {
115  char bi3path[10000];
116  printf("Enter Battle Isle directory:\n" );
117  if ( !scanf ( "%s", bi3path ) )
118  bi3path[0] = 0;
119 
121  appendbackslash ( CGameOptions::Instance()->BI3directory );
123  }
124  } while ( notfound ); /* enddo */
125  battleisleversion = 3;
126 }
127 
128 
130 {
132 }
133 
134 
137  public:
139  vector< pair<int,int> > terraintranslation;
140 
141  struct Terrain2id {
142  int BIpic;
144  int weather;
145  void read ( tnstream& stream ) {
146  int version = stream.readInt();
147  if ( version != 1 )
148  throw tinvalidversion( stream.getDeviceName(), 1, version );
149  BIpic = stream.readInt();
150  terrainid = stream.readInt();
151  weather = stream.readInt();
152  };
153 
154  void write ( tnstream& stream ) const {
155  stream.writeInt( 1 );
156  stream.writeInt( BIpic );
157  stream.writeInt( terrainid );
158  stream.writeInt( weather );
159  };
160  };
164  vector< Terrain2id > terrain2idTranslation;
165 
166 
168  int bigraph;
171  int objectid;
172  void read ( tnstream& stream ) {
173  stream.readInt();
174  bigraph = stream.readInt();
175  terrainid = stream.readInt();
176  terrainweather = stream.readInt();
177  objectid = stream.readInt();
178  };
179 
180  void write ( tnstream& stream ) const {
181  stream.writeInt( 1 );
182  stream.writeInt( bigraph );
183  stream.writeInt( terrainid );
184  stream.writeInt( terrainweather );
185  stream.writeInt( objectid );
186  };
187 
188  };
190  vector<Terraincombixlat> terraincombixlat;
191 
192 
194  int BIpic;
195  int objects[4];
198  void read ( tnstream& stream ) {
199  stream.readInt();
200  BIpic = stream.readInt();
201  for ( int i = 0; i< 4; ++i )
202  objects[i] = stream.readInt();
203  terrainID = stream.readInt();
204  terrainWeather = stream.readInt();
205  };
206 
207  void write ( tnstream& stream ) const {
208  stream.writeInt( 1 );
209  stream.writeInt( BIpic );
210  for ( int i = 0; i< 4; ++i )
211  stream.writeInt( objects[i] );
212  stream.writeInt( terrainID );
213  stream.writeInt( terrainWeather );
214  };
215  };
216 
220  vector<Objecttranslataion> objecttranslate ;
221 
225  vector< pair<int,int> > object2IDtranslate;
226 
227  void runTextIO ( PropertyContainer& pc );
228 
229  void read ( tnstream& stream );
230  void write ( tnstream& stream ) const;
232 };
233 
234 
236 {
237  int version = stream.readInt();
243  if ( version >= 2 ) {
244  filename = stream.readString();
245  location = stream.readString();
246  }
247 
248 }
249 
250 
251 
253 {
254  stream.writeInt ( 2 );
260  stream.writeString( filename );
261  stream.writeString( location );
262 }
263 
264 
266 {
267  vector<int> _terraintranslation;
268  pc.addIntegerArray ( "TerrainTranslation", _terraintranslation );
269 
270  vector<int> _terrain2idtrans;
271  pc.addIntegerArray ( "Terrain2IDTranslation", _terrain2idtrans );
272 
273  vector<int> _terrainobjtranslation;
274  pc.addIntegerArray ( "TerrainObjTranslation", _terrainobjtranslation );
275 
276  vector<int> _objecttranslation;
277  if ( pc.find( "ObjectTranslation" ))
278  pc.addIntegerArray ( "ObjectTranslation", _objecttranslation );
279 
280  vector<int> _object2IDtranslation;
281  pc.addIntegerArray ( "Object2IDTranslation", _object2IDtranslation );
282 
283  vector<int> object3translation;
284  if ( pc.find( "Object3Translation" ))
285  pc.addIntegerArray ( "Object3Translation", object3translation );
286 
287 
288  if ( _terraintranslation.size() % 2 )
289  fatalError ( "Bi3 map translation : terraintranslation - Invalid number of entries ");
290  terraintranslation.clear();
291  for ( int i = 0; i < _terraintranslation.size()/2; i++ )
292  terraintranslation.push_back ( make_pair( _terraintranslation[i*2], _terraintranslation[i*2+1] ));
293 
294 
295  if ( _terrain2idtrans.size() % 3 )
296  fatalError ( "Bi3 map translation : terrain2idTranslation - Invalid number of entries ");
297  terrain2idTranslation.clear();
298  for ( int i = 0; i < _terrain2idtrans.size()/3; i++ ) {
299  Terrain2id t2i;
300  t2i.BIpic = _terrain2idtrans[i*3];
301  t2i.terrainid = _terrain2idtrans[i*3+1];
302  t2i.weather = _terrain2idtrans[i*3+2];
303  terrain2idTranslation.push_back ( t2i );
304  }
305 
306  if ( _terrainobjtranslation.size() % 4 )
307  fatalError ( "Bi3 map translation : terrainobjtranslation - Invalid number of entries ");
308  terraincombixlat.clear();
309  for ( int i = 0; i < _terrainobjtranslation.size()/4; i++ ) {
310  Terraincombixlat tcx;
311  tcx.bigraph = _terrainobjtranslation[i*4];
312  tcx.terrainid = _terrainobjtranslation[i*4+1];
313  tcx.terrainweather = _terrainobjtranslation[i*4+2];
314  tcx.objectid = _terrainobjtranslation[i*4+3];
315  terraincombixlat.push_back ( tcx );
316  }
317 
318  if ( _objecttranslation.size() % 5 )
319  fatalError ( "Bi3 map translation : objecttranslation - Invalid number of entries ");
320  objecttranslate.clear();
321  for ( int i = 0; i < _objecttranslation.size()/5; i++ ) {
323  ot.BIpic = _objecttranslation[i*5];
324  for ( int j = 0; j < 4; j++ )
325  ot.objects[j] = _objecttranslation[i*5 + 1 + j];
326  ot.terrainID = -1;
327  ot.terrainWeather = 0;
328 
329  objecttranslate.push_back ( ot );
330  }
331 
332 
333  if ( object3translation.size() % 7 )
334  fatalError ( "Bi3 map translation : object3translation - Invalid number of entries ");
335  for ( int i = 0; i < object3translation.size()/7; i++ ) {
337  ot.BIpic = object3translation[i*7];
338  for ( int j = 0; j < 4; j++ )
339  ot.objects[j] = object3translation[i*7 + 1 + j];
340  ot.terrainID = object3translation[i*7 + 5];
341  ot.terrainWeather = object3translation[i*7 + 6];
342 
343  objecttranslate.push_back ( ot );
344  }
345 
346 
347  if ( _object2IDtranslation.size() % 2 )
348  fatalError ( "Bi3 map translation : object2IDtranslation - Invalid number of entries ");
349  object2IDtranslate.clear();
350  for ( int i = 0; i < _object2IDtranslation.size()/2; i++ )
351  object2IDtranslate.push_back ( make_pair ( _object2IDtranslation[i*2], _object2IDtranslation[i*2+1] ));
352 }
353 
354 
355 
356 
358 
360  for ( PointerVector<Bi3MapTranslationTable*>::iterator i = bi3ImportTables.begin(); i != bi3ImportTables.end(); ++i )
361  if ( (*i)->filename == filename )
362  return *i;
363  return NULL;
364 }
365 
366 vector<ASCString> getBI3ImportTables()
367 {
368  vector<ASCString> list;
369  for ( PointerVector<Bi3MapTranslationTable*>::iterator i = bi3ImportTables.begin(); i != bi3ImportTables.end(); ++i )
370  list.push_back ( (*i)->filename );
371  return list;
372 }
373 
374 
376 {
377  stream.readInt();
378  readPointerContainer ( bi3ImportTables, stream );
379 }
380 
382 {
383  stream.writeInt( 1 );
384  writePointerContainer ( bi3ImportTables, stream );
385 }
386 
387 
389 {
390  return "bi3maptranslation";
391 }
392 
394 {
396  bmtt->runTextIO ( prc );
397  bmtt->filename = fileName;
398  bmtt->location = location;
399  bi3ImportTables.push_back ( bmtt );
400 }
401 
402 
403 const int fuelfactor = 120;
404 const int materialfactor = 390;
405 const int energyfactor = 390;
406 
407 
408 
409 
410  const char* HeadID = "MSSN";
411  const char* ACTNID = "ACTN";
412  const char* SHOPID = "SHOP";
413  const char* MAPID = "MAP\0";
414  const char* MISSID = "MISS";
415 
416 
417 
418 class tloadBImap {
419  Bi3MapTranslationTable* translationTable;
420 
421  struct THeader {
422  char ID[4]; // { 'MSSN' }
423  int MissPos;
424  int MapPos ;
425  int ShopPos;
426  int ACTNPos;
427  Uint16 DFNum ;
428  int DFPos[32] ; // { Pos nach DFXX }
429  int DFLength[32]; // { +4B von DFXX }
430  };
431 
432  struct TACTN {
433  char ID[4];
434  Uint16 XSize, YSize;
435  };
436 
437  typedef Uint16 TStdProdRec[64];
438  typedef Uint8 TAllianzen[6];
439 
440 
441  struct TMISSPart {
442  char ID[4];
443  Uint16 Stuff1 [3];
444  Uint16 NextMiss;
445  Uint8 StartWeather;
446  Uint8 WhoPlays; // { jeder Mensch/Computer ein Bit }
447  Uint8 PlayType; // { jeder Computer ein Bit }
448  Uint8 Recs2Win; // { Wieviel Gewinnrecords aus map erf llt werden m ssen, damit man gewinnt (f r jeden player gleich) }
449  Uint8 Stuff2[3];
450  Uint8 Landscape;
451  TAllianzen Allianz; // { Wer mit wem }
452  Uint16 Stuff3[65];
453  TStdProdRec StdProd;
454  Uint16 Stuff4[24];
455  };
456 
457  struct TMAPHead {
458  char ID[4];
459  };
460 
461  struct TFileMap {
462  Uint16 What1;
463  Uint16 Round, Move;
464  Uint8 Player, What2;
465  Uint16 Stuff2;
466  Uint16 Zero1;
467  Uint16 Nr1;
468  Uint16 Nr2;
469  Uint16 Nr3;
470  Uint16 Zero2[11];
471  };
472 
473  struct TSHOPHead {
474  char ID[4];
475  Uint16 Num;
476  };
477 
478  typedef int TVehContent[8];
479  typedef TVehContent *PVehContent;
480 
481  union TShopContent {
482  Uint16 XY[4][4];
483  Uint16 All[16];
484  TVehContent Veh;
485  };
486  typedef TShopContent *PShopContent;
487 
488  typedef Uint16 TProduceRec[4];
489 
490  struct TFileShop {
491  Uint16 ID;
492  Uint16 Pos1;
493  union {
494  struct {
495  Uint16 ShopType;
496  Uint16 Stuff06; // { Zero }
497  Uint16 Name;
498  Uint16 Pos2;
499  Uint16 E, M;
500  Uint8 EP, MP ;
501  TShopContent Content;
502  Uint16 ShopType2;
503  TProduceRec Produce;
504  Uint16 Stuff60 ; // { Zero }
505  Uint16 Prior;
506  Uint16 Owner;
507  Uint16 Stuff66[7]; // { Zero }
508  } a;
509  struct {
510  Uint8 Zero2[6];
511  Uint16 W0A;
512  Uint8 Zero3[6];
513  Uint16 W48;
514  Uint16 W4A;
515  Uint8 Zero4[2];
516  Uint16 W4E;
517  } b;
518  Uint8 raw[76];
519  };
520  };
521 
522  dynamic_array<char*> names;
523  int namenum;
524  bool fakemap;
525 
526  protected:
529  public:
530  void LoadFromFile( const char* path, const char* AFileName, TerrainType::Weather* trrn, string* errorOutput );
531  tloadBImap ( Bi3MapTranslationTable* _translationTable ) : translationTable ( _translationTable ) {
532  xoffset = 0;
533  yoffset = 0;
534  fakemap = false;
535  };
536 
537  void ____fakeMap____ ( void ) { fakemap = true; };
538  virtual ~tloadBImap() {};
539  private:
540 
541  tn_file_buf_stream* MissFile;
542  THeader Header;
543 
544  struct TTextItem {
545  int a;
546  int b;
547  char name[1000];
548  };
549 
550  dynamic_array<TTextItem> ShopNameList;
551  void LoadTXTFile ( char* filename );
552 // int TPWMtextfile;
553 
554  void ReadMISSPart(void);
555  void ReadACTNPart(void);
556  void ReadSHOPPart(void);
557  void ReadShopNames( char *txtdata, unsigned long txtsize );
558  Vehicle* getunit ( int typ, int col );
559  VehicleType* getvehicletype ( int typ );
560  char* GetStr ( int a, int b );
561  int convcol ( int c );
562 
563  TMISSPart OrgMissRec;
564  void GetTXTName ( const char* path, const char* filename, char* buf );
565 
566  protected:
567  char* missing;
568  virtual void preparemap ( int x, int y ) = 0;
569  virtual MapField* getfield ( int x, int y );
570 
571 };
572 
573 class ImportBiMap : public tloadBImap {
574  protected:
575  virtual void preparemap ( int x, int y );
576  public:
577  ImportBiMap ( Bi3MapTranslationTable* _translationTable ) : tloadBImap ( _translationTable ) {};
578 };
579 
580 class InsertBiMap : public tloadBImap {
581  protected:
582  virtual void preparemap ( int x, int y );
583  virtual MapField* getfield ( int x, int y );
584  public:
585  InsertBiMap ( int x, int y, Bi3MapTranslationTable* _translationTable ) : tloadBImap ( _translationTable ) {
586  xoffset = x;
587  yoffset = y;
588  };
589 };
590 
591 
593 {
594  return ::getfield ( x, y );
595 }
596 
598 {
599  return ::getfield ( xoffset + x, yoffset + y );
600 }
601 
602 
603 void tloadBImap :: ReadMISSPart(void)
604 {
605 
606  MissFile->seek ( Header.MissPos );
607 
608  MissFile->readdata2 ( OrgMissRec );
609  if ( strncmp ( OrgMissRec.ID, MISSID, 4) ) {
610  strcat ( missing, "\nFatal error: No Battle Isle mission; invalid MissID\n" );
611  throw timporterror ();
612  }
613 
614 /*
615  int I;
616  StdProd = OrgMissRec.StdProd;
617  for (I = 0; I <= 63; I++)
618  StdProd[I] = StdProd[I] & 0x03;
619 
620  PlayerType = OrgMissRec.PlayType & 0x3F;
621  Allianz = OrgMissRec.Allianz;
622  for (I = 0; I <= 5; I++)
623  Allianz[I] = Allianz[I] & 0x3F;
624  Recs2Win = OrgMissRec.Recs2Win;
625  StartWeather = OrgMissRec.StartWeather;
626  if ( StartWeather < 0 || StartWeather > 4 )
627  StartWeather = 0;
628  NextMiss = OrgMissRec.NextMiss;
629  Landscape = OrgMissRec.Landscape;
630 */
631 }
632 
633 int tloadBImap :: convcol ( int c )
634 {
635  int cl = getFirstBit ( c );
636  if ( cl == 6 )
637  return 8;
638  else
639  if ( cl < 2 )
640  cl = 1 - cl;
641  return cl;
642 }
643 
644 
645 const int bi3unitnum = 74;
646 int translateunits[ bi3unitnum ][2] = { {1201,26}, {1270,26}, {1202,13}, {1200,6}, {1203,-1},
647  {1204,16}, {1205,17}, {1206,4}, {1207,65}, {1208,-1},
648  {1209,7}, {1210,66}, {1211,2}, {1212,3}, {1213,17},
649  {1214,51}, {1215,17}, {1216,2}, {1217,10}, {1218,11},
650  {1219,16}, {1220,61}, {1221,49},{1222,56}, {1276,-1},
651  {1223,25}, {1224,72}, {1225,57},{1226,58}, {1227,7},
652  {1228,59}, {1241,9}, {1242,22},{1244,19}, {1243,29},
653  {1245,55}, {1246,19}, {1271,21},{1247,52}, {1248,31},
654  {1251,15}, {1252,15}, {1256,39},{1257,42}, {1258,47},
655  {1259,14}, {1260,36}, {1261,34},{1262,47}, {1263,37},
656  {1264,38}, {1265,5}, {1229,18},{1277,-1}, {1249,-1},
657  {1230,1}, {1231,66}, {1266, 5},{1232,64}, {1233,-1},
658  {1234,4}, {1235,4}, {1267,35},{1250,29}};
659 
660 
661 VehicleType* tloadBImap :: getvehicletype ( int tp )
662 {
663  for ( int j = 0; j < vehicleTypeRepository.getNum(); j++ ) {
664  VehicleType* tnk = vehicleTypeRepository.getObject_byPos ( j );
665  if ( tnk )
666  if ( tnk->bipicture > 0 )
667  if ( tnk->bipicture == 1340 + tp * 2 )
668  return tnk;
669  }
670 
671 
672  if ( tp < bi3unitnum )
673  for ( int i = 0; i < 2; i++ )
674  if ( translateunits[tp][i] > 0 ) {
675  VehicleType* tnk = vehicleTypeRepository.getObject_byID ( translateunits[tp][i] );
676  if ( tnk )
677  return tnk;
678  }
679  return NULL;
680 }
681 
682 Vehicle* tloadBImap :: getunit ( int tp, int col )
683 {
684  if ( tp != 0xffff && tp != 0xff && col != 0xff ) {
685  VehicleType* vt = getvehicletype ( tp );
686  if ( vt ) {
687  Vehicle* eht = new Vehicle ( vt, actmap, col );
688  eht->fillMagically();
689  return eht;
690  }
691  }
692 
693  return NULL;
694 }
695 
697  int xsize,
698  int ysize)
699 {
700  delete actmap;
701  actmap = new GameMap;
702  for (int k = 1; k < 8; k++)
704 
705  actmap->maptitle = "new map";
706 
707  actmap->allocateFields(xsize, ysize);
708 
709  if ( actmap->field== NULL)
710  displaymessage ( "Could not generate map !! \nProbably out of enough memory !",2);
711 
712  for ( int l = 0; l < xsize*ysize; l++ ) {
713  actmap->field[l].typ = bt;
714  actmap->field[l].setparams();
715  actmap->field[l].setMap( actmap, l );
716  }
717 
718  actmap->_resourcemode = 1;
719 }
720 
721 
722 void ImportBiMap :: preparemap ( int x, int y )
723 {
724  generatemap ( defaultterraintype, x, y );
727 }
728 
729 void InsertBiMap :: preparemap ( int x, int y )
730 {
731  if ( yoffset & 1 ) {
732  yoffset--;
733  strcat ( missing, "y position for map insertion must be even; current position decreased\n");
734  }
735  int xp = xoffset;
736  int yp = yoffset;
737  if ( xp + x > actmap->xsize ) {
738  int dx = xp + x - actmap->xsize;
739  strcat ( missing, "map had to be resized in X direction\n");
740  int r = actmap->resize ( 0, 0, 0, dx );
741  if ( r ) {
742  strcat ( missing, "Resizing failed !!\n");
743  throw timporterror();
744  }
745  }
746  if ( yp + y > actmap->ysize ) {
747  int dy = yp + y - actmap->ysize;
748  strcat ( missing, "map had to be resized in Y direction\n");
749  int r = actmap->resize ( 0, dy, 0, 0 );
750  if ( r ) {
751  strcat ( missing, "Resizing failed !!\n");
752  throw timporterror();
753  }
754  }
755 
756  for ( int b = 0; b < y; b++ )
757  for ( int a = 0; a < x; a++ )
758  getfield ( a, b ) -> deleteeverything();
759 }
760 
761 void stu_height ( Vehicle* vehicle )
762 {
763  Uint8 l;
764  MapField* fld = getfield ( vehicle->xpos, vehicle->ypos );
765 
766  vehicle->height = chfahrend;
767 
768  for (l=chsatellit; l> chfahrend ; ) {
769  if (vehicle->typ->height & l )
770  vehicle->height = l;
771  l>>=1;
772  } /* endfor */
773 
774  for (l=chtiefgetaucht; l<= chschwimmend ; ) {
775  if (vehicle->typ->height & l )
776  if (vehicle->typ->terrainaccess.accessible ( fld->bdt ) > 0 )
777  vehicle->height = l;
778  l<<=1;
779  }
780 
781  if (vehicle->typ->height & chfahrend)
782  if (vehicle->typ->terrainaccess.accessible ( fld->bdt ) > 0 )
783  vehicle->height = chfahrend;
784 
785  vehicle->setMovement ( vehicle->typ->movement[getFirstBit( vehicle->height )] );
786 }
787 
788 
789 void tloadBImap :: ReadACTNPart(void)
790 {
791  struct {
792  int X, Y;
793  } Size;
794 
795  TACTN ACTNHead;
796 
797  MissFile->seek ( Header.ACTNPos );
798  MissFile->readdata2( ACTNHead );
799  if ( strncmp ( ACTNHead.ID ,ACTNID,4 )) {
800  strcat ( missing, "\nFatal error: No Battle Isle mission; invalid ACTNID\n" );
801  throw timporterror ();
802  }
803 
804  Size.X = ACTNHead.XSize;
805  Size.Y = ACTNHead.YSize;
806  if ( Size.Y & 1 )
807  Size.Y++;
808 
809  preparemap ( Size.X / 2, Size.Y * 2 );
810 
811  for ( int i = 0; i < 6; i++ )
812  if ( OrgMissRec.WhoPlays & (1<< i))
813  actmap->player[ convcol ( 1 << i) ].stat = Player::PlayerStatus( (OrgMissRec.PlayType>>i) & 1);
814  else
815  actmap->player[convcol ( 1 << i) ].stat = Player::off;
816 
817  /* Terrain */
818  int Y, X;
819 
820  int missnum = 0;
821  dynamic_array<int> miss;
822 
823  Uint16* Line = new Uint16[Size.X];
824 
825  for (Y = 0; Y < Size.Y ; Y++) {
826  MissFile->readdata( Line, Size.X * 2);
827  for (X = 0; X < Size.X ; X++) {
828  for ( int tr = 0; tr < translationTable->terraintranslation.size(); tr++ )
829  if ( Line[X] == translationTable->terraintranslation[tr].first )
830  Line[X] = translationTable->terraintranslation[tr].second;
831  int found = 0;
832  MapField* fld = getfield ( X / 2, Y * 2 + (X & 1) );
833  fld->setTempw(Line[X]);
834  fld->setTemp3(0);
835 
836 
837  for ( int i = 0; i < translationTable->terrain2idTranslation.size(); i++ ) {
838  if ( Line[X] == translationTable->terrain2idTranslation[i].BIpic ) {
839  pterraintype trrn = terrainTypeRepository.getObject_byID ( translationTable->terrain2idTranslation[i].terrainid );
840  int w = translationTable->terrain2idTranslation[i].weather;
841  if ( trrn )
842  if ( trrn->weather[w] ) {
843  fld->typ = trrn->weather[w];
844  fld->setparams();
845  found = 1;
846  }
847  }
848  }
849 
850  if ( !found )
851  for ( int j = 0; j < translationTable->terraincombixlat.size(); j++ )
852  if ( Line[X] == translationTable->terraincombixlat[j].bigraph ) {
853  pterraintype trrn = terrainTypeRepository.getObject_byID ( translationTable->terraincombixlat[j].terrainid );
854  if ( trrn ) {
855  fld->typ = trrn->weather[translationTable->terraincombixlat[j].terrainweather];
856  ObjectType* obj = NULL;
857  if ( translationTable->terraincombixlat[j].objectid > 0 )
858  obj = objectTypeRepository.getObject_byID ( translationTable->terraincombixlat[j].objectid );
859  if ( obj )
860  fld->addobject ( obj, -1, 1 );
861  fld->setparams();
862  found = 1;
863  }
864  }
865 
866  if ( !found )
867  for ( int i = 0; i < terrainTypeRepository.getNum(); i++ ) {
868  pterraintype trrn = terrainTypeRepository.getObject_byPos ( i );
869  if ( trrn )
870  for ( int j = 0; j < cwettertypennum; j++ )
871  if ( trrn->weather[j] )
872  if ( trrn->weather[j]->bi_pict == Line[X] ) {
873  fld->typ = trrn->weather[j];
874  fld->setparams();
875  found = 1;
876  }
877  }
878 
879 
880  if ( !found ) {
881  int fnd = 0;
882  for ( int k = 0; k < missnum; k++ )
883  if ( miss[k] == Line[X] )
884  fnd = 1;
885 
886  if ( !fnd )
887  miss[missnum++] = Line[X];
888 
889  }
890  }
891  }
892 
893  if ( missnum ) {
894  strcat ( missing, "The following terrain fields could not be found: " );
895  for ( int k = 0; k < missnum; k++ ) {
896  strcat ( missing, strrr ( miss[k] ));
897  strcat ( missing, ", ");
898  }
899  strcat ( missing, "\n\n");
900  }
901 
902 
903 
904  missnum = 0;
905 
906  // Objekte
907  for (Y = 0; Y < Size.Y ; Y++) {
908  MissFile->readdata( Line, Size.X * 2 );
909 
910  for (X = 0; X < Size.X ; X++) {
911  int found = 0;
912  int newx = X / 2;
913  int newy = Y * 2 + (X & 1);
914 
915  if ( Line[X] != 0xffff )
916  getfield ( newx, newy )->setTempw(Line[X]);
917 
918 
919  int xl = 0;
920  int xlt[5];
921  int trrID = -1;
922  int trrWeather = 0;
923  xlt[0] = Line[X];
924  for ( int b = 0; b < translationTable->objecttranslate.size(); b++ )
925  if ( translationTable->objecttranslate[b].BIpic == Line[X] ) {
926  for ( int c = 0; c < 4; c++ )
927  if ( translationTable->objecttranslate[b].objects[c] != -1 )
928  xlt[xl++] = translationTable->objecttranslate[b].objects[c];
929  trrID = translationTable->objecttranslate[b].terrainID;
930  trrWeather = translationTable->objecttranslate[b].terrainWeather;
931  }
932  if ( xl == 0 ) {
933  for ( int c = 0; c < translationTable->terraintranslation.size(); c++ )
934  if ( translationTable->terraintranslation[c].first == Line[X] )
935  xlt[xl++] = translationTable->terraintranslation[c].second;
936 
937  if ( xl == 0 )
938  xl = 1;
939  }
940 
941  for ( int m = 0; m < xl; m++ ) {
942  int found_without_force = 0;
943  for ( int pass = 0; pass < 2 && !found_without_force; pass++ ) {
944  for ( int i = 0; i < translationTable->object2IDtranslate.size(); i++ )
945  if ( xlt[m] == translationTable->object2IDtranslate[i].first ) {
946  ObjectType* obj = objectTypeRepository.getObject_byID ( translationTable->object2IDtranslate[i].second );
947  if ( obj ) {
948  MapField* fld = getfield ( newx, newy );
949  if ( pass == 1 || obj->getFieldModification(fld->getWeather()).terrainaccess.accessible ( fld->bdt )) {
950  fld -> addobject ( obj, 0, true );
951  found |= 1;
952  if ( pass == 0 )
953  found_without_force = 1;
954  }
955  }
956  }
957 
958  if ( !(found & 1) )
959  for ( int i = 0; i < objectTypeRepository.getNum(); i++ ) {
960  ObjectType* obj = objectTypeRepository.getObject_byPos ( i );
961  if ( obj )
962  for ( int ww = 0; ww < cwettertypennum; ww++ )
963  if ( obj->weather.test(ww) )
964  for ( unsigned int j = 0; j < obj->weatherPicture[ww].images.size(); j++ )
965  if ( obj->weatherPicture[ww].bi3pic[j] == xlt[m] && !(found & 2) && !( GraphicSetManager::Instance().getMode(xlt[m]) & 256) ) {
966  MapField* fld = getfield ( newx, newy );
967  if ( pass == 1 || obj->getFieldModification(fld->getWeather()).terrainaccess.accessible ( fld->bdt )) {
968  fld -> addobject ( obj, 0, true );
969  found |= 1;
970  if ( pass == 0 )
971  found_without_force = 1;
972  }
973  }
974  }
975  }
976  }
977 
978  if ( trrID >= 0 ) {
979  pterraintype trrn = terrainTypeRepository.getObject_byID ( trrID );
980  if ( trrn ) {
981  if ( !trrn->weather[trrWeather] )
982  trrWeather = 0;
983 
984  if ( trrn->weather[trrWeather] ) {
985  MapField* fld = getfield ( newx, newy );
986  fld->typ = trrn->weather[trrWeather];
987  fld->setparams();
988  }
989  }
990  }
991 
992 
993  if ( !found && Line[X] != 0xffff ) {
994  if ( fakemap ) {
995  ObjectType* o = new ObjectType;
996  *o = *objectTypeRepository.getObject_byID ( 44 );
997  int id = 1000000;
998  while ( objectTypeRepository.getObject_byID ( id ))
999  id++;
1000 
1001  o->id = id;
1002  o->weather = 1;
1003 
1004  o->weatherPicture[0].resize(1);
1005 
1006  // loadbi3pict_double ( Line[X], &o->weatherPicture[0].images[0] );
1007  o->weatherPicture[0].bi3pic[0] = Line[X];
1008 
1009  // addobjecttype ( o );
1010 
1011  // getfield ( newx, newy )->addobject ( o, 0, true );
1012 
1013  } else {
1014 
1015  getfield ( newx, newy )->setTemp3(1);
1016 
1017  int fnd = 0;
1018  for ( int k = 0; k < missnum; k++ )
1019  if ( miss[k] == Line[X] )
1020  fnd = 1;
1021 
1022  if ( !fnd )
1023  if ( Line[X] < 44 || Line[X] > 88 )
1024  miss[missnum++] = Line[X];
1025  }
1026 
1027  }
1028  }
1029 
1030  }
1031 /*
1032  if ( missnum ) {
1033  strcat ( missing, "The following objects could not be found: " );
1034  for ( int k = 0; k < missnum; k++ ) {
1035  strcat ( missing, strrr ( miss[k] ));
1036  strcat ( missing, ", ");
1037  }
1038  strcat ( missing, "\n\n");
1039  }
1040 */
1041 
1042  for (Y = 0; Y < Size.Y ; Y++) {
1043  MissFile->readdata ( Line, Size.X * 2 );
1044  for (X = 0; X < Size.X ; X++) {
1045  int tp = Line[X] & 255;
1046  int cl = convcol(Line[X] >> 8);
1047  Vehicle* eht = getunit ( tp, cl );
1048  if ( eht ) {
1049  MapField* fld = getfield ( X / 2, Y * 2 + (X & 1) );
1050  fld->vehicle = eht;
1051  fld->vehicle->xpos = xoffset + X / 2;
1052  fld->vehicle->ypos = yoffset + Y * 2 + (X & 1);
1053  stu_height ( fld->vehicle );
1054  }
1055  }
1056  }
1057  delete[] Line;
1058 }
1059 
1060 struct blds {
1062  int pictnum;
1065 } ;
1066 
1067 
1068 void tloadBImap :: ReadSHOPPart( void )
1069 {
1070  TSHOPHead SHOPHead;
1071  TFileShop FileShop;
1072 // PVehContent PVC;
1073 
1074  int firstmissingbuilding = 1;
1075 
1076  MissFile->seek ( Header.ShopPos );
1077  MissFile->readdata2 ( SHOPHead );
1078  if ( strncmp ( SHOPHead.ID, SHOPID, 4 )) {
1079  strcat ( missing, "\nFatal error: No Battle Isle mission; invalid ShopID\n" );
1080  throw timporterror ();
1081  }
1082 
1083  int ShopNum = 0;
1084  // int VehContNum = 0;
1085  // int AINum = 0;
1086  for ( int I = 0; I < SHOPHead.Num ; I++ ) {
1087  MissFile->readdata2 ( FileShop );
1088  if ( FileShop.ID == 1) { // wenn kein ki punkt
1089  if (FileShop.a.ShopType == 32) { // Vehicle
1090  int IsVehCont = false;
1091  for ( int J = 0; J < 8; J++ )
1092  if ( FileShop.a.Content.Veh[J] != 0xFFFF )
1093  IsVehCont = true;
1094  if ( IsVehCont ) {
1095  int Y = FileShop.Pos1 / 64;
1096  int X = FileShop.Pos1 % 64;
1097  MapField* fld = getfield ( X / 2, Y * 2 + (X & 1) );
1098  if ( fld->vehicle )
1099  for ( int j = 0; j < 8; j++ )
1100  if ( FileShop.a.Content.Veh[j] >= 0 ) {
1101  Vehicle* eht = getunit ( FileShop.a.Content.Veh[j], fld->vehicle->color/8 );
1102  if ( eht ) {
1103  eht->xpos = xoffset + X / 2;
1104  eht->ypos = yoffset + Y * 2 + (X & 1);
1105  fld->vehicle->addToCargo( eht );
1106  }
1107  }
1108 
1109  }
1110  }
1111 
1112  else {
1113  int Y = FileShop.Pos1 / 64;
1114  int X = FileShop.Pos1 % 64;
1115  int newx = X / 2;
1116  int newy = Y * 2 + (X & 1);
1117 
1118  MapField* fld = getfield ( newx, newy );
1119 
1120  dynamic_array<blds> bldlist;
1121  int bldlistnum = 0;
1122 
1123  for ( int i = 0; i < buildingTypeRepository.getNum(); i++ ) {
1124  BuildingType* bld = buildingTypeRepository.getObject_byPos ( i );
1125  if ( bld )
1126  for ( int w = 0; w < cwettertypennum; w++ )
1127  for ( int p = 0; p < maxbuildingpicnum; p++ )
1128  if ( bld->getBIPicture(bld->entry, w, p) == fld->getTempw() ) {
1129  bldlist[ bldlistnum ].bld = bld;
1130  int cnt = 0;
1131  int terrainmatch = 0;
1132  int objmatch = 0;
1133  bool fail = false;
1134  for ( int m = 0; m < 4; m++ )
1135  for ( int n = 0; n < 6; n++ )
1136  if ( bld->fieldExists( BuildingType::LocalCoordinate(m , n) ) ) {
1138  MapField* fld2 = getfield ( pos.x, pos.y );
1139  if ( !fld2 )
1140  fail = true;
1141  else {
1142  if ( bld->terrainaccess.accessible ( fld2->bdt ) > 0 )
1143  terrainmatch++;
1144  if ( bld->getBIPicture( BuildingType::LocalCoordinate(m,n), w, p) == fld2->getTempw() )
1145  objmatch++;
1146  }
1147  cnt++;
1148  }
1149  if ( !fail ) {
1150  bldlist[ bldlistnum ].pictnum = cnt;
1151  bldlist[ bldlistnum ].terrainmatch = terrainmatch;
1152  bldlist[ bldlistnum ].objectmatch = objmatch;
1153 
1154  bldlistnum++;
1155  }
1156 
1157  }
1158  }
1159 
1160  int found = 0;
1161  if ( bldlistnum ) {
1162  for ( int j = 0; j < bldlistnum-1; )
1163  if ( ( bldlist[ j ].objectmatch < bldlist[ j+1 ].objectmatch ) ||
1164  ( bldlist[ j ].objectmatch == bldlist[ j+1 ].objectmatch && bldlist[ j ].terrainmatch < bldlist[ j+1 ].terrainmatch) ) {
1165  blds tmp = bldlist[ j ];
1166  bldlist[ j ] = bldlist[ j+1 ];
1167  bldlist[ j+1 ] = tmp;
1168  if ( j > 0 )
1169  j--;
1170  } else
1171  j++;
1172 
1173  int actpos = 0;
1174  while ( !found && actpos < bldlistnum ) {
1175  BuildingType* bld = bldlist[actpos].bld;
1176  for ( int w = 0; w < cwettertypennum; w++ )
1177  for ( int p = 0; p < maxbuildingpicnum; p++ )
1178  if ( !found ) {
1179  int match = 1;
1180  for ( int m = 0; m < 4; m++ )
1181  for ( int n = 0; n < 6; n++ )
1182  if ( bld->fieldExists( BuildingType::LocalCoordinate(m , n) ) )
1183  if ( bld->getPicture( BuildingType::LocalCoordinate(m , n), w, p ).valid() ) {
1185  MapField* fld2 = getfield ( pos.x, pos.y );
1186  if ( fld2->getTempw() != bld->getBIPicture( BuildingType::LocalCoordinate(m , n), w, p ))
1187  match = 0;
1188  }
1189  if ( match )
1190  found = 1;
1191  }
1192  actpos++;
1193  }
1194  actpos--;
1195 
1196  if ( found ) {
1197  putbuilding ( actmap, MapCoordinate(xoffset + newx, yoffset + newy), 0, bldlist[actpos].bld, bldlist[actpos].bld->construction_steps - 1, 1 );
1198  if ( fld->building ) {
1199 
1200  for ( int m = 0; m < 4; m++ )
1201  for ( int n = 0; n < 6; n++ )
1202  if ( fld->building->getPicture( BuildingType::LocalCoordinate(m , n) ).valid() ) {
1203  fld->building->getField ( BuildingType::LocalCoordinate(m, n) )->setTemp3(0);
1204  }
1205 
1206  /*
1207  if ( field->object )
1208  for ( int o = 0; o < field->object->objnum; o++ )
1209  field->removeobject ( field->object->object[o]->typ );
1210  }
1211  */
1212  found = 255;
1213  } else
1214  found = 254;
1215  }
1216  }
1217 
1218  if ( fld->building ) {
1219 
1220 // if ( battleisleversion == 3 )
1221  const char* shopStr = GetStr( ShopNum + 2,16);
1222  if ( shopStr )
1223  fld->building->name = shopStr; /* bi3 macht das so */
1224  /*
1225  else
1226  ArrShop.NameStr = GetStr(FileShop.Name, 16); // bi2 wahrscheinlich so
1227  */
1228  int newcol = convcol ( FileShop.a.Owner );
1229  if ( newcol != fld->building->color/8 )
1230  fld->building->convert ( newcol );
1231 
1232  for ( int j = 0; j < 16; j++ ) {
1233  Vehicle* eht = getunit ( FileShop.a.Content.All[j], fld->building->color/8 );
1234  if ( eht ) {
1235  fld->building->addToCargo( eht );
1236  eht->xpos = newx;
1237  eht->ypos = newy;
1238  }
1239  }
1240 
1241  int prodnum = 0;
1242  for ( int k= 0; k < 4; k++ ) {
1243  VehicleType* vt = getvehicletype ( FileShop.a.Produce[k] );
1244  if ( vt ) {
1245  int fnd = 0;
1246  for ( int l = 0; l < prodnum; l++ )
1247  if ( fld->building->getProduction()[l] == vt )
1248  fnd++;
1249 
1250  if ( !fnd )
1251  if ( fld->building->typ->vehicleFit( vt ))
1252  fld->building->addProductionLine( vt );
1253  }
1254  }
1255  for ( int l = 0; l < 64; l++ )
1256  if ( OrgMissRec.StdProd[l] & 3 ) {
1257  VehicleType* vt = getvehicletype ( l );
1258  if ( vt ) {
1259  int fnd = 0;
1260  for ( int l = 0; l < prodnum; l++ )
1261  if ( fld->building->getProduction()[l] == vt )
1262  fnd++;
1263  if ( !fnd )
1264  if ( fld->building->typ->vehicleFit( vt ))
1265  fld->building->addProductionLine( vt );
1266  }
1267  }
1268  fld->building->bi_resourceplus.energy = energyfactor * FileShop.a.EP;
1269  fld->building->bi_resourceplus.material = materialfactor * FileShop.a.MP;
1270  fld->building->bi_resourceplus.fuel = fuelfactor * FileShop.a.EP;
1271 
1272  fld->building->actstorage.energy = energyfactor * FileShop.a.E;
1273  fld->building->actstorage.material = materialfactor * FileShop.a.M;
1274  fld->building->actstorage.fuel = fuelfactor * FileShop.a.E;
1275 
1276  } else {
1277  if ( found == 254 ) {
1278  char tmp[100];
1279  int obj = fld->getTempw();
1280  sprintf( tmp, "The building at position %d / %d using pic #%d could not be set\n", newx, newy, obj );
1281  strcat ( missing, tmp );
1282  } else {
1283  if ( firstmissingbuilding ) {
1284  strcat ( missing, "The buildings at the following coordinates could not be found:\n " );
1285  firstmissingbuilding = 0;
1286  }
1287  char tmp[100];
1288  int obj = fld->getTempw();
1289  sprintf( tmp, "%d / %d using pic #%d\n", newx, newy, obj );
1290  strcat ( missing, tmp );
1291  }
1292 
1293  }
1294  ShopNum++;
1295 
1296  }
1297  }
1298 
1299  }
1300 // if ( TPWMtextfile )
1301 // 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");
1302 
1303 
1304  int missnum = 0;
1305  dynamic_array<int> miss;
1306 
1307  for ( int y = 0; y < actmap->ysize; y++ )
1308  for ( int x = 0; x < actmap->xsize; x++ )
1309  if ( ::getfield(x,y)->getTemp3() ) {
1310  int m = ::getfield(x,y)->getTempw();
1311  if ( m > 0 && m != 0xffff ) {
1312  int fnd = 0;
1313  for ( int k = 0; k < missnum; k++ )
1314  if ( miss[k] == m )
1315  fnd = 1;
1316 
1317  if ( !fnd )
1318  miss[missnum++] = m;
1319 
1320  }
1321  }
1322 
1323 
1324  if ( missnum ) {
1325  strcat ( missing, "The following objects could not be found: " );
1326  for ( int k = 0; k < missnum; k++ ) {
1327  strcat ( missing, strrr ( miss[k] ));
1328  strcat ( missing, ", ");
1329  }
1330  strcat ( missing, "\n\n");
1331  }
1332 
1333 
1334 }
1335 
1336 
1337 char* tloadBImap :: GetStr( int a, int b )
1338 {
1339 // if ( TPWMtextfile )
1340 // return NULL;
1341 // else
1342  for ( int i = 0; i <= ShopNameList.getlength(); i++ )
1343  if ( ShopNameList[i].a == a && ShopNameList[i].b == b )
1344  return strdup ( ShopNameList[i].name );
1345 
1346  return NULL;
1347 }
1348 
1349 /* TPTC: TOCONV.PAS(303): Warning: Nested function, tok=SplitName
1350 
1351 Boolean SplitName(char * S,
1352  char * Name,
1353  Uint16 * R1,
1354  Uint16 * R2)
1355  {
1356  Integer Code;
1357 
1358  Result = false;
1359  strcpy(S,Trim(S));
1360  if (strcmp(S,"") != 0) {
1361  if (S[0] != '#') return;
1362  val(copy(S,2,4),R1,&Code);
1363  if (Code != 0) return;
1364  if (S[5] != ':') return;
1365  val(copy(S,7,4),R2,&Code);
1366  if (Code != 0) return;
1367  if (S[10] != '{') return;
1368  if (S[strlen(S)-1] != '}') return;
1369  strcpy(S,copy(S,12,strlen(S) - 12));
1370  // Delete(S, 1, 11);
1371  // Delete(S, Length(S), 1);
1372  strcpy(Name,S);
1373  sbld(Result,"%b",true);
1374  }
1375  }
1376 
1377 */
1378 
1379 
1380 void tloadBImap :: ReadShopNames( char* databuf, unsigned long datasize )
1381 {
1382  unsigned long dptr=0;
1383  char buf[ 1000];
1384  int c;
1385  do {
1386  do {
1387  c = databuf[dptr++];
1388  } while ( c != '#' && dptr<datasize );
1389  if ( c == '#' ) {
1390  int i;
1391  for ( i = 0; i < 4; i++ ) {
1392  c = databuf[dptr++];
1393  if ( c < '0' || c > '9' )
1394  return;
1395 
1396  buf[i] = c;
1397  }
1398  buf[4] = 0;
1399  int a1 = atoi ( buf );
1400  if ( databuf[dptr++] != ':' )
1401  return;
1402 
1403  for ( i = 0; i < 4; i++ ) {
1404  c = databuf[dptr++];
1405  if ( c < '0' || c > '9' )
1406  return;
1407 
1408  buf[i] = c;
1409  }
1410  buf[4] = 0;
1411  int a2 = atoi ( buf );
1412 
1413  if ( databuf[dptr++] != '{' )
1414  return;
1415 
1416  i = 0;
1417  do {
1418  c = databuf[dptr++];
1419  buf[i++] = c;
1420  } while ( c != '}' && dptr<datasize ); /* enddo */
1421 
1422  if ( c == '}' ) {
1423  buf[i-1] = 0;
1424  int pos = ShopNameList.getlength()+1;
1425  ShopNameList[pos].a = a1;
1426  ShopNameList[pos].b = a2;
1427  strcpy ( ShopNameList[pos].name , buf );
1428  }
1429  }
1430  } while ( dptr<datasize );
1431 }
1432 
1433 
1434 void tloadBImap :: GetTXTName ( const char* path, const char* filename, char* buf )
1435 {
1436  strcpy ( buf, path );
1437  strcat ( buf, "ger" );
1438  strcat ( buf, pathdelimitterstring );
1439  strcat ( buf, filename );
1440  strcpy ( &buf[ strlen ( buf ) - 3], "txt" );
1441  if ( exist ( buf ))
1442  return;
1443 
1444  strcpy ( buf, path );
1445  strcat ( buf, "eng" );
1446  strcat ( buf, pathdelimitterstring );
1447  strcat ( buf, filename );
1448  strcpy ( &buf[ strlen ( buf ) - 3], "txt" );
1449  if ( exist ( buf ))
1450  return;
1451 
1452  buf[0] = 0;
1453  return;
1454 }
1455 
1456 void tloadBImap :: LoadTXTFile ( char* filename )
1457 {
1458 
1459  FILE* fp = fopen ( filename, "rb" );
1460  if ( !fp )
1461  return;
1462 
1463  // get file size
1464  fseek(fp, 0, SEEK_END);
1465  unsigned long txtsize=ftell(fp);
1466  fseek(fp, 0, SEEK_SET);
1467 
1468  // databuffer which holds the textdata
1469  char *txtbuffer=(char *)malloc(txtsize+10000);
1470  memset(txtbuffer, 0, txtsize+10000);
1471 
1472  char buf[1000];
1473  if ( fread ( buf, 1, 4, fp ) != 4)
1474  throw treadafterend( filename );
1475 
1476  if ( strncmp ( buf, "TPWM",4) == 0 ) {
1477  // The file is compressed.
1478 // unsigned long tpwmsize=txtsize; // store the size of the compressed file.
1479  if ( fread(&txtsize, 4, 1, fp) != 1 ) // this is the uncompressed size.
1480  throw treadafterend( filename );
1481 
1482  unsigned long outptr=0;
1483  txtbuffer=(char *)realloc(txtbuffer, txtsize+10000);
1484 
1485  // the tpwm algorithm is quite simple:
1486  // you have datablocks containing 1 codebyte and 8 values.
1487  // the codebyte determines whether to copy a single char or
1488  // to repeat a previous block. Each bit in the codebyte marks
1489  // the meaning (and size) of one value. The MSB is linked to the
1490  // first value and the LSB to the last one.
1491  // A cleared bit means: the value is 1 byte sized and gets copied directly.
1492  // A set bit means: the value is a 2 byte pair and is interpreted as follows:
1493  // The lower nibble (bits 0-3) in the 1st byte is the length of the block +3
1494  // (thus giving a min. block length of 3 and a max. of 18) and the second byte
1495  // plus the high nibble of the first byte shifted left by 4 bits is an offset
1496  // in reverse direction into the already decompressed data (thus giving a range
1497  // from offset to offset-4095.
1498  // or simply look at the code. could be easier to understand ;-)
1499 
1500  while (outptr<txtsize)
1501  {
1502  Uint8 code=0;
1503  Uint8 inbuf[16]; // worst case buffer usage is 8*2
1504  memset(inbuf,0,16);
1505  int inptr=0;
1506  if ( fread(&code, 1, 1, fp) != 1 )
1507  throw treadafterend( filename );
1508  Uint8 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);
1509 
1510  int toread = min(8+bitsset, int(txtsize-outptr));
1511  if ( fread(&inbuf, toread, 1, fp) != 1 )
1512  throw treadafterend( filename );
1513 
1514  for (int i=0; (i<8)&&(outptr<txtsize); i++)
1515  {
1516  if ((code&(0x80>>i))==0)
1517  {
1518  // straight copy
1519  txtbuffer[outptr]=inbuf[inptr];
1520  outptr++; inptr++;
1521  } else {
1522  // repeat
1523  Uint8 d0,d1;
1524  d0=inbuf[inptr]; inptr++;
1525  d1=inbuf[inptr]; inptr++;
1526  int blklen=(d0&0xf)+3;
1527  int blkofs=((d0&0xf0)<<4)+d1;
1528  for (int j=0; (j<blklen)&&(outptr<txtsize); j++)
1529  {
1530  txtbuffer[outptr]=txtbuffer[outptr-blkofs];
1531  outptr++;
1532  }
1533  }
1534  }
1535  }
1536  } else {
1537  // The file is uncompressed.
1538  if ( fread(txtbuffer, txtsize, 1, fp) != 1 )
1539  throw treadafterend( filename );
1540 
1541  }
1542 
1543  txtbuffer[txtsize]=0;
1544 
1545  fclose ( fp );
1546 
1547  ReadShopNames( txtbuffer, txtsize );
1548 
1549  free(txtbuffer);
1550 
1551  /*
1552  LevelDescription:= GetStr(0, 0);
1553  LevelName:= GetStr(1, 24);
1554 
1555  P:= Pos('|', LevelDescription);
1556  if (Length(LevelDescription)> 0) and (P<> 0) then begin
1557  SavePlayerNames:= true;
1558  S:= Copy(LevelDescription, P, Length(LevelDescription)-P+1);
1559  Delete(LevelDescription, P, Length(LevelDescription)-P+1);
1560  Delete(S, 1, 1);
1561  for I:= 0 to 6 do begin
1562  P:= Pos('|', S);
1563  if P= 0 then P:= Length(S)+ 1;
1564  FPlayers[I].Name:= Copy(S, 1, P-1);
1565  Delete(S, 1, P);
1566  P:= Pos('|', S);
1567  if P= 0 then P:= Length(S)+ 1;
1568  try
1569  FPlayers[I].Color:= StrToInt(Copy(S, 1, P-1));
1570  except
1571  FPlayers[I].Color:= 0;
1572  end;
1573  Delete(S, 1, P);
1574  end;
1575  end else
1576  SavePlayerNames:= false;
1577  */
1578 }
1579 
1580 void tloadBImap :: LoadFromFile( const char* path, const char* AFileName, TerrainType::Weather* trrn, string* errorOutput )
1581 {
1582  defaultterraintype = trrn;
1583  char temp[4000];
1584  missing = temp;
1585  missing[0] = 0;
1586  namenum = 0;
1587 // PShopNameItem PSNI;
1588 
1589  char TXTName[1000];
1590  bool error = false;
1591  try {
1592  GetTXTName( path, AFileName, TXTName );
1593 
1594  LoadTXTFile(TXTName);
1595 
1596  char completefilename[1000];
1597  strcpy ( completefilename, path );
1598  strcat ( completefilename, "mis" );
1599  strcat ( completefilename, pathdelimitterstring );
1600  strcat ( completefilename, AFileName );
1601  tn_file_buf_stream stream ( completefilename, tnstream::reading );
1602  MissFile = &stream;
1603  MissFile->readdata2( Header );
1604  if ( strncmp ( Header.ID, HeadID, 4 )) {
1605  strcat ( missing, "\nFatal error: No Battle Isle mission; invalid HeadID\n" );
1606  throw timporterror ();
1607  }
1608  ReadMISSPart();
1609  ReadACTNPart();
1610  ReadSHOPPart();
1611  /*
1612  ReadMAPPart();
1613  LoadDFs();
1614  UnPackDF(AktDFNum);
1615  */
1616 
1617  char* str = GetStr ( 1, 24 );
1618  if ( str )
1619  actmap->maptitle = str;
1620  else
1621  actmap->maptitle.erase();
1622 
1623  if ( actmap->maptitle.empty() )
1624  actmap->maptitle = "imported BI map";
1625 
1626  } /* endtry */
1627  catch ( treadafterend ) {
1628  throw;
1629  }
1630  catch ( tfileerror err ) {
1631  strcat ( missing, "\nA fatal error occured while accessing the file " );
1632  strcat ( missing, err.getFileName().c_str() );
1633  strcat ( missing, "\n" );
1634  error = true;
1635  } /* endcatch */
1636  catch ( ASCexception ) {
1637  strcat ( missing, "\nA fatal error occured" );
1638  error = true;
1639  } /* endcatch */
1640 
1641  if ( !error )
1643  if ( missing[0] ) {
1644  if ( errorOutput )
1645  (*errorOutput)=missing;
1646  else {
1647  tviewanytext vat;
1648  vat.init ( "warning", missing );
1649  vat.run();
1650  vat.done();
1651  }
1652  }
1653 
1654 }
1655 
1656 
1658 
1660 {
1661  defaultImportTranslationTable = filename;
1662 }
1663 
1664 
1665 
1666 void importbattleislemap ( const ASCString& path, const ASCString& mapfilename, TerrainType::Weather* trrn, const ASCString& importTable, ASCString* errorOutput, bool fakemap )
1667 {
1668  GameMap* oldmap = actmap;
1669  actmap = NULL;
1670  GraphicSetManager::Instance().setActive(1);
1671  try {
1672  ImportBiMap lbim ( findTable(importTable) );
1673  if ( fakemap )
1674  lbim.____fakeMap____();
1675  lbim.LoadFromFile ( path.c_str(), mapfilename.c_str(), trrn, errorOutput );
1676  actmap->_resourcemode = 1;
1677  actmap->cleartemps ( 7 );
1678  }
1679  catch ( ASCexception ) {
1680  delete actmap;
1681  actmap = oldmap;
1682  throw;
1683  }
1684  delete oldmap;
1685 }
1686 
1687 
1688 void insertbattleislemap ( int x, int y, const ASCString& path, const ASCString& mapfilename, const ASCString& importTable )
1689 {
1690  GraphicSetManager::Instance().setActive ( 1 );
1691  InsertBiMap lbim ( x, y, findTable(importTable) );
1692  lbim.LoadFromFile ( path.c_str(), mapfilename.c_str(), NULL, NULL );
1693  actmap->_resourcemode = 1;
1694  actmap->cleartemps ( 7 );
1695 }
1696 
1697 
1698 #pragma pack()
1699 
void init(const char *title, const char *text, int xx1=50, int yy1=50, int xxsize=360, int yysize=360)
Definition: dialog.cpp:920
vector< Terrain2id > terrain2idTranslation
The first entry is the picture number that is going to be replaced by the terrain with the ID of the ...
Definition: loadbi3.cpp:164
TerrainType::Weather * typ
the terraintype of the field
Definition: mapfield.h:38
int libs_to_load
Definition: loadbi3.cpp:82
ItemRepositoryLoader< ObjectType > objectTypeRepository("objecttype")
void cleartemps(int b=-1, int value=0)
Definition: gamemap.cpp:964
int xsize
the size of the map
Definition: gamemap.h:201
virtual void writeInt(int i)
Writes a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is p...
Definition: basestrm.cpp:363
MapCoordinate getFieldCoordinate(const MapCoordinate &entryOnMap, const LocalCoordinate &localCoordinate) const
returns the Mapcoordinate of a buildings field
int FirstRecO
Definition: loadbi3.cpp:61
void fillMagically(bool ammo=true, bool resources=true)
fills a unit with all resources it can carry This function should only be called in the mapeditor ! ...
Definition: vehicle.cpp:1075
int id
the id of the object, used when referencing objects in files
Definition: objecttype.h:35
map accessing and usage routines used by ASC and the mapeditor
miscellaneous functions which are used by ASC and all its tools
#define chschwimmend
Definition: typen.h:412
const ASCString & getFileName() const
Definition: simplestream.h:80
int getBIPicture(const LocalCoordinate &localCoordinate, int weather=0, int constructionStep=0) const
virtual void preparemap(int x, int y)=0
ASCString getbi3path(void)
returns the path to the BI3 installation
Definition: loadbi3.cpp:129
Vehicle * vehicle
Definition: mapfield.h:89
vector< ASCString > getBI3ImportTables()
returns the names of the import tables that are available
Definition: loadbi3.cpp:366
TerrainType::Weather * defaultterraintype
Definition: loadbi3.cpp:528
virtual void readTextFiles(PropertyReadingContainer &prc, const ASCString &fileName, const ASCString &location)
Definition: loadbi3.cpp:393
Bi3MapTranslationTable * findTable(const ASCString &filename)
Definition: loadbi3.cpp:359
InsertBiMap(int x, int y, Bi3MapTranslationTable *_translationTable)
Definition: loadbi3.cpp:585
vector< pair< int, int > > terraintranslation
The first entry is the picture number that is going to be replaced by the picture number of the secon...
Definition: loadbi3.cpp:139
virtual int readInt(void)
Reads a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is pe...
Definition: basestrm.cpp:284
virtual ASCString getDeviceName()
returns the name of the stream.
Definition: basestrm.cpp:269
class TerrainType * pterraintype
Definition: terraintype.h:72
Loading Battle Isle 3 maps. The central BI3 map loading class is a straight conversion of Joerg Richt...
int getFirstBit(int zahl)
Count the number of zero bits on the LSB side of "zahl".
Definition: misc.cpp:45
void insertbattleislemap(int x, int y, const ASCString &path, const ASCString &mapfilename, const ASCString &importTable)
Imports a Battle Isle map and inserts it into the current ASC map.
Definition: loadbi3.cpp:1688
int translateunits[bi3unitnum][2]
Definition: loadbi3.cpp:646
void stu_height(Vehicle *vehicle)
Definition: loadbi3.cpp:761
virtual void write(tnstream &stream)
Definition: loadbi3.cpp:381
void setMovement(int newmove, double cargoDivisor=-1)
sets a new distance that the unit can move
Definition: vehicle.cpp:527
void addIntegerArray(const ASCString &name, vector< int > &property, bool required=true)
int bipicture
the image index from the GraphicSet , or -1 if no graphics from graphic sets are used.
Definition: vehicletype.h:224
Functions to evaluate the parsed *.asctxt files.
BitSet weather
bitmapped variable containing the different weather types the objects exist for
Definition: objecttype.h:44
A local coordinate referencing a single field that a building covers.
Definition: buildingtype.h:57
void read(tnstream &stream)
Definition: loadbi3.cpp:145
char * missing
Definition: loadbi3.cpp:567
int objectmatch
Definition: loadbi3.cpp:1064
const char * MISSID
Definition: loadbi3.cpp:414
void generatemap(TerrainType::Weather *bt, int xsize, int ysize)
Definition: loadbi3.cpp:696
virtual MapField * getfield(int x, int y)
Definition: loadbi3.cpp:597
A system that provides a set of images for vehicles, buildings, etc.
int getlength(void)
Definition: basetemp.h:183
ItemRepositoryLoader< BuildingType > buildingTypeRepository("buildingtype")
The interface for all kinds of IO stream.
a single field of the map
Definition: mapfield.h:26
void write(tnstream &stream) const
Definition: loadbi3.cpp:180
int terrainmatch
Definition: loadbi3.cpp:1063
int readgameoptions(const ASCString &filename)
Definition: sgstream.cpp:372
void setgameparameter(GameParameter num, int value)
Definition: gamemap.cpp:1058
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
const char * ACTNID
Definition: loadbi3.cpp:411
void write(tnstream &stream) const
Definition: loadbi3.cpp:207
vector< Terraincombixlat > terraincombixlat
This is a special translation for the fields that must be translated to a terrain AND an additional o...
Definition: loadbi3.cpp:190
vector< int > movement
the distance a unit can travel each round. One value for each of the 8 levels of height ...
Definition: vehicletype.h:203
PointerVector< Bi3MapTranslationTable * > bi3ImportTables
Definition: loadbi3.cpp:357
int height
the current level of height ( BITMAPPED ! )
Definition: vehicle.h:118
int getWeather()
the weather that is on this field
Definition: mapfield.cpp:370
virtual void writeString(const string &pc, bool binary=true)
writes the C++ String pc to the stream.
Definition: basestrm.cpp:545
MapField * getfield(int x, int y)
returns the field at the given coordinates
Definition: spfst.cpp:199
virtual void run(void)
Definition: dialog.cpp:1009
char * malloc(int)
virtual ~tloadBImap()
Definition: loadbi3.cpp:538
ASCString BI3directory
Definition: gameoptions.h:223
int resize(int top, int bottom, int left, int right)
resizes the map. Positive numbers enlarge the map in that direction
Definition: gamemap.cpp:1636
vector< Surface > images
Definition: objecttype.h:149
const char * HeadID
Definition: loadbi3.cpp:410
bool fieldExists(const LocalCoordinate &localCoordinate) const
returns whether this building covers the given field
Definition: buildingtype.h:108
int pictnum
Definition: loadbi3.cpp:1062
The class describing properties that are common to all vehicles of a certain kind.
Definition: vehicletype.h:177
void read(tnstream &stream)
Definition: loadbi3.cpp:235
virtual void read(tnstream &stream)
Definition: loadbi3.cpp:375
const char * MAPID
Definition: loadbi3.cpp:413
int Anzahl
Definition: loadbi3.cpp:65
const int maxbuildingpicnum
The maximum number of number of different images for a building and a weather. For example...
Definition: typen.h:70
#define chtiefgetaucht
Definition: typen.h:410
void done(void)
Definition: dlg_box.cpp:1235
The class describing properties that are common to all buildings of a certain kind.
Definition: buildingtype.h:35
void setChanged(bool flag=true)
Definition: gameoptions.h:272
virtual MapField * getfield(int x, int y)
Definition: loadbi3.cpp:592
vector< Objecttranslataion > objecttranslate
These BI object pictures can be translated to up to four ASC objects.
Definition: loadbi3.cpp:220
ItemRepositoryLoader< VehicleType > vehicleTypeRepository("vehicletype")
const int LIBFilesAnz
Definition: loadbi3.cpp:57
char * strrr(int a)
converts a to a string.
Definition: misc.cpp:66
const int fuelfactor
Definition: loadbi3.cpp:403
void LoadFromFile(const char *path, const char *AFileName, TerrainType::Weather *trrn, string *errorOutput)
Definition: loadbi3.cpp:1580
ItemRepositoryLoader< TerrainType > terrainTypeRepository("terraintype")
enum Player::PlayerStatus stat
const int energyfactor
Definition: loadbi3.cpp:405
void setTemp3(int temp3)
Definition: mapfield.cpp:71
An object that can be placed on fields. Roads, pipelines and ditches are examples of objects...
Definition: objecttype.h:30
Coordinate on the twodimensional map.
Definition: typen.h:202
void setparams(ObjectRemovalStrategy *objectRemovalStrategy)
recalculates the terrain properties, movemalus etc from the terraintype and the objects,
Definition: mapfield.cpp:605
const FieldModification & getFieldModification(int weather) const
Definition: objecttype.cpp:72
void displaymessage(const char *formatstring, int num,...)
displays a dialog box with a message
Definition: dlg_box.cpp:1849
void allocateFields(int x, int y, TerrainType::Weather *terrain=NULL)
Definition: gamemap.cpp:982
const char * Name
Definition: loadbi3.cpp:60
virtual void preparemap(int x, int y)
Definition: loadbi3.cpp:722
virtual ASCString getTypeName()
Definition: loadbi3.cpp:388
TLIBFiles LIBFiles[LIBFilesAnz]
Definition: loadbi3.cpp:67
void readPointerContainer(vector< BaseType * > &v, tnstream &stream)
Definition: basestrm.h:714
The interface for the buildingtype class.
int accessible(const TerrainBits &bts) const
checks whether a field with the given terrainbits is accessible.
int _resourcemode
how are Resources handled on this map 0= "ASC mode": complex system with mineral resources etc 1= "BI...
Definition: gamemap.h:250
BuildingType * bld
Definition: loadbi3.cpp:1061
void calculateallobjects(GameMap *actmap)
recalculates the connection (like road interconnections) of all objects on the map ...
Definition: spfst.cpp:562
bool addobject(const ObjectType *obj, int dir=-1, bool force=false, ObjectRemovalStrategy *objectRemovalStrategy=NULL)
add an object to the field
Definition: mapfield.cpp:212
void runTextIO(PropertyContainer &pc)
Definition: loadbi3.cpp:265
const Surface & getPicture(const LocalCoordinate &localCoordinate, int weather=0, int constructionStep=0) const
int RecSize
Definition: loadbi3.cpp:62
TerrainAccess terrainaccess
the terrain properties which are necessary for the building to be constructed there ...
Definition: buildingtype.h:86
void readClassContainer(C &c, tnstream &stream)
Definition: basestrm.h:752
#define chfahrend
Definition: typen.h:413
void putbuilding(GameMap *actmap, const MapCoordinate &entryPosition, int color, const BuildingType *buildingtyp, int completion, int ignoreunits)
puts a building onto the map. To be used by the map editor! For ingame usage, see ConstructBuildingCo...
Definition: spfst.cpp:210
vector< pair< int, int > > object2IDtranslate
These BI object pictures can be translated to ASC objects.
Definition: loadbi3.cpp:225
Player player[9]
Definition: gamemap.h:253
virtual void seek(int newpos)
Sets the stream pointer to a new location. An exception is thrown if the stream does not support seek...
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
#define chsatellit
Definition: typen.h:417
const int bi3unitnum
Definition: loadbi3.cpp:645
void checkbi3dir(void)
Definition: loadbi3.cpp:85
const char * pathdelimitterstring
Definition: unix/fileio.cpp:24
void write(tnstream &stream) const
Definition: loadbi3.cpp:154
const int materialfactor
Definition: loadbi3.cpp:404
int ysize
Definition: gamemap.h:201
TerrainBits bdt
the terraintype properties. They determine which units can move over the field. This variable is reca...
Definition: mapfield.h:161
ImportBiMap(Bi3MapTranslationTable *_translationTable)
Definition: loadbi3.cpp:577
void appendbackslash(char *string)
Definition: basestrm.cpp:2596
void write(tnstream &stream) const
Definition: loadbi3.cpp:252
virtual ASCString readString(bool includeCR=false)
Reads and returns a string.
Definition: basestrm.cpp:535
int height
the levels of height which this unit can enter
void ____fakeMap____(void)
Definition: loadbi3.cpp:537
int atoi(const std::string &s)
Definition: misc.cpp:152
Interface for all the dialog boxes used by the game and the mapeditor.
int color
The owner of the container.
MapField * field
the array of fields
Definition: gamemap.h:204
int xpos
the position on the map
Definition: vehicle.h:124
ASCString maptitle
the title of the map
Definition: gamemap.h:213
a table to translate a Battle Isle map into an ASC map
Definition: loadbi3.cpp:136
procedure for loading and writing savegames, maps etc.
void addToCargo(Vehicle *veh, int position=-1)
adds the unit to the cargo
const VehicleType * typ
Definition: vehicle.h:83
PlayerStatus
the status of the player
Definition: player.h:150
tloadBImap(Bi3MapTranslationTable *_translationTable)
Definition: loadbi3.cpp:531
const char * SHOPID
Definition: loadbi3.cpp:412
A vector that stores pointers, but deletes the objects (and not only the pointers) on destruction...
Definition: basictypes.h:29
void setTempw(Uint16 tempw)
Definition: mapfield.cpp:63
Uint16 getTempw()
Definition: mapfield.cpp:67
ASCString defaultImportTranslationTable
Definition: loadbi3.cpp:1657
GameMap * actmap
Definition: spfst.cpp:64
struct ObjectType::WeatherPicture weatherPicture[cwettertypennum]
int xoffset
Definition: loadbi3.cpp:527
void writeClassContainer(const C &c, tnstream &stream)
Definition: basestrm.h:742
bool exist(const ASCString &s)
does a file s exist (wildcards allowed)
Definition: basestrm.cpp:2444
const T & min(const T &a, const T &b, const T &c)
Definition: misc.h:80
int yoffset
Definition: loadbi3.cpp:527
the different players in ASC. There may be 8 players (0..7) and neutral units (8) ...
Definition: player.h:99
virtual int readdata(void *buf, int size, bool excpt=true)
Reads data from the stream.
bool find(const ASCString &name)
int ypos
Definition: vehicle.h:124
void fatalError(const ASCString &string)
TerrainAccess terrainaccess
the terrain this unit can move to
Definition: vehicletype.h:221
LocalCoordinate entry
the position of the entrance, which is the field of the building where units can enter and leave ...
Definition: buildingtype.h:74
const int cwettertypennum
The number of different weather.
Definition: typen.h:61
int battleisleversion
Definition: loadbi3.cpp:55
void setMap(GameMap *gamemap_, int index_)
Definition: mapfield.h:37
virtual void preparemap(int x, int y)
Definition: loadbi3.cpp:729
void setDefaultBI3ImportTranslationTable(const ASCString &filename)
to prevent the appearnce of the dialog "choose import translation table" when running in batch mode...
Definition: loadbi3.cpp:1659
void writePointerContainer(const C &c, tnstream &stream)
Definition: basestrm.h:704
void importbattleislemap(const ASCString &path, const ASCString &mapfilename, TerrainType::Weather *trrn, const ASCString &importTable, ASCString *errorOutput, bool fakemap)
Imports a Battle Isle map.
Definition: loadbi3.cpp:1666
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182
int DataSize
Definition: loadbi3.cpp:64
int DataInRecOfs
Definition: loadbi3.cpp:63