void WallGuard::send2city( TowerPtr tower, Pathway pathway ) { setPos( pathway.startPos() ); setBase( tower ); setPathway( pathway ); go(); _setSubAction( go2position ); if( !isDeleted() ) { attach(); } }
void Mugger::timeStep(const unsigned long time) { Walker::timeStep( time ); switch( _d->state ) { case Impl::searchHouse: { city::Helper helper( _city() ); TilePos offset(10, 10); HouseList houses = helper.find<House>( objects::house, pos() - offset, pos() + offset ); std::map< int, HouseList > houseEpxens; foreach( it, houses ) { int money = (*it)->getServiceValue( Service::forum ); houseEpxens[ money ] << *it; } for( std::map< int, HouseList >::reverse_iterator expHList = houseEpxens.rbegin(); expHList != houseEpxens.rend(); ++expHList ) { HouseList& hlist = expHList->second; foreach( hIt, hlist ) { Pathway pathway = PathwayHelper::create( pos(), ptr_cast<Construction>( *hIt ), PathwayHelper::allTerrain ); //find path to most expensive house, fire this!!! if( pathway.isValid() ) { setPos( pathway.startPos() ); setPathway( pathway ); go(); _d->state = Impl::go2destination; break; } } _d->state = Impl::go2anyplace; } }
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(); } }
void Rioter::timeStep(const unsigned long time) { Walker::timeStep( time ); switch( _d->state ) { case Impl::searchHouse: { city::Helper helper( _city() ); ConstructionList constructions = helper.find<Construction>( objects::house ); for( ConstructionList::iterator it=constructions.begin(); it != constructions.end(); ) { HousePtr h = ptr_cast<House>( *it ); if( h->spec().level() <= _d->houseLevel ) { it=constructions.erase( it ); } else { ++it; } } Pathway pathway = _d->findTarget( _city(), constructions, pos() ); //find more expensive house, fire this!!! if( pathway.isValid() ) { setPos( pathway.startPos() ); setPathway( pathway ); go(); _d->state = Impl::go2destination; } else //not find house, try find any, that rioter can destroy { _d->state = Impl::searchAnyBuilding; } } break; case Impl::searchAnyBuilding: { city::Helper helper( _city() ); ConstructionList constructions = helper.find<Construction>( objects::house ); for( ConstructionList::iterator it=constructions.begin(); it != constructions.end(); ) { TileOverlay::Type type = (*it)->type(); TileOverlay::Group group = (*it)->group(); if( type == objects::house || type == objects::road || _d->excludeGroups.count( group ) > 0 ) { it=constructions.erase( it ); } else { it++; } } Pathway pathway = _d->findTarget( _city(), constructions, pos() ); if( pathway.isValid() ) { setPos( pathway.startPos() ); setPathway( pathway ); go(); _d->state = Impl::go2destination; } else { _d->state = Impl::go2anyplace; } } break; case Impl::go2anyplace: { Pathway pathway = PathwayHelper::randomWay( _city(), pos(), 10 ); if( pathway.isValid() ) { setPathway( pathway ); go(); _d->state = Impl::go2destination; } else { die(); _d->state = Impl::wait; } } break; case Impl::go2destination: case Impl::wait: break; case Impl::destroyConstruction: { if( game::Date::isDayChanged() ) { city::Helper helper( _city() ); ConstructionList constructions = helper.find<Construction>( objects::any, pos() - TilePos( 1, 1), pos() + TilePos( 1, 1) ); for( ConstructionList::iterator it=constructions.begin(); it != constructions.end(); ) { if( (*it)->type() == objects::road || _d->excludeGroups.count( (*it)->group() ) > 0 ) { it=constructions.erase( it ); } else { ++it; } } if( constructions.empty() ) { _animationRef().clear(); _setAction( acMove ); _d->state = Impl::searchHouse; } else { foreach( it, constructions ) { ConstructionPtr c = *it; c->updateState( Construction::fire, 1 ); c->updateState( Construction::damage, 1 ); if( c->state( Construction::damage ) < 10 || c->state( Construction::fire ) < 10 ) { events::GameEventPtr e = events::Disaster::create( c->tile(), events::Disaster::riots ); e->dispatch(); } break; } } } } break; default: break; }