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 WalkerPrefect::_back2Prefecture() { bool pathFound = Pathfinder::getInstance().getPath( getIJ(), getBase()->getTile().getIJ(), _getPathway(), false, Size( 0 ) ); if( !pathFound ) { deleteLater(); _d->action = Impl::doNothing; } else { _getPathway().begin(); } _setGraphic( WG_PREFECT ); _d->action = Impl::back2Prefecture; }
void CartPusher::timeStep( const unsigned long time ) { if( (time % 22 == 1) && (_getPathway().getLength() < 2) ) { computeWalkerDestination(); } Walker::timeStep( time ); }
void MarketLady::computeWalkerDestination( MarketPtr market ) { _d->market = market; std::list<GoodType> priorityGoods = _d->market->getMostNeededGoods(); _d->destBuildingPos = TilePos( -1, -1 ); // no destination yet if( priorityGoods.size() > 0 ) { // we have something to buy! // get the list of buildings within reach PathWay pathWay; Propagator pathPropagator( _d->city ); pathPropagator.init( _d->market.as<Construction>() ); pathPropagator.propagate( _d->maxDistance); // try to find the most needed good for (std::list<GoodType>::iterator itGood = priorityGoods.begin(); itGood != priorityGoods.end(); ++itGood) { _d->priorityGood = *itGood; if( _d->priorityGood == G_WHEAT || _d->priorityGood == G_FISH || _d->priorityGood == G_MEAT || _d->priorityGood == G_FRUIT || _d->priorityGood == G_VEGETABLE) { // try get that good from a granary _d->destBuildingPos = getWalkerDestination2<Granary>( pathPropagator, B_GRANARY, _d->market, _d->basket, _d->priorityGood, pathWay, _d->reservationID ); } else { // try get that good from a warehouse _d->destBuildingPos = getWalkerDestination2<Warehouse>( pathPropagator, B_WAREHOUSE, _d->market, _d->basket, _d->priorityGood, pathWay, _d->reservationID ); } if( _d->destBuildingPos.getI() >= 0 ) { // we found a destination! setPathWay(pathWay); break; } } } if( _d->destBuildingPos.getI() < 0) { // we have nothing to buy, or cannot find what we need to buy deleteLater(); return; } setIJ( _getPathway().getOrigin().getIJ() ); }
void CartPusher::onDestination() { Walker::onDestination(); _d->cartPicture = Picture(); 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); _d->reservationID = 0; } else if ( warehouse != NULL ) { warehouse->getGoodStore().applyStorageReservation(_d->stock, _d->reservationID); _d->reservationID = 0; } else if( factory != NULL ) { factory->getGoodStore().applyStorageReservation(_d->stock, _d->reservationID); // factory->computePictures(); _d->reservationID = 0; } } // if( !_getPathway().isReverse() ) { _getPathway().toggleDirection(); computeDirection(); go(); _d->consumerBuilding = 0; } else { deleteLater(); } }
void CartPusher::computeWalkerDestination() { // get the list of buildings within reach PathWay pathWay; Propagator pathPropagator( _getCity() ); _d->consumerBuilding = 0; if( _d->producerBuilding.isNull() ) { StringHelper::debug( 0xff, "CartPusher destroyed: producerBuilding can't be NULL" ); deleteLater(); return; } pathPropagator.init( _d->producerBuilding.as<Construction>() ); pathPropagator.propagate(_d->maxDistance); BuildingPtr destBuilding; if (destBuilding == NULL) { // try send that good to a factory destBuilding = _d->getWalkerDestination_factory(pathPropagator, pathWay); } if (destBuilding == NULL) { // try send that good to a granary destBuilding = _d->getWalkerDestination_granary(pathPropagator, pathWay); } if (destBuilding == NULL) { // try send that good to a warehouse destBuilding = _d->getWalkerDestination_warehouse( pathPropagator, pathWay ); } if( destBuilding != NULL) { //_isDeleted = true; // no destination! setConsumerBuilding( destBuilding ); setPathWay( pathWay ); setIJ( _getPathway().getOrigin().getIJ() ); setSpeed( 1 ); } else { _setDirection( D_NORTH ); setSpeed( 0 ); setIJ( _d->producerBuilding->getAccessRoads().front()->getIJ() ); walk(); } }
void CartSupplier::computeWalkerDestination(BuildingPtr building, const Good::Type type, const int qty ) { _d->baseBuildingPos = building->getTilePos(); _d->storageBuildingPos = TilePos( -1, -1 ); // no destination yet // we have something to buy! // get the list of buildings within reach PathWay pathWay; Propagator pathPropagator( _d->city ); pathPropagator.init( building.as<Construction>() ); pathPropagator.propagate( _d->maxDistance); // try get that good from a granary _d->storageBuildingPos = getSupplierDestination2<Granary>( pathPropagator, B_GRANARY, type, qty, pathWay, _d->reservationID ); if( _d->storageBuildingPos.getI() < 0 ) { // try get that good from a warehouse _d->storageBuildingPos = getSupplierDestination2<Warehouse>( pathPropagator, B_WAREHOUSE, type, qty, pathWay, _d->reservationID ); } if( _d->storageBuildingPos.getI() >= 0 ) { // we found a destination! setPathWay(pathWay); } else { // we have nothing to buy, or cannot find what we need to buy deleteLater(); return; } setIJ( _getPathway().getOrigin().getIJ() ); }
void WalkerPrefect::onMidTile() { ReachedBuildings reachedBuildings; TilePos firePos; bool haveBurningRuinsNear = _looks4Fire( reachedBuildings, firePos ); bool isDestination = _getPathway().isDestination(); switch( _d->action ) { case Impl::doNothing: break; case Impl::patrol: { if( haveBurningRuinsNear ) { //tell our prefecture that need send prefect with water to fight with fire //on next deliverService //found fire, no water, go prefecture getBase().as<Prefecture>()->fireDetect( firePos ); _back2Prefecture(); Walker::onNewDirection(); } else { foreach( BuildingPtr building, reachedBuildings ) { building->applyService( ServiceWalkerPtr( this ) ); HousePtr house = building.as<House>(); if( house.isValid() && house->getHealthLevel() < 1 ) { house->deleteLater(); GameEventMgr::append( DisasterEvent::create( house->getTilePos(), DisasterEvent::plague ) ); } } } if( isDestination ) { _back2Prefecture(); } Walker::onMidTile(); } break; case Impl::back2Prefecture: { if( haveBurningRuinsNear ) { //tell our prefecture that need send prefect with water to fight with fire //on next deliverService getBase().as<Prefecture>()->fireDetect( firePos ); } if( isDestination ) { deleteLater(); _d->action = Impl::doNothing; } Walker::onMidTile(); } break; case Impl::gotoFire: { if( _getPathway().getDestination().getIJ().distanceFrom( getIJ() ) < 1.5f ) { LandOverlayPtr overlay = _getPathway().getDestination().getOverlay(); if( overlay.isValid() && overlay->getType() == B_BURNING_RUINS ) { _d->action = Impl::fightFire; _setGraphic( WG_PREFECT_FIGHTS_FIRE ); Walker::onNewDirection(); isDestination = false; } } if( isDestination ) { if( !haveBurningRuinsNear || _d->water == 0 ) { _back2Prefecture(); } else { _setGraphic( WG_PREFECT_DRAG_WATER ); _d->action = Impl::gotoFire; _checkPath2NearestFire( reachedBuildings ); Walker::onNewDirection(); } } Walker::onMidTile(); } break; case Impl::fightFire: break; }
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 ); } } } } }