void Prefecture::deliverService() { if( getWorkers() > 0 && getWalkerList().size() == 0 ) { bool fireDetect = _fireDetect.getI() >= 0; PrefectPtr walker = Prefect::create( _getCity() ); walker->setMaxDistance( 26 ); //bool patrol = true; if( fireDetect ) { Pathway pathway; TilePos startPos = getAccessRoads().front()->getIJ(); bool pathFounded = Pathfinder::getInstance().getPath( startPos, _fireDetect, pathway, false, Size( 0 ) ); //patrol = !pathFounded; if( pathFounded ) { walker->setPathway( pathway ); walker->setIJ( pathway.getOrigin().getIJ() ); } _fireDetect = TilePos( -1, -1 ); } walker->send2City( PrefecturePtr( this ), fireDetect ? 200 : 0 ); addWalker( walker.as<Walker>() ); } }
void Merchant::Impl::resolveState( WalkerPtr wlk, const TilePos& position ) { switch( nextState ) { case stFindWarehouseForSelling: { destBuildingPos = TilePos( -1, -1 ); // no destination yet // get the list of buildings within reach Propagator pathPropagator( city ); Tilemap& tmap = city->getTilemap(); pathPropagator.init( tmap.at( position ) ); pathPropagator.propagate( maxDistance ); Propagator::DirectRoute route; //try found any available warehouse for selling our goods const GoodStore& buyOrders = city->getBuys(); if( buyOrders.getMaxQty() > 0 ) { route = getWarehouse4Sells( pathPropagator, sell ); } if( !route.first.isValid() ) { route = pathPropagator.getShortestRoute( building::warehouse ); } if( route.first.isValid() ) { // we found a destination! nextState = stSellGoods; destBuildingPos = route.first->getTilePos(); wlk->setPathway( route.second ); wlk->setIJ( route.second.getOrigin().getIJ() ); wlk->go(); } else { nextState = stGoOutFromCity; resolveState( wlk, position ); } } break; case stFindWarehouseForBuying: { destBuildingPos = TilePos( -1, -1 ); // no destination yet // get the list of buildings within reach Propagator pathPropagator( city ); Tilemap& tmap = city->getTilemap(); pathPropagator.init( tmap.at( position ) ); pathPropagator.propagate( maxDistance ); Propagator::DirectRoute route; // try to find goods for city export if( buy.getMaxQty() > 0 ) { route = getWarehouse4Buys( pathPropagator, buy ); } if( route.first.isValid() ) { // we found a destination! nextState = stBuyGoods; destBuildingPos = route.first->getTilePos(); wlk->setPathway( route.second ); wlk->setIJ( route.second.getOrigin().getIJ() ); wlk->go(); } else { nextState = stGoOutFromCity; resolveState( wlk, position ); } } break; case stBuyGoods: { CityHelper helper( city ); WarehousePtr warehouse = helper.find<Warehouse>( building::warehouse, destBuildingPos ); if( warehouse.isValid() ) { std::map< Good::Type, int > cityGoodsAvailable; WarehouseList warehouses = helper.find<Warehouse>( building::warehouse ); foreach( WarehousePtr wh, warehouses ) { for( int i=Good::wheat; i < Good::goodCount; i++ ) { Good::Type goodType = (Good::Type)i; cityGoodsAvailable[ goodType ] += wh->getGoodStore().getCurrentQty( goodType ); } } //const GoodStore& cityOrders = city->getSells(); CityTradeOptions& options = city->getTradeOptions(); //try buy goods for( int n = Good::wheat; n<Good::goodCount; ++n ) { Good::Type goodType = (Good::Type) n; int needQty = buy.getFreeQty( goodType ); int maySell = math::clamp( cityGoodsAvailable[ goodType ] - options.getExportLimit( goodType ) * 100, 0, 9999 ); if( needQty > 0 && maySell > 0) { int mayBuy = std::min( needQty, warehouse->getGoodStore().getMaxRetrieve( goodType ) ); mayBuy = std::min( mayBuy, maySell ); if( mayBuy > 0 ) { // std::cout << "extra retrieve qty=" << qty << " basket=" << _basket.getStock(goodType)._currentQty << std::endl; GoodStock& stock = buy.getStock( goodType ); warehouse->getGoodStore().retrieve( stock, mayBuy ); events::GameEventPtr e = events::FundIssueEvent::exportg( goodType, mayBuy ); e->dispatch(); } } } } nextState = stGoOutFromCity; resolveState( wlk, position ); } break; case stGoOutFromCity: { Pathway pathWay; // we have nothing to buy/sell with city, or cannot find available warehouse -> go out bool pathFound = Pathfinder::getInstance().getPath( position, city->getBorderInfo().roadExit, pathWay, false, 1 ); if( pathFound ) { wlk->setPathway( pathWay ); wlk->setIJ( pathWay.getOrigin().getIJ() ); wlk->go(); } else { wlk->deleteLater(); } nextState = stBackToBaseCity; } break; case stSellGoods: { CityHelper helper( city ); WarehousePtr warehouse = helper.find<Warehouse>( building::warehouse, destBuildingPos ); const GoodStore& cityOrders = city->getBuys(); if( warehouse.isValid() ) { //try sell goods for (int n = Good::wheat; n<Good::goodCount; ++n) { Good::Type goodType = (Good::Type)n; int qty4sell = sell.getCurrentQty( goodType ); if( qty4sell > 0 && cityOrders.getMaxQty( goodType ) > 0 ) { int maySells = std::min( qty4sell, warehouse->getGoodStore().getMaxStore( goodType ) ); if( maySells != 0 ) { // std::cout << "extra retrieve qty=" << qty << " basket=" << _basket.getStock(goodType)._currentQty << std::endl; GoodStock& stock = sell.getStock( goodType ); warehouse->getGoodStore().store( stock, maySells ); events::GameEventPtr e = events::FundIssueEvent::import( goodType, maySells ); e->dispatch(); } } } } nextState = stFindWarehouseForBuying; resolveState( wlk, position ); } break; case stBackToBaseCity: { // walker on exit from city wlk->deleteLater(); EmpirePtr empire = city->getEmpire(); const std::string& ourCityName = city->getName(); EmpireTradeRoutePtr route = empire->getTradeRoute( ourCityName, baseCityName ); if( route.isValid() ) { route->addMerchant( ourCityName, sell, buy ); } nextState = stNothing; } break; default: Logger::warning( "Merchant: unknown state resolved" ); }