void TraineeWalker::_checkDestination(const object::Type buildingType, Propagator &pathPropagator) { DirectPRoutes pathWayList = pathPropagator.getRoutes( buildingType ); for( auto item : pathWayList ) { // for every building within range BuildingPtr building = item.first.as<Building>(); float need = building->evaluateTrainee( type() ); if (need > _d->maxNeed) { _d->maxNeed = need; _d->destLocation = building->pos(); } } }
void TraineeWalker::send2City(BuildingPtr base, bool roadOnly ) { if( !base.isValid() ) { Logger::warning( "!!! WARNING: trainee walker base is null" ); deleteLater(); return; } _d->baseLocation = base->pos(); _computeWalkerPath( roadOnly ); if( !isDeleted() && gfx::tilemap::isValidLocation( _d->destLocation ) ) { BuildingPtr dest = receiver(); dest->reserveTrainee( type() ); attach(); } }
void TraineeWalker::setBase(BuildingPtr originBuilding) { _d->baseLocation = originBuilding.isValid() ? originBuilding->pos() : gfx::tilemap::invalidLocation(); }
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(); } }