void Disorder::timeStep( const unsigned int time )
{
  if( GameDate::isYearChanged() )
  {
    _d->rioterInLastYear = _d->rioterInThisYear;
    _d->rioterInThisYear = 0;
  }

  if( !GameDate::isWeekChanged() )
    return;

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

  WalkerList walkers = _city()->walkers( walker::protestor );

  HouseList criminalizedHouse;
  _d->currentCrimeLevel = 0;
  _d->maxCrimeLevel = 0;

  foreach( house, houses )
  {
    int crimeLvl = (*house)->getServiceValue( Service::crime )+1;
    if( crimeLvl >= _d->minCrimeLevel )
    {
      criminalizedHouse.push_back( *house );
    }

    _d->currentCrimeLevel += crimeLvl;
    _d->maxCrimeLevel = std::max<int>( _d->maxCrimeLevel, crimeLvl );
  }
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;
      }
    }
  }
}
Пример #3
0
void WorkingBuilding::timeStep( const unsigned long time )
{
  Building::timeStep( time );

  for( WalkerList::iterator it=_d->walkerList.begin(); it != _d->walkerList.end(); )
  {
    if( (*it)->isDeleted() ) { it = _d->walkerList.erase( it ); }
    else { ++it; }
  }

  if( game::Date::isMonthChanged() && numberWorkers() > 0 )
  {
    city::Helper helper( _city() );
    TilePos offset( 8, 8 );
    TilePos myPos = pos();
    HouseList houses = helper.find<House>( objects::house, myPos - offset, myPos + offset );
    float averageDistance = 0;
    foreach( it, houses )
    {
      if( (*it)->spec().level() < HouseLevel::smallVilla )
      {
        averageDistance += myPos.distanceFrom( (*it)->pos() );
      }
    }

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

    _d->laborAccessKoeff = math::clamp( math::percentage( averageDistance, 8 ) * 2, 25, 100 );
  }
Пример #4
0
HouseList HouseManager::filterHouses(uint32 townId)
{
    HouseList ret;
    for(const HousePtr& house : m_houses)
        if(house->getTownId() == townId)
            ret.push_back(house);
    return ret;
}
Пример #5
0
HouseList Statistic::_Houses::habitable() const
{
  HouseList houses = find();

  for( auto it=houses.begin(); it != houses.end(); )
  {
    if( (*it)->habitants().count() > 0 ) ++it;
    else it = houses.erase( it );
  }

  return houses;
}
Пример #6
0
HouseList Statistic::_Houses::ready4evolve(const object::TypeSet& checkTypes ) const
{
  HouseList houses = find();

  for( auto it=houses.begin(); it != houses.end(); )
  {
    object::Type btype;
    (*it)->spec().next().checkHouse( *it, nullptr, &btype );
    if( checkTypes.count( btype ) ) it = houses.erase( it );
    else ++it;
  }

  return houses;
}
Пример #7
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##" );
      }
    }
  }
}
Пример #8
0
HousePtr Immigrant::_findBlankHouse()
{
    CityHelper hlp( _getCity() );
    HouseList houses = hlp.find< House >( building::house );
    HousePtr blankHouse;
    _d->destination = TilePos( -1, -1 );

    HouseList::iterator itHouse = houses.begin();
    while( itHouse != houses.end() )
    {
        if( (*itHouse)->getAccessRoads().size() > 0 &&
                ( (*itHouse)->getHabitants().count() < (*itHouse)->getMaxHabitants() ) )
        {
            itHouse++;
        }
        else
        {
            itHouse = houses.erase( itHouse );
        }
    }

    if( houses.size() > 0 )
    {
        itHouse = houses.begin();
        std::advance(itHouse, rand() % houses.size() );
        blankHouse = *itHouse;
        _d->destination = blankHouse->getTilePos();
    }

    return blankHouse;
}
Пример #9
0
void RandomPlague::_exec( Game& game, unsigned int time)
{
  int population = game.city()->states().population;
  if( _d->popRange.contain( population ) )
  {
    Logger::info( "Execute random plague event" );
    _d->isDeleted = true;

    HouseList houses = game.city()->statistic().houses.habitable();

    unsigned int number4burn = math::clamp<unsigned int>( (houses.size() * _d->strong / 100), 1u, 100u );

    for( unsigned int k=0; k < number4burn; k++ )
    {
      HousePtr house = houses.random();
      house->setState( pr::health, 0.f );
    }
  }
}
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 ProsperityRating::_checkStats()
{
  HouseList habitable = _city()->statistic().houses.habitable();

  int prosperityCap = 0;
  for( auto house : habitable)
  {
    prosperityCap += house->spec().prosperity();
    if( house->spec().isPatrician() )
      _d->now.patricianCount += house->habitants().count();
    else
      _d->now.plebsCount += house->habitants().count();
  }

  if( habitable.size() > 0 )
  {
    prosperityCap /= habitable.size();
  }

  _d->now.prosperity = math::clamp<int>( prosperityCap, 0, _d->now.prosperity + 2 );
  _d->now.houseCapTrand = _d->now.prosperity - _d->prev.prosperity;
}
Пример #12
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 );
}
Пример #13
0
HousePtr Emigrant::_findBlankHouse()
{
  city::Helper hlp( _city() );

  HousePtr blankHouse;

  TilePos offset( 5, 5 );
  HouseList houses = hlp.find<House>( building::house, pos() - offset, pos() + offset );

  _checkHouses( houses );

  if( houses.empty() )
  {
    houses = hlp.find<House>( building::house );
    _checkHouses( houses );
  }

  if( houses.size() > 0 )
  {
    blankHouse = houses.random();
  }

  return blankHouse;
}
Пример #14
0
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 ); }
      }
    }
  }
}