示例#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] ) );
  }
示例#2
0
void BuildAny::_exec( Game& game, unsigned int )
{  
  if( _overlay.isNull() )
    return;

  TileOverlayPtr ctOv = game.city()->getOverlay( _pos );

  bool mayBuild = true;
  if( ctOv.isValid() )
  {
    mayBuild = ctOv->isDestructible();
  }

  city::Helper helper( game.city() );
  TilePos offset(10, 10);
  EnemySoldierList enemies = helper.find<EnemySoldier>( walker::any, _pos - offset, _pos + offset );
  if( !enemies.empty() && _overlay->group() != objects::disasterGroup )
  {
    GameEventPtr e = WarningMessage::create( "##too_close_to_enemy_troops##" );
    e->dispatch();
    return;
  }

  if( !_overlay->isDeleted() && mayBuild )
  {
    CityAreaInfo info = { game.city(), _pos, TilesArray() };
    bool buildOk = _overlay->build( info );

    if( !buildOk )
      return;

    helper.updateDesirability( _overlay, city::Helper::onDesirability );
    game.city()->addOverlay( _overlay );

    ConstructionPtr construction = ptr_cast<Construction>( _overlay );
    if( construction.isValid() )
    {
      const MetaData& buildingData = MetaDataHolder::getData( _overlay->type() );
      game.city()->funds().resolveIssue( FundIssue( city::Funds::buildConstruction,
                                                    -(int)buildingData.getOption( MetaDataOptions::cost ) ) );

      if( construction->group() != objects::disasterGroup )
      {
        GameEventPtr e = PlaySound::create( "buildok", 1, 100 );
        e->dispatch();
      }

      if( construction->isNeedRoadAccess() && construction->getAccessRoads().empty() )
      {
        GameEventPtr e = WarningMessage::create( "##building_need_road_access##" );
        e->dispatch();
      }

      std::string error = construction->errorDesc();
      if( !error.empty() )
      {
        GameEventPtr e = WarningMessage::create( error );
        e->dispatch();
      }

      WorkingBuildingPtr wb = ptr_cast<WorkingBuilding>( construction );
      if( wb.isValid() && wb->maximumWorkers() > 0 )
      {
        unsigned int worklessCount = statistic::getWorklessNumber( game.city() );
        if( worklessCount < wb->maximumWorkers() )
        {
          GameEventPtr e = WarningMessage::create( "##city_need_more_workers##" );
          e->dispatch();
        }
      }
    }
  }
  else
  {
    ConstructionPtr construction = ptr_cast<Construction>( _overlay );
    if( construction.isValid() )
    {
      GameEventPtr e = WarningMessage::create( construction->errorDesc() );
      e->dispatch();
    }
  }
}