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

buildingtype.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           buildingtype.cpp  -  description
00003                              -------------------
00004     begin                : Fri Sep 29 2000
00005     copyright            : (C) 1994-2003 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00013 /***************************************************************************
00014  *                                                                         *
00015  *   This program is free software; you can redistribute it and/or modify  *
00016  *   it under the terms of the GNU General Public License as published by  *
00017  *   the Free Software Foundation; either version 2 of the License, or     *
00018  *   (at your option) any later version.                                   *
00019  *                                                                         *
00020  ***************************************************************************/
00021 
00022 #include <algorithm>
00023 
00024 #include "vehicletype.h"
00025 #include "buildingtype.h"
00026 #include "graphicset.h"
00027 #include "gameoptions.h"
00028 #include "textfiletags.h"
00029 #include "stringtokenizer.h"
00030 #include "textfile_evaluation.h"
00031 #include "graphics/surface.h"
00032 
00033 #include "errors.h"
00034 #include "sgstream.h"
00035 #include "graphics/blitter.h"
00036 #include "graphics/ColorTransform_PlayerColor.h"
00037 
00038 
00039 /*
00040 const char*  cbuildingfunctions[cbuildingfunctionnum+1]  =
00041               { "HQ",
00042                 "training",
00043                 "unused (was: refinery)",
00044                 "vehicle production",
00045                 "ammunition production",
00046                 "unused (was: energy prod)",
00047                 "unused (was: material prod)",
00048                 "unused (was: fuel prod)",
00049                 "repair facility",
00050                 "recycling",
00051                 "research",
00052                 "sonar",
00053                 "wind power plant",
00054                 "solar power plant",
00055                 "matter converter (was: power plant)",
00056                 "mining station",
00057                 "external resource transfer",
00058                 "construct units that cannot move out",
00059                 "resource sink",
00060                 "external resource transfer",
00061                 "external ammo transfer",
00062                 "no object chaining",
00063                 "self destruct on conquer",
00064                 "view satellites",
00065                 NULL };
00066 */
00067 
00068 BuildingType :: BuildingType ( void )
00069 {
00070    for ( int x = 0; x < 4; x++ )
00071       for ( int y = 0; y < 6; y++ ) {
00072          field_Exists[x][y] = false;
00073          for ( int w = 0; w < cwettertypennum; ++w )
00074             for ( int c = 0; c < maxbuildingpicnum; ++c )
00075                 bi_picture[w][c][x][y] = -1;
00076       }
00077 
00078    buildingNotRemovable = false;
00079    
00080    static const float matrix[] = { 1, 0, 0,
00081                                    0, 1, 0,
00082                                    0, 0, 1 };
00083    
00084    productionEfficiency = ResourceMatrix( matrix );
00085    
00086 }
00087 
00088 
00089 int BuildingType :: getMemoryFootprint() const
00090 {
00091    int size = sizeof(*this);
00092    
00093    for ( int i = 0; i < cwettertypennum; ++i )
00094       for ( int j = 0; j < maxbuildingpicnum; ++j )
00095          for ( int k = 0; k < 4; ++k )
00096             for ( int l = 0; l < 6; ++l )
00097                size += w_picture[i][j][k][l].getMemoryFootprint() - sizeof( Surface ); 
00098    return size;
00099 }
00100 
00101 
00102 int   BuildingType :: getBIPicture( const LocalCoordinate& localCoordinate, int weather , int constructionStep ) const
00103 {
00104    return bi_picture [weather][constructionStep][localCoordinate.x][localCoordinate.y];
00105 }
00106         
00107 
00108 const Surface&   BuildingType :: getPicture ( const LocalCoordinate& localCoordinate, int weather, int constructionStep ) const
00109 {
00110    if( constructionStep >= construction_steps )
00111      constructionStep = construction_steps-1;
00112      
00113    if ( !weatherBits.test(weather))
00114       weather = 0;
00115      
00116    if ( bi_picture [weather][constructionStep][localCoordinate.x][localCoordinate.y] <= 0 ) 
00117       return w_picture[weather][constructionStep][localCoordinate.x][localCoordinate.y];
00118    else 
00119       return GraphicSetManager::Instance().getPic(bi_picture [weather][constructionStep][localCoordinate.x][localCoordinate.y]);
00120    
00121 }
00122 
00123 void  BuildingType::paint ( Surface& s, SPoint pos, const PlayerColor& player, int weather, int constructionStep ) const
00124 {
00125    for ( int x = 0; x < 4; x++ )
00126       for ( int y = 0; y < 6; y++ ) 
00127          if ( fieldExists(LocalCoordinate(x,y) ))
00128             paintSingleField(s,pos,LocalCoordinate(x,y),player,weather,constructionStep);
00129      
00130 }
00131 
00132 void  BuildingType::paint ( Surface& s, SPoint pos  ) const
00133 {
00134    for ( int x = 0; x < 4; x++ )
00135       for ( int y = 0; y < 6; y++ ) 
00136          if ( fieldExists(LocalCoordinate(x,y) ))
00137             paintSingleField(s,pos,LocalCoordinate(x,y));
00138      
00139 }
00140 
00141 
00142 void  BuildingType:: paintSingleField ( Surface& s, SPoint pos, const LocalCoordinate& localCoordinate, const PlayerColor& player, int weather, int constructionStep ) const
00143 {
00144    megaBlitter<ColorTransform_PlayerCol,
00145                ColorMerger_AlphaOverwrite,
00146                SourcePixelSelector_Plain,
00147                TargetPixelSelector_All>
00148             ( getPicture(localCoordinate,weather,constructionStep), 
00149                s, 
00150                SPoint( pos.x + localCoordinate.x * fielddistx + ( localCoordinate.y & 1 ) * fielddisthalfx, pos.y + localCoordinate.y * fielddisty), 
00151                player, 
00152                nullParam, nullParam, nullParam );
00153    
00154    // s.Blit( getPicture(localCoordinate,weather,constructionStep),SPoint( pos.x + localCoordinate.x * fielddistx + ( localCoordinate.y & 1 ) * fielddisthalfx, pos.y + localCoordinate.y * fielddisty));
00155 }
00156 
00157 void  BuildingType:: paintSingleField ( Surface& s, SPoint pos, const LocalCoordinate& localCoordinate, int weather, int constructionStep ) const
00158 {
00159    megaBlitter<ColorTransform_None,
00160                ColorMerger_AlphaOverwrite,
00161                SourcePixelSelector_Plain,
00162                TargetPixelSelector_All>
00163             ( getPicture(localCoordinate,weather,constructionStep), 
00164                s, 
00165                SPoint( pos.x + localCoordinate.x * fielddistx + ( localCoordinate.y & 1 ) * fielddisthalfx, pos.y + localCoordinate.y * fielddisty), 
00166                nullParam, nullParam, nullParam, nullParam );
00167    
00168    // s.Blit( getPicture(localCoordinate,weather,constructionStep),SPoint( pos.x + localCoordinate.x * fielddistx + ( localCoordinate.y & 1 ) * fielddisthalfx, pos.y + localCoordinate.y * fielddisty));
00169 }
00170 
00171 
00172 
00173 MapCoordinate  BuildingType :: getFieldCoordinate ( const MapCoordinate& entryOnMap, const LocalCoordinate& localCoordinates ) const
00174 {
00175    int orgx = entryOnMap.x - entry.x - (entry.y & ~entryOnMap.y & 1 );
00176    int orgy = entryOnMap.y - entry.y;
00177 
00178    int dx = orgy & 1;
00179 
00180    int yy = orgy + localCoordinates.y;
00181    int xx = orgx + localCoordinates.x + (dx & ~yy);
00182    MapCoordinate mc ( xx, yy );
00183    return mc;
00184 }
00185 
00186 BuildingType::LocalCoordinate BuildingType::getLocalCoordinate( const MapCoordinate& entryOnMap, const MapCoordinate& field ) const
00187 {
00188    int homex = entryOnMap.x - entry.x;
00189    int homey = entryOnMap.y - entry.y;
00190 
00191    if ( (entry.y & 1) && !(entryOnMap.y & 1))
00192       homex -= 1;
00193       
00194 
00195    int ly = field.y - homey;
00196    int lx = field.x - homex;
00197    if ( (ly & 1) && (homey & 1 ))
00198       lx -= 1;
00199    
00200    if ( lx >= 0 && lx < 4 && ly >= 0 && ly < 6 && fieldExists(LocalCoordinate(lx,ly)))
00201       return LocalCoordinate(lx,ly);
00202    else
00203       return LocalCoordinate();  
00204 }
00205 
00206 
00207 
00208 const int building_version = 12;
00209 
00210 
00211 void BuildingType :: read ( tnstream& stream )
00212 {
00213    int version = stream.readInt();
00214    if ( version <= building_version && version >= 1) {
00215 
00216       bool picsAvail[ cwettertypennum ][ maxbuildingpicnum ][4][6];
00217    
00218       for ( int v = 0; v < cwettertypennum; v++ )
00219          for ( int w = 0; w < maxbuildingpicnum; w++ )
00220             for ( int x = 0; x < 4; x++ )
00221                for ( int y = 0; y < 6 ; y++ ) {
00222                    picsAvail[v][w][x][y] = stream.readInt( );
00223                    if ( picsAvail[v][w][x][y] ) {
00224                       field_Exists[x][y] = true;
00225                       weatherBits.set(v);
00226                    }   
00227                }    
00228                    
00229 
00230       for ( int v = 0; v < cwettertypennum; v++ )
00231          for ( int w = 0; w < maxbuildingpicnum; w++ )
00232             for ( int x = 0; x < 4; x++ )
00233                for ( int y = 0; y < 6 ; y++ ) {
00234                    int i = stream.readInt( );
00235                    bi_picture[v][w][x][y] = i;
00236                    if ( i > 0 ) {
00237                       field_Exists[x][y] = true;
00238                       weatherBits.set(v);
00239                    }   
00240                }  
00241 
00242                    /*
00243       if ( version >= 9 ) 
00244          for ( int x = 0; x < 4; x++ )
00245             for ( int y = 0; y < 6 ; y++ )
00246                field_Exists[x][y] = stream.readInt( );
00247          */
00248   
00249      //@todo foobar
00250      
00251       
00252                    
00253       entry.x = stream.readInt( );
00254       entry.y = stream.readInt( );
00255 
00256       stream.readInt( ); // was: powerlineconnect.x
00257       stream.readInt( ); // was: powerlineconnect.y
00258       stream.readInt( ); // was: pipelineconnect.x
00259       stream.readInt( ); // was: pipelineconnect.y
00260 
00261       id = stream.readInt( );
00262       bool __loadName = stream.readInt( );
00263       _armor = stream.readInt( );
00264       jamming = stream.readInt( );
00265       view = stream.readInt( );
00266       stream.readInt( ); // was: loadcapacity
00267       stream.readChar( ); // was: loadcapability =
00268       stream.readChar( ); // was: unitheightreq =
00269       productionCost.material = stream.readInt( );
00270       productionCost.fuel = stream.readInt( );
00271       if ( version <= 9 ) {
00272          int special = stream.readInt( );
00273          convertOldFunctions( special, stream.getLocation() );
00274       }
00275 
00276       technologylevel = stream.readChar( );
00277       researchid = stream.readChar( );
00278 
00279       terrainaccess.read ( stream );
00280 
00281       construction_steps = stream.readInt( );
00282       maxresearchpoints = stream.readInt( );
00283       asc_mode_tank.energy = stream.readInt( );
00284       asc_mode_tank.material = stream.readInt( );
00285       asc_mode_tank.fuel = stream.readInt( );
00286       maxplus.energy = stream.readInt( );
00287       maxplus.material = stream.readInt( );
00288       maxplus.fuel = stream.readInt( );
00289       efficiencyfuel = stream.readInt( );
00290       efficiencymaterial = stream.readInt( );
00291       stream.readInt( ); // guibuildicon
00292       stream.readInt( ); // terrain_access = (TerrainAccess*)
00293  
00294       bi_mode_tank.energy = stream.readInt( );
00295       bi_mode_tank.material = stream.readInt( );
00296       bi_mode_tank.fuel = stream.readInt( );
00297 
00298       if ( version >= 5 ) {
00299          defaultProduction.energy = stream.readInt( );
00300          defaultProduction.material = stream.readInt( );
00301          defaultProduction.fuel = stream.readInt( );
00302       }
00303 
00304 
00305       buildingheight = 1 << log2 ( stream.readInt() );
00306       stream.readInt( ); // was: unitheight_forbidden =
00307       externalloadheight = stream.readInt( );
00308 
00309       if ( version >= 3)
00310          stream.readInt(); // was: vehicleCategoriesLoadable =
00311 
00312 
00313       if ( version >= 2 ) {
00314          if ( version <= 11 ) {
00315             for ( int x = 0; x < 4; x++ )
00316                for ( int y = 0; y < 6; y++ ) {
00317                   int id = stream.readInt();
00318                   if ( id > 0 )
00319                      destructionObjects.insert( make_pair(LocalCoordinate(x,y), id));
00320                }
00321          }
00322       } else {
00323          for ( int w = 0; w < 9; w++ )
00324              stream.readInt( ); 
00325          destructionObjects.clear();
00326       }
00327 
00328       if ( __loadName )
00329          name = stream.readString();
00330 
00331       for ( int k = 0; k < maxbuildingpicnum ; k++)
00332          for ( int j = 0; j <= 5; j++)
00333             for ( int i = 0; i <= 3; i++)
00334                for ( int w = 0; w < cwettertypennum; w++ )
00335                  if ( picsAvail[w][k][i][j] ) 
00336                     if ( bi_picture[w][k][i][j] == -1 ) 
00337                        w_picture[w][k][i][j].read(stream );
00338                  
00339 
00340 
00341       if ( version >= 4 )
00342          ContainerBaseType::read ( stream );
00343 
00344       if ( version >= 6 )
00345          nominalresearchpoints = stream.readInt();
00346 
00347       if ( version >= 7 ) {
00348          techDependency.read( stream );
00349          defaultMaxResearchpoints = stream.readInt();
00350       }
00351 
00352       if ( version >= 8 )
00353          infotext = stream.readString();
00354 
00355       if ( version >= 11 )
00356          buildingNotRemovable = stream.readInt();
00357       
00358       if ( version >= 12 ) {
00359          int num = stream.readInt();
00360          for ( int i = 0; i < num; ++i ) {
00361             int x = stream.readInt();
00362             int y = stream.readInt();
00363             int id = stream.readInt();
00364             destructionObjects.insert( make_pair( LocalCoordinate(x,y),id));
00365          }
00366       }
00367       
00368    } else
00369       throw tinvalidversion  ( stream.getLocation(), building_version, version );
00370 }
00371 
00372 void BuildingType :: write ( tnstream& stream ) const
00373 {
00374    stream.writeInt ( building_version );
00375 
00376    for ( int v = 0; v < cwettertypennum; v++ )
00377       for ( int w = 0; w < maxbuildingpicnum; w++ )
00378          for ( int x = 0; x < 4; x++ )
00379             for ( int y = 0; y < 6 ; y++ ) {
00380                 stream.writeInt ( w_picture[v][w][x][y].valid() );
00381             }
00382 
00383    for ( int v = 0; v < cwettertypennum; v++ )
00384       for ( int w = 0; w < maxbuildingpicnum; w++ )
00385          for ( int x = 0; x < 4; x++ )
00386             for ( int y = 0; y < 6 ; y++ )
00387                 stream.writeInt ( bi_picture[v][w][x][y] );
00388 
00389            /*     
00390    for ( int x = 0; x < 4; x++ )
00391       for ( int y = 0; y < 6 ; y++ )
00392          stream.writeInt( field_Exists[x][y] );
00393          */
00394                 
00395                 
00396    stream.writeInt ( entry.x );
00397    stream.writeInt ( entry.y );
00398    stream.writeInt ( -1 ); // was powerlineconnect.x
00399    stream.writeInt ( -1 ); // was powerlineconnect.y
00400    stream.writeInt ( -1 ); // was pipelineconnect.x
00401    stream.writeInt ( -1 ); // was pipelineconnect.y
00402 
00403    stream.writeInt ( id );
00404    stream.writeInt ( !name.empty() );
00405    stream.writeInt ( _armor );
00406    stream.writeInt ( jamming );
00407    stream.writeInt ( view );
00408    stream.writeInt ( 0 );
00409    stream.writeChar ( 0);
00410    stream.writeChar ( 0 );
00411    stream.writeInt ( productionCost.material );
00412    stream.writeInt ( productionCost.fuel );
00413    stream.writeChar ( technologylevel );
00414    stream.writeChar ( researchid );
00415 
00416    terrainaccess.write ( stream );
00417 
00418    stream.writeInt ( construction_steps );
00419    stream.writeInt ( maxresearchpoints );
00420    stream.writeInt ( asc_mode_tank.energy );
00421    stream.writeInt ( asc_mode_tank.material );
00422    stream.writeInt ( asc_mode_tank.fuel );
00423    
00424    stream.writeInt ( maxplus.energy );
00425    stream.writeInt ( maxplus.material );
00426    stream.writeInt ( maxplus.fuel );
00427    stream.writeInt ( efficiencyfuel );
00428    stream.writeInt ( efficiencymaterial );
00429    stream.writeInt ( 1 ); // guibuildicon
00430    stream.writeInt ( 1 );
00431 
00432    stream.writeInt ( bi_mode_tank.energy );
00433    stream.writeInt ( bi_mode_tank.material );
00434    stream.writeInt ( bi_mode_tank.fuel );
00435 
00436    stream.writeInt ( defaultProduction.energy );
00437    stream.writeInt ( defaultProduction.material );
00438    stream.writeInt ( defaultProduction.fuel );
00439 
00440    stream.writeInt ( buildingheight );
00441    stream.writeInt ( 0 );
00442    stream.writeInt ( externalloadheight );
00443 
00444    stream.writeInt ( 0 );
00445 
00446    if ( !name.empty() )
00447       stream.writeString ( name );
00448 
00449     for (int k = 0; k < maxbuildingpicnum; k++)
00450        for (int j = 0; j <= 5; j++)
00451           for (int i = 0; i <= 3; i++)
00452              for ( int w = 0; w < cwettertypennum; w++ )
00453                 if ( w_picture[w][k][i][j].valid() )
00454                    if ( bi_picture[w][k][i][j] == -1 )
00455                       w_picture[w][k][i][j].write(stream);
00456 
00457     ContainerBaseType::write ( stream );
00458 
00459     stream.writeInt( nominalresearchpoints );
00460 
00461     techDependency.write ( stream );
00462     stream.writeInt( defaultMaxResearchpoints );
00463 
00464     stream.writeString ( infotext );
00465     stream.writeInt( buildingNotRemovable );
00466     
00467     stream.writeInt( destructionObjects.size());
00468     for ( DestructionObjects::const_iterator i = destructionObjects.begin(); i != destructionObjects.end(); ++i) {
00469        stream.writeInt( i->first.x);
00470        stream.writeInt( i->first.y);
00471        stream.writeInt( i->second);
00472     }
00473     
00474 }
00475 
00476 
00477 ASCString BuildingType :: LocalCoordinate :: toString ( ) const
00478 {
00479   ASCString s;
00480   s += 'A'+x;
00481   s += '1'+y;
00482   return s;
00483 }
00484 
00485 class InvalidString : public ASCexception {};
00486 
00487 BuildingType :: LocalCoordinate :: LocalCoordinate ( const ASCString& s )
00488 {
00489   ASCString s2 = s;
00490   s2.toUpper();
00491   if ( s2.length() < 2 ) {
00492      x = -1;
00493      y = -1;
00494      throw InvalidString();
00495   } else {
00496      x = s2[0] - 'A';
00497      y = s2[1] - '1';
00498      if ( x < 0 || x > 5 || y < 0 || y > 7 )
00499         throw InvalidString();
00500   }
00501 }
00502 
00503 
00504 void BuildingType :: runTextIO ( PropertyContainer& pc )
00505 {
00506    try {
00507 
00508       pc.addBreakpoint();
00509    
00510       ContainerBaseType::runTextIO ( pc );
00511    
00512       pc.addInteger ( "ConstructionStages", construction_steps );
00513 
00514       for ( int i = 0; i < cwettertypennum; i++ )
00515          for ( int x = 0; x < 4; x++ )
00516             for ( int y = 0; y < 6; y++ )
00517                if ( w_picture[i][0][x][y].valid() )
00518                   weatherBits.set(i);
00519 
00520       pc.addTagArray( "Weather", weatherBits, cwettertypennum, weatherTags );
00521 
00522 
00523       ASCString fieldNames;
00524       for ( int a = 0; a < 4; a++ )
00525          for ( int b = 0; b < 6; b++ )
00526             if ( w_picture[0][0][a][b].valid() ) {
00527                fieldNames += LocalCoordinate( a, b).toString();
00528                fieldNames += " ";
00529             }
00530 
00531       pc.addString( "Fields", fieldNames );
00532 
00533       typedef vector<LocalCoordinate> Fields;
00534       Fields fields;
00535       StringTokenizer st ( fieldNames );
00536       ASCString t = st.getNextToken();
00537       while ( !t.empty() ) {
00538          LocalCoordinate lc ( t );
00539          fields.push_back ( lc );
00540          t = st.getNextToken();
00541          field_Exists[lc.x][lc.y] = true;
00542       }
00543 
00544 
00545 
00546             
00547       bool bi3pics = false;
00548 
00549       for ( int i = 0; i < 4; i++ )
00550          for ( int j = 0; j < 6; j++ )
00551             if ( bi_picture[0][0][i][j] >= 0 )
00552                bi3pics = true;
00553 
00554       pc.addBool  ( "UseGFXpics", bi3pics );
00555 
00556       if ( bi3pics ) {
00557          pc.openBracket ( "GFXpictures");
00558          for ( int w = 0; w < cwettertypennum; w++ )
00559             if ( weatherBits.test(w) ) {
00560                pc.openBracket (weatherTags[w] );
00561 
00562                for ( int c = 0; c < construction_steps; c++ ) {
00563                   pc.openBracket ( ASCString("Stage")+strrr(c+1) );
00564 
00565                   for ( Fields::iterator i = fields.begin(); i != fields.end(); i++ ) 
00566                      pc.addInteger ( i->toString(), bi_picture[w][c][i->x][i->y] );
00567                   
00568 
00569                   pc.closeBracket();
00570                }
00571                pc.closeBracket();
00572                
00573             }
00574          pc.closeBracket();
00575       } else {
00576          pc.openBracket ( "Pictures");
00577          if ( !pc.isReading() ) {
00578             for ( int w = 0; w < cwettertypennum; w++ )
00579                if ( weatherBits.test(w) ) {
00580                   Surface s = Surface::createSurface( construction_steps*500, 250, 32, 0 );
00581                   for ( int c = 0; c < construction_steps; c++ )
00582                      for ( int x = 0; x < 4; x++ )
00583                         for ( int y = 0; y < 6; y++ )
00584                            if ( w_picture[w][c][x][y].valid() )
00585                               megaBlitter<ColorTransform_None,
00586                                           ColorMerger_AlphaOverwrite,
00587                                           SourcePixelSelector_Plain,
00588                                           TargetPixelSelector_All>
00589                                        ( w_picture[w][c][x][y], 
00590                                           s,
00591                                           SPoint( 500*c + x * fielddistx + (y&1)*fielddisthalfx, y * fielddisty), 
00592                                           nullParam, nullParam, nullParam, nullParam );
00593                   pc.addImage ( weatherTags[w], s, extractFileName_withoutSuffix ( filename )+weatherAbbrev[w]+".png", false  );
00594                }
00595          } else {
00596             for ( int w = 0; w < cwettertypennum; w++ )
00597                if ( weatherBits.test(w) ) {
00598                   ASCString fileName = extractFileName_withoutSuffix ( filename )+weatherAbbrev[w]+".png";
00599                   Surface s;
00600                   pc.addImage ( weatherTags[w], s, fileName, false );
00601 
00602 //                  if ( s.GetPixelFormat().BitsPerPixel() != 8 )
00603                      //fatalError("Building image " + filename + " does not have 8 Bit color depth!");
00604             
00605                   int depth = s.GetPixelFormat().BitsPerPixel();
00606                   for ( int c = 0; c < construction_steps; c++ )
00607                      for ( Fields::iterator i = fields.begin(); i != fields.end(); i++ ) {
00608                         Surface& img = w_picture[w][c][i->x][i->y];
00609                         img = Surface::createSurface(fieldsizex,fieldsizey,depth);
00610                         int xx = 500*c + i->x * fielddistx + (i->y&1)*fielddisthalfx;
00611                         int yy = i->y * fielddisty;
00612                         if ( depth == 8 ) {
00613                            img.Blit( s, SDLmm::SRect(SPoint(xx,yy),fieldsizex,fieldsizey), SPoint(0,0));
00614                            applyFieldMask(img);
00615                         } else {
00616                            MegaBlitter<4,4,ColorTransform_None,ColorMerger_PlainOverwrite,SourcePixelSelector_Rectangle> blitter;
00617                            blitter.setSrcRectangle( SDLmm::SRect(SPoint(xx,yy),fieldsizex,fieldsizey) );
00618                            blitter.blit( s, img, SPoint(0,0) );
00619                            applyFieldMask(img,0,0,false);
00620                         }
00621                      }
00622 
00623                }
00624 
00625          }
00626          pc.closeBracket();
00627       }
00628 
00629       bool rubble = destructionObjects.size() > 0;
00630       pc.addBool ( "RubbleObjects", rubble );
00631       if ( rubble ) {
00632          if ( pc.isReading() ) 
00633             destructionObjects.clear();
00634          
00635          pc.openBracket ( "Rubble");
00636          for ( Fields::iterator i = fields.begin(); i != fields.end(); i++ ) {
00637             vector<int> ids;
00638             typedef DestructionObjects::const_iterator J;
00639             pair<J,J> b = destructionObjects.equal_range(*i);
00640             for ( J j = b.first; j != b.second; ++j)
00641                ids.push_back(j->second);
00642             pc.addIntegerArray ( i->toString(), ids );
00643             
00644             if ( pc.isReading() ) {
00645                for ( vector<int>::iterator j = ids.begin(); j != ids.end(); ++j )
00646                   destructionObjects.insert(make_pair(*i, *j));
00647             }
00648          }
00649          pc.closeBracket();
00650       }
00651 
00652 
00653       ASCString entryString = entry.toString();
00654       pc.addString ( "Entry", entryString );
00655       if ( pc.isReading() ) {
00656          StringTokenizer st ( entryString );
00657          entry = LocalCoordinate ( st.getNextToken() );
00658       }
00659 
00660       pc.addInteger( "Armor", _armor );
00661 
00662       if ( pc.find( "Features" ) || !pc.isReading())
00663          pc.addTagArray ( "Features", features, functionNum, containerFunctionTags );
00664       else {
00665          int special = 0;
00666          pc.addTagInteger ( "Functions", special, cbuildingfunctionnum, buildingFunctionTags );
00667          convertOldFunctions( special, pc.getFileName() );
00668       } 
00669       pc.addInteger ( "Techlevel", technologylevel );
00670 
00671       pc.openBracket("TerrainAccess" );
00672        terrainaccess.runTextIO ( pc );
00673       pc.closeBracket();
00674 
00675 
00676       pc.openBracket ( "ConstructionCost" );
00677        productionCost.runTextIO ( pc );
00678       pc.closeBracket ();
00679 
00680       pc.addTagInteger( "Height", buildingheight, choehenstufennum, heightTags );
00681 
00682       pc.addTagInteger( "ExternalLoading", externalloadheight, choehenstufennum, heightTags );
00683 
00684       pc.addBool ( "NotRemovable", buildingNotRemovable, false );
00685 
00686       techDependency.runTextIO( pc, ASCString("b")+strrr(id) );
00687 
00688    }
00689    catch ( InvalidString ) {
00690       pc.error ( "Could not parse building field coordinate");
00691    }
00692 }
00693 
00694 void BuildingType::convertOldFunctions( int abilities, const ASCString& location  )
00695 {
00696    features.reset();
00697    if ( abilities & 1 ) warning ( location + ": The HQ function for buildings is not supported any more");
00698    if ( abilities & 2 ) features.set( TrainingCenter );
00699    if ( abilities & (1 << 3) ) features.set( InternalVehicleProduction );
00700    if ( abilities & (1 << 4) ) features.set( AmmoProduction );
00701    if ( abilities & (1 << 8) ) features.set( InternalUnitRepair );
00702    if ( abilities & (1 << 9) ) features.set( RecycleUnits );
00703    if ( abilities & (1 << 10) ) features.set( Research );
00704    if ( abilities & (1 << 11) ) features.set( Sonar );
00705    if ( abilities & (1 << 12) ) features.set( WindPowerPlant );
00706    if ( abilities & (1 << 13) ) features.set( SolarPowerPlant );
00707    if ( abilities & (1 << 14) ) features.set( MatterConverter );
00708    if ( abilities & (1 << 15) ) features.set( MiningStation );
00709    if ( abilities & (1 << 16) ) {
00710       features.set( ExternalMaterialTransfer );
00711       features.set( ExternalFuelTransfer );
00712       features.set( ExternalAmmoTransfer );
00713    }
00714    if ( abilities & (1 << 17) ) features.set( ProduceNonLeavableUnits );
00715    if ( abilities & (1 << 18) ) features.set( ResourceSink );
00716    if ( abilities & (1 << 19) ) {
00717       features.set( ExternalMaterialTransfer );
00718       features.set( ExternalFuelTransfer );
00719    }
00720    if ( abilities & (1 << 20) ) features.set( ExternalAmmoTransfer );
00721    if ( abilities & (1 << 21) ) features.set( NoObjectChaining );
00722    if ( abilities & (1 << 22) ) features.set( SelfDestructOnConquer );
00723    if ( abilities & (1 << 23) ) features.set( SatelliteView );
00724 }
00725 

Generated on Tue Jun 24 01:27:36 2008 for Advanced Strategic Command by  doxygen 1.4.2