Beispiel #1
0
//An easy to use, do-everything-in-one-call sort of function
commandList GalconAI::update(std::list<Planet> & planets, const std::list<Fleet> & fleets, const std::vector<ShipStats> & shipstats, std::vector<std::list<Building*> > buildRules)
{
  //Set up the list of commands
  commandList rb;
  
  //See if we have waited long enough and the AI is active
  int time = SDL_GetTicks();
  if ((time - updateTime_ < set_.delay && updateTime_ != -1) || !active_) return rb;
  updateTime_ = time;
  std::cout << "Update) Attack: " << attTotal_ << " Defense: " << defTotal_ << std::endl;

  //Compute the best target
  computeTarget(planets, fleets, shipstats);

  //Get the commands from rebalancing, attacking, and building
  rb = rebalance(fleets, shipstats);
  commandList at = attack(shipstats);
  commandList bd = build(buildRules, shipstats);

  //Append at to rb
  for (commandList::iterator i = at.begin(); i != at.end(); i++)
    {
      rb.push_back(*i);
    }
  for (commandList::iterator i = bd.begin(); i != bd.end(); i++)
    {
      rb.push_back(*i);
    }

  //Return the combined list of commands
  return rb;
}
RubberBall::RubberBall(AbstractKart *kart)
          : Flyable(kart, PowerupManager::POWERUP_RUBBERBALL, 0.0f /* mass */),
            TrackSector()
{
    // For debugging purpose: pre-fix each debugging line with the id of
    // the ball so that it's easy to collect all debug output for one
    // particular ball only.
    m_next_id++;
    m_id = m_next_id;

    // Don't let Flyable update the terrain information, since this object
    // has to do it earlier than that.
    setDoTerrainInfo(false);
    float forw_offset = 0.5f*kart->getKartLength() + m_extend.getZ()*0.5f+5.0f;

    createPhysics(forw_offset, btVector3(0.0f, 0.0f, m_speed*2),
                  new btSphereShape(0.5f*m_extend.getY()),
                  -70.0f /*gravity*/,
                  true /*rotates*/);

    // Do not adjust the up velocity
    setAdjustUpVelocity(false);
    m_max_lifespan       = 9999;
    m_target             = NULL;
    m_aiming_at_target   = false;
    m_fast_ping          = false;
    // At the start the ball aims at quads till it gets close enough to the
    // target:
    m_height_timer       = 0.0f;
    m_interval           = m_st_interval;
    m_current_max_height = m_max_height;
    m_ping_sfx           = sfx_manager->createSoundSource("ball_bounce");
    // Just init the previoux coordinates with some value that's not getXYZ()
    m_previous_xyz       = m_owner->getXYZ();
    m_previous_height    = 2.0f;  //
    // A negative value indicates that the timer is not active
    m_delete_timer       = -1.0f;
    m_tunnel_count       = 0;

    LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
    // FIXME: what does the rubber ball do in case of battle mode??
    if(!world) return;

    computeTarget();

    // initialises the current graph node
    TrackSector::update(getXYZ());
    TerrainInfo::update(getXYZ());
    initializeControlPoints(m_owner->getXYZ());

}   // RubberBall
/** Updates the rubber ball.
 *  \param dt Time step size.
 *  \returns True if the rubber ball should be removed.
 */
bool RubberBall::updateAndDelete(float dt)
{
    LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
    // FIXME: what does the rubber ball do in case of battle mode??
    if(!world) return true;

    if(m_delete_timer>0)
    {
        m_delete_timer -= dt;
        if(m_delete_timer<=0)
        {
            hit(NULL);
#ifdef PRINT_BALL_REMOVE_INFO
            Log::debug("RubberBall", "ball %d deleted.", m_id);
#endif
            return true;
        }
    }

    // Update the target in case that the first kart was overtaken (or has
    // finished the race).
    computeTarget();
    updateDistanceToTarget();

    // Determine the new position. This new position is only temporary,
    // since it still needs to be adjusted for the height of the terrain.
    Vec3 next_xyz;
    if(m_aiming_at_target)
        moveTowardsTarget(&next_xyz, dt);
    else
        interpolate(&next_xyz, dt);

    // If the ball is close to the ground, we have to start the raycast
    // slightly higher (to avoid that the ball tunnels through the floor).
    // But if the ball is close to the ceiling of a tunnel and we would
    // start the raycast slightly higher, the ball might end up on top
    // of the ceiling.
    // The ball is considered close to the ground if the height above the
    // terrain is less than half the current maximum height.
    bool close_to_ground = 2.0*m_previous_height < m_current_max_height;

    float vertical_offset = close_to_ground ? 4.0f : 2.0f;
    // Note that at this stage getHoT still reports the height at
    // the previous location (since TerrainInfo wasn't updated). On
    // the other hand, we can't update TerrainInfo without having
    // at least a good estimation of the height.
    next_xyz.setY(getHoT() + vertical_offset);
    // Update height of terrain (which isn't done as part of
    // Flyable::update for rubber balls.
    TerrainInfo::update(next_xyz);

    m_height_timer += dt;
    float height    = updateHeight()+m_extend.getY()*0.5f;
    float new_y     = getHoT()+height;

    if(UserConfigParams::logFlyable())
        printf("ball %d: %f %f %f height %f new_y %f gethot %f ",
                m_id, next_xyz.getX(), next_xyz.getY(), next_xyz.getZ(), height, new_y, getHoT());

    // No need to check for terrain height if the ball is low to the ground
    if(height > 0.5f)
    {
        float terrain_height = getMaxTerrainHeight(vertical_offset)
                             - m_extend.getY();
        if(new_y>terrain_height)
            new_y = terrain_height;
    }

    if(UserConfigParams::logFlyable())
        Log::verbose("RubberBall", "newy2 %f gmth %f", new_y,
                     getMaxTerrainHeight(vertical_offset));

    next_xyz.setY(new_y);
    m_previous_xyz = getXYZ();
    m_previous_height = next_xyz.getY()-getHoT();
    setXYZ(next_xyz);

    if(checkTunneling())
        return true;

    // Determine new distance along track
    TrackSector::update(next_xyz);

    // Ball squashing:
    // ===============
    if(height<1.5f*m_extend.getY())
        m_node->setScale(core::vector3df(1.0f, height/m_extend.getY(),1.0f));
    else
        m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));

    return Flyable::updateAndDelete(dt);
}   // updateAndDelete