Ejemplo n.º 1
0
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);
    }
  }
}
Ejemplo n.º 2
0
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();
    }
}
Ejemplo n.º 3
0
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();
  }
}
Ejemplo n.º 4
0
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" );
  }
Ejemplo n.º 5
0
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 );
          }
        }
      }
   }
}