void PictureDao::update (Picture picture)
{
    m_database->open();

    PictureProperties properties = picture.pictureProperties();

    QString query ("UPDATE pictures SET ");

    query += "name='" + picture.name() + "',";
    query += "path=" + m_database->formatString( picture.path() ) + ",";

    query += "brightness=" + QString::number(properties.brightness) + ",";
    query += "contrast=" + QString::number(properties.contrast) + ",";
    query += "gamma=" + QString::number(properties.gamma) + ",";

    query += "wb_red=" + QString::number(properties.wb_red) + ",";
    query += "wb_green=" + QString::number(properties.wb_green) + ",";
    query += "wb_blue=" + QString::number(properties.wb_blue);

    query += " WHERE id=" + QString::number(picture.id()) + ";";

    qDebug() << query;

    m_database->exec( query );

    m_database->close();
}
Beispiel #2
0
void SdlEngine::loadPicture(Picture& ioPicture, bool streaming)
{
  if( !ioPicture.surface() )
  {
    Size size = ioPicture.size();
    Logger::warning( StringHelper::format( 0xff, "SdlEngine:: can't make surface, size=%dx%d", size.width(), size.height() ) );
  }

  SDL_Texture* tx = 0;
  if( streaming )
  {
    tx = SDL_CreateTexture(_d->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, ioPicture.width(), ioPicture.height() );
  }
  else
  {
    tx = SDL_CreateTextureFromSurface(_d->renderer, ioPicture.surface());
  }

  if( !tx )
  {
    Logger::warning( "SdlEngine: cannot create texture from surface" + ioPicture.name() );
  }

  ioPicture.init( tx, ioPicture.surface(), 0 );

  if( streaming )
  {
    ioPicture.update();
  }

  SDL_SetTextureBlendMode( ioPicture.texture(), SDL_BLENDMODE_BLEND );
  SDL_SetSurfaceBlendMode( ioPicture.surface(), SDL_BLENDMODE_BLEND );
}
Beispiel #3
0
bool Waymark::build( const city::AreaInfo& info )
{
  Tilemap& tmap = info.city->tilemap();
  TilesArray around = tmap.getNeighbors( info.pos );
  TilePos entryPos = info.city->getBorderInfo( PlayerCity::roadEntry ).epos();
  bool isEntryMark = around.contain( entryPos );

  unsigned int picIndex = isEntryMark ? 89 : 85;
  const TilePos& pos = info.pos;
  if( pos.i() == 0 || pos.i() == tmap.size() - 1 )
  {
    picIndex += (pos.i() == 0 ? 1 : 3 );
  }
  else if( pos.j() == 0 || pos.j() == tmap.size() - 1 )
  {
    picIndex += (pos.j() == 0 ? 2 : 0 );
  }
  else
  {
    Picture pic = object::Info::find( object::terrain ).randomPicture( Size::square(1) );
    Tile& oTile = tmap.at( info.pos );
    oTile.setPicture( pic );
    oTile.setImgId( imgid::fromResource( pic.name() ) );
    deleteLater();
  }

  _picture().load( config::rc.land3a, picIndex );
  _isFlat = picture().height() <= config::tilemap.cell.picSize().height();

  return Overlay::build( info );
}
Beispiel #4
0
void LoaderHelper::decodeTerrain( Tile &oTile, PlayerCityPtr city, unsigned int forceId )
{
  unsigned int imgId = oTile.originalImgId();
  TileOverlay::Type ovType = construction::unknown;
  if( oTile.getFlag( Tile::tlRoad ) )   // road
  {
    ovType = construction::road;
    Picture pic = Picture::load( ResourceGroup::land1a, 230 + math::random( 59) );
    oTile.setPicture( pic );
    oTile.setOriginalImgId( TileHelper::convPicName2Id( pic.name() ) );
  }
  else if( (imgId >= 372 && imgId <= 427) )
  {
    oTile.setFlag( Tile::tlCoast, true );
    if( imgId >= 388 )
      oTile.setFlag( Tile::tlRubble, true );
  }
  else /*if( oTile.getFlag( Tile::tlBuilding ) )*/
  {
    unsigned id = forceId > 0 ? forceId : oTile.originalImgId();
    ovType = convImgId2ovrType( id );
  }

  if( ovType == construction::unknown )
    return;

  TileOverlayPtr overlay; // This is the overlay object, if any
  overlay = TileOverlayFactory::instance().create( ovType );
  if( ovType == building::elevation )
  {
    std::string elevationPicName = TileHelper::convId2PicName( oTile.originalImgId() );
    overlay->setPicture( Picture::load( elevationPicName ) );
  }

  if( overlay != NULL )
  {
    //Logger::warning( "Building at ( %d, %d ) with ID: %x", oTile.i(), oTile.j(), oTile.originalImgId() );
    if( oTile.overlay().isValid() )
      return;

    overlay->build( city, oTile.pos() );
    city->overlays().push_back( overlay );
  }
}
void PictureDao::create (Picture picture)
{
    m_database->open();

    QString query ("INSERT INTO pictures (name,path,brightness,contrast,gamma,wb_red,wb_green,wb_blue) VALUES (");

    PictureProperties properties = picture.pictureProperties();

    query += "'" + picture.name() + "',";
    query += m_database->formatString( picture.path() ) +",";
    query += QString::number(properties.brightness) +",";
    query += QString::number(properties.contrast) +",";
    query += QString::number(properties.gamma) +",";
    query += QString::number(properties.wb_red) +",";
    query += QString::number(properties.wb_green) +",";
    query += QString::number(properties.wb_blue) +");";

    m_database->exec( query );

    m_database->close();
}
Beispiel #6
0
bool Waymark::build( const CityAreaInfo& info )
{  
  bool isEntryMark = false;

  Tilemap& tmap = info.city->tilemap();
  TilesArray around = tmap.getNeighbors( info.pos );
  TilePos entryPos = info.city->borderInfo().roadEntry;
  foreach( it, around )
  {
    if( (*it)->pos() == entryPos )
    {
      isEntryMark = true;
      break;
    }
  }

  unsigned int picIndex = isEntryMark ? 89 : 85;
  const TilePos& pos = info.pos;
  if( pos.i() == 0 || pos.i() == tmap.size() - 1 )
  {
    picIndex += (pos.i() == 0 ? 1 : 3 );
  }
  else if( pos.j() == 0 || pos.j() == tmap.size() - 1 )
  {
    picIndex += (pos.j() == 0 ? 2 : 0 );
  }
  else
  {
    Picture pic = MetaDataHolder::randomPicture( objects::terrain, Size(1) );
    Tile& oTile = tmap.at( info.pos );
    oTile.setPicture( pic );
    oTile.setOriginalImgId( imgid::fromResource( pic.name() ) );
    deleteLater();
  }

  setPicture( ResourceGroup::land3a, picIndex );
  _isFlat = picture().height() <= tilemap::cellPicSize().height();

  return TileOverlay::build( info );
}
Beispiel #7
0
bool C3Sav::Impl::loadCity( std::fstream& f, Game& game )
{
    uint32_t tmp;

    // need to rewrite better
    std::vector<short int> graphicGrid;
    graphicGrid.resize( 26244, 0 );
    std::vector<unsigned char> edgeGrid;
    edgeGrid.resize( 26244, 0 );
    std::vector<short int> terrainGrid;
    terrainGrid.resize( 26244, 0 );
    std::vector<unsigned char> rndmTerGrid;
    rndmTerGrid.resize(26244, 0);
    std::vector<unsigned char> randomGrid;
    randomGrid.resize( 26244, 0 );
    std::vector<unsigned char> zeroGrid;
    zeroGrid.resize( 26244, 0 );

    if( !f.is_open() )
    {
        Logger::warning( "GameLoaderC3Sav: can't open file " );
        return false;
    }

    f.read( (char*)&tmp, 4); // read dummy

    std::string cityName = LoaderHelper::getDefaultCityName( tmp );
    game.city()->setName( cityName );

    f.read((char*)&tmp, 4); // read scenario flag

    try
    {
        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed ids is %d", tmp );
        PKWareInputStream *pk = new PKWareInputStream(&f, false, tmp);
        for (int i = 0; i < 162 * 162; i++)
        {
            graphicGrid[i] = pk->readShort();
        }
        pk->empty();
        delete pk;

        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed egdes is %d", tmp );
        pk = new PKWareInputStream(&f, false, tmp);
        for (int i = 0; i < 162 * 162; i++)
        {
            edgeGrid[i] = pk->readByte();
        }
        pk->empty();
        delete pk;

        SkipCompressed(f); // skip building ids

        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed terraindata is %d", tmp );
        pk = new PKWareInputStream(&f, false, tmp);
        for (int i = 0; i < 162 * 162; i++)
        {
            terrainGrid[i] = pk->readShort();
        }
        pk->empty();
        delete pk;

        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);

        f.read((char*)&randomGrid[0], 26244);

        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);

        // here goes walkers array
        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed walkers data is %d", tmp );
        pk = new PKWareInputStream(&f, false, tmp);
        for (int j = 0; j < 1000; j++)
        {
            pk->skip(10);
            pk->readShort();
            pk->skip(8);
            pk->readByte();
            pk->readByte();
            pk->skip(106);
        }
        pk->empty();
        delete pk;
        int length;
        f.read((char*)&length, 4); // read next length :-)

        if (length <= 0)
            f.seekg(1200, std::ios::cur);
        else
            f.seekg(length, std::ios::cur);

        SkipCompressed(f);
        SkipCompressed(f);

        // 3x int
        f.read((char*)&tmp, 4);
        f.read((char*)&tmp, 4);
        f.read((char*)&tmp, 4);
        SkipCompressed(f);
        f.seekg(70, std::ios::cur);
        SkipCompressed(f); // skip building list
        f.seekg(208, std::ios::cur);
        SkipCompressed(f); // skip unknown
        f.seekg(788, std::ios::cur); // skip unused data
        f.read((char*)&tmp, 4); //mapsize

        int size = tmp;
        PlayerCityPtr oCity = game.city();
        Tilemap& oTilemap = oCity->tilemap();

        oCity->resize(size);
        oCity->setCameraPos( TilePos( 0, 0 ) );

        initEntryExit( f, game.city() );

        f.seekg(1312, std::ios::cur);
        char climate;
        f.read(&climate, 1);
        oCity->setClimate((ClimateType)climate);

        // here goes the WORK!


        // loads the graphics map
        int border_size = (162 - size) / 2;

        std::map< int, std::map< int, unsigned char > > edgeData;

        game.city()->setCameraPos( TilePos( size/2, size/2 ) );

        for (int itA = 0; itA < size; ++itA)
        {
            for (int itB = 0; itB < size; ++itB)
            {
                int i = itB;
                int j = size - itA - 1;

                int index = 162 * (border_size + itA) + border_size + itB;

                Tile& tile = oTilemap.at(i, j);

                unsigned int imgId = graphicGrid[index];
                Picture pic = imgid::toPicture( imgId );

                if( pic.isValid() )
                {
                    tile.setPicture( pic );
                    tile.setOriginalImgId( imgId );
                }
                else
                {
                    TileOverlay::Type ovType = LoaderHelper::convImgId2ovrType( imgId );
                    if( ovType == constants::objects::unknown )
                    {
                        Logger::warning( "!!! GameLoaderC3Sav: Unknown building %x at [%d,%d]", imgId, i, j );
                    }

                    baseBuildings[ tile.pos() ] = imgId;
                    pic = Picture::load( ResourceGroup::land1a, 230 + math::random( 57 ) );
                    tile.setPicture( pic );
                    tile.setOriginalImgId( imgid::fromResource( pic.name() ) );
                }

                edgeData[ i ][ j ] = edgeGrid[index];
                tile::decode( tile, terrainGrid[index] );
                tile::fixPlateauFlags( tile );
            }
        }

        for (int i = 0; i < size; ++i)
        {
            for (int j = 0; j < size; ++j)
            {
                unsigned char ed = edgeData[ i][ j ];
                if( ed == 0x00)
                {
                    int size = 1;

                    {
                        int dj;
                        try
                        {
                            // find size, 5 is maximal size for building
                            for (dj = 0; dj < 5; ++dj)
                            {
                                int edd = edgeData[ i ][ j - dj ];
                                // find bottom left corner
                                if (edd == 8 * dj + 0x40)
                                {
                                    size = dj + 1;
                                    break;
                                }
                            }
                        }
                        catch(...)
                        {
                            size = dj + 1;
                        }
                    }

                    Tile& master = oTilemap.at(i, j - size + 1);

                    //Logger::warning( "Master will be at (%d,%d)", master.i(), master.j() );
                    for (int di = 0; di < size; ++di)
                    {
                        for (int dj = 0; dj < size; ++dj)
                        {
                            oTilemap.at(master.i() + di, master.j() + dj).setMasterTile(&master);
                        }
                    }
                }

                // Check if it is building and type of building
                //if (ttile.getMasterTile() == NULL)
                std::map<TilePos, unsigned int>::iterator bbIt = baseBuildings.find( TilePos( i, j ) );
                unsigned int bbImgId = bbIt == baseBuildings.end() ? 0 : bbIt->second;

                Tile& tile = oTilemap.at( i, j );
                Tile* masterTile = tile.masterTile();
                if( !masterTile )
                    masterTile = &tile;

                if( masterTile->overlay().isNull() )
                {
                    LoaderHelper::decodeTerrain( *masterTile, oCity, bbImgId );
                }
            }
        }

    }
    catch(PKException)
    {
        THROW("fatal error when unpacking");
    }

    return true;
}
static void __finalizeMap(Game& game, int pass )
{
  PlayerCityPtr oCity = game.city();
  Tilemap& oTilemap = oCity->tilemap();
  unsigned int mapSize = oTilemap.size();

  //check one water tiles
  for( unsigned int i=0; i < mapSize; i++ )
    for( unsigned int j=0; j < mapSize; j++ )
    {
      TilePos tpos = TilePos( i, j );
      Tile& wtile = oTilemap.at( tpos );
      if( wtile.originalImgId() > 0 )
        continue;

      int direction = 0;
      for( int k=0; k < 8; k++ )
      {
        Tile& t = oTilemap.at( tpos + psAr[k] );
        bool isWater = !t.getFlag( Tile::tlCoast ) && ( t.getFlag( Tile::tlWater ) || t.getFlag( Tile::tlDeepWater ) );
        if( isWater )
        {
          direction += directions[k];
        }
      }


      int start=0, rnd=4;
      switch( pass )
      {
      case passCheckNorthCoastTiles:
        switch( direction )
        {
        case drN: case drN|drNW: case drNW|drNE|drN: case drNE|drN: case drNE|drNW: start=128; break;
        }
      break;

      case passCheckEastCoastTiles:
        switch( direction )
        {
        case drE: case drNE|drE: case drNE|drSE: case drNE|drSE|drE: case drSE|drE: start=132; break;
        }
      break;

      case passCheckSouthCoastTiles:
        switch( direction )
        {
        case drS: case drSW|drS: case drSE|drS: case drSW|drSE|drS: case drSW|drSE: start=136; break;
        }
      break;

      case passCheckWestCoastTiles:
        switch( direction )
        {
        case drW: case drSW|drNW|drW: case drSW|drW: case drNW|drW: case drSW|drNW: start=140; break;
        }
      break;

      case passCheckSmallCoastTiles:
        switch( direction )
        {
        case drE|drS|drSE:
        case drE|drNE|drSE|drS:
        case drE|drSW|drSE|drS:
        case drE|drSW|drSE|drS|drNE:
        case drE|drSW|drSE|drNE:
        case drE|drSW|drNE: case drNE|drSE|drSW|drS:
        case drSE|drNE|drS: case drNE|drS|drE: case drSW|drE:
        case drSW|drS|drE: case drNE|drS: case drNE|drSW|drS:
        case drNE|drSW|drE|drS:
        case drE|drS: case drNE|drSE|drSW: case drSW|drSE|drE: start = 171; rnd=0; break;

        case drNW|drSW|drW|drN: case drNW|drW|drN: case drNW|drNE|drW|drN:
        case drNW|drNE|drW: case 0xd9: case 0x58: case 0x19:
        case 0xd8: case 0xd1: case 0x49: case 0x18: case 0xc1: case 0x41:
        case 0x51: case 0x09: case 0x59: case 0xd0: start=173; rnd=0; break;

        case 0x13: case 0xb1: case 0x23: case 0x93: case 0x33: case 0xb3: case 0x83:
        case 0x31: case 0xa3: case 0x21: case 0x82: case 0xa1: case 0xa2: case 0x92:
        case 0xb2: case 0x03: case 0xb0: start=170; rnd=0; break;

        case 0xa0: start=168; rnd=0; break;
        case 0x50: start=169; rnd=0; break;

        case 0xcc: case 0x4c: case 0x6c: case 0xec:
        case 0xc4: case 0x68: case 0xe4: case 0xe8: case 0xa8: case 0x84:
        case 0x28: case 0xac: case 0xa4: case 0x0c: case 0x8c: case 0x2c:
        case 0xe0:  start = 172; rnd=0; break;
        }
      break;

      case 6:
      break;

      case passCheckInsideCornerTiles:
        switch( direction )
        {
        case drNE: start=PicID::coastNE; break;
        case drSE: start=PicID::coastSE; break;
        case 0x40: start=152; break;
        case 0x80: start=156; break;
        }
      break;

      case 8:
        switch( direction )
        {
        case 0x6e: case 0xed: case 0x9b: case 0xcd: case 0xff: case 0xee:
        case 0xdf: case 0x05: case 0x37: case 0x77: case 0xfb: case 0x9a:
        case 0xeb: case 0xa5: case 0xf9: case 0xb7: case 0xbf: case 0x1b:
        case 0x35: case 0xe5: case 0x95: case 0x17: case 0x7d: case 0xe7:
        case 0xad: case 0x71: case 0xdc: case 0xdb: case 0xa6: case 0xb9:
        case 0xa7: case 0x27: case 0xdd: case 0xf3: case 0x7e: case 0x75:
        case 0xd3: case 0xc5: case 0x55: case 0xfe: case 0xbb: case 0x7c:
        case 0x5a: case 0x53: case 0x45: case 0xce: case 0xef: case 0x7f:
        case 0x8d: case 0x1d: case 0xf5: case 0xf7: case 0xf1:
        case 0x97: case 0x2e: case 0xc3: case 0x5c: case 0x0a: case 0x69:
        case 0xb5: case 0x25: case 0x8a: case 0x3b: case 0xe6: case 0x6a:
        case 0xcb: case 0x3f: case 0xaa: case 0x57: case 0xfd: case 0xd5:
        case 0x7a: case 0x85: case 0xfc: case 0xca: case 0x8b: case 0x9f:
        case 0x4f: case 0xde: case 0x9d: case 0xe9: case 0x6f: case 0xd7:
        case 0xae: case 0xaf: case 0xf8: case 0x3c: case 0xe2: case 0xea:
        case 0x96: case 0x3a: case 0xcf: case 0xbd: case 0xbe: case 0x94:
        case 0x73: case 0x4a: case 0xc6: case 0x5d: case 0x2a: case 0xa9:
        case 0x6d: case 0xf4: case 0xda: case 0x5e: case 0xfa: case 0x7b:
        case 0x79: case 0x65: case 0xc7: case 0xe1: case 0x4d: case 0x2b:
        case 0xab: case 0x0e: case 0x87: case 0x1a: case 0x67: case 0x3d:
        case 0xf6: case 0x1f: case 0xd6: case 0xb4: case 0x8f: case 0x9c:
        case 0x48: case 0x5f: case 0x5b: case 0xd4: case 0xf0: case 0x0f:
        case 0x15: case 0x0b: case 0xb8: case 0x07: case 0x1c: case 0x61:
        case 0x8e: case 0x86: case 0x2d: case 0x4b: case 0xe3: case 0xc2:
        case 0xba: case 0xf2: case 0x1e: case 0x39: case 0x38: case 0xd2:
        case 0x78: case 0x0d: case 0x6b: case 0x3e: case 0x63: case 0x29:
        case 0x47: case 0x21: case 0xbc: case 0x2f: case 0xb6: case 0x43:
        case 0x9e: case 0x4e: start=120; rnd=0; break;
        }
      break;

      case 9:
        switch( direction )
        {
        case 0:
        {
          Picture pic = Picture::load( ResourceGroup::land1a, 62 + math::random( 57 ) );
          wtile.setPicture( pic );
          //wtile.setOriginalImgId( TileHelper::convPicName2Id( pic.name() ) );
          wtile.setOriginalImgId( direction );
        }
        break;
        }
      break;

      case 0xff:
        wtile.setOriginalImgId( direction );
      break;
      }

      if( start > 0 )
      {
        if( rnd > 0 )
          rnd = math::random( 4 );

        wtile.setFlag( Tile::tlWater, true );
        wtile.setFlag( Tile::tlCoast, true );
        Picture pic = Picture::load( ResourceGroup::land1a, start + rnd );
        wtile.setPicture( pic );
        wtile.setOriginalImgId( imgid::fromResource( pic.name() ) );
      }
    }
}
void ClearTile::_exec( Game& game, unsigned int )
{
  Tilemap& tmap = game.city()->tilemap();

  Tile& cursorTile = tmap.at( _pos );

  if( cursorTile.getFlag( Tile::isDestructible ) )
  {
    Size size( 1 );
    TilePos rPos = _pos;

    OverlayPtr overlay = cursorTile.overlay();

    bool deleteRoad = cursorTile.getFlag( Tile::tlRoad );

    if( overlay.isValid()  )
    {
      const MetaData& md = MetaDataHolder::find( overlay->type() );
      if( !overlay->canDestroy() )
      {
        GameEventPtr e = WarningMessage::create( _( overlay->errorDesc() ), WarningMessage::neitral );
        e->dispatch();

        if( md.getFlag( MetaDataOptions::requestDestroy, false ) )
        {
          e = RequestDestroy::create( overlay );
          e->dispatch();
        }
        return;
      }

      if( md.getFlag( MetaDataOptions::precisionDestroy, false ) )
      {
        //overlay->partlyDestroy( _pos );
      }
    }

    if( overlay.isValid() )
    {
      size = overlay->size();
      rPos = overlay->pos();
      overlay->deleteLater();
    }

    TilesArray clearedTiles = tmap.area( rPos, size );
    for( auto tile : clearedTiles )
    {
      tile->setMaster( NULL );
      tile->setFlag( Tile::tlTree, false);
      tile->setFlag( Tile::tlRoad, false);
      tile->setFlag( Tile::tlGarden, false);
      tile->setOverlay( NULL );

      deleteRoad |= tile->getFlag( Tile::tlRoad );

      if( tile->getFlag( Tile::tlMeadow ) || tile->getFlag( Tile::tlWater ) )
      {
        //tile->setPicture( imgid::toResource( tile->originalImgId() ) );
      }
      else
      {
        // choose a random landscape picture:
        // flat land1a 2-9;
        // wheat: land1a 18-29;
        // green_something: land1a 62-119;  => 58
        // green_flat: land1a 232-289; => 58

        // choose a random background image, green_something 62-119 or green_flat 232-240
        // 30% => choose green_sth 62-119
        // 70% => choose green_flat 232-289
        int startOffset  = ( (math::random( 10 ) > 6) ? 62 : 232 );
        int imgId = math::random( 58-1 );

        Picture pic;
        pic.load( ResourceGroup::land1a, startOffset + imgId );
        tile->setPicture( pic );
        tile->setImgId( imgid::fromResource( pic.name() ) );
      }
    }

    // recompute roads;
    // there is problem that we NEED to recompute all roads map for all buildings
    // because MaxDistance2Road can be any number
    //
    if( deleteRoad )
    {
      game.city()->setOption( PlayerCity::updateRoads, 1 );
    }
  }

  game.city()->setOption( PlayerCity::updateTiles, 1 );
}
Beispiel #10
0
void LoaderHelper::decodeTerrain( Tile &oTile, PlayerCityPtr city, unsigned int forceId )
{
  int changeId = 0;
  unsigned int imgId = oTile.originalImgId();
  object::Type ovType = object::unknown;
  if( oTile.getFlag( Tile::tlRoad ) )   // road
  {
    ovType = object::road;
    Picture pic = MetaDataHolder::randomPicture( object::terrain, Size(1) );
    oTile.setPicture( pic );
    changeId = imgid::fromResource( pic.name() );
  }
  else if( oTile.getFlag( Tile::tlTree ) )
  {
    ovType = object::tree;
    Picture pic = MetaDataHolder::randomPicture( object::terrain, Size(1) );
    oTile.setPicture( pic );
    changeId = imgid::fromResource( pic.name() );
  }
  else if( oTile.getFlag( Tile::tlMeadow ) )
  {
    /*bool oldgfx = !SETTINGS_VALUE( c3gfx ).toString().empty();
    oldgfx |= SETTINGS_VALUE( oldgfx ).toBool();
    if( !oldgfx )
    {
      Picture pic = MetaDataHolder::randomPicture( objects::meadow, Size(1) );
      oTile.setPicture( pic );
      changeId = imgid::fromResource( pic.name() );
    }*/
  } 
  else if( imgId >= 0x29c && imgId <= 0x2a1 ) //aqueduct
  {
    ovType = object::aqueduct;
    Picture pic = MetaDataHolder::randomPicture( object::terrain, Size(1) );
    oTile.setPicture( pic );
    oTile.setFlag( Tile::clearAll, true );
    changeId = imgid::fromResource( pic.name() );
  }
  else if( imgId >= 372 && imgId <= 427 )
  {
    oTile.setFlag( Tile::tlCoast, true );
    if( imgId >= 388 )
      oTile.setFlag( Tile::tlRubble, true );
  }
  else if( imgId >= 863 && imgId <= 870 )
  {
    Picture pic = MetaDataHolder::randomPicture( object::terrain, Size(1) );
    oTile.setPicture( pic );
    oTile.setFlag( Tile::clearAll, true );    
    changeId = imgid::fromResource( pic.name() );
    oTile.setOriginalImgId( changeId );
  }
  else
  {
    unsigned id = forceId > 0 ? forceId : oTile.originalImgId();
    ovType = convImgId2ovrType( id );
  }

  if( ovType == object::unknown )
    return;

  OverlayPtr overlay; // This is the overlay object, if any
  overlay = TileOverlayFactory::instance().create( ovType );
  if( ovType == object::elevation )
  {
    std::string elevationPicName = imgid::toResource( oTile.originalImgId() );
    overlay->setPicture( Picture( elevationPicName ) );
  }

  if( overlay != NULL )
  {
    //Logger::warning( "Building at ( %d, %d ) with ID: %x", oTile.i(), oTile.j(), oTile.originalImgId() );
    if( oTile.overlay().isValid() )
      return;

    city::AreaInfo info( city, oTile.pos() );
    overlay->build( info );
    city->addOverlay( overlay );
  }  

  if( changeId > 0 )
  {
    oTile.setOriginalImgId( changeId );
  }
}