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-2010 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 = 14;
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       stream.readChar( ); // was: researchid 
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       height = 1 << getFirstBit ( 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       if ( version >= 13 )
00369          for ( int w = 0; w < cwettertypennum; ++w )
00370             originalImageFilename[w] = stream.readString();
00371       
00372       if ( version >= 14 )
00373          description = stream.readString();
00374    } else
00375       throw tinvalidversion  ( stream.getLocation(), building_version, version );
00376 }
00377 
00378 void BuildingType :: write ( tnstream& stream ) const
00379 {
00380    stream.writeInt ( building_version );
00381 
00382    for ( int v = 0; v < cwettertypennum; v++ )
00383       for ( int w = 0; w < maxbuildingpicnum; w++ )
00384          for ( int x = 0; x < 4; x++ )
00385             for ( int y = 0; y < 6 ; y++ ) {
00386                 stream.writeInt ( w_picture[v][w][x][y].valid() );
00387             }
00388 
00389    for ( int v = 0; v < cwettertypennum; v++ )
00390       for ( int w = 0; w < maxbuildingpicnum; w++ )
00391          for ( int x = 0; x < 4; x++ )
00392             for ( int y = 0; y < 6 ; y++ )
00393                 stream.writeInt ( bi_picture[v][w][x][y] );
00394 
00395            /*     
00396    for ( int x = 0; x < 4; x++ )
00397       for ( int y = 0; y < 6 ; y++ )
00398          stream.writeInt( field_Exists[x][y] );
00399          */
00400                 
00401                 
00402    stream.writeInt ( entry.x );
00403    stream.writeInt ( entry.y );
00404    stream.writeInt ( -1 ); // was powerlineconnect.x
00405    stream.writeInt ( -1 ); // was powerlineconnect.y
00406    stream.writeInt ( -1 ); // was pipelineconnect.x
00407    stream.writeInt ( -1 ); // was pipelineconnect.y
00408 
00409    stream.writeInt ( id );
00410    stream.writeInt ( !name.empty() );
00411    stream.writeInt ( _armor );
00412    stream.writeInt ( jamming );
00413    stream.writeInt ( view );
00414    stream.writeInt ( 0 );
00415    stream.writeChar ( 0);
00416    stream.writeChar ( 0 );
00417    stream.writeInt ( productionCost.material );
00418    stream.writeInt ( productionCost.fuel );
00419    stream.writeChar ( technologylevel );
00420    stream.writeChar ( 0 );
00421 
00422    terrainaccess.write ( stream );
00423 
00424    stream.writeInt ( construction_steps );
00425    stream.writeInt ( maxresearchpoints );
00426    stream.writeInt ( asc_mode_tank.energy );
00427    stream.writeInt ( asc_mode_tank.material );
00428    stream.writeInt ( asc_mode_tank.fuel );
00429    
00430    stream.writeInt ( maxplus.energy );
00431    stream.writeInt ( maxplus.material );
00432    stream.writeInt ( maxplus.fuel );
00433    stream.writeInt ( efficiencyfuel );
00434    stream.writeInt ( efficiencymaterial );
00435    stream.writeInt ( 1 ); // guibuildicon
00436    stream.writeInt ( 1 );
00437 
00438    stream.writeInt ( bi_mode_tank.energy );
00439    stream.writeInt ( bi_mode_tank.material );
00440    stream.writeInt ( bi_mode_tank.fuel );
00441 
00442    stream.writeInt ( defaultProduction.energy );
00443    stream.writeInt ( defaultProduction.material );
00444    stream.writeInt ( defaultProduction.fuel );
00445 
00446    stream.writeInt ( height );
00447    stream.writeInt ( 0 );
00448    stream.writeInt ( externalloadheight );
00449 
00450    stream.writeInt ( 0 );
00451 
00452    if ( !name.empty() )
00453       stream.writeString ( name );
00454 
00455     for (int k = 0; k < maxbuildingpicnum; k++)
00456        for (int j = 0; j <= 5; j++)
00457           for (int i = 0; i <= 3; i++)
00458              for ( int w = 0; w < cwettertypennum; w++ )
00459                 if ( w_picture[w][k][i][j].valid() )
00460                    if ( bi_picture[w][k][i][j] == -1 )
00461                       w_picture[w][k][i][j].write(stream);
00462 
00463     ContainerBaseType::write ( stream );
00464 
00465     stream.writeInt( nominalresearchpoints );
00466 
00467     techDependency.write ( stream );
00468     stream.writeInt( defaultMaxResearchpoints );
00469 
00470     stream.writeString ( infotext );
00471     stream.writeInt( buildingNotRemovable );
00472     
00473     stream.writeInt( destructionObjects.size());
00474     for ( DestructionObjects::const_iterator i = destructionObjects.begin(); i != destructionObjects.end(); ++i) {
00475        stream.writeInt( i->first.x);
00476        stream.writeInt( i->first.y);
00477        stream.writeInt( i->second);
00478     }
00479     
00480     for ( int w = 0; w < cwettertypennum; ++w )
00481        stream.writeString( originalImageFilename[w] );
00482     
00483     stream.writeString( description );
00484 }
00485 
00486 
00487 ASCString BuildingType :: LocalCoordinate :: toString ( ) const
00488 {
00489   ASCString s;
00490   s += 'A'+x;
00491   s += '1'+y;
00492   return s;
00493 }
00494 
00495 class InvalidString : public ASCexception {};
00496 
00497 BuildingType :: LocalCoordinate :: LocalCoordinate ( const ASCString& s )
00498 {
00499   ASCString s2 = s;
00500   s2.toUpper();
00501   if ( s2.length() < 2 ) {
00502      x = -1;
00503      y = -1;
00504      throw InvalidString();
00505   } else {
00506      x = s2[0] - 'A';
00507      y = s2[1] - '1';
00508      if ( x < 0 || x > 5 || y < 0 || y > 7 )
00509         throw InvalidString();
00510   }
00511 }
00512 
00513 
00514 void BuildingType :: runTextIO ( PropertyContainer& pc )
00515 {
00516    try {
00517 
00518       pc.addBreakpoint();
00519    
00520       ContainerBaseType::runTextIO ( pc );
00521    
00522       pc.addInteger ( "ConstructionStages", construction_steps );
00523 
00524       for ( int i = 0; i < cwettertypennum; i++ )
00525          for ( int x = 0; x < 4; x++ )
00526             for ( int y = 0; y < 6; y++ )
00527                if ( w_picture[i][0][x][y].valid() )
00528                   weatherBits.set(i);
00529 
00530       pc.addTagArray( "Weather", weatherBits, cwettertypennum, weatherTags );
00531 
00532 
00533       ASCString fieldNames;
00534       for ( int a = 0; a < 4; a++ )
00535          for ( int b = 0; b < 6; b++ )
00536             if ( w_picture[0][0][a][b].valid() || bi_picture[0][0][a][b] > 0 ) {
00537                fieldNames += LocalCoordinate( a, b).toString();
00538                fieldNames += " ";
00539             }
00540 
00541       pc.addString( "Fields", fieldNames );
00542 
00543       typedef vector<LocalCoordinate> Fields;
00544       Fields fields;
00545       StringTokenizer st ( fieldNames );
00546       ASCString t = st.getNextToken();
00547       while ( !t.empty() ) {
00548          LocalCoordinate lc ( t );
00549          fields.push_back ( lc );
00550          t = st.getNextToken();
00551          field_Exists[lc.x][lc.y] = true;
00552       }
00553 
00554 
00555 
00556             
00557       bool bi3pics = false;
00558 
00559       for ( int i = 0; i < 4; i++ )
00560          for ( int j = 0; j < 6; j++ )
00561             if ( bi_picture[0][0][i][j] >= 0 )
00562                bi3pics = true;
00563 
00564       pc.addBool  ( "UseGFXpics", bi3pics );
00565 
00566       if ( bi3pics ) {
00567          pc.openBracket ( "GFXpictures");
00568          for ( int w = 0; w < cwettertypennum; w++ )
00569             if ( weatherBits.test(w) ) {
00570                pc.openBracket (weatherTags[w] );
00571 
00572                for ( int c = 0; c < construction_steps; c++ ) {
00573                   pc.openBracket ( ASCString("Stage")+strrr(c+1) );
00574 
00575                   for ( Fields::iterator i = fields.begin(); i != fields.end(); i++ ) 
00576                      pc.addInteger ( i->toString(), bi_picture[w][c][i->x][i->y] );
00577                   
00578 
00579                   pc.closeBracket();
00580                }
00581                pc.closeBracket();
00582                
00583             }
00584          pc.closeBracket();
00585       } else {
00586          pc.openBracket ( "Pictures");
00587          if ( !pc.isReading() ) {
00588             for ( int w = 0; w < cwettertypennum; w++ )
00589                if ( weatherBits.test(w) ) {
00590                   Surface s = Surface::createSurface( construction_steps*500, 250, 32, 0 );
00591                   for ( int c = 0; c < construction_steps; c++ )
00592                      for ( int x = 0; x < 4; x++ )
00593                         for ( int y = 0; y < 6; y++ )
00594                            if ( w_picture[w][c][x][y].valid() )
00595                               megaBlitter<ColorTransform_None,
00596                                           ColorMerger_AlphaOverwrite,
00597                                           SourcePixelSelector_Plain,
00598                                           TargetPixelSelector_All>
00599                                        ( w_picture[w][c][x][y], 
00600                                           s,
00601                                           SPoint( 500*c + x * fielddistx + (y&1)*fielddisthalfx, y * fielddisty), 
00602                                           nullParam, nullParam, nullParam, nullParam );
00603                   ASCString file = extractFileName_withoutSuffix ( filename )+weatherAbbrev[w]+".png";
00604                   pc.addImage ( weatherTags[w], s, file, false  );
00605                   pc.addString( ASCString(weatherTags[w]) + "_OriginalImageFilename", originalImageFilename[w] );
00606                }
00607          } else {
00608             for ( int w = 0; w < cwettertypennum; w++ )
00609                if ( weatherBits.test(w) ) {
00610                   ASCString fileName = extractFileName_withoutSuffix ( filename )+weatherAbbrev[w]+".png";
00611                   Surface s;
00612                   pc.addImage ( weatherTags[w], s, fileName, false );
00613                   originalImageFilename[w] = fileName;
00614 
00615 //                  if ( s.GetPixelFormat().BitsPerPixel() != 8 )
00616                      //fatalError("Building image " + filename + " does not have 8 Bit color depth!");
00617             
00618                   int depth = s.GetPixelFormat().BitsPerPixel();
00619                   for ( int c = 0; c < construction_steps; c++ )
00620                      for ( Fields::iterator i = fields.begin(); i != fields.end(); i++ ) {
00621                         Surface& img = w_picture[w][c][i->x][i->y];
00622                         img = Surface::createSurface(fieldsizex,fieldsizey,depth);
00623                         int xx = 500*c + i->x * fielddistx + (i->y&1)*fielddisthalfx;
00624                         int yy = i->y * fielddisty;
00625                         if ( depth == 8 ) {
00626                            img.Blit( s, SDLmm::SRect(SPoint(xx,yy),fieldsizex,fieldsizey), SPoint(0,0));
00627                            applyFieldMask(img);
00628                         } else {
00629                            MegaBlitter<4,4,ColorTransform_None,ColorMerger_PlainOverwrite,SourcePixelSelector_Rectangle> blitter;
00630                            blitter.setSrcRectangle( SDLmm::SRect(SPoint(xx,yy),fieldsizex,fieldsizey) );
00631                            blitter.blit( s, img, SPoint(0,0) );
00632                            applyFieldMask(img,0,0,false);
00633                         }
00634                      }
00635 
00636                }
00637 
00638          }
00639          pc.closeBracket();
00640       }
00641 
00642       bool rubble = destructionObjects.size() > 0;
00643       pc.addBool ( "RubbleObjects", rubble );
00644       if ( rubble ) {
00645          if ( pc.isReading() ) 
00646             destructionObjects.clear();
00647          
00648          pc.openBracket ( "Rubble");
00649          for ( Fields::iterator i = fields.begin(); i != fields.end(); i++ ) {
00650             vector<int> ids;
00651             typedef DestructionObjects::const_iterator J;
00652             pair<J,J> b = destructionObjects.equal_range(*i);
00653             for ( J j = b.first; j != b.second; ++j)
00654                ids.push_back(j->second);
00655             pc.addIntegerArray ( i->toString(), ids );
00656             
00657             if ( pc.isReading() ) {
00658                for ( vector<int>::iterator j = ids.begin(); j != ids.end(); ++j )
00659                   destructionObjects.insert(make_pair(*i, *j));
00660             }
00661          }
00662          pc.closeBracket();
00663       }
00664 
00665 
00666       ASCString entryString = entry.toString();
00667       pc.addString ( "Entry", entryString );
00668       if ( pc.isReading() ) {
00669          StringTokenizer st ( entryString );
00670          entry = LocalCoordinate ( st.getNextToken() );
00671       }
00672       if ( !fieldExists( entry ))
00673          pc.error( "Building " + name + " has invalid entrance position!" );
00674 
00675       pc.addInteger( "Armor", _armor );
00676 
00677       if ( pc.find( "Features" ) || !pc.isReading())
00678          pc.addTagArray ( "Features", features, functionNum, containerFunctionTags );
00679       else {
00680          int special = 0;
00681          pc.addTagInteger ( "Functions", special, cbuildingfunctionnum, buildingFunctionTags );
00682          convertOldFunctions( special, pc.getFileName() );
00683       } 
00684       pc.addInteger ( "Techlevel", technologylevel );
00685 
00686       pc.openBracket("TerrainAccess" );
00687        terrainaccess.runTextIO ( pc );
00688       pc.closeBracket();
00689 
00690 
00691       pc.openBracket ( "ConstructionCost" );
00692        productionCost.runTextIO ( pc );
00693       pc.closeBracket ();
00694 
00695       pc.addTagInteger( "Height", height, choehenstufennum, heightTags );
00696 
00697       pc.addTagInteger( "ExternalLoading", externalloadheight, choehenstufennum, heightTags );
00698 
00699       pc.addBool ( "NotRemovable", buildingNotRemovable, false );
00700 
00701       techDependency.runTextIO( pc, ASCString("b")+strrr(id) );
00702 
00703    }
00704    catch ( InvalidString ) {
00705       pc.error ( "Could not parse building field coordinate");
00706    }
00707 }
00708 
00709 void BuildingType::convertOldFunctions( int abilities, const ASCString& location  )
00710 {
00711    features.reset();
00712    if ( abilities & 1 ) warningMessage ( location + ": The HQ function for buildings is not supported any more");
00713    if ( abilities & 2 ) features.set( TrainingCenter );
00714    if ( abilities & (1 << 3) ) features.set( InternalVehicleProduction );
00715    if ( abilities & (1 << 4) ) features.set( AmmoProduction );
00716    if ( abilities & (1 << 8) ) features.set( InternalUnitRepair );
00717    if ( abilities & (1 << 9) ) features.set( RecycleUnits );
00718    if ( abilities & (1 << 10) ) features.set( Research );
00719    if ( abilities & (1 << 11) ) features.set( Sonar );
00720    if ( abilities & (1 << 12) ) features.set( WindPowerPlant );
00721    if ( abilities & (1 << 13) ) features.set( SolarPowerPlant );
00722    if ( abilities & (1 << 14) ) features.set( MatterConverter );
00723    if ( abilities & (1 << 15) ) features.set( MiningStation );
00724    if ( abilities & (1 << 16) ) {
00725       features.set( ExternalMaterialTransfer );
00726       features.set( ExternalFuelTransfer );
00727       features.set( ExternalAmmoTransfer );
00728    }
00729    if ( abilities & (1 << 17) ) features.set( ProduceNonLeavableUnits );
00730    if ( abilities & (1 << 18) ) features.set( ResourceSink );
00731    if ( abilities & (1 << 19) ) {
00732       features.set( ExternalMaterialTransfer );
00733       features.set( ExternalFuelTransfer );
00734    }
00735    if ( abilities & (1 << 20) ) features.set( ExternalAmmoTransfer );
00736    if ( abilities & (1 << 21) ) features.set( NoObjectChaining );
00737    if ( abilities & (1 << 22) ) features.set( SelfDestructOnConquer );
00738    if ( abilities & (1 << 23) ) features.set( SatelliteView );
00739 }
00740 

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