diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 20bb72e9c..0d596b7be 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -39,7 +39,7 @@ Attachment::Attachment(Kart* _kart) m_previous_owner = NULL; m_kart->getModelTransform()->addKid(m_holder); - for(int i=ATTACH_PARACHUTE; i<=ATTACH_TINYTUX; i++) + for(int i=ATTACH_FIRST; i<ATTACH_MAX; i++) { ssgEntity *p=attachment_manager->getModel((attachmentType)i); m_holder->addKid(p); @@ -56,6 +56,7 @@ Attachment::~Attachment() //----------------------------------------------------------------------------- void Attachment::set(attachmentType _type, float time, Kart *current_kart) { + clear(); m_holder->selectStep(_type); m_type = _type; m_time_left = time; @@ -63,58 +64,82 @@ void Attachment::set(attachmentType _type, float time, Kart *current_kart) } // set // ----------------------------------------------------------------------------- -void Attachment::hitBanana(const Item &item, int random_attachment) +/** Removes any attachement currently on the kart. As for the anvil attachment, + * takes care of resetting the owner kart's physics structures to account for + * the updated mass. + */ +void Attachment::clear() +{ + m_type=ATTACH_NOTHING; + m_time_left=0.0; + m_holder->select(0); + + // Resets the weight of the kart if the previous attachment affected it + // (e.g. anvil). This must be done *after* setting m_type to + // ATTACH_NOTHING in order to reset the physics parameters. + m_kart->updatedWeight(); +} // clear + +// ----------------------------------------------------------------------------- +void Attachment::hitBanana(const Item &item, int new_attachment) { if(user_config->m_profile) return; float leftover_time = 0.0f; switch(getType()) // If there already is an attachment, make it worse :) { - case ATTACH_BOMB: projectile_manager->newExplosion(m_kart->getXYZ()); - m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true); - clear(); - if(random_attachment==-1) - random_attachment = m_random.get(3); - break; - case ATTACH_ANVIL :// if the kart already has an anvil, attach a new anvil, - // and increase the overall time - random_attachment = 2; - leftover_time = m_time_left; - break; + case ATTACH_BOMB: + projectile_manager->newExplosion(m_kart->getXYZ()); + m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true); + clear(); + if(new_attachment==-1) + new_attachment = m_random.get(3); + break; + case ATTACH_ANVIL: + // if the kart already has an anvil, attach a new anvil, + // and increase the overall time + new_attachment = 2; + leftover_time = m_time_left; + break; case ATTACH_PARACHUTE: - random_attachment = 2; // anvil - leftover_time = m_time_left; - break; - default: if(random_attachment==-1) - random_attachment = m_random.get(3); + new_attachment = 2; // anvil + leftover_time = m_time_left; + break; + default: + if(new_attachment==-1) + new_attachment = m_random.get(3); } // switch // Save the information about the attachment in the race state // so that the clients can be updated. if(network_manager->getMode()==NetworkManager::NW_SERVER) { - race_state->itemCollected(m_kart->getWorldKartId(), - item.getItemId(), - random_attachment); + race_state->itemCollected(m_kart->getWorldKartId(), + item.getItemId(), + new_attachment); } - switch (random_attachment) + switch (new_attachment) { - case 0: set( ATTACH_PARACHUTE, stk_config->m_parachute_time+leftover_time); + case 0: + set( ATTACH_PARACHUTE,stk_config->m_parachute_time+leftover_time); m_initial_speed = m_kart->getSpeed(); // if ( m_kart == m_kart[0] ) // sound -> playSfx ( SOUND_SHOOMF ) ; break ; - case 1: set( ATTACH_BOMB, stk_config->m_bomb_time+leftover_time); + case 1: + set( ATTACH_BOMB, stk_config->m_bomb_time+leftover_time); // if ( m_kart == m_kart[0] ) // sound -> playSfx ( SOUND_SHOOMF ) ; break ; - case 2: set( ATTACH_ANVIL, stk_config->m_anvil_time+leftover_time); + case 2: + set( ATTACH_ANVIL, stk_config->m_anvil_time+leftover_time); // if ( m_kart == m_kart[0] ) // sound -> playSfx ( SOUND_SHOOMF ) ; // Reduce speed once (see description above), all other changes are // handled in Kart::updatePhysics - m_kart->adjustSpeedWeight(stk_config->m_anvil_speed_factor); + m_kart->adjustSpeed(stk_config->m_anvil_speed_factor); + m_kart->updatedWeight(); break ; } // switch } // hitBanana @@ -137,40 +162,35 @@ void Attachment::update(float dt) switch (m_type) { - case ATTACH_PARACHUTE: // Partly handled in Kart::updatePhysics - // Otherwise: disable if a certain percantage of - // initial speed was lost - if(m_kart->getSpeed()<= - m_initial_speed*stk_config->m_parachute_done_fraction) - { - m_time_left = -1; - } - break; + case ATTACH_PARACHUTE: + // Partly handled in Kart::updatePhysics + // Otherwise: disable if a certain percantage of + // initial speed was lost + if(m_kart->getSpeed()<= + m_initial_speed*stk_config->m_parachute_done_fraction) + { + m_time_left = -1; + } + break; case ATTACH_ANVIL: // handled in Kart::updatePhysics case ATTACH_NOTHING: // Nothing to do, but complete all cases for switch - case ATTACH_MAX: break; - case ATTACH_BOMB: if(m_time_left<=0.0) - { - projectile_manager->newExplosion(m_kart->getXYZ()); - m_kart->handleExplosion(m_kart->getXYZ(), - /*direct_hit*/ true); - } - break; - case ATTACH_TINYTUX: if(m_time_left<=0.0) m_kart->endRescue(); - break; + case ATTACH_MAX: + break; + case ATTACH_BOMB: + if(m_time_left<=0.0) + { + projectile_manager->newExplosion(m_kart->getXYZ()); + m_kart->handleExplosion(m_kart->getXYZ(), + /*direct_hit*/ true); + } + break; + case ATTACH_TINYTUX: + if(m_time_left<=0.0) m_kart->endRescue(); + break; } // switch // Detach attachment if its time is up. if ( m_time_left <= 0.0f) - { - if(m_type==ATTACH_ANVIL) - { - // Resets the weight, and multiplies the velocity by 1.0, - // i.e. no change of velocity. - m_kart->getAttachment()->clear(); - m_kart->adjustSpeedWeight(1.0f); - } clear(); - } // if m_time_left<0 } // update //----------------------------------------------------------------------------- diff --git a/src/items/attachment.hpp b/src/items/attachment.hpp index a3bb641ed..f6cf2954b 100644 --- a/src/items/attachment.hpp +++ b/src/items/attachment.hpp @@ -26,13 +26,19 @@ class Kart; class Item; -// Some loop in Attachment.cpp depend on PARACHUTE being the first element, -// and TINYTUX being the last one. So if new elemts are added, make sure -// to add them in between those values. -enum attachmentType { ATTACH_PARACHUTE, - ATTACH_BOMB, - ATTACH_ANVIL, ATTACH_TINYTUX, - ATTACH_MAX, ATTACH_NOTHING}; +// Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX. +// So if new elements are added, make sure to add them in between those values. +// Also, please note that Attachment::Attachment relies on ATTACH_FIRST being 0. +enum attachmentType +{ + ATTACH_FIRST = 0, + ATTACH_PARACHUTE = 0, + ATTACH_BOMB, + ATTACH_ANVIL, + ATTACH_TINYTUX, + ATTACH_MAX, + ATTACH_NOTHING +}; class Attachment @@ -52,36 +58,34 @@ public: void set (attachmentType _type, float time, Kart *previous_kart=NULL); void set (attachmentType _type) { set(_type, m_time_left); } - void clear () { - m_type=ATTACH_NOTHING; - m_time_left=0.0; - m_holder->select(0); - } + void clear (); attachmentType getType () const { return m_type; } float getTimeLeft () const { return m_time_left; } void setTimeLeft (float t){ m_time_left = t; } Kart* getPreviousOwner () const { return m_previous_owner; } - float WeightAdjust () const { + + float weightAdjust () const { return m_type==ATTACH_ANVIL ?stk_config->m_anvil_weight:0.0f; } - float AirResistanceAdjust () const { + float airResistanceAdjust () const { return m_type==ATTACH_PARACHUTE ?stk_config->m_parachute_friction:0.0f; } - float SpeedAdjust () const { + float speedAdjust () const { return m_type==ATTACH_ANVIL ?stk_config->m_anvil_speed_factor:1.0f; } + /** Randomly selects the new attachment. For a server process, the * attachment can be passed into this function. \param item The item that was collected. - \param random_attachment Optional: only used on the clients, it - specifies the new attachment to use + \param new_attachment Optional: only used on the clients, it + specifies the new attachment to use */ - void hitBanana(const Item &item, int random_attachment=-1); + void hitBanana(const Item &item, int new_attachment=-1); void update (float dt); void moveBombFromTo(Kart *from, Kart *to); }; diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index b492167d2..dc5a130b5 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -126,7 +126,8 @@ void Powerup::use() if(kart->getPosition() == 1) { kart->attach(ATTACH_ANVIL, stk_config->m_anvil_time); - kart->adjustSpeedWeight(stk_config->m_anvil_speed_factor*0.5f); + kart->updatedWeight(); + kart->adjustSpeed(stk_config->m_anvil_speed_factor*0.5f); m_sound_use_anvil->position(m_owner->getXYZ()); m_sound_use_anvil->play(); break; diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 94046f8b4..1278881a0 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -181,7 +181,7 @@ void Kart::createPhysics() m_vehicle_raycaster = new btDefaultVehicleRaycaster(RaceManager::getWorld()->getPhysics()->getPhysicsWorld()); m_tuning = new btKart::btVehicleTuning(); - m_tuning->m_maxSuspensionTravelCm = m_kart_properties->getSuspensionTravelCM(); + m_tuning->m_maxSuspensionTravelCm = m_kart_properties->getSuspensionTravelCM(); m_vehicle = new btKart(*m_tuning, m_body, m_vehicle_raycaster, m_kart_properties->getTrackConnectionAccel()); @@ -285,18 +285,28 @@ bool Kart::isInRest() const } // isInRest //----------------------------------------------------------------------------- -/** Modifies the physics parameter to simulate an attached anvil. - * The velocity is multiplicated by f, and the mass of the kart is increased. +/** Multiplies the velocity of the kart by a factor f (both linear + * and angular). This is used by anvils, which suddenly slow down the kart + * when they are attached. */ -void Kart::adjustSpeedWeight(float f) +void Kart::adjustSpeed(float f) { m_body->setLinearVelocity(m_body->getLinearVelocity()*f); + m_body->setAngularVelocity(m_body->getAngularVelocity()*f); +} // adjustSpeed + +//----------------------------------------------------------------------------- +/** This method is to be called every time the mass of the kart is updated, + * which includes attaching an anvil to the kart (and detaching). + */ +void Kart::updatedWeight() +{ // getMass returns the mass increased by the attachment btVector3 inertia; float m=getMass(); m_kart_chassis.calculateLocalInertia(m, inertia); m_body->setMassProps(m, inertia); -} // adjustSpeedWeight +} // updatedWeight //----------------------------------------------------------------------------- void Kart::reset() @@ -911,7 +921,7 @@ void Kart::processSkidMarks() { if(isOnGround()) { - //FIXME: no getCoord anymore m_skidmark_left ->add(*getCoord(), ANGLE, LENGTH); + //FIXME: no getCoord anymore m_skidmark_left ->add(*getCoord(), ANGLE, LENGTH); //FIXME m_skidmark_right->add(*getCoord(), ANGLE, LENGTH); } else diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 8a5297d95..748267630 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -158,7 +158,7 @@ public: float getMass () const { return m_kart_properties->getMass() - + m_attachment.WeightAdjust(); + + m_attachment.weightAdjust(); } float getMaxPower () const {return m_kart_properties->getMaxPower();} float getTimeFullSteer () const {return m_kart_properties->getTimeFullSteer();} @@ -209,7 +209,8 @@ public: void eliminate (); bool isRescue () const {return m_rescue;} void resetBrakes (); - void adjustSpeedWeight(float f); + void adjustSpeed (float f); + void updatedWeight (); void forceRescue (); void handleExplosion (const Vec3& pos, bool direct_hit); const std::string& getName () const {return m_kart_properties->getName();}