inline Pathway Statistic::_Walkers::freeTile( TilePos target, TilePos currentPos, const int range ) const
{
  for( int currentRange=1; currentRange <= range; currentRange++ )
  {
    TilePos offset( currentRange, currentRange );
    gfx::TilesArray tiles = _parent.map.perimetr( currentPos - offset, currentPos + offset );
    tiles = tiles.walkables( true );

    float crntDistance = target.distanceFrom( currentPos );
    for( auto tile : tiles )
    {
      SmartList<T> eslist = _parent.rcity.walkers( tile->pos() ).select<T>();

      if( !eslist.empty() )
        continue;

      if( target.distanceFrom( tile->pos() ) > crntDistance )
        continue;

      Pathway pathway = PathwayHelper::create( currentPos, tile->pos(), PathwayHelper::allTerrain );
      if( pathway.isValid() )
      {
        return pathway;
      }
    }
  }

  return Pathway();
}
Exemple #2
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 );
  }
Pathway FishingBoat::Impl::findFishingPlace(PlayerCityPtr city, TilePos pos )
{
  city::Helper helper( city );
  FishPlaceList places = helper.find<FishPlace>( walker::fishPlace, city::Helper::invalidPos );

  int minDistance = 999;
  FishPlacePtr nearest;
  foreach( it, places )
  {
    FishPlacePtr place = *it;
    int currentDistance = pos.distanceFrom( place->pos() );
    if( currentDistance < minDistance )
    {
      minDistance = currentDistance;
      nearest = place;
    }
  }
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 );
}