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 );
}
Exemple #2
0
const Picture& Road::picture( const city::AreaInfo& areaInfo) const
{
  if( areaInfo.city.isNull() )
    return Picture::getInvalid();

  Tilemap& tmap = areaInfo.city->tilemap();
  int directionFlags = 0;  // bit field, N=1, E=2, S=4, W=8
  if (!areaInfo.tiles().empty())
  {
    for( auto tile : areaInfo.tiles() )
    {
      const TilePos& epos = tile->epos();

      if( tile->getFlag( Tile::tlRoad ) || tile->overlay().is<Road>() )
      {
        const TilePos& p = areaInfo.pos;
        if( epos == p.northnb() ) directionFlags |= road2north; // road to the north
        else if ( epos == p.southnb() ) directionFlags |= road2south; // road to the south
        else if ( epos == p.eastnb() ) directionFlags |= road2east; // road to the east
        else if ( epos == p.westnb() ) directionFlags |= road2west; // road to the west
      }
    }
  }

  TilesArray roads;
  if( areaInfo.city.isValid() )
    roads = tmap.getNeighbors( areaInfo.pos, Tilemap::FourNeighbors );

  for( auto tile : roads )
  {
    const TilePos& epos = tile->epos();
    const TilePos& p = areaInfo.pos;
    if( tile->getFlag( Tile::tlRoad ) || tile->overlay().is<Road>() )
    {
      if      (epos.j() > p.j()) { directionFlags |= road2north; } // road to the north
      else if (epos.j() < p.j()) { directionFlags |= road2south; } // road to the south
      else if (epos.i() > p.i()) { directionFlags |= road2east; } // road to the east
      else if (epos.i() < p.i()) { directionFlags |= road2west; } // road to the west
    }
  }

  const TilePos& p = areaInfo.pos;
  if( areaInfo.city.isValid() )
  {
    int mapBorder = tmap.size()-1;
    if( p.i() == 0 )         { directionFlags |= road2west; }
    if( p.i() == mapBorder ) { directionFlags |= road2east; }
    if( p.j() == 0 )         { directionFlags |= road2south; }
    if( p.j() == mapBorder ) { directionFlags |= road2north; }
  }

  int index=0;
  if( _paved == 0 )
  {
    switch (directionFlags)
    {
    case 0: index = 101; break; // no road!
    case 1: // North
    {
      index = 101;
      _changeIndexIfAqueduct( areaInfo, index, 120 );
    }
    break;
    case 2: // East
    {
      index = 102;
      _changeIndexIfAqueduct( areaInfo, index, 119 );
    }
    break;
    case 4: // South
    {
      index = 103;
      _changeIndexIfAqueduct( areaInfo, index, 120 );
    }
    break;
    case 8: // West
    {
      index = 104;
      _changeIndexIfAqueduct( areaInfo, index, 119 );
    }
    break;
    case 3: index = 97;  break; // North+East
    case 5: // 93/95 // North+South
    {
      index = 93+2*((p.i() + p.j()) % 2);
      _changeIndexIfAqueduct( areaInfo, index, 120);
    }
    break;
    case 6: index = 98;  break; // East+South
    case 7: index = 106; break; // North+East+South
    case 9: index = 100; break; // North+West
    case 10: // 94/96 // East+West
    {
      index = 94+2*((p.i() + p.j())%2);
      _changeIndexIfAqueduct( areaInfo, index, 119);
    }
    break;
    case 11: index = 109; break; // North+East+West
    case 12: index = 99; break;  // South+West
    case 13: index = 108; break; // North+South+West
    case 14: index = 107; break; // East+South+West
    case 15: index = 110; break; // North+East+South+West
    }
  }
  else
  {
    switch (directionFlags)
    {
    case 0: index = 52; break; // no road!
    case 1: index = 52+4*((p.i() + p.j())%2); break; // North
    case 2: index = 53; break; // East
    case 4: index = 54; break; // South
    case 8: index = 55; break; // West
    case 3: index = 48;  break; // North+East
    case 5: index = 44+2*((p.i() + p.j())%2); break;  // 93/95 // North+South
    case 6: index = 49;  break; // East+South
    case 9: index = 51; break; // North+West
    case 10: index = 45+2*((p.i() + p.j())%2); break;  // 94/96 // East+West
    case 12: index = 50; break;  // South+West

    case 7: index = 57; break;
    case 11: index = 60; break;
    case 13: index = 59; break;
    case 14: index = 58; break;
      //index = 78 + (p.i() + p.j()) % 14; break;

    case 15: index = 61; break;
    }
  }

  static Picture ret;
  ret.load( ResourceGroup::road, index);

  return ret;
}