示例#1
0
void Unemployed::drawTile(Engine& engine, Tile& tile, const Point& offset)
{
  Point screenPos = tile.mappos() + offset;

  if( tile.overlay().isNull() )
  {
    //draw background
    //engine.draw( tile.picture(), screenPos );

    drawPass( engine, tile, offset, Renderer::ground );
    drawPass( engine, tile, offset, Renderer::groundAnimation );
  }
  else
  {
    bool needDrawAnimations = false;
    OverlayPtr overlay = tile.overlay();
    WorkingBuildingPtr workBuilding = overlay.as<WorkingBuilding>();
    int worklessPercent = 0;

    if( _isVisibleObject( overlay->type() ) )
    {
      needDrawAnimations = true;
    }
    else if( overlay->type() == object::house )
    {
      HousePtr house = overlay.as<House>();

      int worklessNumber = (int)house->getServiceValue( Service::recruter );
      int matureNumber = (int)house->habitants().mature_n();
      worklessPercent = math::percentage( worklessNumber, matureNumber );
      needDrawAnimations = (house->spec().level() == 1) && house->habitants().empty();

      if( !needDrawAnimations )
      {
        drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase );
      }
    }
    else if( workBuilding.isValid() )
    {
      worklessPercent = math::percentage( workBuilding->needWorkers(), workBuilding->maximumWorkers() );
      needDrawAnimations = workBuilding->needWorkers() > 0;
      if( !needDrawAnimations )
        drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base );
    }

    if( needDrawAnimations )
    {
      Layer::drawTile( engine, tile, offset );
      registerTileForRendering( tile );
    }
    else if( worklessPercent > 0 )
    {
      drawColumn( engine, screenPos, worklessPercent );
    }
  }

  tile.setWasDrawn();
}
void AboutConstruction::_resolveToggleWorking()
{
  WorkingBuildingPtr working = base().as<WorkingBuilding>();
  if( working.isValid() )
  {
    working->setActive( !working->isActive() );
    _setWorkingActive( working->isActive() );
  }
}
示例#3
0
InfoBoxWorkingBuilding::InfoBoxWorkingBuilding( Widget* parent, WorkingBuildingPtr building)
    : GuiInfoBox( parent, Rect( 0, 0, 510, 256 ), -1 ), _sd( new Impl )
{
  _sd->building = building;
  setTitle( BuildingDataHolder::instance().getData( building->getType() ).getPrettyName() );
  paint(); 
}
示例#4
0
void Unemployed::handleEvent(NEvent& event)
{
  if( event.EventType == sEventMouse )
  {
    switch( event.mouse.type  )
    {
    case mouseMoved:
    {
      Tile* tile = _camera()->at( event.mouse.pos(), false );  // tile under the cursor (or NULL)
      std::string text = "";
      if( tile != 0 )
      {
        HousePtr house = tile->overlay().as<House>();
        WorkingBuildingPtr workBuilding = tile->overlay().as<WorkingBuilding>();

        if( house.isValid() )
        {
          int workless = house->getServiceValue( Service::recruter );

          if( workless > 0 )
            text = utils::format( 0xff, "%s %d %s", _("##this_house_have##"), workless, _("##unemployers##") );
          else
            text = "##this_house_haveno_unemployers##";
        }
        else if( workBuilding.isValid() )
        {
          int need = workBuilding->needWorkers();

          if( need > 0 )
            text = utils::format( 0xff, "%s %d %s", _("##this_building_need##"), need, _("##workers##") );
          else
            text = "##this_building_have_all_workers##";
        }
      }

      _setTooltipText( text );
    }
    break;

    default: break;
    }
  }

  Layer::handleEvent( event );
}
bool WorkersHire::Impl::haveRecruter( WorkingBuildingPtr building )
{
  for( auto recruter : recrutesInCity )
  {
    if( recruter->baseLocation() == building->pos() )
        return true;
  }

  return false;
}
void WorkersHire::Impl::hireWorkers(PlayerCityPtr city, WorkingBuildingPtr bld)
{
  if( excludeTypes.count( bld->type() ) > 0 )
    return;

  if( bld->numberWorkers() == bld->maximumWorkers() )
    return;

  if( haveRecruter( bld ) )
    return;

  if( bld->roadside().size() > 0 )
  {
    RecruterPtr hr = Recruter::create( city );
    hr->setPriority( priorities );
    hr->setMaxDistance( distance );

    hr->send2City( bld, bld->needWorkers() );
  }
}
示例#7
0
void FireWorkers::exec(Game& game)
{
  Tilemap& tilemap = game.getCity()->getTilemap();
  const int defaultFireWorkersDistance = 40;

  for( int curRange=1; curRange < defaultFireWorkersDistance; curRange++ )
  {
    TilemapArea perimetr = tilemap.getRectangle( _center - TilePos( curRange, curRange ),
                                                 _center + TilePos( curRange, curRange ) );
    foreach( Tile* tile, perimetr )
    {
      WorkingBuildingPtr wrkBuilding = tile->getOverlay().as<WorkingBuilding>();
      if( wrkBuilding.isValid() )
      {
        int bldWorkersCount = wrkBuilding->getWorkersCount();
        wrkBuilding->removeWorkers( _workers );
        _workers -= math::clamp<int>( bldWorkersCount, 0, _workers );
      }

      if( !_workers )
        return;
    }
  }
示例#8
0
int Statistic::_Objects::laborAccess(WorkingBuildingPtr wb) const
{
  if( wb.isNull() )
    return 0;

  TilePos offset( maxLaborDistance, maxLaborDistance );
  TilePos wbpos = wb->pos();
  HouseList houses = find<House>( object::house, wbpos - offset, wbpos + offset );
  float averageDistance = 0;
  for( auto house : houses )
  {
    if( house->level() > HouseLevel::vacantLot
        && house->level() < HouseLevel::smallVilla )
    {
      averageDistance += wbpos.distanceFrom( house->pos() );
    }
  }

  if( houses.size() > 0 )
    averageDistance /= houses.size();

  return math::clamp( math::percentage( averageDistance, maxLaborDistance ) * 2, 25, 100 );
}
示例#9
0
void FireWorkers::_exec(Game& game, unsigned int)
{
  Tilemap& tilemap = game.city()->tilemap();

  for( int curRange=1; curRange < defaultReturnWorkersDistance; curRange++ )
  {
    TilePos range( curRange, curRange );
    TilesArray perimetr = tilemap.rect( _center - range,
                                                _center + range );
    for( auto& tile : perimetr )
    {
      WorkingBuildingPtr wrkBuilding = tile->overlay<WorkingBuilding>();
      if( wrkBuilding.isValid() )
      {
        int removedFromWb = wrkBuilding->removeWorkers( _workers );
        _workers -= removedFromWb;
      }

      if( !_workers )
        return;
    }
  }

  if( _workers > 0 )
  {
    WorkingBuildingList buildings = game.city()->statistic().objects.find<WorkingBuilding>( object::any );
    for( auto&& building : buildings )
    {
      int removedFromWb = building->removeWorkers( _workers );
      _workers -= removedFromWb;

      if( !_workers )
        return;
    }
  }
}
void CityServiceWorkersHire::_hireByType( const BuildingType type )
{
  CityHelper hlp( _city );
  WorkingBuildings buildings = hlp.getBuildings< WorkingBuilding >( type );
  for( WorkingBuildings::iterator it = buildings.begin(); it != buildings.end(); ++it )
  {
    WorkingBuildingPtr wb = *it;
    if( _haveHr( wb ) )
      continue;

    if( wb.isValid() && wb->getAccessRoads().size() > 0 
        && wb->getWorkers() < wb->getMaxWorkers() )
    {
      WorkersHunterPtr hr = WorkersHunter::create( _city );
      hr->setMaxDistance( 20 );
      hr->send2City( wb, wb->getMaxWorkers() - wb->getWorkers());
    }
  }
}
void AboutConstruction::_updateWorkingText()
{
  WorkingBuildingPtr working = base().as<WorkingBuilding>();
  _setWorkingActive( working.isValid() ? working->isActive() : false );
}
示例#12
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();
    }
  }
}
 foreach( WorkingBuildingPtr building, buildings )
 {
   ret.currentWorkers += building->getWorkers();
   ret.needWorkers += building->getMaxWorkers();
 }