Applied Yann's patch to fix bug 2287611 (if a new attachment is

attached while an anvil or so is active, the additional weight
of the anvil will never go away).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2523 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-11-28 03:44:41 +00:00
parent c1fab8dc83
commit 2c0aaaaf21
5 changed files with 117 additions and 81 deletions

View File

@ -39,7 +39,7 @@ Attachment::Attachment(Kart* _kart)
m_previous_owner = NULL; m_previous_owner = NULL;
m_kart->getModelTransform()->addKid(m_holder); 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); ssgEntity *p=attachment_manager->getModel((attachmentType)i);
m_holder->addKid(p); m_holder->addKid(p);
@ -56,6 +56,7 @@ Attachment::~Attachment()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Attachment::set(attachmentType _type, float time, Kart *current_kart) void Attachment::set(attachmentType _type, float time, Kart *current_kart)
{ {
clear();
m_holder->selectStep(_type); m_holder->selectStep(_type);
m_type = _type; m_type = _type;
m_time_left = time; m_time_left = time;
@ -63,58 +64,82 @@ void Attachment::set(attachmentType _type, float time, Kart *current_kart)
} // set } // 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; if(user_config->m_profile) return;
float leftover_time = 0.0f; float leftover_time = 0.0f;
switch(getType()) // If there already is an attachment, make it worse :) switch(getType()) // If there already is an attachment, make it worse :)
{ {
case ATTACH_BOMB: projectile_manager->newExplosion(m_kart->getXYZ()); case ATTACH_BOMB:
m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true); projectile_manager->newExplosion(m_kart->getXYZ());
clear(); m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true);
if(random_attachment==-1) clear();
random_attachment = m_random.get(3); if(new_attachment==-1)
break; new_attachment = m_random.get(3);
case ATTACH_ANVIL :// if the kart already has an anvil, attach a new anvil, break;
// and increase the overall time case ATTACH_ANVIL:
random_attachment = 2; // if the kart already has an anvil, attach a new anvil,
leftover_time = m_time_left; // and increase the overall time
break; new_attachment = 2;
leftover_time = m_time_left;
break;
case ATTACH_PARACHUTE: case ATTACH_PARACHUTE:
random_attachment = 2; // anvil new_attachment = 2; // anvil
leftover_time = m_time_left; leftover_time = m_time_left;
break; break;
default: if(random_attachment==-1) default:
random_attachment = m_random.get(3); if(new_attachment==-1)
new_attachment = m_random.get(3);
} // switch } // switch
// Save the information about the attachment in the race state // Save the information about the attachment in the race state
// so that the clients can be updated. // so that the clients can be updated.
if(network_manager->getMode()==NetworkManager::NW_SERVER) if(network_manager->getMode()==NetworkManager::NW_SERVER)
{ {
race_state->itemCollected(m_kart->getWorldKartId(), race_state->itemCollected(m_kart->getWorldKartId(),
item.getItemId(), item.getItemId(),
random_attachment); 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(); m_initial_speed = m_kart->getSpeed();
// if ( m_kart == m_kart[0] ) // if ( m_kart == m_kart[0] )
// sound -> playSfx ( SOUND_SHOOMF ) ; // sound -> playSfx ( SOUND_SHOOMF ) ;
break ; 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] ) // if ( m_kart == m_kart[0] )
// sound -> playSfx ( SOUND_SHOOMF ) ; // sound -> playSfx ( SOUND_SHOOMF ) ;
break ; 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] ) // if ( m_kart == m_kart[0] )
// sound -> playSfx ( SOUND_SHOOMF ) ; // sound -> playSfx ( SOUND_SHOOMF ) ;
// Reduce speed once (see description above), all other changes are // Reduce speed once (see description above), all other changes are
// handled in Kart::updatePhysics // 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 ; break ;
} // switch } // switch
} // hitBanana } // hitBanana
@ -137,40 +162,35 @@ void Attachment::update(float dt)
switch (m_type) switch (m_type)
{ {
case ATTACH_PARACHUTE: // Partly handled in Kart::updatePhysics case ATTACH_PARACHUTE:
// Otherwise: disable if a certain percantage of // Partly handled in Kart::updatePhysics
// initial speed was lost // Otherwise: disable if a certain percantage of
if(m_kart->getSpeed()<= // initial speed was lost
m_initial_speed*stk_config->m_parachute_done_fraction) if(m_kart->getSpeed()<=
{ m_initial_speed*stk_config->m_parachute_done_fraction)
m_time_left = -1; {
} m_time_left = -1;
break; }
break;
case ATTACH_ANVIL: // handled in Kart::updatePhysics case ATTACH_ANVIL: // handled in Kart::updatePhysics
case ATTACH_NOTHING: // Nothing to do, but complete all cases for switch case ATTACH_NOTHING: // Nothing to do, but complete all cases for switch
case ATTACH_MAX: break; case ATTACH_MAX:
case ATTACH_BOMB: if(m_time_left<=0.0) break;
{ case ATTACH_BOMB:
projectile_manager->newExplosion(m_kart->getXYZ()); if(m_time_left<=0.0)
m_kart->handleExplosion(m_kart->getXYZ(), {
/*direct_hit*/ true); projectile_manager->newExplosion(m_kart->getXYZ());
} m_kart->handleExplosion(m_kart->getXYZ(),
break; /*direct_hit*/ true);
case ATTACH_TINYTUX: if(m_time_left<=0.0) m_kart->endRescue(); }
break; break;
case ATTACH_TINYTUX:
if(m_time_left<=0.0) m_kart->endRescue();
break;
} // switch } // switch
// Detach attachment if its time is up. // Detach attachment if its time is up.
if ( m_time_left <= 0.0f) 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(); clear();
} // if m_time_left<0
} // update } // update
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -26,13 +26,19 @@
class Kart; class Kart;
class Item; class Item;
// Some loop in Attachment.cpp depend on PARACHUTE being the first element, // Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX.
// and TINYTUX being the last one. So if new elemts are added, make sure // So if new elements are added, make sure to add them in between those values.
// to add them in between those values. // Also, please note that Attachment::Attachment relies on ATTACH_FIRST being 0.
enum attachmentType { ATTACH_PARACHUTE, enum attachmentType
ATTACH_BOMB, {
ATTACH_ANVIL, ATTACH_TINYTUX, ATTACH_FIRST = 0,
ATTACH_MAX, ATTACH_NOTHING}; ATTACH_PARACHUTE = 0,
ATTACH_BOMB,
ATTACH_ANVIL,
ATTACH_TINYTUX,
ATTACH_MAX,
ATTACH_NOTHING
};
class Attachment class Attachment
@ -52,36 +58,34 @@ public:
void set (attachmentType _type, float time, Kart *previous_kart=NULL); void set (attachmentType _type, float time, Kart *previous_kart=NULL);
void set (attachmentType _type) { set(_type, m_time_left); } void set (attachmentType _type) { set(_type, m_time_left); }
void clear () { void clear ();
m_type=ATTACH_NOTHING;
m_time_left=0.0;
m_holder->select(0);
}
attachmentType getType () const { return m_type; } attachmentType getType () const { return m_type; }
float getTimeLeft () const { return m_time_left; } float getTimeLeft () const { return m_time_left; }
void setTimeLeft (float t){ m_time_left = t; } void setTimeLeft (float t){ m_time_left = t; }
Kart* getPreviousOwner () const { return m_previous_owner; } Kart* getPreviousOwner () const { return m_previous_owner; }
float WeightAdjust () const {
float weightAdjust () const {
return m_type==ATTACH_ANVIL return m_type==ATTACH_ANVIL
?stk_config->m_anvil_weight:0.0f; ?stk_config->m_anvil_weight:0.0f;
} }
float AirResistanceAdjust () const { float airResistanceAdjust () const {
return m_type==ATTACH_PARACHUTE return m_type==ATTACH_PARACHUTE
?stk_config->m_parachute_friction:0.0f; ?stk_config->m_parachute_friction:0.0f;
} }
float SpeedAdjust () const { float speedAdjust () const {
return m_type==ATTACH_ANVIL return m_type==ATTACH_ANVIL
?stk_config->m_anvil_speed_factor:1.0f; ?stk_config->m_anvil_speed_factor:1.0f;
} }
/** Randomly selects the new attachment. For a server process, the /** Randomly selects the new attachment. For a server process, the
* attachment can be passed into this function. * attachment can be passed into this function.
\param item The item that was collected. \param item The item that was collected.
\param random_attachment Optional: only used on the clients, it \param new_attachment Optional: only used on the clients, it
specifies the new attachment to use 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 update (float dt);
void moveBombFromTo(Kart *from, Kart *to); void moveBombFromTo(Kart *from, Kart *to);
}; };

View File

@ -126,7 +126,8 @@ void Powerup::use()
if(kart->getPosition() == 1) if(kart->getPosition() == 1)
{ {
kart->attach(ATTACH_ANVIL, stk_config->m_anvil_time); 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->position(m_owner->getXYZ());
m_sound_use_anvil->play(); m_sound_use_anvil->play();
break; break;

View File

@ -181,7 +181,7 @@ void Kart::createPhysics()
m_vehicle_raycaster = m_vehicle_raycaster =
new btDefaultVehicleRaycaster(RaceManager::getWorld()->getPhysics()->getPhysicsWorld()); new btDefaultVehicleRaycaster(RaceManager::getWorld()->getPhysics()->getPhysicsWorld());
m_tuning = new btKart::btVehicleTuning(); 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_vehicle = new btKart(*m_tuning, m_body, m_vehicle_raycaster,
m_kart_properties->getTrackConnectionAccel()); m_kart_properties->getTrackConnectionAccel());
@ -285,18 +285,28 @@ bool Kart::isInRest() const
} // isInRest } // isInRest
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Modifies the physics parameter to simulate an attached anvil. /** Multiplies the velocity of the kart by a factor f (both linear
* The velocity is multiplicated by f, and the mass of the kart is increased. * 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->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 // getMass returns the mass increased by the attachment
btVector3 inertia; btVector3 inertia;
float m=getMass(); float m=getMass();
m_kart_chassis.calculateLocalInertia(m, inertia); m_kart_chassis.calculateLocalInertia(m, inertia);
m_body->setMassProps(m, inertia); m_body->setMassProps(m, inertia);
} // adjustSpeedWeight } // updatedWeight
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Kart::reset() void Kart::reset()
@ -911,7 +921,7 @@ void Kart::processSkidMarks()
{ {
if(isOnGround()) 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); //FIXME m_skidmark_right->add(*getCoord(), ANGLE, LENGTH);
} }
else else

View File

@ -158,7 +158,7 @@ public:
float getMass () const float getMass () const
{ {
return m_kart_properties->getMass() return m_kart_properties->getMass()
+ m_attachment.WeightAdjust(); + m_attachment.weightAdjust();
} }
float getMaxPower () const {return m_kart_properties->getMaxPower();} float getMaxPower () const {return m_kart_properties->getMaxPower();}
float getTimeFullSteer () const {return m_kart_properties->getTimeFullSteer();} float getTimeFullSteer () const {return m_kart_properties->getTimeFullSteer();}
@ -209,7 +209,8 @@ public:
void eliminate (); void eliminate ();
bool isRescue () const {return m_rescue;} bool isRescue () const {return m_rescue;}
void resetBrakes (); void resetBrakes ();
void adjustSpeedWeight(float f); void adjustSpeed (float f);
void updatedWeight ();
void forceRescue (); void forceRescue ();
void handleExplosion (const Vec3& pos, bool direct_hit); void handleExplosion (const Vec3& pos, bool direct_hit);
const std::string& getName () const {return m_kart_properties->getName();} const std::string& getName () const {return m_kart_properties->getName();}