Пример #1
0
WalkerList EnemySoldier::_findEnemiesInRange( unsigned int range )
{
  Tilemap& tmap = _city()->tilemap();
  WalkerList walkers;

  for( unsigned int k=0; k <= range; k ++ )
  {
    TilesArray tiles = tmap.rect( k, pos() );

    walker::Type rtype;
    for( auto tile : tiles )
    {
      const WalkerList& tileWalkers = _city()->walkers( tile->pos() );

      for( auto wlk : tileWalkers )
      {
        rtype = wlk->type();
        if( rtype == type() || !WalkerHelper::isHuman( wlk ) || isFriendTo( wlk ) )
          continue;

        walkers.push_back( wlk );
      }
    }
  }

  return walkers;
}
Пример #2
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;
}
Пример #3
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;
  }
}
Пример #4
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();
  }
}
Пример #5
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();
}
Пример #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
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();
  }
}
Пример #8
0
void RomeSoldier::_reachedPathway()
{
  Soldier::_reachedPathway();

  switch( (int)_subAction() )
  {

  case expedition:
    deleteLater();
  break;

  case go2position:
  {
    WalkerList walkersOnTile = _city()->statistic().walkers.find<Walker>( type(), pos() );
    walkersOnTile.remove( this );

    if( walkersOnTile.size() > 0 ) //only me in this tile
    {
      _back2base();
    }
    else
    {
      _setSubAction( patrol );
    }
  }
  break;

  case duckout:
  {
    deleteLater();
  }
  break;

  default:
  break;
  }
}
Пример #9
0
inline SmartList<T> Statistic::_Walkers::find( walker::Type type,
                                               TilePos start, TilePos stop ) const
{
  WalkerList walkersInArea;

  TilePos stopPos = stop;

  if( start == gfx::tilemap::invalidLocation() )
  {
    const WalkerList& all =_parent.rcity.walkers();
    walkersInArea.insert( walkersInArea.end(), all.begin(), all.end() );
  }
  else if( stopPos == gfx::tilemap::invalidLocation() )
  {
    const WalkerList& wlkOnTile = _parent.rcity.walkers( start );
    walkersInArea.insert( walkersInArea.end(), wlkOnTile.begin(), wlkOnTile.end() );
  }
  else
  {
    gfx::TilesArea area( _parent.rcity.tilemap(), start, stop );
    for( auto& tile : area)
    {
      const WalkerList& wlkOnTile = _parent.rcity.walkers( tile->pos() );
      walkersInArea.insert( walkersInArea.end(), wlkOnTile.begin(), wlkOnTile.end() );
    }
  }

  SmartList< T > result;
  for( auto& w : walkersInArea )
  {
    if( w->type() == type || type == walker::any )
      result.addIfValid( w.as<T>() );
  }

  return result;
}
Пример #10
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 )
}