void Wheel::reset() { dSpaceID space = dGeomGetSpace(ph.geom); dGeomDestroy(ph.geom); dBodyDestroy(ph.body); Utils::Xml x(cst.xmlFile, "wheel"); createPhysics(x, space); disposePhysics(x); }
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
// ----------------------------------------------------------------------------- Bowling::Bowling(AbstractKart *kart) : Flyable(kart, PowerupManager::POWERUP_BOWLING, 50.0f /* mass */) { m_has_hit_kart = false; float y_offset = 0.5f*kart->getKartLength() + m_extend.getZ()*0.5f; // if the kart is looking backwards, release from the back if( kart->getControls().getLookBack()) { y_offset = -y_offset; m_speed = -m_speed*2; } else { float min_speed = m_speed*4.0f; /* make it go faster when throwing forward so the player doesn't catch up with the ball and explode by touching it */ m_speed = kart->getSpeed() + m_speed; if(m_speed < min_speed) m_speed = min_speed; } const Vec3& normal = kart->getNormal(); createPhysics(y_offset, btVector3(0.0f, 0.0f, m_speed*2), new btSphereShape(0.5f*m_extend.getY()), 0.4f /*restitution*/, -70.0f*normal /*gravity*/, true /*rotates*/); // Even if the ball is fired backwards, m_speed must be positive, // otherwise the ball can start to vibrate when energy is added. m_speed = fabsf(m_speed); // Do not adjust the up velociy depending on height above terrain, since // this would disable gravity. setAdjustUpVelocity(false); // unset no_contact_response flags, so that the ball // will bounce off the track int flag = getBody()->getCollisionFlags(); flag = flag & (~ btCollisionObject::CF_NO_CONTACT_RESPONSE); getBody()->setCollisionFlags(flag); // should not live forever, auto-destruct after 20 seconds m_max_lifespan = 20; m_roll_sfx = SFXManager::get()->createSoundSource("bowling_roll"); m_roll_sfx->play(); m_roll_sfx->setLoop(true); } // Bowling
void Wheel::initXml(const char* xmlFile, dSpaceID space) { Utils::Xml x(xmlFile, "wheel"); cst.xmlFile = xmlFile; cst.nodeName = x.mustString("name"); createNodesAndMesh(x); createPhysics(x, space); disposePhysics(x); setupContact(x); MyTools::byOdeToOgre(ph.geom, cst.wheelNode); }
Tumbler::Tumbler(Player *pl, Pim::SpriteBatchNode *b, Pim::Vec2 p) : Troll(b, p) { createPhysics(); attackAnim.firstFramePos = Pim::Vec2(0.f, 34.f); attackAnim.frameWidth = 30; attackAnim.frameHeight = 30; attackAnim.frameTime = 0.25f; attackAnim.horizontalFrames = 4; attackAnim.framesInAnimation = 4; attackAnim.totalFrames = 4; walkAnim.firstFramePos = Pim::Vec2(120.f, 34.f); walkAnim.frameWidth = 30; walkAnim.frameHeight = 30; walkAnim.frameTime = 0.3f; walkAnim.horizontalFrames = 4; walkAnim.framesInAnimation = 4; walkAnim.totalFrames = 4; deathAnim.firstFramePos = Pim::Vec2(240.f, 34.f); deathAnim.frameWidth = 30; deathAnim.frameHeight = 30; deathAnim.frameTime = 0.2f; deathAnim.horizontalFrames = 7; deathAnim.framesInAnimation = 7; deathAnim.totalFrames = 7; scoreValue = 75; player = pl; walkSpeed = 5.f; health = 100; ai = new TumblerAI(this, player); b2offset = Pim::Vec2(0.f, 4.f); timeToDie = 1.4f; rect = walkAnim.frameIndex(0); }
// ----------------------------------------------------------------------------- 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