示例#1
0
void Disaster::_exec( Game& game, unsigned int )
{
  Tilemap& tmap = game.city()->tilemap();
  Tile& tile = tmap.at( _pos );
  TilePos rPos = _pos;

  bool mayContinue = tile.getFlag( Tile::isDestructible );

  if( _type == Disaster::rift )
  {
    mayContinue = tile.getFlag( Tile::isConstructible );
    mayContinue |= is_kind_of<Construction>( tile.overlay() );
  }

  if( mayContinue )
  {
    Size size( 1 );

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

    switch( _type )
    {
    case Disaster::collapse:
    {
      GameEventPtr e = PlaySound::create( "explode", rand() % 2, 100 );      
      e->dispatch();
    }
    break;

    default:
    break;
    }

    city::PeacePtr peaceSrvc;
    peaceSrvc << game.city()->findService( city::Peace::defaultName() );
    if( peaceSrvc.isValid() )
    {
      peaceSrvc->buildingDestroyed( overlay, _type );
    }

    TilesArray clearedTiles = tmap.getArea( rPos, size );
    foreach( tile, clearedTiles )
    {
      bool needBuildRuins = !( _type == Disaster::rift && (*tile)->pos() == _pos );      

      TileOverlayPtr ov;
      if( needBuildRuins )
      {
        TileOverlay::Type dstr2constr[] = { objects::burning_ruins, objects::collapsed_ruins,
                                            objects::plague_ruins, objects::collapsed_ruins,
                                            objects::collapsed_ruins };

        ov = TileOverlayFactory::instance().create( dstr2constr[_type] );

        if( ov.isValid() )
        {
          SmartPtr< Ruins > ruins = ptr_cast< Ruins >( ov );
          if( ruins.isValid() )
          {
            std::string typev = _infoType > 1000
                                  ? utils::format( 0xff, "house%02d", _infoType - 1000 )
                                  : MetaDataHolder::findTypename( _infoType );
            ruins->setInfo( utils::format( 0xff, "##ruins_%s_text##", typev.c_str() ) );
            ruins->afterBuild();
          }
        }
      }
      else
      {
        ov = TileOverlayFactory::instance().create( objects::rift );

        TilesArray tiles = game.city()->tilemap().getNeighbors(_pos, Tilemap::FourNeighbors);

        /*foreach( it, tiles )
        {
          ConstructionPtr c = ptr_cast<Construction>( (*it)->overlay() );
          if( c.isValid() )
          {
            c->burn();
          }
        }*/
      }

      Dispatcher::instance().append( BuildAny::create( (*tile)->pos(), ov ) );
    }

    std::string dstr2string[] = { "##alarm_fire_in_city##", "##alarm_building_collapsed##",
                                  "##alarm_plague_in_city##", "##alarm_earthquake##" };
    emit game.city()->onDisasterEvent()( _pos, _( dstr2string[_type] ) );
  }