Improved/fixed terrain specific slowdown. Slowdowns are not specified in materials.xml

with two values: one specifying the percentage of max kart speed that can be reached
(e.g. 0.5 means a kart can only drive 50% of its maximum speed on this terrain),
the 'slowdown' value specifying how long it will take for a kart to be slowed down
to that value (e.g. a value of 3 for slowdown and 0.5 for max-speed means that
it will take 3 seconds of continuously driving on that terrain till the speed
is reduced to 50% of the karts maximum value).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6290 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2010-10-16 13:07:25 +00:00
parent 9451a488a1
commit b0ed33197b
5 changed files with 160 additions and 160 deletions

View File

@@ -62,7 +62,7 @@ Material::Material(const XMLNode *node, int index)
node->get("zipper", &m_zipper );
node->get("reset", &m_resetter );
node->get("max-speed", &m_max_speed_fraction);
node->get("slowdown", &m_slowdown );
node->get("slowdown", &m_slowdown_severity );
node->get("anisotropic", &m_anisotropic );
node->get("backface-culling", &m_backface_culling );
std::string s("");
@@ -132,7 +132,7 @@ void Material::init(unsigned int index)
m_zipper = false;
m_resetter = false;
m_max_speed_fraction = 1.0f;
m_slowdown = 1.0f;
m_slowdown_severity = 1.0f;
m_sfx_name = "";
m_sfx_min_speed = 0.0f;
m_sfx_max_speed = 30;

View File

@@ -66,7 +66,7 @@ private:
bool m_lightmap;
float m_friction;
/** How much the top speed is reduced per second. */
float m_slowdown;
float m_slowdown_severity;
/** Maximum speed at which no more slow down occurs. */
float m_max_speed_fraction;
/** The minimum speed at which a special sfx is started to be played. */
@@ -103,15 +103,21 @@ public:
const std::string&
getTexFname () const { return m_texname; }
int getIndex () const { return m_index; }
// ------------------------------------------------------------------------
/** Returns the fraction of maximum speed on this material. */
float getMaxSpeedFraction() const { return m_max_speed_fraction; }
/** Returns the slowdown that happens if a kart is
* faster than the maximum speed. */
float getSlowDown () const { return m_slowdown; }
// ------------------------------------------------------------------------
/** Returns how long it will take for a slowdown to take effect.
* It is the time it takes till the full slowdown applies to
* karts. So a short time will slowdown a kart much faster. */
float getSlowDownSeverity() const { return m_slowdown_severity; }
// ------------------------------------------------------------------------
/** Returns true if this material should have smoke effect. */
bool hasSmoke () const { return m_graphical_effect==GE_SMOKE;}
// ------------------------------------------------------------------------
/** Returns true if this material should have water splashes. */
bool hasWaterSplash () const { return m_graphical_effect==GE_WATER;}
// ------------------------------------------------------------------------
/** Returns the name of a special sfx to play while a kart is on this
* terrain. The string will be "" if no special sfx exists. */
const std::string &

View File

@@ -103,12 +103,8 @@ Kart::Kart (const std::string& ident, int position,
// m_custom_sounds.resize(SFXManager::NUM_CUSTOMS);
// Set position and heading:
m_reset_transform = init_transform;
m_max_speed = m_kart_properties->getMaxSpeed();
m_max_speed_reverse_ratio = m_kart_properties->getMaxSpeedReverseRatio();
m_reset_transform = init_transform;
m_speed = 0.0f;
m_wheel_rotation = 0;
// Create SFXBase for each custom sound (TODO: add back when properly done)
@@ -202,7 +198,7 @@ void Kart::createPhysics()
shiftCenterOfGravity.setIdentity();
// Shift center of gravity downwards, so that the kart
// won't topple over too easy.
shiftCenterOfGravity.setOrigin(getGravityCenterShift());
shiftCenterOfGravity.setOrigin(m_kart_properties->getGravityCenterShift());
m_kart_chassis.addChildShape(shiftCenterOfGravity, shape);
// Set mass and inertia
@@ -399,8 +395,7 @@ void Kart::reset()
m_bounce_back_time = 0.0f;
m_skidding = 1.0f;
m_time_last_crash = 0.0f;
m_max_speed_reduction = 0.0f;
m_power_reduction = 1.0f;
m_current_speed_fraction = 1.0f;
m_slipstream_mode = SS_NONE;
m_last_material = NULL;
if(m_terrain_sound)
@@ -583,7 +578,7 @@ float Kart::getActualWheelForce()
const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio();
for(unsigned int i=0; i<gear_ratio.size(); i++)
{
if(m_speed <= getMaxSpeed()*gear_ratio[i])
if(m_speed <= m_kart_properties->getMaxSpeed()*gear_ratio[i])
{
return getMaxPower()*m_kart_properties->getGearPowerIncrease()[i]
+zipperF;
@@ -739,7 +734,6 @@ void Kart::update(float dt)
m_body->getBroadphaseHandle()->m_collisionFilterGroup = old_group;
}
const Material* material=TerrainInfo::getMaterial();
m_power_reduction = 1.0f;
if (getHoT()==Track::NOHIT) // kart falling off the track
{
// let kart fall a bit before rescuing
@@ -748,6 +742,14 @@ void Kart::update(float dt)
if(min->getY() - getXYZ().getY() > 17)
forceRescue();
}
// Sometimes the material can be 0. This can happen if a kart is above
// another kart (e.g. mass collision, or one kart falling on another
// kart). Bullet does not have any triangle information in this case,
// and so material can not be set. In this case it is simply ignored
// since it can't hurt (material is only used for friction, zipper and
// rescue, so those things are not triggered till the kart is on the
// track again)
else if(material)
{
// If a terrain specific sfx is already being played, when a new
@@ -796,26 +798,19 @@ void Kart::update(float dt)
}
m_last_material = material;
// Sometimes the material can be 0. This can happen if a kart is above
// another kart (e.g. mass collision, or one kart falling on another
// kart). Bullet does not have any triangle information in this case,
// and so material can not be set. In this case it is simply ignored
// since it can't hurt (material is only used for friction, zipper and
// rescue, so those things are not triggered till the kart is on the
// track again)
if (material->isReset() && isOnGround()) forceRescue();
else if(material->isZipper() && isOnGround()) handleZipper();
else
{
m_power_reduction = material->getSlowDown();
// Normal driving on terrain. Adjust for maximum terrain speed
float max_speed_here = material->getMaxSpeedFraction()*getMaxSpeed();
// If the speed is too fast, reduce the maximum speed gradually.
// Gradually adjust the fraction of the maximum kart speed to
// the amount specified for the terrain.
// The actual capping happens in updatePhysics
if(max_speed_here<m_speed)
m_max_speed_reduction += dt*material->getSlowDown();
if(m_current_speed_fraction<=material->getMaxSpeedFraction())
m_current_speed_fraction = material->getMaxSpeedFraction();
else
m_max_speed_reduction = 0.0f;
m_current_speed_fraction -=
dt/material->getSlowDownSeverity();
}
} // if there is material
@@ -1128,7 +1123,9 @@ bool Kart::playCustomSFX(unsigned int type)
*/
void Kart::updatePhysics(float dt)
{
// Check if accel is pressed for the first time.
// Check if accel is pressed for the first time. The actual timing
// is done in getStartupBoost - it returns 0 if the start was actually
// too slow to qualify for a boost.
if(!m_has_started && m_controls.m_accel)
{
m_has_started = true;
@@ -1153,24 +1150,12 @@ void Kart::updatePhysics(float dt)
else if(m_speed < 0.0f)
engine_power *= 5.0f;
// FIXME: horrible hack. A small acceleration value will cause the engine power to
// be reduced (for the end controller)
if (fabsf(m_controls.m_accel) < 1.0f)
{
engine_power *= fabsf(m_controls.m_accel);
}
// Engine slow down due to terrain (see m_power_reduction is set in
// update() depending on terrain type. Don't apply this if kart is already
// going slowly, this would make it hard accelerating to get out of there
if(m_speed > 4.0)
engine_power *= m_power_reduction;
// Lose some traction when skidding, to balance the adventage
// Up to r5483 AIs were allowed to cheat in medium and high diff levels
if(m_controls.m_drift)
engine_power *= 0.5f;
applyEngineForce(engine_power);
applyEngineForce(engine_power*m_controls.m_accel);
// Either all or no brake is set, so test only one to avoid
// resetting all brakes most of the time.
@@ -1196,21 +1181,13 @@ void Kart::updatePhysics(float dt)
{
resetBrakes();
// going backward, apply reverse gear ratio (unless he goes too fast backwards)
if ( -m_speed < getMaxSpeedOnTerrain()*m_max_speed_reverse_ratio )
if ( -m_speed < getMaxSpeedOnTerrain()
*m_kart_properties->getMaxSpeedReverseRatio() )
{
// The backwards acceleration is artificially increased to
// allow players to get "unstuck" quicker if they hit e.g.
// a wall. At the same time we have to prevent that driving
// backards gives an advantage (see m_max_speed_reverse_ratio),
// and that a potential slowdown due to the terrain the
// kart is driving on feels right. The speedup factor on
// normal terrain (power_reduction/slowdown_factor should
// be 2.5 (which was experimentally determined to feel
// right).
float f = 2.5f - 3.8f*(1-m_power_reduction);
// Avoid that a kart gets really stuck:
if(f<0.1f) f=0.1f;
applyEngineForce(-engine_power*f);
// a wall.
applyEngineForce(-engine_power*2.5f);
}
else // -m_speed >= max speed on this terrain
{
@@ -1464,7 +1441,7 @@ void Kart::updateGraphics(const Vec3& offset_xyz,
}
m_kart_model->update(m_wheel_rotation, getSteerPercent(), wheel_up_axis);
Vec3 center_shift = getGravityCenterShift();
Vec3 center_shift = m_kart_properties->getGravityCenterShift();
float y = m_vehicle->getWheelInfo(0).m_chassisConnectionPointCS.getY()
- m_default_suspension_length[0]
- m_vehicle->getWheelInfo(0).m_wheelsRadius
@@ -1499,7 +1476,7 @@ void Kart::updateGraphics(const Vec3& offset_xyz,
if(m_slipstream_mode == SS_USE)
m_nitro->setCreationRate(20.0f);
float speed_ratio = getSpeed()/getMaxSpeed();
float speed_ratio = getSpeed()/getMaxSpeedOnTerrain();
float offset_heading = getSteerPercent()*m_kart_properties->getSkidVisual()
* speed_ratio * m_skidding*m_skidding;
Moveable::updateGraphics(center_shift,

View File

@@ -98,18 +98,15 @@ protected: // Used by the AI atm
/** Easier access for player_kart. */
Camera *m_camera;
private:
/** Maximum speed of the kart. */
float m_max_speed;
/** Depending on terrain a certain reduction to the maximum speed applies.
* This reduction is accumulated in m_max_speed_reduction. */
float m_max_speed_reduction;
* This reduction is accumulated in m_current_speed_fraction, which will
* always be between the fraction for the terrain and 1.0. */
float m_current_speed_fraction;
/** True if the kart hasn't moved since 'ready-set-go' - used to
* determine startup boost. */
bool m_has_started;
float m_power_reduction;
float m_max_gear_rpm; /**<Maximum engine rpm's for the current gear*/
float m_max_speed_reverse_ratio;
float m_bounce_back_time; /**<A short time after a collision acceleration
* is disabled to allow the karts to bounce back*/
@@ -221,31 +218,46 @@ public:
void loadData();
virtual void updateGraphics(const Vec3& off_xyz,
const btQuaternion& off_rotation);
void createPhysics ();
bool isInRest () const;
void setSuspensionLength();
void applyEngineForce (float force);
float handleNitro (float dt);
float getActualWheelForce();
bool isSlipstreamReady() const;
void resetBrakes ();
void startEngineSFX ();
void adjustSpeed (float f);
void updatedWeight ();
virtual void collectedItem (Item *item, int random_attachment);
virtual void reset ();
virtual void handleZipper ();
virtual void crashed (Kart *k);
virtual void update (float dt);
virtual void finishedRace (float time);
void beep ();
bool playCustomSFX (unsigned int type);
void setController(Controller *controller);
// ------------------------------------------------------------------------
/** Returns this kart's kart model. */
KartModel* getKartModel() { return m_kart_model; }
// ------------------------------------------------------------------------
const KartProperties*
/** Returns the kart properties of this kart. */
const KartProperties*
getKartProperties() const { return m_kart_properties; }
// ------------------------------------------------------------------------
/** Sets the kart properties. */
void setKartProperties(const KartProperties *kp)
{
m_kart_properties=kp;
}
void setKartProperties(const KartProperties *kp) { m_kart_properties=kp; }
// ------------------------------------------------------------------------
/** Sets the attachment and time it stays attached. */
void attach(attachmentType attachment_, float time)
{
m_attachment->set(attachment_, time);
}
void attach(attachmentType attachment_, float time)
{ m_attachment->set(attachment_, time); }
// ------------------------------------------------------------------------
/** Sets a new powerup. */
void setPowerup (PowerupManager::PowerupType t, int n)
{
m_powerup.set(t, n);
} // setPowerup
{ m_powerup.set(t, n); }
// ------------------------------------------------------------------------
/** Sets the position in race this kart has (1<=p<=n). */
virtual void setPosition(int p)
@@ -253,7 +265,6 @@ public:
m_race_position = p;
m_controller->setPosition(p);
} // setPosition
// ------------------------------------------------------------------------
/** Returns the current attachment. */
const Attachment* getAttachment() const {return m_attachment; }
@@ -271,7 +282,6 @@ public:
// ------------------------------------------------------------------------
/** Sets the camera for this kart. */
void setCamera(Camera *camera) {m_camera=camera; }
// ------------------------------------------------------------------------
/** Returns the current powerup. */
const Powerup *getPowerup () const { return &m_powerup; }
@@ -305,101 +315,108 @@ public:
{ return m_view_blocked_by_plunger > 0; }
// ------------------------------------------------------------------------
/** Sets that the view is blocked by a plunger. */
void blockViewWithPlunger() { m_view_blocked_by_plunger = 10;}
/** Returns a bullet transform object located at the kart's position
and oriented in the direction the kart is going. Can be useful
e.g. to calculate the starting point and direction of projectiles
*/
btTransform getKartHeading (const float customPitch=-1);
// Functions to access the current kart properties (which might get changed,
// e.g. mass increase or air_friction increase depending on attachment etc.)
void blockViewWithPlunger() { m_view_blocked_by_plunger = 10;}
// -------------------------------------------------------------------------
const video::SColor &getColor () const {return m_kart_properties->getColor();}
float getMass () const
{
return m_kart_properties->getMass()
+ m_attachment->weightAdjust();
}
float getMaxPower () const {return m_kart_properties->getMaxPower();}
float getTimeFullSteer () const {return m_kart_properties->getTimeFullSteer();}
float getBrakeFactor () const {return m_kart_properties->getBrakeFactor();}
float getFrictionSlip () const {return m_kart_properties->getFrictionSlip();}
float getSkidding () const {return m_skidding;}
float getMaxSteerAngle () const
{return m_kart_properties->getMaxSteerAngle(getSpeed());}
const Vec3& getGravityCenterShift () const
{return m_kart_properties->getGravityCenterShift(); }
float getSteerPercent () const {return m_controls.m_steer; }
KartControl&
getControls () {return m_controls; }
const KartControl&
getControls () const {return m_controls; }
/** Returns a bullet transform object located at the kart's position
and oriented in the direction the kart is going. Can be useful
e.g. to calculate the starting point and direction of projectiles. */
btTransform getKartHeading (const float customPitch=-1);
// -------------------------------------------------------------------------
/** Returns the color used for this kart. */
const video::SColor &getColor() const
{return m_kart_properties->getColor();}
// ------------------------------------------------------------------------
/** Returns the current mass of this kart, including any attachment this
* kart might have. */
float getMass() const { return m_kart_properties->getMass()
+ m_attachment->weightAdjust();}
// ------------------------------------------------------------------------
/** Returns the maximum engine power for this kart. */
float getMaxPower () const {return m_kart_properties->getMaxPower(); }
// ------------------------------------------------------------------------
/** Returns the strenght of the brakes for this kart. */
float getBrakeFactor() const {return m_kart_properties->getBrakeFactor();}
// ------------------------------------------------------------------------
/** Returns the time till full steering is reached for this kart. */
float getTimeFullSteer() const
{ return m_kart_properties->getTimeFullSteer(); }
// ------------------------------------------------------------------------
/** Returns the maximum steering angle for this kart, which depends on the
* speed. */
float getMaxSteerAngle () const
{ return m_kart_properties->getMaxSteerAngle(getSpeed()); }
// ------------------------------------------------------------------------
/** Returns the amount of skidding for this kart. */
float getSkidding() const { return m_skidding; }
// ------------------------------------------------------------------------
/** Returns the current steering value for this kart. */
float getSteerPercent() const { return m_controls.m_steer; }
// ------------------------------------------------------------------------
/** Returns all controls of this kart. */
KartControl& getControls() { return m_controls; }
// ------------------------------------------------------------------------
/** Returns all controls of this kart - const version. */
const KartControl& getControls() const { return m_controls; }
// ------------------------------------------------------------------------
/** Sets the kart controls. Used e.g. by replaying history. */
void setControls(const KartControl &c) { m_controls = c; }
/** Returns the maximum speed of the kart independent of the
* terrain it is on. */
float getMaxSpeed () const {return m_max_speed; }
/** Returns the maximum speed of the kart but includes the effect of
void setControls(const KartControl &c) { m_controls = c; }
// ------------------------------------------------------------------------
/** Returns the maximum speed of the kart including the effect of
* the terrain it is on. */
float getMaxSpeedOnTerrain() const {return m_max_speed-
m_max_speed_reduction; }
float getMaxSpeedOnTerrain() const
{return m_kart_properties->getMaxSpeed()
*m_current_speed_fraction; }
// ------------------------------------------------------------------------
/** Returns the length of the kart. */
float getKartLength () const {return m_kart_model->getLength(); }
float getKartLength () const {return m_kart_model->getLength();}
// ------------------------------------------------------------------------
/** Returns the height of the kart. */
float getKartHeight () const {return m_kart_model->getHeight(); }
float getKartHeight () const {return m_kart_model->getHeight();}
// ------------------------------------------------------------------------
/** Returns the width of the kart. */
float getKartWidth () const {return m_kart_model->getWidth(); }
float getKartWidth () const {return m_kart_model->getWidth(); }
// ------------------------------------------------------------------------
/** Returns the bullet vehicle which represents this kart. */
btKart *getVehicle () const {return m_vehicle; }
btUprightConstraint *getUprightConstraint() const {return m_uprightConstraint;}
void createPhysics ();
bool isInRest () const;
//have to use this instead of moveable getVelocity to get velocity for bullet rigid body
btKart *getVehicle () const {return m_vehicle; }
// ------------------------------------------------------------------------
/** Returns the upright constraint for this kart. */
btUprightConstraint *getUprightConstraint() const
{return m_uprightConstraint;}
// ------------------------------------------------------------------------
/** Returns the speed of the kart. */
float getSpeed () const {return m_speed; }
// ------------------------------------------------------------------------
/** This is used on the client side only to set the speed of the kart
* from the server information. */
void setSpeed (float s) {m_speed = s; }
void setSuspensionLength();
void applyEngineForce (float force);
float handleNitro (float dt);
float getActualWheelForce();
// ------------------------------------------------------------------------
/** Returns which kart is giving slip stream to this kart. */
const Kart* getSlipstreamKart() const {return m_slipstream_target;};
// ------------------------------------------------------------------------
/** Returns a name to be displayed for this kart. */
virtual const irr::core::stringw& getName() const
{ return m_kart_properties->getName(); }
// ------------------------------------------------------------------------
/** Returns a unique identifier for this kart (name of the directory the
* kart was loaded from). */
const std::string& getIdent() const {return m_kart_properties->getIdent();}
// ------------------------------------------------------------------------
/** Returns the start transform, i.e. position and rotation. */
const btTransform getResetTransform() const {return m_reset_transform;}
// ------------------------------------------------------------------------
/** Returns the controller of this kart. */
Controller* getController() { return m_controller; }
// ------------------------------------------------------------------------
/** Returns the controller of this kart (const version). */
const Controller* getController() const { return m_controller; }
// ------------------------------------------------------------------------
/** True if the wheels are touching the ground. */
bool isOnGround () const;
// ------------------------------------------------------------------------
/** Returns true if the kart is close to the ground, used to dis/enable
* the upright constraint to allow for more realistic explosions. */
bool isNearGround () const;
bool isSlipstreamReady() const;
/** Returns which kart is giving slip stream to this kart. */
const Kart* getSlipstreamKart() const {return m_slipstream_target;};
void resetBrakes ();
void startEngineSFX ();
void adjustSpeed (float f);
void updatedWeight ();
/** Returns a name to be displayed for this kart. */
virtual const irr::core::stringw& getName() const {return m_kart_properties->getName();}
const std::string& getIdent () const {return m_kart_properties->getIdent();}
// addMessages gets called by world to add messages to the gui
virtual void addMessages () {};
virtual void collectedItem (Item *item, int random_attachment);
virtual void reset ();
virtual void handleZipper ();
virtual void crashed (Kart *k);
virtual void update (float dt);
virtual void finishedRace (float time);
void beep ();
bool playCustomSFX (unsigned int type);
/** Returns the start transform, i.e. position and rotation. */
const btTransform getResetTransform() const {return m_reset_transform;}
/** Returns the controller of this kart. */
Controller* getController() { return m_controller; }
/** Returns the controller of this kart (const version). */
const Controller* getController() const { return m_controller; }
void setController(Controller *controller);
// ------------------------------------------------------------------------
};

View File

@@ -231,9 +231,9 @@ void Physics::KartKartCollision(Kart *kartA, Kart *kartB)
// Now compute the vector to the side (right or left depending
// on where the kart was hit).
Vec3 side((orientation>=0) ? -1.0f : 1.0f, 0, 0);
float speed_frac = faster_kart->getSpeed()/faster_kart->getMaxSpeed();
float speed_frac = faster_kart->getSpeed()/faster_kart->getMaxSpeedOnTerrain();
Vec3 impulse =
faster_kart->getTrans().getBasis()*side*side_impulse*speed_frac;
faster_kart->getTrans().getBasis()*side*side_impulse*speed_frac;
printf("orientation is %f impulse is %f %f %f\n",
orientation, impulse.getX(),impulse.getY(),impulse.getZ());
slower_kart->getBody()->applyCentralImpulse(impulse);