objecttype.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           objecttype.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 
00019 #include <algorithm>
00020 #include <set>
00021 
00022 #include "objecttype.h"
00023 #include "graphicset.h"
00024 #include "textfileparser.h"
00025 #include "textfiletags.h"
00026 #include "sgstream.h"
00027 #include "textfile_evaluation.h"
00028 #include "mapalgorithms.h"
00029 #include "graphics/blitter.h"
00030 #include "graphics/drawing.h"
00031 #include "fieldimageloader.h"
00032 #include "memsize_interface.h"
00033 #include "iconrepository.h"
00034 
00035 
00036 #ifndef converter
00037 #include "gamemap.h"
00038 #endif
00039 
00040 
00041 
00042 ObjectType :: FieldModification::FieldModification()
00043 {
00044    terrain_and.flip();
00045 }
00046 
00047 ObjectType :: ObjectType ( void ) : rotateImage(false)
00048 {
00049    namingMethod = AddToTerrain;
00050    groupID = -1;
00051 
00052    displayMethod = 0;
00053    canExistBeneathBuildings = false;
00054    netBehaviour = 0;
00055    viewbonus_abs = -1;
00056    viewbonus_plus = 0;
00057    imageHeight = 0;
00058    physicalHeight = 0;
00059    growthRate = 0;
00060    growOnUnits = false;
00061    lifetime = -1;
00062    growthDuration = -1;
00063 }
00064 
00065 const int ObjectType::namingMethodNum = 3;
00066 
00067 const char* ObjectType::namingMethodNames[namingMethodNum+1] = { "ReplaceTerrain", "AddToTerrain", "UnNamed", NULL };
00068 
00069       
00070 
00071 
00072 const ObjectType::FieldModification&  ObjectType::getFieldModification ( int weather ) const
00073 {
00074    return fieldModification[getWeather(weather)];
00075 }
00076 
00077 bool  ObjectType :: buildable ( MapField* fld ) const
00078 {
00079    #ifndef converter
00080    if ( fld->building && !growOnUnits )
00081       return false;
00082 
00083    if ( getFieldModification( fld->getWeather() ).terrainaccess.accessible ( fld->bdt ) <= 0 )
00084        return false;
00085 
00086    #endif
00087    return true;
00088 }
00089 
00090 int ObjectType :: getEffectiveHeight() const
00091 {
00092   return 1 << physicalHeight;
00093 }
00094 
00095 
00096 int ObjectType :: getWeather( int weather ) const
00097 {
00098    while ( !this->weather.test(weather) ) {
00099       if ( weather == 5 )
00100          weather = 4;
00101       else
00102          if ( weather == 2 )
00103             weather = 1;
00104          else
00105             weather = 0;
00106    }
00107    return weather;
00108 }
00109 
00110 
00111 const OverviewMapImage* ObjectType :: getOverviewMapImage( int picnum, int weather  ) const
00112 {
00113    weather = getWeather(weather);
00114 
00115    if ( weatherPicture[weather].images.size() <= picnum )
00116       picnum = 0;
00117 
00118    if ( weatherPicture[weather].bi3pic[picnum] > 0 )
00119       return GraphicSetManager::Instance().getQuickView( weatherPicture[weather].bi3pic[picnum] );
00120    else {
00121       if ( weatherPicture[weather].overviewMapImage.size() <= picnum )
00122          weatherPicture[weather].overviewMapImage.resize( picnum+1 );
00123 
00124       if ( !weatherPicture[weather].overviewMapImage[picnum].valid() )
00125          weatherPicture[weather].overviewMapImage[picnum].create( weatherPicture[weather].images[picnum] );
00126 
00127       return &weatherPicture[weather].overviewMapImage[picnum];
00128    }
00129 }
00130 
00131 
00132 const Surface& ObjectType :: getPicture ( int i, int w ) const
00133 {
00134    w = getWeather(w);
00135 
00136    if ( weatherPicture[w].images.size() <= i ) {
00137       if ( i >= 64 && weatherPicture[w].images.size() > 34 )
00138          i = 34;
00139       else
00140          i = 0;
00141    }
00142 
00143    if ( weatherPicture[w].bi3pic[i] > 0 )
00144       return GraphicSetManager::Instance().getPic(weatherPicture[w].bi3pic[i]);
00145    else {
00146       const Surface& s = weatherPicture[w].images[i];
00147       if ( s.valid() )
00148          return s;
00149       else {
00150          if ( i < 65 && weatherPicture[w].images.size() >= 66 ) {
00151             const Surface& s2 = weatherPicture[w].images[65];
00152             if ( s2.valid())
00153                return s2;
00154          } 
00155          if ( i < 64 && weatherPicture[w].images.size() >= 65 ) {
00156             const Surface& s2 = weatherPicture[w].images[64];
00157             if ( s2.valid())
00158                return s2;
00159          } 
00160          return IconRepository::getIcon("red-x-field.png");
00161       }
00162    }
00163 }
00164 
00165 
00166 void ObjectType :: display ( Surface& surface, const SPoint& pos, int dir, int weather ) const
00167 {
00168    weather = getWeather(weather);
00169 
00170    if ( id == 4 ) {
00171      switch ( dir ) {
00172         case  68 : realDisplay( surface, pos,  9, weather ); break;
00173         case  34 : realDisplay( surface, pos, 10, weather ); break;
00174         case  17 : realDisplay( surface, pos, 11, weather ); break;
00175         case 136 : realDisplay( surface, pos, 12, weather ); break;
00176         case   0 : realDisplay( surface, pos,  0, weather ); break;
00177         default  : {
00178            for (int i = 0; i <= 7; i++)
00179               if ( dir & (1 << i))
00180                  realDisplay( surface, pos,  i+1, weather ); 
00181         }
00182      }
00183    } else
00184       realDisplay( surface, pos, dir, weather ); 
00185 
00186 }
00187 
00188 
00189 template<
00190 int BytesPerSourcePixel,
00191 int BytesPerTargetPixel
00192 >
00193 class ColorConverter_PassThrough
00194 {
00195    public:
00196       typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType SourcePixelType;
00197       typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType TargetPixelType;
00198    private:
00199       SourcePixelType srcColorKey;
00200       TargetPixelType destColorKey;
00201    public:
00202       ColorConverter_PassThrough( const Surface& sourceSurface, Surface& targetSurface )
00203       {}
00204       ;
00205       TargetPixelType convert ( SourcePixelType sp )
00206       {
00207          return sp;
00208       };
00209 };
00210 
00211 
00212 
00213 void ObjectType::realDisplay ( Surface& surface, const SPoint& pos, int dir, int weather ) const
00214 {
00215    int flip = 0;
00216    if ( dir < weatherPicture[weather].flip.size() )
00217       flip = weatherPicture[weather].flip[dir];
00218 
00219    if ( displayMethod==1 ) { // SHADOW: buried pipeline, tracks, ...
00220       const Surface& s = getPicture( dir, weather);
00221       if ( dir != 0 && rotateImage ) {
00222          megaBlitter<ColorTransform_None, ColorMerger_AlphaLighter, SourcePixelSelector_CacheRotation,TargetPixelSelector_All>(s, surface, pos, nullParam,0.7,make_pair(&s,directionangle[dir%6]),nullParam); 
00223       } else {
00224          megaBlitter<ColorTransform_None, ColorMerger_AlphaLighter, SourcePixelSelector_DirectFlip,TargetPixelSelector_All>(s, surface, pos, nullParam, 0.7, flip, nullParam); 
00225       }
00226    } else
00227       if ( displayMethod == 2 ) {  // translation
00228          const Surface& s = getPicture( dir, weather);
00229          if ( !s.valid() )
00230             return;
00231          
00232          if ( s.GetPixelFormat().BitsPerPixel() == 8 ) {
00233             MegaBlitter< 1,4,
00234                         ColorTransform_None, 
00235                         ColorMerger_Alpha_XLAT_TableShifter, 
00236                         SourcePixelSelector_DirectFlip,
00237                         TargetPixelSelector_All,
00238                         ColorConverter_PassThrough
00239                      >
00240                blitter;
00241             blitter.setFlipping( flip & 1, flip & 2 );
00242             blitter.blit( s, surface, pos );
00243          } // else
00244            // warning("objects with palette translation as display method may not have truecolor images");
00245       } else
00246          if ( displayMethod == 4 ) {
00247             const Surface& s = getPicture( dir, weather);
00248             if ( !s.valid() )
00249                return;
00250    
00251             if ( dir != 0 && rotateImage ) {
00252                megaBlitter<ColorTransform_None, ColorMerger_AlphaMixer, SourcePixelSelector_CacheRotation ,TargetPixelSelector_All>(s, surface, pos, nullParam,nullParam,make_pair(&s,directionangle[dir%6]),nullParam); 
00253             } else {
00254                megaBlitter<ColorTransform_None, ColorMerger_AlphaMixer, SourcePixelSelector_DirectFlip,    TargetPixelSelector_All>(s, surface, pos, nullParam,nullParam, flip, nullParam); 
00255             }
00256          } else {
00257             bool disp = true;
00258             #ifndef karteneditor
00259             if ( displayMethod == 3 ) // mapeditorOnly
00260                disp = false;
00261             #endif
00262             if ( disp ) {
00263                const Surface& s = getPicture( dir, weather);
00264                if ( !s.valid() )
00265                   return;
00266                if ( flip ) {
00267                   // if ( s.flags() & SDL_SRCALPHA )
00268                      megaBlitter<ColorTransform_None, ColorMerger_AlphaMerge, SourcePixelSelector_DirectFlip,TargetPixelSelector_All>(s, surface, pos, nullParam,nullParam, flip, nullParam); 
00269                   // else   
00270                   //   megaBlitter<ColorTransform_None, ColorMerger_AlphaOverwrite, SourcePixelSelector_DirectFlip,TargetPixelSelector_All>(getPicture( dir, weather), surface, pos, nullParam,nullParam, flip, nullParam); 
00271                } else {  
00272                   if ( dir != 0 && rotateImage ) {
00273                      // if ( s.flags() & SDL_SRCALPHA )
00274                         megaBlitter<ColorTransform_None, ColorMerger_AlphaMerge, SourcePixelSelector_CacheRotation ,TargetPixelSelector_All>(s, surface, pos, nullParam,nullParam,make_pair(&s,directionangle[dir%6]),nullParam); 
00275                      // else
00276                      //   megaBlitter<ColorTransform_None, ColorMerger_AlphaOverwrite, SourcePixelSelector_CacheRotation,TargetPixelSelector_All>(s, surface, pos, nullParam,nullParam,make_pair(&s,directionangle[dir]),nullParam); 
00277                   } else {
00278                      // if ( s.flags() & SDL_SRCALPHA )
00279                         megaBlitter<ColorTransform_None, ColorMerger_AlphaMerge, SourcePixelSelector_Plain,TargetPixelSelector_All>(s, surface, pos, nullParam,nullParam,nullParam,nullParam); 
00280                      // else
00281                      //   megaBlitter<ColorTransform_None, ColorMerger_AlphaOverwrite, SourcePixelSelector_Plain,TargetPixelSelector_All>(getPicture( dir, weather), surface, pos, nullParam,nullParam,nullParam,nullParam); 
00282                   }
00283                }   
00284             }
00285          }   
00286 }
00287 
00288 
00289 void ObjectType :: display ( Surface& surface, const SPoint& pos ) const
00290 {
00291    display ( surface, pos, rotateImage? 0 : 64, 0 );
00292 }
00293 
00294 
00295 
00296 
00297 #ifndef converter
00298 
00299 namespace ForestCalculation {
00300 
00301 /*
00302    These smoothing functions are straight conversions from Joerg Richter's routines
00303    he made for his Battle Isle Map editor
00304    Many thanks for giving them to me !
00305 */
00306 
00307 const int woodformnum = 28;
00308 int woodform[ woodformnum ] = { 63,30,60,39,51,28,35,48,6,57,15,14,56,7,49,47,59,31,61,60,55, -1,-1,-1,-1,-1,-1,-1 };
00309 
00310 
00311 int SmoothTreesData0[] = {
00312      4, 7, 10,101,
00313      1,0x0001,243,
00314      1,0x0115,243,          // die die garnicht gehen
00315     30,0x3F, 30,243,0x3F, 60,243,0x3F, 39,243,0x3F, 51,243,
00316        0x3F, 28,243,0x3F, 35,243,0x3F, 48,243,0x3F,  6,243,
00317        0x3F, 57,243,0x3F, 15,243,0x3F, 14,243,0x3F, 56,243,
00318        0x3F,  7,243,0x3F, 49,243,0x3F, 47,243,0x3F, 59,243,
00319        0x3F, 31,243,0x3F, 61,243,0x3F, 62,243,0x3F, 55,243,
00320        0x3F, 23,243,0x3F, 46,243,0x3F, 29,243,0x3F, 58,243,
00321        0x3F, 53,243,0x3F, 43,243,0x3F, 22,243,0x3F, 38,243,
00322        0x3F, 50,243,0x3F, 52,243,
00323      7,264,265,266,267,268,269,270
00324   };
00325 
00326 int SmoothTreesData[] = {
00327      4, 7, 10,101,
00328      1,0x0001,243,
00329      1,0x0115,243,
00330     30,0x3F, 30,244,0x3F, 60,245,0x3F, 39,246,0x3F, 51,247,
00331        0x3F, 28,248,0x3F, 29,248,0x3F, 35,249,0x3F, 43,249,
00332        0x3F, 48,250,0x3F, 50,250,0x3F, 52,250,0x3F,  6,251,
00333        0x3F, 22,251,0x3F, 38,251,0x3F, 57,252,0x3F, 15,253,
00334        0x3F, 14,254,0x3F, 46,254,0x3F, 56,255,0x3F, 58,255,
00335        0x3F,  7,256,0x3F, 23,256,0x3F, 49,257,0x3F, 53,257,
00336        0x3F, 47,258,0x3F, 59,259,0x3F, 31,260,0x3F, 61,261,
00337        0x3F, 62,262,0x3F, 55,263,
00338      7,264,265,266,267,268,269,270
00339   };
00340 
00341 int UnSmoothTreesData[] = {
00342      4, 7, 8, 9,
00343      1,0x011C,243,
00344      0,
00345      0,
00346      1,243
00347   };
00348 
00349 
00350 
00351 
00352 int  SmoothBanksData [] = {
00353      4, 7, 16, 77,
00354      1, 0x0103, 95,    // was zu ersetzen ist         - blaues wasser }
00355      4, 0x010F, 95,    // was als 1 zu betrachten ist - wasser und strand }
00356         0x010E,  0,                                // - Hafen }
00357         0x0109,110,                                // - Steine und Schilf }
00358         0x0107,121,                                // - Schilf }
00359     20,0x3F,59, 98, 0x3F,51, 98, 0x3F,47, 99, 0x3F,39, 99, // durch was ersetzen }
00360        0x3F,31,100, 0x3F,30,100, 0x3F,61,101, 0x3F,60,101,
00361        0x3F,55,102, 0x3F,62,103, 0x3F,35,104, 0x3F,28,105,
00362        0x3F,56,106, 0x3F,48,106, 0x3F,49,106, 0x3F,57,106,
00363        0x3F,14,107, 0x3F,15,107, 0x3F, 7,107, 0x3F, 6,107,
00364      0                                            // wenn nicht gefunden }
00365   };
00366 
00367 int  UnSmoothBanksData [] = {
00368      4, 7, 8, 9,
00369      1, 0x010C, 98,          // { alle str"nder ersetzen }
00370      0,
00371      0,
00372      1, 95                  // durch flaches wasser ersetzen }
00373   };
00374 
00375 
00376 int  SmoothDarkBanksData [] = {
00377      4, 7, 16, 77,
00378      1,0x0103,385,                       // dunkels wasser }
00379      4,0x0103,385,                       // dunkles wasser }
00380        0x010A,373,
00381        0x0104,449,
00382        0x0104,463,
00383     20,0x3F,59,373, 0x3F,51,373, 0x3F,47,374, 0x3F,39,374,          // durch was ersetzen }
00384        0x3F,31,375, 0x3F,30,375, 0x3F,61,376, 0x3F,60,376,
00385        0x3F,55,377, 0x3F,62,378, 0x3F,35,379, 0x3F,28,380,
00386        0x3F,56,381, 0x3F,48,381, 0x3F,49,381, 0x3F,57,381,
00387        0x3F,14,382, 0x3F,15,382, 0x3F, 7,382, 0x3F, 6,382,
00388      0                                       // wenn nicht gefunden }
00389   };
00390 
00391 int  UnSmoothDarkBanksData [] = {
00392      4, 7, 8, 9,
00393      1,0x010A,373,
00394      0,
00395      0,
00396      1,385
00397   };
00398 
00399 
00400 
00401 class Smoothing {
00402          GameMap* actmap;
00403        public:
00404          Smoothing ( GameMap* gamemap ) : actmap ( gamemap ) {};
00405          MapField* getfield ( int x, int y )
00406          {
00407             return actmap->getField ( x, y );
00408          }
00409 
00410          int IsInSetOfWord( int Wert, int* A )
00411          {
00412            int Pos = 0;
00413            int Anz1 = A[Pos];
00414            Pos++;
00415            int res = 0;
00416            int Anz2;
00417            while ( Anz1 > 0 ) {
00418              int W = A[Pos];
00419              Pos++;
00420              Anz2 = W & 0xff;
00421 
00422              if ( W & 0x100 ) {
00423                 if (( Wert>= A[Pos]) && (Wert< A[Pos]+Anz2))
00424                      res = 1;
00425                    Pos++;
00426              } else {
00427                 while ( Anz2 > 0) {
00428                   if ( Wert == A[Pos] )
00429                      res = 1;
00430                   Pos++;
00431                   Anz2--;
00432                 }
00433              }
00434 
00435              Anz1--;
00436            }
00437 
00438            return res;
00439          };
00440 
00441 
00442          int  GetNeighbourMask( int x, int y, int* Arr, ObjectType* o )
00443          {
00444             int res = 0;
00445             for ( int d = 0; d < sidenum; d++ ) {
00446                int x1 = x;
00447                int y1 = y;
00448                getnextfield ( x1, y1, d );
00449                MapField* fld = getfield ( x1, y1 );
00450                if ( fld ) {
00451 
00452                   Object* obj = fld->checkForObject ( o );
00453                   if ( obj )
00454                      if ( obj->typ->weather.test(0) )
00455                         if ( IsInSetOfWord ( obj->typ->weatherPicture[0].bi3pic[ obj->dir ], Arr ))
00456                            res += 1 << d;
00457 
00458                   // if ( fld->checkforobject ( o ) )
00459                   //    res += 1 << d;
00460                } else
00461                   res += 1 << d;
00462 
00463             }
00464             return res;
00465          };
00466 
00467          int  GetNeighbourMask( int x, int y, int* Arr )
00468          {
00469             int res = 0;
00470             for ( int d = 0; d < sidenum; d++ ) {
00471                int x1 = x;
00472                int y1 = y;
00473                getnextfield ( x1, y1, d );
00474                MapField* fld = getfield ( x1, y1 );
00475                if ( fld ) {
00476 
00477                   if ( IsInSetOfWord ( fld->typ->bi_pict, Arr ))
00478                      res += 1 << d;
00479 
00480                } else
00481                   res += 1 << d;
00482 
00483             }
00484             return res;
00485          };
00486 
00487 
00488          /*
00489                Res:= 0;
00490                for I:= Oben to LOben do begin
00491                  GetNear(P, I, R);
00492                  if ValidEck(R) then
00493                    Res:= Res or
00494           (Byte(IsInSetOfWord(  TRawArrEck(   Mission.ACTN[R.Y, R.X] )[TerObj], Arr)) shl Ord(I))
00495                  else
00496                    Res:= Res or 1 shl Ord(I);
00497                end;
00498                GetNeighbourMask:= Res;
00499              end;
00500          */
00501 
00502 
00503          int SearchAndGetInt( int Wert, int* Arr, int* Res )
00504          {
00505             int Anz = Arr[0];
00506             int Pos = 1;
00507             while ( Anz> 0 ) {
00508               if (( Wert & Arr[Pos]) == Arr[Pos+1] ) {
00509                  *Res = Arr[Pos+2];
00510                  return  Anz > 0;
00511               }
00512               Pos += 3;
00513               Anz--;
00514             }
00515             return  Anz> 0;
00516          };
00517 
00518 
00519          int SmoothIt( ObjectType* TerObj, int* SmoothData )
00520          {
00521            int P0 = SmoothData[0];
00522            int P1 = SmoothData[1];
00523            int P2 = SmoothData[2];
00524            int P3 = SmoothData[3];
00525            int Res = 0;
00526            for ( int Y = 0 ; Y < actmap->ysize; Y++ )
00527              for ( int X = 0; X < actmap->xsize; X++ ) {
00528                  if ( TerObj ) {
00529                     Object* obj = getfield ( X, Y )-> checkForObject ( TerObj );
00530                     if ( obj  && obj->typ->weather.test(0) ) {
00531                        int Old = obj->dir; // bipicnum
00532                                            //    Old:= TRawArrEck(Mission.ACTN[Y, X])[TerObj];  // bisherige Form / oder Bildnummer ?
00533 
00534                        if ( IsInSetOfWord( obj->typ->weatherPicture[0].bi3pic[ obj->dir ], &SmoothData[P0] )) {    // Nur die "allesWald"-fielder werden gesmootht
00535                           int Mask = GetNeighbourMask( X, Y, &SmoothData[P1], TerObj );
00536                           if ( Mask < 63 ) {
00537                              int nw;
00538                              if ( !SearchAndGetInt(Mask, &SmoothData[P2], &nw) ) {  // Wenn kein passendes field gefunden wurde
00539                                 if ( SmoothData[P3] == 0  ||  SmoothData[P3] == 1 )
00540                                    nw = SmoothData[P3+ 1];
00541                                 else
00542                                    nw = SmoothData[P3+ 1 ]; // + (ticker % SmoothData[P3] )
00543                              }
00544                              for ( int i = 0; i < TerObj->weatherPicture[0].bi3pic.size(); i++ )
00545                                 if ( TerObj->weatherPicture[0].bi3pic[ i ] == nw )
00546                                    obj->dir = i;
00547                           }
00548                        }
00549                        if ( Old != obj->dir )
00550                           Res = 1;
00551                     }
00552                  } else {
00553                     MapField* fld = getfield ( X, Y );
00554                     TerrainType::Weather* old = fld->typ;
00555                     // int odir = fld->direction;
00556 
00557                     if ( IsInSetOfWord( fld->typ->bi_pict, &SmoothData[P0] )) {    // Nur die "allesWald"-fielder werden gesmootht
00558                        int Mask = GetNeighbourMask( X, Y, &SmoothData[P1] );
00559                        if ( Mask < 63 ) {
00560                           int nw;
00561                           if ( !SearchAndGetInt(Mask, &SmoothData[P2], &nw) ) {  // Wenn kein passendes field gefunden wurde
00562                              if ( SmoothData[P3] == 0  ||  SmoothData[P3] == 1 )
00563                                 nw = SmoothData[P3+ 1];
00564                              else
00565                                 nw = SmoothData[P3+ 1 ]; // + (ticker % SmoothData[P3] )
00566                           }
00567                           /*
00568                           for ( int i = 0; i < terrainTypeRepository.getNum; i++ ) {
00569                              pterraintype trrn = terrainTypeRepository.getObject_byPos( i );
00570                              if ( trrn )
00571                                 for ( int j = 0; j < cwettertypennum; j++ )
00572                                    if ( trrn->weather[j] )
00573                                       for ( int k = 0; k < sidenum; k++ )
00574                                          if ( trrn->weather[j]->pict )
00575                                             if ( trrn->weather[j]->bi_pict == nw ) {
00576                                                fld->typ = trrn->weather[j];
00577                                                fld->direction = k;
00578                                                fld->setparams();
00579                                             }
00580                           }
00581                           */
00582                        }
00583                     }
00584                     if ( old != fld->typ  )
00585                        Res = 1;
00586 
00587                  }
00588               }
00589            return Res;
00590          };
00591 
00592 
00593 
00594          void smooth ( int what, ObjectType* woodObj )
00595          {
00596            int ShowAgain = 0;
00597            if ( what & 2 ) {
00598              if ( SmoothIt( NULL, UnSmoothBanksData) )
00599                 ShowAgain = 1;
00600              if ( SmoothIt( NULL, UnSmoothDarkBanksData) )
00601                 ShowAgain = 1;
00602              if ( SmoothIt( NULL, SmoothBanksData) )
00603                 ShowAgain = 1;
00604              if ( SmoothIt( NULL, SmoothDarkBanksData) )
00605                 ShowAgain = 1;
00606            }
00607 
00608            if ( what & 1 ) {
00609               if ( woodObj  ) {
00610                 int count = 0;
00611                 while ( SmoothIt ( woodObj, SmoothTreesData0 ) && count < 20 ) {
00612                    ShowAgain = 1;
00613                    count++;
00614                 }
00615                 if  ( SmoothIt ( woodObj, SmoothTreesData) )
00616                    ShowAgain = 1;
00617               }
00618            }
00619          /*    while SmoothIt(1, SmoothDarkTreesData0) do ShowAgain:= true;
00620              if SmoothIt(1, SmoothDarkTreesData) then ShowAgain:= true;
00621              if ShowAgain then begin
00622                ShowAll;
00623                Repaint;
00624              end;    */
00625          };
00626 
00627 };
00628 
00629 
00630 /*
00631 procedure TMissView.Smooth;
00632   var
00633     ShowAgain: Boolean;
00634   begin
00635     ShowAgain:= false;
00636     if SmoothIt(0, SmoothBanksData) then ShowAgain:= true;
00637     if SmoothIt(0, SmoothDarkBanksData) then ShowAgain:= true;
00638 
00639     while SmoothIt(1, SmoothTreesData0) do ShowAgain:= true;
00640     if SmoothIt(1, SmoothTreesData) then ShowAgain:= true;
00641 {    while SmoothIt(1, SmoothDarkTreesData0) do ShowAgain:= true;
00642     if SmoothIt(1, SmoothDarkTreesData) then ShowAgain:= true;}
00643     if ShowAgain then begin
00644       ShowAll;
00645       Repaint;
00646     end;
00647   end;
00648 
00649 function IsInSetofWord(Wert: Word; var A: array of Word): Boolean;
00650   var
00651     Anz1: Word;
00652     Anz2: Word;
00653     W: Word;
00654     Pos: Word;
00655   begin
00656     Pos:= 0;
00657     Anz1:= A[Pos];
00658     Inc(Pos);
00659     IsInSetOfWord:= false;
00660     while Anz1> 0 do begin
00661       W:= A[Pos];
00662       Inc(Pos);
00663       Anz2:= Lo(W);
00664       case Hi(W) of
00665         0: begin
00666             while Anz2> 0 do begin
00667               if Wert= A[Pos] then IsInSetOfWord:= true;
00668               Inc(Pos);
00669               Dec(Anz2);
00670             end;
00671           end;
00672         1: begin
00673             if (Wert>= A[Pos]) and (Wert< A[Pos]+Anz2) then
00674               IsInSetOfWord:= true;
00675             Inc(Pos);
00676           end;
00677       end;
00678       Dec(Anz1);
00679     end;
00680   end;
00681 
00682 
00683 
00684 ****************
00685 Smoothdaten
00686 ****************
00687 
00688 {
00689   Aufbau eines Set of Ints
00690 
00691   1. word anzahl der bl"cke
00692   dann folgen die bl"cke
00693 
00694   aufbau eines blocks:
00695     1. word:
00696        hibyte- optionsnummer
00697          0- nur rawdaten   lobyte ist anzahl der folgenden raws
00698          1- ab hier        lobyte ist anzahl der ab hier
00699     weitere ist entweder raw oder startzahl
00700 }
00701 
00702 
00703   SmoothBanksData: array[0..77] of Word= (
00704      4, 7, 16, 77,
00705      1, $0103, 95,    { was zu ersetzen ist         - blaues wasser }
00706      4, $010F, 95,    { was als 1 zu betrachten ist - wasser und strand }
00707         $010E,  0,                                { - Hafen }
00708         $0109,110,                                { - Steine und Schilf }
00709         $0107,121,                                { - Schilf }
00710     20,$3F,59, 98, $3F,51, 98, $3F,47, 99, $3F,39, 99, { durch was ersetzen }
00711        $3F,31,100, $3F,30,100, $3F,61,101, $3F,60,101,
00712        $3F,55,102, $3F,62,103, $3F,35,104, $3F,28,105,
00713        $3F,56,106, $3F,48,106, $3F,49,106, $3F,57,106,
00714        $3F,14,107, $3F,15,107, $3F, 7,107, $3F, 6,107,
00715      0                                            { wenn nicht gefunden }
00716   );
00717 
00718   UnSmoothBanksData: array[0..10] of Word= (
00719      4, 7, 8, 9,
00720      1, $010C, 98,          { alle str"nder ersetzen }
00721      0,
00722      0,
00723      1, 95                  { durch flaches wasser ersetzen }
00724   );
00725 
00726 
00727   SmoothDarkBanksData: array[0..77] of Word= (
00728      4, 7, 16, 77,
00729      1,$0103,385,                       { dunkels wasser }
00730      4,$0103,385,                       { dunkles wasser }
00731        $010A,373,
00732        $0104,449,
00733        $0104,463,
00734     20,$3F,59,373, $3F,51,373, $3F,47,374, $3F,39,374,          { durch was ersetzen }
00735        $3F,31,375, $3F,30,375, $3F,61,376, $3F,60,376,
00736        $3F,55,377, $3F,62,378, $3F,35,379, $3F,28,380,
00737        $3F,56,381, $3F,48,381, $3F,49,381, $3F,57,381,
00738        $3F,14,382, $3F,15,382, $3F, 7,382, $3F, 6,382,
00739      0                                       { wenn nicht gefunden }
00740   );
00741 
00742   UnSmoothDarkBanksData: array[0..10] of Word= (
00743      4, 7, 8, 9,
00744      1,$010A,373,
00745      0,
00746      0,
00747      1,385
00748   );
00749 
00750 */
00751 
00752 
00753 void smooth ( int what, GameMap* gamemap, ObjectType* woodObj )
00754 {
00755   Smoothing s ( gamemap );
00756   s.smooth ( what, woodObj );
00757 }
00758 
00759 
00760 void calculateforest( GameMap* actmap, ObjectType* woodObj )
00761 {
00762    for ( int y = 0; y < actmap->ysize ; y++)
00763      for ( int x = 0; x < actmap->xsize ; x++) {
00764         MapField* fld = actmap->getField(x,y);
00765 
00766         for ( MapField::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); i++ )
00767            if ( i->typ == woodObj )
00768               i->dir = 0;
00769      }
00770 
00771    Smoothing s ( actmap );
00772    s.smooth( 1, woodObj );
00773    return;
00774 
00775    int run = 0;
00776    int changed ;
00777    do {
00778       changed = 0;
00779       for ( int y = 0; y < actmap->ysize ; y++)
00780          for ( int x = 0; x < actmap->xsize ; x++) { 
00781             MapField* fld = actmap->getField(x,y);
00782    
00783             for ( MapField::ObjectContainer::iterator o = fld->objects.begin(); o != fld->objects.end(); o++ )
00784                if ( o->typ == woodObj ) {
00785                   int c = 0;
00786                   for ( int i = 0; i < sidenum; i++) {
00787                      int a = x;
00788                      int b = y;
00789                      getnextfield( a, b, i );
00790                      MapField* fld2 = actmap->getField(a,b);
00791 
00792                      if ( fld2 ) {
00793                         Object* oi = fld2->checkForObject ( o->typ );
00794                         if ( oi )
00795                            if ( oi->dir <= 20  ||  run == 0 )
00796                               c |=  1 << i ;
00797                       }
00798                   }
00799 
00800                   // int found = 0;
00801                   int dr;
00802                   for ( int j = 0; j < woodformnum; j++ )
00803                      if ( woodform[j] == c ) {
00804                         dr = j;
00805                         // found = 1;
00806                      }
00807 
00808 //                  if ( !found )
00809 //                     dr = 21 + ticker % 7;
00810 
00811                   if ( o->dir != dr  && !(o->dir >= 21  && dr >= 21)) {
00812                      o->dir = dr;
00813                      fld->setparams();
00814                      changed = 1;
00815                   }
00816                }
00817          } 
00818       run++;
00819    } while ( changed );
00820 }
00821 
00822 } // namespace forestcalculation
00823 
00824 
00825 #else // ifdef converter
00826 
00827 
00828 
00829 #endif
00830 
00831 
00832 int ObjectType :: getMemoryFootprint() const
00833 {
00834    int size = sizeof( *this );
00835    for ( int ww = 0; ww < cwettertypennum; ww++ ) {
00836       size += for_each( weatherPicture[ww].images.begin(), weatherPicture[ww].images.end(), MemorySum<Surface>() ).size;
00837       size += for_each( weatherPicture[ww].overviewMapImage.begin(), weatherPicture[ww].overviewMapImage.end(), MemorySum<OverviewMapImage>() ).size;
00838    }
00839 
00840    return size;
00841 }
00842 
00843 
00844 
00845 const int object_version = 22;
00846 
00847 void ObjectType :: read ( tnstream& stream )
00848 {
00849    int version = stream.readInt();
00850 
00851    if ( version < 9 )
00852       fatalError ( "sorry, the old file format for objects cannot be loaded any more" );
00853 
00854    if ( version <= object_version && version >= 9 ) {
00855 
00856        id = stream.readInt();
00857        groupID = stream.readInt();
00858 
00859        int ___weather = stream.readInt();
00860        weather.reset();
00861        for ( int i = 0; i < cwettertypennum; i++ )
00862           if ( ___weather & ( 1 << i ))
00863              weather.set ( i );
00864 
00865        visibleago = stream.readInt();
00866 
00867        if ( version <= 20 ) {
00868           vector<int> IDs;
00869           readClassContainer( IDs, stream );
00870           linkableObjects.clear();
00871           for ( int i = 0; i < IDs.size(); ++i )
00872              linkableObjects.push_back( IntRange(IDs[i]));
00873 
00874           readClassContainer( IDs, stream );
00875           linkableTerrain.clear();
00876           for ( int i = 0; i < IDs.size(); ++i )
00877              linkableTerrain.push_back( IntRange(IDs[i]));
00878        } else {
00879          readClassContainer( linkableObjects, stream );
00880          readClassContainer( linkableTerrain, stream );
00881        }
00882        armor = stream.readInt();
00883 
00884        for ( int i = 0; i < cwettertypennum; ++i ) {
00885           fieldModification[i].terrainaccess.read( stream );
00886           fieldModification[i].terrain_and.read ( stream );
00887           fieldModification[i].terrain_or.read ( stream );
00888           fieldModification[i].movemalus_plus.read ( stream, 0 );
00889           fieldModification[i].movemalus_abs.read ( stream, -1 );
00890        }
00891 
00892 
00893        attackbonus_plus = stream.readInt();
00894        attackbonus_abs  = stream.readInt();
00895 
00896        defensebonus_plus = stream.readInt();
00897        defensebonus_abs =  stream.readInt();
00898 
00899        basicjamming_plus = stream.readInt();
00900        basicjamming_abs = stream.readInt();
00901 
00902        if ( version >= 10 ) {
00903           viewbonus_plus = stream.readInt();
00904           viewbonus_abs = stream.readInt();
00905        }
00906 
00907        if ( version <= 10 ) {
00908          imageHeight = stream.readInt();
00909          physicalHeight = imageHeight / 30;
00910        } else {
00911          imageHeight = stream.readInt();
00912          physicalHeight = stream.readInt();
00913        }
00914 
00915 
00916        buildcost.read( stream );
00917        removecost.read ( stream );
00918        build_movecost = stream.readInt();
00919        remove_movecost = stream.readInt();
00920 
00921        canExistBeneathBuildings = stream.readInt();
00922 
00923        name = stream.readString();
00924 
00925        netBehaviour = stream.readInt();
00926 
00927        displayMethod = stream.readInt();
00928 
00929        if ( version < 15 ) {
00930           Surface s;
00931           s.read( stream );
00932           s.read( stream );
00933        }
00934 
00935        techDependency.read ( stream );
00936 
00937        if ( version >= 12 )
00938           growthRate = stream.readFloat();
00939        else
00940           growthRate = 0;
00941 
00942        if ( version >= 13 )
00943           lifetime = stream.readInt();
00944        else
00945           lifetime = -1;
00946 
00947 
00948        for ( int ww = 0; ww < cwettertypennum; ww++ )
00949          if ( weather.test ( ww ) ) {
00950 
00951             int pictnum = stream.readInt();
00952             stream.readInt(  ); // weatherPicture[ww].gfxReference = 
00953 
00954             weatherPicture[ww].bi3pic.resize( pictnum );
00955             weatherPicture[ww].flip.resize( pictnum );
00956             weatherPicture[ww].images.resize( pictnum );
00957 
00958             for ( int n = 0; n < pictnum; n++ ) {
00959                int bi3 = stream.readInt();
00960                if ( bi3 == 1 ) {
00961                   weatherPicture[ww].bi3pic[n] = stream.readInt();
00962                   weatherPicture[ww].flip[n] = stream.readInt();
00963                } else {
00964                   weatherPicture[ww].bi3pic[n] = -1;
00965                   weatherPicture[ww].images[n].read ( stream );
00966                   if ( object_version >= 13 )
00967                      weatherPicture[ww].flip[n] = stream.readInt();
00968                   else   
00969                      weatherPicture[ww].flip[n] = 0;
00970                }
00971             }
00972             if ( version >= 22 )
00973                weatherPicture[ww].originalFilename = stream.readString();
00974          }
00975 
00976       if ( version >= 16 )
00977          namingMethod = NamingMethod( stream.readInt() );
00978 
00979       if ( version >= 17 )
00980          growthDuration = stream.readInt();
00981 
00982       if ( version >= 18 )
00983          rotateImage = stream.readInt();
00984 
00985       if ( version >= 19 )
00986          growOnUnits = stream.readInt();
00987 
00988       if ( version >= 20 )
00989          readClassContainer( secondaryIDs, stream );
00990 
00991    } else
00992        throw tinvalidversion  ( stream.getLocation(), object_version, version );
00993 }
00994 
00995 
00996 void ObjectType :: write ( tnstream& stream ) const
00997 {
00998     stream.writeInt ( object_version );
00999 
01000     stream.writeInt ( id );
01001     stream.writeInt ( groupID );
01002 
01003     int ___weather = 0;
01004     for ( int i = 0; i < cwettertypennum; i++ )
01005        if ( weather.test ( i ))
01006           ___weather |= 1 << i;
01007     stream.writeInt ( ___weather );
01008     stream.writeInt ( visibleago );
01009 
01010     writeClassContainer ( linkableObjects, stream );
01011     writeClassContainer ( linkableTerrain, stream );
01012 
01013     stream.writeInt ( armor );
01014 
01015     for ( int i = 0; i < cwettertypennum; i++ ) {
01016        fieldModification[i].terrainaccess.write( stream );
01017        fieldModification[i].terrain_and.write ( stream );
01018        fieldModification[i].terrain_or.write ( stream );
01019        fieldModification[i].movemalus_plus.write ( stream );
01020        fieldModification[i].movemalus_abs.write ( stream );
01021     }
01022 
01023 
01024     stream.writeInt ( attackbonus_plus );
01025     stream.writeInt ( attackbonus_abs );
01026     stream.writeInt ( defensebonus_plus );
01027     stream.writeInt ( defensebonus_abs );
01028 
01029     stream.writeInt ( basicjamming_plus );
01030     stream.writeInt ( basicjamming_abs );
01031 
01032     stream.writeInt ( viewbonus_plus );
01033     stream.writeInt ( viewbonus_abs );
01034 
01035 
01036     stream.writeInt ( imageHeight );
01037     stream.writeInt ( physicalHeight );
01038 
01039     buildcost.write( stream );
01040     removecost.write ( stream );
01041     stream.writeInt( build_movecost );
01042     stream.writeInt( remove_movecost );
01043 
01044     stream.writeInt( canExistBeneathBuildings );
01045 
01046     stream.writeString ( name );
01047 
01048     stream.writeInt ( netBehaviour );
01049 
01050     stream.writeInt ( displayMethod );
01051 
01052     techDependency.write ( stream );
01053 
01054     stream.writeFloat( growthRate );
01055     stream.writeInt( lifetime );
01056 
01057 
01058     for ( int ww = 0; ww < cwettertypennum; ww++ )
01059        if ( weather.test( ww ) ) {
01060           stream.writeInt( weatherPicture[ww].images.size() );
01061           stream.writeInt( 0 ); // weatherPicture[ww].gfxReference
01062 
01063           for ( int l = 0; l < weatherPicture[ww].images.size(); l++ ) {
01064              if ( weatherPicture[ww].bi3pic[l] >= 0 ) {
01065                 stream.writeInt ( 1 );
01066                 stream.writeInt ( weatherPicture[ww].bi3pic[l] );
01067              } else {
01068                 stream.writeInt ( 2 );
01069                 weatherPicture[ww].images[l].write( stream );
01070              }
01071              stream.writeInt ( weatherPicture[ww].flip.at(l) );
01072           }
01073           stream.writeString( weatherPicture[ww].originalFilename );
01074        }
01075 
01076     stream.writeInt( namingMethod );
01077     stream.writeInt( growthDuration );
01078     stream.writeInt( rotateImage );
01079     stream.writeInt( growOnUnits );
01080 
01081     writeClassContainer( secondaryIDs, stream );
01082 
01083 }
01084 
01085 
01086 void ObjectType :: FieldModification :: runTextIO ( PropertyContainer& pc )
01087 {
01088    pc.addDFloatArray ( "Movemalus_plus", movemalus_plus );
01089    size_t mm = movemalus_plus.size();
01090    movemalus_plus.resize( cmovemalitypenum );
01091    for ( size_t i = mm; i < cmovemalitypenum; i++ ) {
01092       if ( i == 0 )
01093          movemalus_plus[i] = 0;
01094       else
01095          movemalus_plus[i] = movemalus_plus[0];
01096    }
01097 
01098 
01099    pc.addDFloatArray ( "Movemalus_abs", movemalus_abs );
01100    mm = movemalus_abs.size();
01101    movemalus_abs.resize( cmovemalitypenum );
01102    for ( size_t i = mm; i < cmovemalitypenum; i++ ) {
01103       if ( i == 0 )
01104          movemalus_abs[i] = -1;
01105       else
01106          movemalus_abs[i] = movemalus_abs[0];
01107    }
01108 
01109    pc.openBracket ( "TerrainAccess" );
01110    terrainaccess.runTextIO ( pc );
01111    pc.closeBracket ();
01112 
01113    pc.addTagArray ( "TerrainProperties_Filter", terrain_and, terrainPropertyNum, terrainProperties, true );
01114    pc.addTagArray ( "TerrainProperties_Add", terrain_or, terrainPropertyNum, terrainProperties );
01115 }
01116 
01117 void ObjectType :: runTextIO ( PropertyContainer& pc )
01118 {
01119    pc.addBreakpoint();
01120 
01121    pc.addInteger  ( "ID", id );
01122 
01123    if ( pc.find( "SecondaryIDs") || !pc.isReading())
01124       pc.addIntegerArray("SecondaryIDs", secondaryIDs );
01125 
01126    pc.addInteger  ( "GroupID", groupID, -1 );
01127    pc.addTagArray ( "Weather", weather, cwettertypennum, weatherTags );
01128    pc.addBool     ( "visible_in_fogOfWar", visibleago );
01129    pc.addIntRangeArray ( "LinkableObjects", linkableObjects );
01130    if ( pc.find ( "LinkableTerrain" ) || !pc.isReading() )
01131       pc.addIntRangeArray ( "LinkableTerrain", linkableTerrain );
01132 
01133    pc.addBool ( "canExistBeneathBuildings", canExistBeneathBuildings, false );
01134 
01135    pc.addInteger  ( "Armor", armor );
01136 
01137    bool oldWeatherSpecification;
01138 
01139    if ( pc.find ( "Movemalus_plus" )) {
01140       oldWeatherSpecification = true;
01141 
01142       fieldModification[0].runTextIO ( pc );
01143 
01144       for ( int i = 1; i < cwettertypennum; ++i )
01145          fieldModification[i] = fieldModification[0];
01146 
01147    } else
01148       oldWeatherSpecification= false;
01149 
01150 
01151    pc.addInteger  ( "AttackBonus_abs", attackbonus_abs );
01152    pc.addInteger  ( "AttackBonus_plus", attackbonus_plus );
01153    pc.addInteger  ( "DefenseBonus_abs", defensebonus_abs );
01154    pc.addInteger  ( "DefenseBonus_plus", defensebonus_plus );
01155    pc.addInteger  ( "Jamming_abs", basicjamming_abs );
01156 
01157    if ( pc.find( "Jammming_plus"))
01158       pc.addInteger  ( "Jammming_plus", basicjamming_plus );
01159    else
01160       pc.addInteger  ( "Jamming_plus", basicjamming_plus );
01161 
01162    pc.addInteger  ( "Height", imageHeight );
01163    if ( pc.find ( "PhysicalHeight" ) || !pc.isReading() ) {
01164       pc.addInteger  ( "PhysicalHeight", physicalHeight );
01165    } else
01166       physicalHeight = imageHeight / 30;
01167 
01168    pc.addInteger  ( "ViewBonus_abs", viewbonus_abs, -1 );
01169    pc.addInteger  ( "ViewBonus_plus", viewbonus_plus, 0 );
01170 
01171    pc.openBracket ( "ConstructionCost" );
01172    buildcost.runTextIO ( pc );
01173    pc.addInteger  ( "Movement", build_movecost );
01174    pc.closeBracket ();
01175 
01176    pc.openBracket ( "RemovalCost" );
01177    removecost.runTextIO ( pc );
01178    pc.addInteger  ( "Movement", remove_movecost );
01179    pc.closeBracket ();
01180 
01181    pc.addString( "Name", name );
01182    pc.addTagInteger ( "NamingMethod", namingMethod, namingMethodNum, namingMethodNames, int(0) );
01183 
01184    pc.addDFloat( "GrowthRate", growthRate, 0 );
01185    pc.addInteger( "MaxChildSpawnNumber", growthDuration, -1 );
01186    pc.addInteger( "LifeTime", lifetime, -1 );
01187    pc.addBool( "GrowOnUnits", growOnUnits, false );
01188 
01189 
01190    pc.addTagInteger ( "NetBehaviour", netBehaviour, netBehaviourNum, objectNetMethod, int(NetToSelf) );
01191 
01192    if ( pc.isReading() && pc.find ( "NoSelfChaining" )) {
01193       bool no_autonet;
01194       pc.addBool  ( "NoSelfChaining", no_autonet );
01195       if ( !no_autonet )
01196          netBehaviour |= NetToSelf;
01197    }
01198 
01199 
01200    for ( int i = 0; i < cwettertypennum; i++ )
01201       if ( weather.test(i) ) {
01202 
01203          pc.openBracket  ( weatherTags[i] );
01204          bool bi3pics = false;
01205 
01206          if ( !pc.isReading() )
01207             for ( int j = 0; j < weatherPicture[i].bi3pic.size(); j++ )
01208                 if ( weatherPicture[i].bi3pic[j] >= 0 )
01209                    bi3pics = true;
01210 
01211          pc.addBool  ( "UseGFXpics", bi3pics );
01212          if ( bi3pics ) {
01213             pc.addIntegerArray ( "GFXpictures", weatherPicture[i].bi3pic );
01214             pc.addIntegerArray ( "FlipPictures", weatherPicture[i].flip );
01215             // int oldsize = weatherPicture[i].flip.size();
01216             weatherPicture[i].flip.resize( weatherPicture[i].bi3pic.size() );
01217             weatherPicture[i].images.resize( weatherPicture[i].bi3pic.size() );
01218          } else {
01219             ASCString s = extractFileName_withoutSuffix( filename );
01220             if ( s.empty() ) {
01221                s = "object";
01222                s += strrr(id);
01223             }
01224             ASCString filename = s + weatherAbbrev[i];
01225             pc.addImageArray ( "picture",   weatherPicture[i].images, filename );
01226             if ( pc.isReading() )
01227                weatherPicture[i].originalFilename = filename;
01228             else
01229                pc.addString( "OriginalImageFilename", weatherPicture[i].originalFilename );
01230             
01231             weatherPicture[i].bi3pic.resize( weatherPicture[i].images.size() );
01232             weatherPicture[i].flip.resize( weatherPicture[i].images.size() );
01233 
01234             if ( pc.find ( "FlipPictures" ) || !pc.isReading() ) {
01235                vector<int>   imgReferences;
01236                imgReferences.resize ( weatherPicture[i].images.size() );
01237 
01238                if ( pc.isReading() )
01239                   for ( int j = 0; j < weatherPicture[i].images.size(); j++ ) {
01240                      weatherPicture[i].bi3pic[j] = -1;
01241                      weatherPicture[i].flip[j] = 0;
01242                      imgReferences[j] = -1;
01243                   }
01244 
01245                pc.addIntegerArray ( "FlipPictures", weatherPicture[i].flip );
01246                pc.addIntegerArray ( "ImageReference", imgReferences );
01247 
01248                if ( pc.isReading() ) {
01249                   for ( int j = 0; j < weatherPicture[i].images.size(); j++ )
01250                      if ( j < imgReferences.size() && imgReferences[j] >= 0 && imgReferences[j] < weatherPicture[i].images.size() )
01251                         weatherPicture[i].images[j] = weatherPicture[i].images[imgReferences[j]];
01252    
01253                   while ( weatherPicture[i].flip.size() < weatherPicture[i].images.size() )
01254                      weatherPicture[i].flip.push_back(0);
01255                }
01256             } else {
01257                for ( int u = 0; u < weatherPicture[i].images.size(); u++ ) {
01258                   weatherPicture[i].bi3pic[u] = -1;
01259                   weatherPicture[i].flip[u] = 0;
01260                }
01261             }
01262 
01263             if ( pc.isReading() ) {
01264                int operations;
01265                std::set<void*> processedImages;
01266                pc.addNamedInteger("GraphicOperations", operations, graphicOperationNum, graphicOperations, 0 );
01267                if ( operations == 1 )  {
01268                   for ( int j = 0; j < weatherPicture[i].images.size(); j++ )
01269                      if ( processedImages.find( weatherPicture[i].images[j].getBaseSurface() ) == processedImages.end() ) {
01270                         snowify( weatherPicture[i].images[j] );
01271                         processedImages.insert( weatherPicture[i].images[j].getBaseSurface() ) ;
01272                      }
01273                } else
01274                   if ( operations == 2 )  {
01275                      for ( int j = 0; j < weatherPicture[i].images.size(); j++ )
01276                         if ( processedImages.find( weatherPicture[i].images[j].getBaseSurface() ) == processedImages.end() ) {
01277                            snowify( weatherPicture[i].images[j], false );
01278                            processedImages.insert( weatherPicture[i].images[j].getBaseSurface() ) ;
01279                         }
01280                      
01281                   } 
01282             }
01283 
01284          }
01285          
01286          if ( pc.find ( "DisplayMethod" ) || !pc.isReading() ) {
01287             pc.addNamedInteger( "DisplayMethod", displayMethod, objectDisplayingMethodNum, objectDisplayingMethodTags );
01288             if ( displayMethod == 2 && pc.isReading() && weatherPicture[i].images[0].GetPixelFormat().BitsPerPixel() != 8 )
01289                pc.error("Error parsing object " + name + " (ID=" + ASCString::toString(id)+"): invalid image; displaymethod=translation is only a available for 8 Bit images");
01290 
01291          } else
01292             displayMethod = 0;
01293 
01294          
01295          if ( !oldWeatherSpecification ) {
01296             fieldModification[i].runTextIO( pc );
01297          }
01298          pc.closeBracket (  );
01299       }
01300 
01301    techDependency.runTextIO( pc );
01302 
01303    if ( weatherPicture[0].images.size() == 1 && (netBehaviour&KeepOrientation) )
01304       rotateImage = true;
01305 
01306 
01307 
01308 }

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