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

terraintype.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           terraintype.cpp  -  description
00003                              -------------------
00004     begin                : Fri Jul 27 2001
00005     copyright            : (C) 2001 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 // #include "basegfx.h"
00019 #include "terraintype.h"
00020 #include "gameoptions.h"
00021 #include "graphicset.h"
00022 #include "sgstream.h"
00023 #include "textfileparser.h"
00024 #include "textfiletags.h"
00025 #include "textfile_evaluation.h"
00026 #include "overviewmapimage.h"
00027 #include "graphics/blitter.h"
00028 #include "fieldimageloader.h"
00029 
00030 const char*  terrainProperty[terrainPropertyNum+1]  = {"shallow water"       ,  // 0
00031                                              "normal lowland",
00032                                              "swamp",
00033                                              "forest",
00034                                              "high mountains",                  // 4
00035                                              "road",
00036                                              "railroad",
00037                                              "entry of building (not to be used for terrain)" ,
00038                                              "harbour",
00039                                              "runway"  ,
00040                                              "pipeline",                        // 10
00041                                              "buried pipeline",
00042                                              "water",
00043                                              "deep water",
00044                                              "hard sand",
00045                                              "soft sand",
00046                                              "track possible",
00047                                              "small rocks",
00048                                              "mud",
00049                                              "snow",
00050                                              "deep snow",
00051                                              "mountains",
00052                                              "very shallow water",
00053                                              "large rocks",
00054                                              "lava",
00055                                              "ditch",
00056                                              "hillside",
00057                                              "turret foundation",
00058                                              "morass",
00059                                              "Installation",
00060                                              "pack ice",
00061                                              "river",
00062                                              "frozen water",
00063                                              "bridge",
00064                                              "lava barrier",
00065                                              "spaceport",
00066                                              "beacon",
00067                                              "fire",
00068                                              NULL };
00069 
00070 
00071 
00072 
00073 void TerrainAccess::read ( tnstream& stream ) {
00074    terrain.read ( stream );
00075    terrain.reset( 7 );
00076    terrainreq.read ( stream );
00077    terrainnot.read ( stream );
00078    terrainnot.reset( 7 );
00079    terrainkill.read ( stream );
00080 
00081    for ( int a = 0; a < 10; a++ )
00082        stream.readInt( ); //dummy
00083 };
00084 
00085 void TerrainAccess::write ( tnstream& stream ) const {
00086    terrain.write ( stream );
00087    terrainreq.write ( stream );
00088    terrainnot.write ( stream );
00089    terrainkill.write ( stream );
00090 
00091    for ( int a = 0; a < 10; a++ )
00092        stream.writeInt( 0 ); //dummy
00093 };
00094 
00095 void TerrainAccess::runTextIO ( PropertyContainer& pc )
00096 {
00097    pc.addTagArray ( "terrain_any", terrain, terrainPropertyNum, terrainProperties );
00098    pc.addTagArray ( "terrain_all", terrainreq, terrainPropertyNum, terrainProperties );
00099    pc.addTagArray ( "terrain_not", terrainnot, terrainPropertyNum, terrainProperties );
00100    pc.addTagArray ( "terrain_kill", terrainkill, terrainPropertyNum, terrainProperties );
00101 }
00102 
00103 TerrainType::MoveMalus::MoveMalus()
00104 {
00105    resize( cmovemalitypenum);
00106    for ( int i = 0; i <  cmovemalitypenum; i++ )
00107       at(i) = 100;
00108 }
00109 
00110 TerrainType::TerrainType()
00111 {
00112    id = -1;
00113    for ( int i = 0; i < cwettertypennum; i++ )
00114       weather[i] = NULL;
00115 
00116 }
00117 
00118 
00119 void      TerrainType::Weather::paint ( Surface& s, SPoint pos )
00120 {
00121    Surface* img;
00122    if ( bi_pict == -1 )
00123       img = &image;
00124    else 
00125       img = &GraphicSetManager::Instance().getPic( bi_pict);
00126 
00127    megaBlitter<ColorTransform_None, 
00128                ColorMerger_AlphaOverwrite, 
00129                SourcePixelSelector_Plain,
00130                TargetPixelSelector_All>
00131             (*img,s,pos,nullParam,nullParam,nullParam,nullParam);
00132 }
00133 
00134 
00135 const OverviewMapImage* TerrainType::Weather::getQuickView()
00136 {
00137    if  ( bi_pict >= 0 ) {
00138       return GraphicSetManager::Instance().getQuickView( bi_pict );
00139    } else {
00140       if (!quickView ) {
00141          quickView = new OverviewMapImage( image );
00142       }
00143       return quickView;
00144    }
00145 }
00146 
00147 TerrainType::Weather::~Weather()
00148 { 
00149    delete quickView; 
00150 }
00151 
00152 
00153 const int terrain_version = 4;
00154 
00155 
00156 void TerrainType::MoveMalus::read( tnstream& stream, int defaultValue, int moveMalusCount )
00157 {
00158    clear();
00159 
00160    int version;
00161    if ( moveMalusCount <= 0 ) {
00162       version = stream.readInt();
00163       moveMalusCount = stream.readInt();
00164    } else
00165       version = 0;
00166 
00167    #ifndef converter
00168     int mmcount = moveMalusCount;
00169     if (mmcount < moveMalusCount )
00170        mmcount = moveMalusCount;
00171    #else
00172     int mmcount = moveMalusCount ;
00173    #endif
00174 
00175    for ( int j=0; j< mmcount ; j++ ) {
00176       if (j < moveMalusCount ) {
00177          int i;
00178          if ( version < 2 )
00179             i = stream.readChar();
00180          else
00181             i = stream.readInt();
00182          push_back ( i );
00183       } else
00184          if ( j == 0 )
00185             push_back ( defaultValue );
00186          else
00187             push_back ( at(0) );
00188    }
00189 }
00190 
00191 void TerrainType::MoveMalus::write ( tnstream& stream ) const
00192 {
00193   stream.writeInt(2);
00194   stream.writeInt( size() );
00195   for ( int m = 0; m < size(); m++ )
00196      stream.writeInt ( at(m) );
00197 }
00198 
00199 void TerrainType::Weather::read ( tnstream& stream )
00200 {
00201    read( stream, terrain_version );
00202 }
00203 
00204 
00205 void TerrainType::Weather::read ( tnstream& stream, int version )
00206 {
00207    bool loadImage = true;
00208    if (version <=2 ) {
00209       loadImage = stream.readInt();
00210 
00211       for ( int j = 1; j < 8; j++ )
00212          stream.readInt(); // pgbt->picture[j]
00213 
00214       for ( int j = 0; j < 8; j++ )
00215          stream.readInt(); // pgbt->direcpict[j] = (void*)
00216    }
00217 
00218    if ( version == 1 ) {
00219       stream.readInt(); //dummy1
00220       defensebonus = stream.readWord();
00221       attackbonus = stream.readWord();
00222       basicjamming = stream.readChar();
00223    } else {
00224       defensebonus = stream.readInt();
00225       attackbonus = stream.readInt();
00226       basicjamming = stream.readInt();
00227    }
00228    int move_maluscount = stream.readChar();
00229    stream.readInt(); // pgbt->movemalus = (char*)
00230    stream.readInt(); // pgbt->terraintype
00231    stream.readInt(); // bool readQuickView
00232 
00233    art.read ( stream );
00234 
00235    bi_pict = stream.readInt();
00236    for ( int j = 1; j < 6; j++ )
00237       stream.readInt(); //pgbt->bi_picture[j] =
00238 
00239    move_malus.read( stream, minmalq, move_maluscount );
00240 
00241 /*
00242    for ( j=0; j<8 ;j++ )
00243       if ( pgbt->picture[j] )
00244          if ( pgbt->bi_picture[j] == -1 ) {
00245             pgbt->picture[j] = asc_malloc ( fieldsize );
00246             stream.readdata ( pgbt->picture[j], fieldsize );
00247             } else
00248                loadbi3pict_double ( pgbt->bi_picture[j],
00249                                     &pgbt->picture[j],
00250                                     CGameOptions::Instance()->bi3.interpolate.terrain );
00251 
00252 */
00253    if ( loadImage )
00254       if ( bi_pict == -1 )
00255          image.read ( stream );
00256 }
00257 
00258 void TerrainType::Weather::write ( tnstream& stream ) const
00259 {
00260    stream.writeInt ( defensebonus );
00261    stream.writeInt ( attackbonus );
00262    stream.writeInt ( basicjamming );
00263    stream.writeChar ( 0 ); // was: movemalus count
00264    stream.writeInt ( 1 );
00265    stream.writeInt ( 1 );
00266    stream.writeInt ( 0); // was: quickview
00267    art.write ( stream );
00268 
00269 
00270    stream.writeInt ( bi_pict );
00271    for ( int m = 1; m< 6; m++ )
00272       stream.writeInt ( -1 );
00273 
00274    move_malus.write ( stream );
00275 
00276    if ( bi_pict == -1 )
00277       image.write ( stream );
00278 }
00279 
00280 
00281 void TerrainType::read( tnstream& stream )
00282 {
00283    int version = stream.readInt();
00284    if ( version == terrain_version || version == 1) {
00285 
00286       stream.readInt(); // name = (char*)
00287       id   = stream.readInt();
00288 
00289       bool ___loadWeather[cwettertypennum];
00290       for ( int ww = 0; ww < cwettertypennum; ww++ )
00291          ___loadWeather[ww] = stream.readInt();
00292 
00293       for ( int nf = 0; nf < 8; nf++ )
00294          stream.readInt(); // neighbouringfield[nf]
00295 
00296       name = stream.readString();
00297 
00298       for ( int i=0; i<cwettertypennum ;i++ ) {
00299          if ( ___loadWeather[i] ) {
00300             weather[i] = new TerrainType::Weather ( this );
00301             weather[i]->read( stream, version );
00302          } else
00303             weather[i] = NULL;
00304 
00305       } /* endfor */
00306 
00307    } else
00308       throw tinvalidversion ( stream.getDeviceName(), terrain_version, version );
00309 
00310    /*
00311    if ( version >= 5 ) {
00312       filename = stream.readString();
00313       location = stream.readString();
00314    }
00315    */
00316 }
00317 
00318 
00319 void TerrainType::write ( tnstream& stream ) const
00320 {
00321    stream.writeInt ( terrain_version );
00322    stream.writeInt ( !name.empty() );
00323    stream.writeInt ( id );
00324    for ( int m = 0; m < cwettertypennum; m++ )
00325       stream.writeInt ( weather[m] != NULL );
00326 
00327    for ( int m = 0; m < 8; m++ )
00328       stream.writeInt ( 0 ); // bbt->neighbouringfield[nf]
00329 
00330    stream.writeString( name );
00331    for ( int i = 0; i < cwettertypennum ; i++ ) 
00332       if ( weather[i] ) 
00333          weather[i]->write( stream );
00334 
00335    /*
00336    stream.writeString(filename);
00337    stream.writeString(location);
00338    */
00339 }
00340 
00341 
00342 int TerrainType::getMemoryFootprint() const
00343 {
00344    int size = sizeof(*this);
00345    
00346    for ( int w = 0; w < cwettertypennum; ++w )
00347       if ( weather[w] ) 
00348          size += weather[w]->getMemoryFootprint();
00349       
00350    return size;
00351 }
00352 
00353 int TerrainType::Weather::getMemoryFootprint() const
00354 {
00355    int size = sizeof(*this);
00356    size += image.getMemoryFootprint();
00357    if ( quickView )
00358       size += quickView->getMemoryFootprint();
00359    return size;
00360 }
00361 
00362 
00363 TerrainType::~TerrainType()
00364 {
00365    for ( int i = 0; i< cwettertypennum; ++i) {
00366       delete weather[i];
00367       weather[i] = NULL;
00368    }
00369 }
00370 
00371 
00372 TerrainAccess :: TerrainAccess ( void )
00373 {
00374    terrain.flip();
00375 }
00376 
00377 int TerrainAccess :: accessible ( const TerrainBits& bts ) const
00378 {
00379    if (     (terrain & bts).any()
00380          && (terrainreq & bts) == terrainreq
00381          && (terrainnot & bts ).none()
00382       ) return 1;
00383    else
00384       if ( (terrainkill & bts).any() )
00385          return -1;
00386       else
00387          return 0;
00388 }
00389 
00390 
00391 void TerrainBits::setInt ( int terrain1, int terrain2 )
00392 {
00393    reset();
00394    for ( int i = 0; i < 32; i++ )
00395       if ( terrain1 & ( 1 << i ))
00396          set(i);
00397 
00398    for ( int i = 0; i < 32; i++ )
00399       if ( terrain2 & ( 1 << i ))
00400          set(32+i);
00401 }
00402 
00403 void TerrainBits::read ( tnstream& stream )
00404 {
00405      int terrain1 = stream.readInt();
00406      int terrain2 = stream.readInt();
00407      setInt ( terrain1, terrain2 );
00408   };
00409 
00410 void TerrainBits::write ( tnstream& stream ) const
00411 {
00412      int terrain1 = 0;
00413      int terrain2 = 0;
00414      for ( int i = 0; i < 32; i++ )
00415         if ( test(i) )
00416            terrain1 |=   1 << i ;
00417 
00418      for ( int i = 0; i < 32; i++ )
00419         if ( test(32+i) )
00420            terrain2 |=   1 << i ;
00421 
00422      stream.writeInt( terrain1 );
00423      stream.writeInt( terrain2 );
00424 }
00425 
00426 
00427 void TerrainType :: runTextIO ( PropertyContainer& pc )
00428 {
00429    pc.addBreakpoint(); 
00430   
00431    
00432    BitSet weatherBits;
00433    for ( int i = 0; i < cwettertypennum; i++ )
00434       if ( weather[i] )
00435          weatherBits.set(i);
00436 
00437    pc.addString( "Name", name );
00438    pc.addInteger( "ID", id );
00439 
00440    if ( pc.find( "SecondaryIDs") || !pc.isReading())
00441       pc.addIntegerArray("SecondaryIDs", secondaryIDs );
00442 
00443 
00444    pc.addTagArray( "Weather", weatherBits, cwettertypennum, weatherTags );
00445 
00446    for ( int i = 0; i < cwettertypennum; i++ )
00447       if ( weatherBits.test(i) ) {
00448 
00449          if ( pc.isReading() )
00450             weather[i] = new TerrainType::Weather ( this );
00451 
00452          pc.openBracket  ( weatherTags[i] );
00453          weather[i]->runTextIO ( pc );
00454          pc.closeBracket (  );
00455       }
00456 
00457 }
00458 
00459 void TerrainType::Weather::runTextIO ( PropertyContainer& pc )
00460 {
00461    bool bi3pics = false;
00462 
00463    if ( !pc.isReading() )
00464       if ( bi_pict >= 0 )
00465          bi3pics = true;
00466 
00467    pc.addBool  ( "UseGFXpics", bi3pics, false );
00468    if ( !bi3pics ) {
00469       bi_pict = -1;
00470       int w = cwettertypennum-1;
00471       for ( int i = 0; i < cwettertypennum-1; i++ )
00472          if ( terraintype->weather[i] == this )
00473             w = i;
00474 
00475       ASCString s = extractFileName_withoutSuffix ( terraintype->filename );
00476       if ( s.empty() ) {
00477          s = "terrain";
00478          s += strrr(terraintype->id);
00479       }
00480       pc.addImage ( "picture", image, s + weatherAbbrev[w], true );
00481       // applyFieldMask( image );
00482 
00483       if ( pc.isReading() ) {
00484          int operations;
00485          pc.addNamedInteger("GraphicOperations", operations, graphicOperationNum, graphicOperations, 0 );
00486          if ( operations == 1 )  
00487             snowify( image );
00488          else
00489             if ( operations == 2 )
00490                snowify( image, false );
00491       }
00492 
00493    } else {
00494       pc.addInteger ( "GFX_Picture", bi_pict );
00495       if  ( bi_pict < 0 )
00496          fatalError ( "invalid BI-image " );
00497    }
00498    
00499    pc.addInteger ( "DefenseBonus", defensebonus, 0 );
00500    pc.addInteger ( "AttackBonus",  attackbonus, 0 );
00501    pc.addInteger ( "BasicJamming", basicjamming, 0 );
00502    pc.addDFloatArray ( "MoveMalus", move_malus );
00503    while ( move_malus.size() < cmovemalitypenum ) 
00504      if ( move_malus.size() == 0 )
00505         move_malus.push_back ( minmalq );
00506      else
00507         move_malus.push_back ( move_malus[0] );
00508 
00509 
00510    pc.addTagArray ( "TerrainProperties", art, terrainPropertyNum, terrainProperties );
00511 }
00512 
00513 
00514 
00515 
00516 TerrainBits getTerrainBitType ( TerrainBitTypes tbt )
00517 {
00518    TerrainBits tb;
00519    switch ( tbt ) {
00520       case cbwater0 : tb.setInt( 1<<22 ); break;
00521       case cbwater1 : tb.setInt( 1 );   break;
00522       case cbwater2 : tb.setInt( 4096 ); break;
00523       case cbwater3 : tb.setInt( 8192 ); break;
00524       case cbwater  : tb.setInt (  (1<<22)  // very shallow water
00525                                  | (1<< 0)  // shallow water
00526                                  | (1<<12)  // water
00527                                  | (1<<13)  // deep water
00528                                  | (1<<31)  // river
00529                                  ); break;
00530       case cbstreet : tb.setInt ( 32, 0 ); break;
00531       case cbrailroad : tb.setInt ( 64, 0 ); break;
00532       case cbbuildingentry : tb.setInt ( 128, 0 ); break;
00533       case cbharbour     : tb.setInt ( 256, 0 ); break;
00534       case cbrunway      : tb.setInt ( 512, 0 ); break;
00535       case cbpipeline    : tb.setInt ( 1024, 0 ); break;
00536       case cbpowerline   : tb.setInt ( 2048, 0 ); break;
00537       case cbfahrspur    : tb.setInt ( 1<<16, 0 ); break;
00538       case cbfestland    : tb.flip(); tb ^= getTerrainBitType( cbwater ); break;
00539       case cbsnow1       : tb.setInt ( 1<<19, 0 ); break;
00540       case cbsnow2       : tb.setInt ( 1<<20, 0 ); break;
00541       case cbhillside    : tb.setInt ( 1<<26, 0 ); break;
00542       case cbsmallrocks  : tb.setInt ( 1<<17, 0 ); break;
00543       case cblargerocks  : tb.setInt ( 1<<23, 0 ); break;
00544       case cbfrozenwater : tb.setInt ( 0, 1 ); break;
00545       case cbicebreaking : tb |= getTerrainBitType( cbfrozenwater )
00546                               | getTerrainBitType( cbsnow1 )
00547                               | getTerrainBitType(cbsnow2 );
00548       case cbriver       : tb.setInt(  1 << 31, 0 ); break;
00549 
00550    };
00551    return tb;
00552 }
00553 
00554 

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