void Notify::_exec(Game& game, unsigned int)
{
  world::CityPtr pCity = game.empire()->findCity( _d->cityname );

  if( is_kind_of<PlayerCity>( pCity ) )
  {
    PlayerCityPtr plrCity = ptr_cast<PlayerCity>( pCity );
    MilitaryPtr mil = statistic::getService<Military>( plrCity );

    if( mil.isValid() )
    {
      mil->addNotification( _d->message, _d->object, (Notification::Type)_d->type );
    }
  }
}
Example #2
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 );
    }
  }
}
Example #3
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());
    }
  }
}
Example #4
0
void Migration::timeStep( const unsigned int time )
{
  if( game::Date::isMonthChanged() )
  {
    std::string trouble = reason();
    if( haveTroubles() )
    {
      events::GameEventPtr e = events::WarningMessage::create(trouble, 1);
      e->dispatch();
    }
  }

  if( time % _d->updateTickInterval != 1 )
    return;

  LOG_MIGRATION.info( "Calculation started" );
  const int worklessCitizenAway = SETTINGS_VALUE( worklessCitizenAway );

  float migrationKoeff = _d->getMigrationKoeff( _city() );
  Info::Parameters params = _d->lastMonthParams( _city() );
  LOG_MIGRATION.info( "Current migration factor is %f", migrationKoeff );

  _d->emigrantsIndesirability = defaultEmIndesirability; //base undesirability value
  float emDesKoeff = math::clamp<float>( (float)SETTINGS_VALUE( emigrantSalaryKoeff ), 1.f, 99.f );

  //if salary in city more then empire people more effectively go to our city
  const int diffSalary = _city()->empire()->workerSalary() - _city()->treasury().workerSalary();
  int diffSalaryInfluence = diffSalary * emDesKoeff;

  //emigrant like when lot of food stock int city
  const int minMonthWithFood = SETTINGS_VALUE( minMonthWithFood );
  int foodStackInfluence = ( params[ Info::monthWithFood ] < minMonthWithFood
                                   ? ((minMonthWithFood - params[ Info::monthWithFood ]) * 3)
                                   : -params[ Info::monthWithFood ] );

  int sentimentInfluence = (params[ Info::sentiment ] - 50) / 5;

  //emigrant need workplaces
  const int& curWorklessValue = params[ Info::workless ];
  int worklessInfluence = curWorklessValue == 0
                          ? -noWorklessAward
                          : (curWorklessValue * (curWorklessValue < worklessCitizenAway ? 1 : 2));

  int taxLevelInfluence = ( params[ Info::tax ] > migration::normalTax
                            ? params[ Info::tax ] * 2
                            : (migration::normalTax-params[ Info::tax ]) );

  const int& monthWithourWar = _city()->states().age > 1
                                  ? params[ Info::monthWtWar ]
                                  : DateTime::monthsInYear;

  int warInfluence = ( monthWithourWar < DateTime::monthsInYear
                          ? (DateTime::monthsInYear - monthWithourWar) * 5
                          : -std::min( monthWithourWar, 10 ) );

  warInfluence += params[ Info::milthreat ];

  int slumsInfluence = ( _d->isPoorHousing( params[ Info::slumNumber ], params[ Info::houseNumber ] ) ? shacksPenalty*2 : 0);
  int shacksInfluence = ( _d->isPoorHousing( params[ Info::shackNumber ], params[ Info::houseNumber ] ) ? shacksPenalty : 0 );

  if( _d->worklessMinInfluence > 0 )
  {
    _d->emigrantsIndesirability += worklessInfluence * std::min<int>( _city()->states().population, 150 ) / _d->worklessMinInfluence;
  }
  else
  {
    _d->emigrantsIndesirability += worklessInfluence;
  }

  _d->emigrantsIndesirability += diffSalaryInfluence;
  _d->emigrantsIndesirability += foodStackInfluence;
  _d->emigrantsIndesirability += params[ Info::crimeLevel ];
  _d->emigrantsIndesirability += taxLevelInfluence;
  _d->emigrantsIndesirability += warInfluence;
  _d->emigrantsIndesirability += shacksInfluence;
  _d->emigrantsIndesirability += slumsInfluence;
  _d->emigrantsIndesirability += sentimentInfluence;
  _d->emigrantsIndesirability += params[ Info::blackHouses ];

  _d->emigrantsIndesirability *= migrationKoeff;

  LOG_MIGRATION.info( "Current undesirability is %d", _d->emigrantsIndesirability );
  if( warInfluence > warBlockedMigration )
  {
    LOG_MIGRATION.info( "Enemies in city: migration stopped" );
    return;
  }

  MilitaryPtr mil = _city()->statistic().services.find<Military>();

  if( mil.isValid() )
  {
    bool cityUnderAttack = mil->isUnderAttack();

    if( cityUnderAttack )
      _d->emigrantsIndesirability *= cityUnderAttackPenalty;
  }  

  if( _d->lastUpdate.monthsTo( game::Date::current() ) > 0 )
  {
    _d->lastUpdate = game::Date::current();
    _d->lastMonthMigration = _d->lastMonthComing - _d->lastMonthLeaving;
    _d->lastMonthComing = 0;
    _d->lastMonthLeaving = 0;

    LOG_MIGRATION.info( "Current workless=%f undesrbl=%f",
                     curWorklessValue * migrationKoeff,
                     _d->emigrantsIndesirability * migrationKoeff );
  }

  if( curWorklessValue * migrationKoeff > worklessCitizenAway
      || _d->emigrantsIndesirability * migrationKoeff > maxIndesirability )
  {

  }
  else
  {
    _d->chanceCounter++;
    float variance = utils::eventProbability( (maxIndesirability-_d->emigrantsIndesirability)/100.f,
                                              _d->chanceCounter, _d->emigrantsIndesirability );
    if( variance >= 1)
    {
      _d->createMigrationToCity( _city() );
      _d->chanceCounter = 0;
    }
  }

  _d->updateTickInterval = math::random( game::Date::days2ticks( _d->checkRange ) ) + 10;
  LOG_MIGRATION.info( "Calculation finished." );
}
void Info::timeStep(const unsigned int time )
{
  if( !game::Date::isMonthChanged() )
    return;

  if( game::Date::current().month() != _d->lastDate.month() )
  {
    bool yearChanged = game::Date::current().year() != _d->lastDate.year();
    _d->lastDate = game::Date::current();

    _d->lastYearHistory.erase( _d->lastYearHistory.begin() );
    _d->lastYearHistory.push_back( Parameters() );

    Parameters& last = _d->lastYearHistory.back();
    last.date = _d->lastDate;
    last[ population  ] = _city()->population();
    last[ funds       ] = _city()->funds().treasury();
    last[ taxpayes    ] =  0;//_d->city->getLastMonthTaxpayer();
    last[ foodStock   ] = statistic::getFoodStock( _city() );
    last[ foodMontlyConsumption ] = statistic::getFoodMonthlyConsumption( _city() );
    last[ monthWithFood ] = last[ foodMontlyConsumption ] > 0 ? (last[ foodStock ] / last[ foodMontlyConsumption ]) : 0;

    int foodProducing = statistic::getFoodProducing( _city() );
    int yearlyFoodConsumption = last[ foodMontlyConsumption ] * DateTime::monthsInYear;
    last[ foodKoeff   ] = ( foodProducing - yearlyFoodConsumption > 0 )
                            ? foodProducing / (yearlyFoodConsumption+1)
                            : -(yearlyFoodConsumption / (foodProducing+1) );

    int currentWorkers, rmaxWorkers;
    statistic::getWorkersNumber( _city(), currentWorkers, rmaxWorkers );

    last[ needWorkers ] = rmaxWorkers - currentWorkers;
    last[ maxWorkers  ] = rmaxWorkers;
    last[ workless    ] = statistic::getWorklessPercent( _city() );
    last[ payDiff     ] = _city()->empire()->workerSalary() - _city()->funds().workerSalary();
    last[ tax         ] = _city()->funds().taxRate();
    last[ cityWages   ] = _city()->funds().workerSalary();
    last[ romeWages   ] = _city()->empire()->workerSalary();
    last[ crimeLevel  ] = statistic::getCrimeLevel( _city() );
    last[ favour      ] = _city()->favour();
    last[ prosperity  ] = _city()->prosperity();
    last[ monthWtWar  ] = statistic::months2lastAttack( _city() );
    last[ peace       ] = 0;

    PeacePtr peaceSrvc;
    peaceSrvc << _city()->findService( Peace::defaultName() );
    if( peaceSrvc.isValid() )
    {
      last[ peace ] = peaceSrvc->value();
    }

    MilitaryPtr mil;
    mil << _city()->findService( Military::defaultName() );
    if( mil.isValid() )
    {
      last[ Info::milthreat ] = mil->threatValue();
    }

    Helper helper( _city() );
    HouseList houses = helper.find<House>( objects::house );

    last[ houseNumber ] = 0;
    last[ shackNumber ] = 0;
    foreach( it, houses )
    {
      HousePtr h = *it;

      if( h->habitants().count() > 0 )
      {
        int hLvl = h->spec().level();
        last[ slumNumber ] += ( hLvl == HouseLevel::hovel || hLvl == HouseLevel::tent ? 1 : 0);
        last[ shackNumber ] += ( hLvl >= HouseLevel::shack || hLvl < HouseLevel::hut ? 1 : 0);
        last[ houseNumber ]++;
      }
    }
Example #6
0
int Statistic::_Military::months2lastAttack() const
{
  MilitaryPtr ml = _parent.services.find<Military>();
  return ml.isValid() ? ml->monthFromLastAttack() : 0;
}