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;
}
Exemple #2
0
void Wolf::timeStep(const unsigned long time)
{
  Animal::timeStep( time );

  switch( action() )
  {
  case acFight:
  {
    WalkerList walkers = _city()->walkers( _d->attackPos ).exclude<Wolf>();

    if( !walkers.empty() )
    {
      walkers.front()->updateHealth( defaultAttackValue );
      walkers.front()->acceptAction( acFight, pos() );
    }
    else
    {
      _findNewWay( pos() );
    }
  }
  break;

  default:
  break;
  }
}
Exemple #3
0
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();
  }
}
Exemple #4
0
std::string Wharf::troubleDesc() const
{
  if( _d->boat.isValid() )
  {
    WalkerList places = _city()->walkers( walker::fishPlace );
    if( places.empty() )
    {
      return "##no_fishplace_in_city##";
    }
  }

  return CoastalFactory::troubleDesc();
}
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 )
}
Exemple #6
0
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();
  }
}
Exemple #7
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 )
}