void CartSupplier::onDestination() { Walker::onDestination(); CityHelper helper( _d->city ); if( _getPathway().isReverse() ) { // walker is back in the market deleteLater(); // put the content of the stock to receiver BuildingPtr building = helper.find<Building>( _d->baseBuildingPos ); GoodStore* storage = 0; if( building.is<Factory>() ) { storage = &building.as<Factory>()->getGoodStore(); } else if( building.is<Granary>() ) { storage = &building.as<Granary>()->getGoodStore(); } else if( building.is<Warehouse>() ) { storage = &building.as<Warehouse>()->getGoodStore(); } if( storage ) { storage->applyStorageReservation( _d->stock, _d->rcvReservationID ); storage->store( _d->stock, _d->stock._currentQty ); } } else { // walker is near the granary/warehouse _getPathway().rbegin(); computeDirection(); go(); // get goods from destination building BuildingPtr building = helper.find<Building>( _d->storageBuildingPos ); if( building.is<Granary>() ) { GranaryPtr granary = building.as<Granary>(); // this is a granary! // std::cout << "MarketBuyer arrives at granary, res=" << _reservationID << std::endl; granary->getGoodStore().applyRetrieveReservation( _d->stock, _d->reservationID ); } else if( building.is<Warehouse>() ) { WarehousePtr warehouse = building.as<Warehouse>(); // this is a warehouse! // std::cout << "Market buyer takes IRON from warehouse" << std::endl; // warehouse->retrieveGoods(_basket.getStock(G_IRON)); warehouse->getGoodStore().applyRetrieveReservation(_d->stock, _d->reservationID); } } }
void CartPusher::_reachedPathway() { Walker::_reachedPathway(); _d->anim = CartAnimation(); if( _d->consumerBuilding != NULL ) { GranaryPtr granary = ptr_cast<Granary>(_d->consumerBuilding); WarehousePtr warehouse = ptr_cast<Warehouse>(_d->consumerBuilding); FactoryPtr factory = ptr_cast<Factory>(_d->consumerBuilding); good::Store* goodStore = 0; if( granary.isValid() ) { goodStore = &granary->store(); } else if( warehouse.isValid() ) { goodStore = &warehouse->store(); } else if( factory.isValid() ) { goodStore = &factory->store(); } if( goodStore ) { int saveQty = _d->stock.qty(); wait( _d->stock.qty() ); goodStore->applyStorageReservation(_d->stock, _d->reservationID); _d->reservationID = 0; _d->cantUnloadGoods = (saveQty == _d->stock.qty()); } } // if( !_pathway().isReverse() ) { _pathway().toggleDirection(); _centerTile(); go(); _d->consumerBuilding = NULL; } else { deleteLater(); } }
void CartPusher::onDestination() { Walker::onDestination(); _d->cartPicture = NULL; if( _d->consumerBuilding != NULL ) { GranaryPtr granary = _d->consumerBuilding.as<Granary>(); WarehousePtr warehouse = _d->consumerBuilding.as<Warehouse>(); FactoryPtr factory = _d->consumerBuilding.as<Factory>(); if( granary != NULL ) { granary->getGoodStore().applyStorageReservation(_d->stock, _d->reservationID); granary->computePictures(); _d->reservationID = 0; } else if ( warehouse != NULL ) { warehouse->getGoodStore().applyStorageReservation(_d->stock, _d->reservationID); warehouse->computePictures(); _d->reservationID = 0; } else if( factory != NULL ) { factory->getGoodStore().applyStorageReservation(_d->stock, _d->reservationID); // factory->computePictures(); _d->reservationID = 0; } } // if( !_pathWay.isReverse() ) { _pathWay.toggleDirection(); _action._action=WA_MOVE; computeDirection(); _d->consumerBuilding = 0; } else { deleteLater(); } }
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" ); }
void MarketLady::onDestination() { Walker::onDestination(); if( _getPathway().isReverse() ) { // walker is back in the market deleteLater(); // put the content of the basket in the market _d->market->getGoodStore().storeAll( _d->basket ); } else { // walker is near the granary/warehouse _getPathway().rbegin(); _setAction( WA_MOVE ); computeDirection(); // get goods from destination building LandOverlayPtr building = _d->city->getTilemap().at( _d->destBuildingPos ).getTerrain().getOverlay(); if( building.is<Granary>() ) { GranaryPtr granary = building.as<Granary>(); // this is a granary! // std::cout << "MarketLady arrives at granary, res=" << _reservationID << std::endl; granary->getGoodStore().applyRetrieveReservation(_d->basket, _d->reservationID); // take other goods if possible for (int n = 1; n<G_MAX; ++n) { // for all types of good (except G_NONE) GoodType goodType = (GoodType) n; int qty = _d->market->getGoodDemand(goodType) - _d->basket.getCurrentQty(goodType); if (qty != 0) { qty = std::min(qty, granary->getGoodStore().getMaxRetrieve(goodType)); qty = std::min(qty, _d->basket.getMaxQty(_d->priorityGood) - _d->basket.getCurrentQty(_d->priorityGood)); if (qty != 0) { // std::cout << "extra retrieve qty=" << qty << " basket=" << _basket.getStock(goodType)._currentQty << std::endl; GoodStock& stock = _d->basket.getStock(goodType); granary->getGoodStore().retrieve(stock, qty); } } } } else if( building.is<Warehouse>() ) { WarehousePtr warehouse = building.as<Warehouse>(); // this is a warehouse! // std::cout << "Market buyer takes IRON from warehouse" << std::endl; // warehouse->retrieveGoods(_basket.getStock(G_IRON)); warehouse->getGoodStore().applyRetrieveReservation(_d->basket, _d->reservationID); // take other goods if possible for (int n = 1; n<G_MAX; ++n) { // for all types of good (except G_NONE) GoodType goodType = (GoodType) n; int qty = _d->market->getGoodDemand(goodType) - _d->basket.getCurrentQty(goodType); if (qty != 0) { qty = std::min(qty, warehouse->getGoodStore().getMaxRetrieve(goodType)); qty = std::min(qty, _d->basket.getMaxQty(_d->priorityGood) - _d->basket.getCurrentQty(_d->priorityGood)); if (qty != 0) { // std::cout << "extra retrieve qty=" << qty << " basket=" << _basket.getStock(goodType)._currentQty << std::endl; GoodStock& stock = _d->basket.getStock(goodType); warehouse->getGoodStore().retrieve(stock, qty); } } } } unsigned long delay = 20; while( _d->basket.getCurrentQty() > 100 ) { for( int gtype=G_WHEAT; gtype <= G_WINE; gtype++ ) { GoodStock& currentStock = _d->basket.getStock( (GoodType)gtype ); if( currentStock._currentQty > 0 ) { MarketLadyHelperPtr boy = MarketLadyHelper::create( this ); GoodStock& boyBasket = boy->getBasket(); boyBasket._goodType = (GoodType)gtype; boyBasket._maxQty = 100; _d->basket.retrieve( boyBasket, math::clamp( currentStock._currentQty, 0, 100 ) ); boy->setDelay( delay ); delay += 20; boy->send2City( _d->city, _d->market ); } } } } }