Ejemplo n.º 1
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.º 2
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" );
  }