Example #1
0
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>() );
  }
}
Example #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" );
  }