コード例 #1
0
ファイル: animals.cpp プロジェクト: dalerank/caesaria-game
void Wolf::_findNewWay( const TilePos& start )
{  
  WalkerList walkers = _city()->statistic().walkers
                                           .find<Walker>( walker::any, config::distance::animalRandrom, start )
                                           .exclude<Wolf>();

  Pathway pathway;
  if( !walkers.empty() )
  {
    WalkerPtr wlk = walkers.random();
    pathway = PathwayHelper::create( start, wlk->pos(), PathwayHelper::allTerrain );
  }

  if( !pathway.isValid() )
  {
    pathway = PathwayHelper::randomWay( _city(), start, config::distance::animalRandrom );
  }

  if( pathway.isValid() )
  {
    setPos( start );
    setPathway( pathway );
    go();
  }
  else
  {
    die();
  }
}
コード例 #2
0
void WalkerDebugInfo::showPath( WalkerPtr walker, gfx::Engine& engine, gfx::Camera* camera )
{
  Point camOffset = camera->offset();
  const Pathway& pathway = walker->pathway();

  const TilesArray& tiles = pathway.allTiles();

  Point pos = walker->mappos();
  if( pathway.isReverse() )
  {
    int rStart = pathway.length() - pathway.curStep();
    for( int step=rStart-1; step >= 0; step-- )
    {
      engine.drawLine(  0xff0000ff, pos + camOffset, tiles[ step ]->mappos() + camOffset + Point( 30, 0 ) );
      pos = tiles[ step ]->mappos() + Point( 30, 0 );
    }
  }
  else
  {
    for( unsigned int step=pathway.curStep()+1; step < tiles.size(); step++ )
    {
      Tile* tile = tiles[ step ];
      engine.drawLine(  0xff00ff00, pos + camOffset, tile->mappos() + camOffset + Point( 30, 0 ) );
      pos = tile->mappos() + Point( 30, tile->height() * 15 );
    }
  }
}
コード例 #3
0
void PlayerArmy::_reachedWay()
{
    if( _d->mode == PlayerArmy::go2location )
    {
        _attackAny();
        return2fort();
    }
    else if( _d->mode == PlayerArmy::go2home )
    {
        PlayerCityPtr pCity = ptr_cast<PlayerCity>( _d->base );
        if( pCity.isValid() )
        {
            for( auto sldr : _d->soldiersInfo )
            {
                int type = sldr.save[ "type" ];
                WalkerPtr walker = WalkerManager::instance().create( (walker::Type)type, pCity );
                walker->load( sldr.save );
                walker->attach();
            }

            auto fort = pCity->getOverlay( _d->fortPos ).as<Fort>();
            if( fort.isValid() )
            {
                fort->returnSoldiers();
                fort->resetExpedition();
            }
        }

        deleteLater();
    }
}
コード例 #4
0
ファイル: seamerchant.cpp プロジェクト: KSLcom/caesaria-game
void SeaMerchant::Impl::resolveState(PlayerCityPtr city, WalkerPtr wlk )
{
  switch( nextState )
  {
  case stFindDock:
  {    
    destBuildingPos = TilePos( -1, -1 );  // no destination yet    

    Pathway pathway;
    // get the list of buildings within reach   
    if( tryDockCount < maxTryDockCount )
    {
      city::Helper helper( city );
      DockList docks = helper.find<Dock>( objects::dock );

      if( !docks.empty() )
      {
        DockList freeDocks;
        foreach( dock, docks )
        {
          if( !(*dock)->isBusy() )
          {
            freeDocks.push_back( *dock );
          }
        }

        if( freeDocks.empty() )
        {
          pathway = findRandomRaid( docks, wlk->pos() );
          nextState = stWaitFreeDock;
        }
        else
        {
          pathway = findNearbyDock( freeDocks, wlk->pos() );
          nextState = stRequestGoods;
        }
      }
    }
    tryDockCount++;

    if( pathway.isValid() )
    {
      // we found a destination!      
      wlk->setPathway( pathway );
      wlk->go();
    }
    else
    {
      nextState = stGoOutFromCity;
      resolveState( city, wlk );
    }
  }
コード例 #5
0
bool RomeSoldier::die()
{
  bool created = Soldier::die();

  if( !created )
  {
    WalkerPtr w = Corpse::create(_city(), this );
    Logger::warningIf( w.isNull(), "RomeSoldier: cannot create corpse for type " + WalkerHelper::getTypename( type() ) );
    return w.isValid();
  }

  return created;
}
コード例 #6
0
void RomeSoldier::timeStep(const unsigned long time)
{
  Soldier::timeStep( time );

  if( game::Date::isMonthChanged() )
  {
    unsigned int dst2base = pos().distanceFrom( _d->basePos );
    if( dst2base > maxDistanceFromBase )
    {
      updateMorale( dst2base * -10 / maxDistanceFromBase );
      if( morale() == 0 )
      {
        _duckout();
      }
    }
  }

  switch( _subAction() )
  {
  case fightEnemy:
  {
    WalkerList enemies = _findEnemiesInRange( attackDistance() );

    if( !enemies.empty() )
    {
      WalkerPtr p = enemies.front();
      turn( p->pos() );
      p->updateHealth( -3 );
      p->acceptAction( Walker::acFight, pos() );
    }
    else
    {
      bool haveEnemy = _tryAttack();
      if( !haveEnemy )
        send2patrol();
    }
  }
  break;

  case patrol:
    if( game::Date::current().day() % 2 == 0 )
    {
      _tryAttack();
    }
  break;

  default: break;
  } // end switch( _d->action )
}
コード例 #7
0
ファイル: soldier.cpp プロジェクト: KSLcom/caesaria-game
bool Soldier::isFriendTo(WalkerPtr wlk) const
{
  bool isFriend = _dfunc()->friends.count( wlk->type() ) > 0;
  if( !isFriend )
  {
    isFriend = WalkerRelations::isNeutral( type(), wlk->type() );

    if( nation() != world::unknownNation )
    {
      isFriend = WalkerRelations::isNeutral( nation(), wlk->nation() );
    }
  }

  return isFriend;
}
コード例 #8
0
void WorkingBuilding::addWalker( WalkerPtr walker )
{
  if( walker.isValid() )
  {
    _d->walkerList.push_back( walker );
  }
}
コード例 #9
0
ファイル: animals.cpp プロジェクト: dalerank/caesaria-game
void Wolf::_centerTile()
{
  Animal::_centerTile();

  WalkerList walkers = _city()->statistic().walkers
                                           .neighbors<Walker>( pos() )
                                           .exclude<Wolf>();

  if( !walkers.empty() )
  {
    WalkerPtr wlk = walkers.random();

    turn( wlk->pos() );
    _setAction( acFight );
    //setSpeedMultiplier( 0.0 );
    _d->attackPos = wlk->pos();
  }
}
コード例 #10
0
void WalkerDebugInfo::showPath( WalkerPtr walker, gfx::Engine& engine, gfx::Camera* camera, NColor color )
{
  Point camOffset = camera->offset();
  const Pathway& pathway = walker->pathway();

  const TilesArray& tiles = pathway.allTiles();   

  NColor pathColor = color;

  if( color == 0)
  {
    if( walker->agressive() > 0 )
    {
      pathColor = DefaultColors::red;
    }
    else
    {
      pathColor = pathway.isReverse() ? DefaultColors::blue : DefaultColors::green;
    }
  }

  Point pos = walker->mappos();
  Point xOffset( tilemap::cellSize().width(), 0 );
  PointsArray points;
  if( pathway.isReverse() )
  {
    int rStart = pathway.length() - pathway.curStep();
    for( int step=rStart-1; step >= 0; step-- )
    {      
      pos = tiles[ step ]->mappos() + camOffset + xOffset;
      points.push_back( pos );
    }    
  }
  else
  {
    for( unsigned int step=pathway.curStep()+1; step < tiles.size(); step++ )
    {
      pos = tiles[ step ]->mappos() + camOffset + xOffset;
      points.push_back( pos );
    }
  }

  engine.drawLines( pathColor, points );
}
コード例 #11
0
ファイル: thinks.cpp プロジェクト: dalerank/caesaria-game
std::string WalkerThinks::check(WalkerPtr walker, PlayerCityPtr city, const StringArray& own)
{
  city::InfoPtr info = city->statistic().services.find<Info>();

  if( info.isNull() )
  {
    Logger::warning( "CitizenIdea::check no city service info" );
    return "##unknown_reason##";
  }

  if( walker.is<Animal>() )
  {
    std::string text = fmt::format( "##animal_{}_say##", walker->info().typeName() );
    return text;
  }

  Info::Parameters params = info->lastParams();
  ThinksConstructor ret( walker->info().typeName() );
  ret.append(own);

  ret.addIf( params[ Info::monthWithFood ] < 3,     "_so_hungry" )
     .addIf( params[ Info::godsMood ] < 3,          "_gods_angry" )
     .addIf( params[ Info::colosseumCoverage ] < 3, "_need_colosseum" )
     .addIf( params[ Info::theaterCoverage ] < 3,   "_need_theater" )
     .addIf( params[ Info::entertainment ] < 20,    "_low_entertainment" )
     .addIf( params[ Info::needWorkers ] > 0,       "_need_workers" )
     .addIf( params[ Info::workless ] > 15,         "_high_workless" )
     .addIf( params[ Info::tax ] > 10,              "_high_tax" )
     .addIf( params[ Info::payDiff ] < 0,           "_low_salary" );

  if( !ret.empty() )
    return ret.random();

  ret.clear();
  ret.append(own);
  ret.addIf( params[ Info::lifeValue ] > 90, "_good_life" )
     .addIf( params[ Info::lifeValue ] > 75, "_average_life" )
     .addIf( params[ Info::lifeValue ] > 50, "_normal_life" )
     .addIf( params[ Info::education ] > 90, "_good_education" );

  return ret.empty() ? "##unknown_reason##" : ret.random();
}
コード例 #12
0
inline bool Statistic::_Map::isTileBusy( const TilePos& p, WalkerPtr caller, bool& needMeMove ) const
{
  needMeMove = false;
  auto walkers = _parent.rcity.walkers( p ).select<T>();

  if( !walkers.empty() )
  {
    needMeMove = (caller.object() != walkers.front().object());
  }

  return walkers.size() > 1;
}
コード例 #13
0
ファイル: city_impl.cpp プロジェクト: binakot/caesaria-game
void Walkers::update(PlayerCityPtr, unsigned int time)
{
  WalkerList::iterator it = begin();
  while( it != end() )
  {
    WalkerPtr walker = *it;
    walker->timeStep( time );
    if( walker->isDeleted() )
    {
      // remove the walker from the walkers list
      //grid.remove( *it );
      it = erase(it);
    }
    else { ++it; }
  }

  merge();

  grid.update( *this );
  grid.sort();
}
コード例 #14
0
void Peace::addCriminal( WalkerPtr wlk )
{
  if( is_kind_of<Rioter>( wlk ) )
  {
    _d->rioterSeen = true;
  }
  /*else if( is_kind_of<Protestor>( wlk ) )
  {
    _d->protestorOrMugglerSeen = true;
  }*/
  else
  {
    Logger::warning( "Peace:addCrimianl unknown walker %d", wlk->type() );
    _d->someCriminalSeen = true;
  }
}
コード例 #15
0
ファイル: city_impl.cpp プロジェクト: binakot/caesaria-game
void Walkers::postpone(WalkerPtr w)
{
  ++idCount;
  w->setUniqueId( idCount );
  FlowList::postpone( w );
}
コード例 #16
0
ファイル: romearcher.cpp プロジェクト: KSLcom/caesaria-game
void RomeArcher::timeStep(const unsigned long time)
{
  Soldier::timeStep( time );

  switch( _subAction() )
  {
  case Soldier::fightEnemy:
  {
    WalkerList enemies = _findEnemiesInRange( attackDistance() );

    if( !enemies.empty() )
    {
      WalkerPtr p = enemies.front();
      turn( p->pos() );

      if( _animationRef().index() == (int)(_animationRef().frameCount()-1) )
      {
        _fire( p->pos() );
        _updateAnimation( time+1 );
      }
    }
    else
    {
      //_check4attack();
      send2patrol();
    }
  }
  break;

  case Soldier::destroyBuilding:
  {
    ConstructionList constructions = _findContructionsInRange( attackDistance() );

    if( !constructions.empty() )
    {
      ConstructionPtr b = constructions.front();
      turn( b->pos() );

      if( _animationRef().index() == (int)(_animationRef().frameCount()-1) )
      {
        _fire( b->pos() );
        _updateAnimation( time+1 );
      }
    }
    else
    {
      //_check4attack();
      send2patrol();
    }
  }

  case Soldier::patrol:
    if( game::Date::current().day() % 2 == 0 )
    {
      _tryAttack();
    }
  break;

  default: break;
  } // end switch( _d->action )
}
コード例 #17
0
ファイル: merchant.cpp プロジェクト: BlackFoks/opencaesar3
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" );
  }