void TraineeWalker::_computeWalkerPath( bool roadOnly ) { if( !gfx::tilemap::isValidLocation( _d->baseLocation ) ) { Logger::warning( "!!! WARNING: trainee walker baselocation is unaccessible at [%d,%d]", _d->baseLocation.i(), _d->baseLocation.j() ); deleteLater(); return; } BuildingPtr base = ( _city()->getOverlay( _d->baseLocation ).as<Building>()); if( !base.isValid() ) { Logger::warning( "!!! WARNING: trainee walker base is null at [%d,%d]", _d->baseLocation.i(), _d->baseLocation.j() ); deleteLater(); return; } _d->maxNeed = 0; // need of this trainee in buildings Pathway finalPath; BuildingList buildings; for( auto buildingType : _d->necBuildings ) buildings.append( _city()->statistic().objects.find<Building>( buildingType ) ); TilesArray startArea = roadOnly ? base->roadside() : base->enterArea(); DirectRoute droute; _d->maxNeed = 0; unsigned int minDistance = _d->maxDistance; bool isNeedTrainee = false; for( auto bld : buildings ) { float howMuchNeedMyService = bld->evaluateTrainee( type() ); if( howMuchNeedMyService > 0 ) { isNeedTrainee = true; break; } } if( !isNeedTrainee ) { Logger::warning( "!!! WARNING: not need trainee walker from [%d,%d]", base->pos().i(), base->pos().j() ); deleteLater(); return; } std::set<BuildingPtr> checkedBuilding; for( auto itile : startArea ) { TilePos startPos = itile->pos(); for( auto bld : buildings ) { bool buildingAlsoServicing = checkedBuilding.count( bld ) > 0; if( buildingAlsoServicing ) continue; checkedBuilding.insert( bld ); float curNeed = bld->evaluateTrainee( type() ); if( _d->maxNeed < curNeed ) { Pathway way = PathwayHelper::create( startPos, bld, roadOnly ? PathwayHelper::roadOnly : PathwayHelper::allTerrain ); if( way.isValid() && way.length() < minDistance ) { _d->maxNeed = curNeed; droute = DirectRoute( bld.object(), way ); } } } } if( droute.first.isValid() ) { finalPath = droute.second; _d->destLocation = droute.first->pos(); } if( finalPath.isValid() ) { // some building needs that trainee!!! setPos( finalPath.startPos() ); setPathway( finalPath ); } else { // nobody needs him... deleteLater(); } }