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_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
//-----------------------------------------------------------------------------

View File

@ -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);
};

View File

@ -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;

View File

@ -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

View File

@ -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();}