Пример #1
0
bool EnemySoldier::_tryAttack()
{
  WalkerList enemies = _findEnemiesInRange( attackDistance() );

  if( !enemies.empty() )
  {
    _setSubAction( Soldier::fightEnemy );
    setTarget( enemies.front()->pos() );
    fight();
  }
  else
  {
    ConstructionList constructions = _findContructionsInRange( attackDistance() );
    if( !constructions.empty() )
    {
      _setSubAction( Soldier::destroyBuilding );
      setTarget( constructions.front()->pos() );
      fight();
    }
  }

  if( action() == acFight )
  {
    bool needMeMove = false;
    _city()->statistic().map.isTileBusy<EnemySoldier>( pos(), this, needMeMove );

    if( needMeMove )
    {
      _move2freePos( target() );
    }
  }

  return action() == acFight;
}
Пример #2
0
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 )
}
Пример #3
0
ConstructionList EnemySoldier::_findContructionsInRange( unsigned int range )
{
  ConstructionList ret;
  Tilemap& tmap = _map();

  for( unsigned int k=0; k <= range; k++ )
  {
    ConstructionList blds = tmap.rect( k, pos() )
                                .overlays()
                                .select<Construction>();

    for( auto b : blds )
    {
      if( !_atExclude.count( b->group() ) )
      {
        ret.push_back( b );
      }
    }
  }

  if( ret.empty() )
    return ret;

  switch( _atPriority )
  {
  case attackFood:
  case attackCitizen:
  case attackIndustry:
  {
    ConstructionList tmpRet;
    object::Group needGroup;
    switch( _atPriority )
    {
    case attackIndustry: needGroup = object::group::industry; break;
    case attackFood: needGroup = object::group::food; break;
    case attackCitizen:  needGroup = object::group::house; break;
    case attackSenate: needGroup = object::group::administration; break;
    default: needGroup = object::group::unknown; break;
    }

    for( auto bld : ret )
    {
      if( bld->group() == needGroup )
      {
        tmpRet << bld;
      }
    }

    if( !tmpRet.empty() )
      return tmpRet;
  }
  break;

  case attackBestBuilding:
  {
    ConstructionPtr maxBuilding = ret.front();
    unsigned int maxCost = __getCost( maxBuilding );

    foreach( it, ret )
    {
      unsigned int cost = __getCost( *it );
      if( cost > maxCost )
      {
        maxCost = cost;
        maxBuilding = *it;
      }
    }

    if( maxBuilding.isValid() )
    {
      ret.clear();
      ret << maxBuilding;
      return ret;
    }
  }
  break;

  default:
  break;
  }