/** Updates the bowling ball ineach frame. If this function returns true, the * object will be removed by the projectile manager. * \param dt Time step size. * \returns True of this object should be removed. */ bool Bowling::updateAndDelete(float dt) { bool can_be_deleted = Flyable::updateAndDelete(dt); if(can_be_deleted) return true; const AbstractKart *kart=0; Vec3 direction; float minDistance; getClosestKart(&kart, &minDistance, &direction); if(kart && minDistance<m_st_max_distance_squared) // move bowling towards kart { // limit angle, so that the bowling ball does not turn // around to hit a kart behind if(fabs(m_body->getLinearVelocity().angle(direction)) < 1.3) { direction*=1/direction.length()*m_st_force_to_target; m_body->applyCentralForce(direction); } } // Bowling balls lose energy (e.g. when hitting the track), so increase // the speed if the ball is too slow, but only if it's not too high (if // the ball is too high, it is 'pushed down', which can reduce the // speed, which causes the speed to increase, which in turn causes // the ball to fly higher and higher. //btTransform trans = getTrans(); float hat = getXYZ().getY()-getHoT(); if(hat-0.5f*m_extend.getY()<0.01f) { const Material *material = getMaterial(); if(!material || material->isDriveReset()) { hit(NULL); return true; } } btVector3 v = m_body->getLinearVelocity(); float vlen = v.length2(); if (hat<= m_max_height) { if(vlen<0.8*m_speed*m_speed) { // bowling lost energy (less than 80%), i.e. it's too slow - speed it up: if(vlen==0.0f) { v = btVector3(.5f, .0, 0.5f); // avoid 0 div. } // m_body->setLinearVelocity(v*(m_speed/sqrt(vlen))); } // vlen < 0.8*m_speed*m_speed } // hat< m_max_height if(vlen<0.1) { hit(NULL); return true; } if (m_roll_sfx->getStatus()==SFXBase::SFX_PLAYING) m_roll_sfx->setPosition(getXYZ()); return false; } // updateAndDelete
// ----------------------------------------------------------------------------- Plunger::Plunger(AbstractKart *kart) : Flyable(kart, PowerupManager::POWERUP_PLUNGER) { const float gravity = 0.0f; float forward_offset = 0.5f*kart->getKartLength()+0.5f*m_extend.getZ(); float up_velocity = 0.0f; float plunger_speed = 2 * m_speed; // if the kart is looking backwards, release from the back m_reverse_mode = kart->getControls().m_look_back; // find closest kart in front of the current one const AbstractKart *closest_kart=0; Vec3 direction; float kart_dist_2; getClosestKart(&closest_kart, &kart_dist_2, &direction, kart /* search in front of this kart */, m_reverse_mode); btTransform kart_transform = kart->getAlignedTransform(); btMatrix3x3 kart_rotation = kart_transform.getBasis(); float heading =kart->getHeading(); float pitch = kart->getTerrainPitch(heading); // aim at this kart if it's not too far if(closest_kart != NULL && kart_dist_2 < 30*30) { float fire_angle = 0.0f; getLinearKartItemIntersection (kart->getXYZ(), closest_kart, plunger_speed, gravity, forward_offset, &fire_angle, &up_velocity); btTransform trans = kart->getTrans(); trans.setRotation(btQuaternion(btVector3(0, 1, 0), fire_angle)); m_initial_velocity = btVector3(0.0f, up_velocity, plunger_speed); createPhysics(forward_offset, m_initial_velocity, new btCylinderShape(0.5f*m_extend), 0.5f /* restitution */ , gravity, /* rotates */false , /*turn around*/false, &trans); } else { createPhysics(forward_offset, btVector3(pitch, 0.0f, plunger_speed), new btCylinderShape(0.5f*m_extend), 0.5f /* restitution */, gravity, false /* rotates */, m_reverse_mode, &kart_transform); } //adjust height according to terrain setAdjustUpVelocity(false); // pulling back makes no sense in battle mode, since this mode is not a race. // so in battle mode, always hide view if( m_reverse_mode || race_manager->isBattleMode() ) m_rubber_band = NULL; else { m_rubber_band = new RubberBand(this, kart); } m_keep_alive = -1; } // Plunger
Cake::Cake (AbstractKart *kart) : Flyable(kart, PowerupManager::POWERUP_CAKE) { m_target = NULL; // 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().m_look_back; 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) trans.setRotation(btQuaternion(btVector3(0,1,0), fire_angle)); 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 */, -m_gravity, 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 */, -m_gravity, 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