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
Exemple #2
0
Cake::Cake (AbstractKart *kart) : Flyable(kart, PowerupManager::POWERUP_CAKE)
{
    m_target = NULL;

    setDoTerrainInfo(false);

    btVector3 gravity_vector;
    btQuaternion q = kart->getTrans().getRotation();
    gravity_vector = Vec3(0, -1, 0).rotate(q.getAxis(), q.getAngle());
    gravity_vector = gravity_vector.normalize() * m_gravity;
    // A bit of a hack: the mass of this kinematic object is still 1.0
    // (see flyable), which enables collisions. I tried setting
    // collisionFilterGroup/mask, but still couldn't get this object to
    // collide with the track. By setting the mass to 1, collisions happen.
    // (if bullet is compiled with _DEBUG, a warning will be printed the first
    // time a homing-track collision happens).
    float forward_offset=kart->getKartLength()/2.0f + m_extend.getZ()/2.0f;

    float up_velocity = m_speed/7.0f;

    // give a speed proportional to kart speed. m_speed is defined in flyable
    m_speed *= kart->getSpeed() / 23.0f;

    //when going backwards, decrease speed of cake by less
    if (kart->getSpeed() < 0) m_speed /= 3.6f;

    m_speed += 16.0f;

    if (m_speed < 1.0f) m_speed = 1.0f;

    btTransform trans = kart->getTrans();

    float heading=kart->getHeading();
    float pitch = kart->getTerrainPitch(heading);

    // Find closest kart in front of the current one
    const bool  backwards = kart->getControls().getLookBack();
    const AbstractKart *closest_kart=NULL;
    Vec3        direction;
    float       kart_dist_squared;
    getClosestKart(&closest_kart, &kart_dist_squared, &direction,
                   kart /* search in front of this kart */, backwards);

    // aim at this kart if 1) it's not too far, 2) if the aimed kart's speed
    // allows the projectile to catch up with it
    //
    // this code finds the correct angle and upwards velocity to hit an opponents'
    // vehicle if they were to continue travelling in the same direction and same speed
    // (barring any obstacles in the way of course)
    if(closest_kart != NULL && kart_dist_squared < m_st_max_distance_squared &&
        m_speed>closest_kart->getSpeed())
    {
        m_target = (AbstractKart*)closest_kart;

        float fire_angle     = 0.0f;
        getLinearKartItemIntersection (kart->getXYZ(), closest_kart,
                                       m_speed, m_gravity, forward_offset,
                                       &fire_angle, &up_velocity);

        // apply transformation to the bullet object (without pitch)
        btQuaternion q;
        q = trans.getRotation() * btQuaternion(btVector3(0, 1, 0), fire_angle);
        trans.setRotation(q);
        m_initial_velocity = Vec3(0.0f, up_velocity, m_speed);

        createPhysics(forward_offset, m_initial_velocity,
                      new btCylinderShape(0.5f*m_extend),
                      0.5f /* restitution */, gravity_vector,
                      true /* rotation */, false /* backwards */, &trans);
    }
    else
    {
        m_target = NULL;
        // kart is too far to be hit. so throw the projectile in a generic way,
        // straight ahead, without trying to hit anything in particular
        trans = kart->getAlignedTransform(pitch);

        m_initial_velocity = Vec3(0.0f, up_velocity, m_speed);

        createPhysics(forward_offset, m_initial_velocity,
                      new btCylinderShape(0.5f*m_extend),
                      0.5f /* restitution */, gravity_vector,
                      true /* rotation */, backwards, &trans);
    }


    //do not adjust height according to terrain
    setAdjustUpVelocity(false);

    m_body->setActivationState(DISABLE_DEACTIVATION);

    m_body->applyTorque( btVector3(5,-3,7) );

}   // Cake