void HealthCare::Impl::updateReasons( PlayerCityPtr city )
{
  int lvl = math::clamp<int>( value / (health::maxValue/health::levelNumber), 0, health::levelNumber-1 );
  std::string mainReason = healthDescription[ lvl ];

  int clinics_n = city->statistic().objects.count( object::clinic );

  mainReason += clinics_n > 0 ? "_clinic##" : "##";

  reasons << mainReason;
  if( lvl > health::levelNumber / 3 )
  {
    for( int i=0; reasonsInfo[ i ].type != object::unknown; i++ )
    {
      object::TypeSet availableTypes;
      availableTypes.insert( reasonsInfo[ i ].type );

      HouseList housesWantEvolve = city->statistic().houses.ready4evolve( availableTypes );
      if( housesWantEvolve.size() > 0 )
      {
        reasons << reasonsInfo[i].info;
      }
    }
  }
}
示例#2
0
void Migration::Impl::createMigrationFromCity( PlayerCityPtr city )
{
  HouseList houses = city->statistic().houses.find();
  const int minWorkersNumber = 4;
  for( HouseList::iterator i=houses.begin(); i != houses.end(); )
  {
    int houseWorkless = (*i)->unemployed();

    if( !(*i)->enterArea().empty() && houseWorkless > minWorkersNumber ) { ++i; }
    else { i = houses.erase( i ); }
  }

  if( !houses.empty() )
  {
    int number = math::random( houses.size() );
    HouseList randHouses = houses.random( number );
    for( auto house : randHouses )
    {
      ImmigrantPtr emigrant = Immigrant::create( city );
      if( emigrant.isValid() )
      {
        house->removeHabitants( minWorkersNumber );
        emigrant->leaveCity( *(house->enterArea().front()) );
        emigrant->setThinks( "##immigrant_no_work_for_me##" );
      }
    }
  }
}
示例#3
0
void Neptune::_doBlessing(PlayerCityPtr city)
{
  FishingBoatList boats = city->statistic().walkers.find<FishingBoat>( walker::fishingBoat, TilePos(-1, -1));

  boats = boats.random( math::max<size_t>( boats.size() / 5, 5 ) );
  for( auto boat : boats )
  {
    boat->addFish( boat->fishMax() - boat->fishQty() );
  }
}
void Disorder::Impl::changeCrimeLevel(PlayerCityPtr city, int delta )
{
  city->statistic().houses
                   .find()
                   .for_each(
                              [delta](HousePtr house)
                              {
                                house->appendServiceValue( Service::crime, delta );
                              }
                            );
}
示例#5
0
Info::Parameters Migration::Impl::lastMonthParams( PlayerCityPtr city )
{
  InfoPtr info = city->statistic().services.find<Info>();

  Info::Parameters params;
  if( info.isValid() )
  {
    params = info->lastParams();
  }

  return params;
}
示例#6
0
void Level::Impl::checkFailedMission( Level* lvl, bool forceFailed )
{
  PlayerCityPtr pcity = game->city();

  const city::VictoryConditions& vc = pcity->victoryConditions();
  MilitaryPtr mil = pcity->statistic().services.find<Military>();
  InfoPtr info = pcity->statistic().services.find<Info>();

  if (mil.isValid() && info.isValid())
  {
    const city::Info::MaxParameters& params = info->maxParams();

    bool failedByDestroy = mil->value() > 0 && params[ Info::population ].value > 0 && !pcity->states().population;
    bool failedByTime = ( !vc.isSuccess() && game::Date::current() > vc.finishDate() );

    if( failedByDestroy || failedByTime || forceFailed )
    {
      game->pause();
      events::dispatch<ScriptFunc>("OnMissionLose");
      steamapi::missionLose(vc.name());
    }
  }
}
示例#7
0
unsigned int Migration::Impl::calcVacantHouse( PlayerCityPtr city )
{
  unsigned int vh = 0;
  HouseList houses = city->statistic().houses.find();
  for( auto house : houses )
  {
    if( house->roadside().size() > 0 && house->state( pr::settleLock ) == 0 )
    {
      vh += math::clamp<int>( house->capacity() - house->habitants().count(), 0, 0xff );
    }
  }

  return vh;
}
示例#8
0
void Neptune::_doSmallCurse(PlayerCityPtr city)
{
  GameEventPtr event = ShowInfobox::create( _("##smallcurse_of_neptune_title##"),
                                            _("##smallcurse_of_neptune_description##"),
                                            ShowInfobox::send2scribe );
  event->dispatch();

  DockList docks = city->statistic().objects.find<Dock>();

  DockPtr dock = docks.random();
  if( dock.isValid() )
  {
    dock->collapse();
  }
}
示例#9
0
void Notify::_exec(Game& game, unsigned int)
{
  world::CityPtr pCity = game.empire()->findCity( _d->cityname );

  PlayerCityPtr plrCity = ptr_cast<PlayerCity>( pCity );
  if( plrCity.isValid() )
  {    
    MilitaryPtr mil = plrCity->statistic().services.find<Military>();

    if( mil.isValid() )
    {
      mil->addNotification( _d->message, _d->object, (Notification::Type)_d->type );
    }
  }
}
示例#10
0
std::string WalkerThinks::check(WalkerPtr walker, PlayerCityPtr city, const StringArray& own)
{
  city::InfoPtr info = city->statistic().services.find<Info>();

  if( info.isNull() )
  {
    Logger::warning( "CitizenIdea::check no city service info" );
    return "##unknown_reason##";
  }

  if( walker.is<Animal>() )
  {
    std::string text = fmt::format( "##animal_{}_say##", walker->info().typeName() );
    return text;
  }

  Info::Parameters params = info->lastParams();
  ThinksConstructor ret( walker->info().typeName() );
  ret.append(own);

  ret.addIf( params[ Info::monthWithFood ] < 3,     "_so_hungry" )
     .addIf( params[ Info::godsMood ] < 3,          "_gods_angry" )
     .addIf( params[ Info::colosseumCoverage ] < 3, "_need_colosseum" )
     .addIf( params[ Info::theaterCoverage ] < 3,   "_need_theater" )
     .addIf( params[ Info::entertainment ] < 20,    "_low_entertainment" )
     .addIf( params[ Info::needWorkers ] > 0,       "_need_workers" )
     .addIf( params[ Info::workless ] > 15,         "_high_workless" )
     .addIf( params[ Info::tax ] > 10,              "_high_tax" )
     .addIf( params[ Info::payDiff ] < 0,           "_low_salary" );

  if( !ret.empty() )
    return ret.random();

  ret.clear();
  ret.append(own);
  ret.addIf( params[ Info::lifeValue ] > 90, "_good_life" )
     .addIf( params[ Info::lifeValue ] > 75, "_average_life" )
     .addIf( params[ Info::lifeValue ] > 50, "_normal_life" )
     .addIf( params[ Info::education ] > 90, "_good_education" );

  return ret.empty() ? "##unknown_reason##" : ret.random();
}
Trade::Trade(PlayerCityPtr city, Widget* parent, int id )
    : Base( parent, city, id ), _d( new Impl )
{
    setupUI( ":/gui/tradeadv.gui" );

    _d->city = city;
    _d->allgoods = city->statistic().goods.details( false );

    GET_DWIDGET_FROM_UI( _d, btnEmpireMap  )
    GET_DWIDGET_FROM_UI( _d, btnPrices )
    GET_DWIDGET_FROM_UI( _d, gbInfo )

    CONNECT( _d->btnEmpireMap, onClicked(), this, Trade::deleteLater );
    CONNECT( _d->btnPrices, onClicked(), _d.data(), Impl::showGoodsPriceWindow );

    _d->updateGoodsInfo();

    TexturedButton* btnHelp = new TexturedButton( this, Point( 12, height() - 39), Size( 24 ), -1, ResourceMenu::helpInfBtnPicId );
    CONNECT( btnHelp, onClicked(), this, Trade::_showHelp );
}
void HealthCare::Impl::updateValue(PlayerCityPtr city)
{
  HouseList habitable = city->statistic().houses.habitable();

  value = 0;
  avgMinHealth = 100;
  int houseWithBadHealth = 0;
  for( auto house : habitable )
  {
    unsigned int hLvl = house->state( pr::health );
    value += hLvl;
    if( hLvl < health::bad )
    {
      avgMinHealth += hLvl;
      houseWithBadHealth++;
    }
  }

  value /= (habitable.size()+1);
  avgMinHealth /= (houseWithBadHealth+1);
}
void Disorder::Impl::weekUpdate( unsigned int time, PlayerCityPtr rcity )
{
  HouseList houses = rcity->statistic().houses.find();

  const WalkerList& walkers = rcity->statistic().walkers.find( walker::protestor );

  HouseList criminalizedHouse;
  crime.level.current = 0;
  crime.level.maximum = 0;

  for( auto house : houses )
  {
    int currentValue = house->getServiceValue( Service::crime )+1;
    if( currentValue >= crime.level.minimum )
    {
      criminalizedHouse.push_back( house );
    }

    crime.level.current += currentValue;
    crime.level.maximum = std::max<int>( crime.level.maximum, currentValue );
  }

  if( houses.size() > 0 )
    crime.level.current /= houses.size();

  if( criminalizedHouse.size() > walkers.size() )
  {
    HousePtr house = criminalizedHouse.random();
    int hCrimeLevel = house->getServiceValue( Service::crime );

    int sentiment = rcity->sentiment();
    int randomValue = math::random( crime::maxValue );
    if (sentiment >= minSentiment4protest )
    {
      if ( randomValue >= sentiment + 20 )
      {
        if ( hCrimeLevel > crime::level4protestor )
        {
          generateProtestor( rcity, house );
        }
      }
    }
    else if ( sentiment >= minSentiment4mugger )
    {
      if ( randomValue >= sentiment + 40 )
      {
        if ( hCrimeLevel >= crime::level4mugger )
        {
          generateMugger( rcity, house );
        }
        else if ( hCrimeLevel > crime::level4protestor )
        {
          generateProtestor( rcity, house );
        }
      }
    }
    else if( sentiment < minSentiment4mugger )
    {
      if ( randomValue >= sentiment + 50 )
      {
        if ( hCrimeLevel >= crime::level4rioter ) { generateRioter( rcity, house ); }
        else if ( hCrimeLevel >= crime::level4mugger ) { generateMugger( rcity, house ); }
        else if ( hCrimeLevel > crime::level4protestor ) { generateProtestor( rcity, house ); }
      }
    }
  }
}