void RandomFire::_exec( Game& game, unsigned int time) { int population = game.city()->population(); if( population > _d->minPopulation && population < _d->maxPopulation ) { Logger::warning( "Execute random fire event" ); _d->isDeleted = true; Priorities<int> exclude; exclude << objects::waterGroup << objects::roadGroup << objects::disasterGroup; ConstructionList ctrs; ctrs << game.city()->overlays(); for( ConstructionList::iterator it=ctrs.begin(); it != ctrs.end(); ) { if( exclude.count( (*it)->group() ) ) { it = ctrs.erase( it ); } else { ++it; } } unsigned int number4burn = math::clamp<unsigned int>( (ctrs.size() * _d->strong / 100), 1u, 100u ); for( unsigned int k=0; k < number4burn; k++ ) { ConstructionPtr building = ctrs.random(); building->burn(); } } }
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; }