Added new object to handle max-speed of karts. ATM it will slow down
depending on terrain, so zipper etc. handling is not yet finished but will come soon. Also zipper parameters can now be specified per kart. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6325 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -71,12 +71,6 @@
|
||||
to timer when bomb is passed on. -->
|
||||
<bomb time="30.0" time-increase="-5.0"/>
|
||||
|
||||
<!-- time is the time a zipper is active. force is the additional
|
||||
zipper force. speed-gain is the one time additional speed.
|
||||
max-speed-fraction is a factor multiplied to the maximum
|
||||
speed on the terrain. -->
|
||||
<zipper time="3.5" force="250.0" speed-gain="4.5" max-speed-fraction="2.0"/>
|
||||
|
||||
<!-- Powerup collect-mode decides what is collected if a kart has already an
|
||||
powerup: same: get one more item of the same type.
|
||||
new: always get a new item.
|
||||
@@ -150,6 +144,14 @@
|
||||
big-container: how much energy a big container gives. -->
|
||||
<nitro power-boost="3" consumption="1" small-container="1" big-container="3"/>
|
||||
|
||||
<!-- time is the time a zipper is active. force is the additional
|
||||
zipper force. speed-gain is the one time additional speed.
|
||||
max-speed-increase is the additional speed allowed on top
|
||||
of the kart-specific maximum kart speed. Fade-out time determines
|
||||
how long it takes for a zipper to fade out (after 'time'). -->
|
||||
<zipper time="3.5" force="250.0" speed-gain="4.5" max-speed-increase="15"
|
||||
fade-out-time="1.0" />
|
||||
|
||||
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
|
||||
decrease: multiplicative decrease of skidding factor in each frame.
|
||||
max: maximum skidding factor = maximum increase of steering angle.
|
||||
|
||||
@@ -105,10 +105,6 @@ void STKConfig::load(const std::string &filename)
|
||||
CHECK_NEG(m_bomb_time_increase, "bomb-time-increase" );
|
||||
CHECK_NEG(m_anvil_time, "anvil-time" );
|
||||
CHECK_NEG(m_anvil_weight, "anvil-weight" );
|
||||
CHECK_NEG(m_zipper_time, "zipper-time" );
|
||||
CHECK_NEG(m_zipper_force, "zipper-force" );
|
||||
CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" );
|
||||
CHECK_NEG(m_zipper_max_speed_fraction, "zipper-max-speed-fraction" );
|
||||
CHECK_NEG(m_item_switch_time, "item-switch-time" );
|
||||
CHECK_NEG(m_bubble_gum_counter, "bubblegum disappear counter");
|
||||
CHECK_NEG(m_explosion_impulse, "explosion-impulse" );
|
||||
@@ -140,9 +136,7 @@ void STKConfig::init_defaults()
|
||||
m_parachute_time = m_parachute_done_fraction =
|
||||
m_parachute_time_other = m_anvil_speed_factor =
|
||||
m_bomb_time = m_bomb_time_increase =
|
||||
m_anvil_time = m_zipper_time =
|
||||
m_zipper_force = m_zipper_speed_gain =
|
||||
m_zipper_max_speed_fraction = m_music_credit_time =
|
||||
m_anvil_time = m_music_credit_time =
|
||||
m_explosion_impulse = m_explosion_impulse_objects =
|
||||
m_delay_finish_time = m_skid_fadeout_time =
|
||||
m_near_ground = m_item_switch_time =
|
||||
@@ -283,14 +277,6 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
bomb_node->get("time-increase", &m_bomb_time_increase);
|
||||
}
|
||||
|
||||
if(const XMLNode *zipper_node= root->getNode("zipper"))
|
||||
{
|
||||
zipper_node->get("time", &m_zipper_time );
|
||||
zipper_node->get("force", &m_zipper_force );
|
||||
zipper_node->get("speed-gain", &m_zipper_speed_gain );
|
||||
zipper_node->get("max-speed-fraction", &m_zipper_max_speed_fraction);
|
||||
}
|
||||
|
||||
if(const XMLNode *powerup_node= root->getNode("powerup"))
|
||||
{
|
||||
std::string s;
|
||||
|
||||
@@ -66,12 +66,6 @@ public:
|
||||
float m_bomb_time_increase; /**<Time added to bomb timer when it's
|
||||
passed on. */
|
||||
float m_anvil_time; /**<Time an anvil is active. */
|
||||
float m_zipper_time; /**<Duration a zipper is active. */
|
||||
float m_zipper_force; /**<Additional force added to the
|
||||
acceleration. */
|
||||
float m_zipper_speed_gain; /**<Initial one time speed gain. */
|
||||
float m_zipper_max_speed_fraction;/**<Fraction of max speed allowed past
|
||||
regular max speed */
|
||||
float m_item_switch_time; /**< Time items will be switched. */
|
||||
int m_bubble_gum_counter; /**< How many times bananas must be eaten
|
||||
before they disappear. */
|
||||
|
||||
@@ -618,6 +618,10 @@
|
||||
RelativePath="..\..\karts\kart_properties_manager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\karts\max_speed.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\karts\moveable.cpp"
|
||||
>
|
||||
@@ -1532,6 +1536,10 @@
|
||||
RelativePath="..\..\karts\kart_properties_manager.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\karts\max_speed.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\karts\moveable.hpp"
|
||||
>
|
||||
|
||||
@@ -93,7 +93,7 @@ DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart)
|
||||
case RaceManager::RD_EASY:
|
||||
m_wait_for_players = true;
|
||||
m_make_use_of_slipstream = false;
|
||||
m_max_handicap_accel = 0.9f;
|
||||
m_max_handicap_speed = 0.9f;
|
||||
m_item_tactic = IT_TEN_SECONDS;
|
||||
m_false_start_probability = 0.08f;
|
||||
m_min_start_delay = 0.3f;
|
||||
@@ -106,7 +106,7 @@ DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart)
|
||||
case RaceManager::RD_MEDIUM:
|
||||
m_wait_for_players = true;
|
||||
m_make_use_of_slipstream = false;
|
||||
m_max_handicap_accel = 0.95f;
|
||||
m_max_handicap_speed = 0.95f;
|
||||
m_item_tactic = IT_CALCULATE;
|
||||
m_false_start_probability = 0.04f;
|
||||
m_min_start_delay = 0.25f;
|
||||
@@ -119,7 +119,7 @@ DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart)
|
||||
case RaceManager::RD_HARD:
|
||||
m_wait_for_players = false;
|
||||
m_make_use_of_slipstream = true;
|
||||
m_max_handicap_accel = 1.0f;
|
||||
m_max_handicap_speed = 1.0f;
|
||||
m_item_tactic = IT_CALCULATE;
|
||||
m_false_start_probability = 0.01f;
|
||||
// See http://www.humanbenchmark.com/tests/reactiontime/stats.php
|
||||
@@ -298,7 +298,8 @@ void DefaultAIController::update(float dt)
|
||||
// use the zipper instead
|
||||
if(m_controls->m_nitro &&
|
||||
m_kart->getPowerup()->getType()==PowerupManager::POWERUP_ZIPPER &&
|
||||
m_kart->getSpeed()>1.0f && m_kart->getZipperTimeLeft()<=0)
|
||||
m_kart->getSpeed()>1.0f &&
|
||||
m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0)
|
||||
{
|
||||
// Make sure that not all AI karts use the zipper at the same
|
||||
// time in time trial at start up, so during the first 5 seconds
|
||||
@@ -691,6 +692,11 @@ void DefaultAIController::handleAcceleration( const float dt)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: this needs to be rewritten, it doesn't make any sense:
|
||||
// wait for players triggers the opposite (if a player is ahead
|
||||
// of this AI, go full speed). Besides, it's going to use full
|
||||
// speed anyway.
|
||||
if( m_wait_for_players )
|
||||
{
|
||||
//Find if any player is ahead of this kart
|
||||
@@ -704,7 +710,7 @@ void DefaultAIController::handleAcceleration( const float dt)
|
||||
|
||||
if( player_winning )
|
||||
{
|
||||
m_controls->m_accel = m_max_handicap_accel;
|
||||
m_controls->m_accel = m_max_handicap_speed;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,9 +78,8 @@ private:
|
||||
* position than all the human players. */
|
||||
bool m_wait_for_players;
|
||||
|
||||
/** The allowed maximum speed, in percentage, from 0.0 to 1.0. Used only
|
||||
* when m_wait_for_players == true. */
|
||||
float m_max_handicap_accel;
|
||||
/** The allowed maximum speed in percent of the kart's maximum speed. */
|
||||
float m_max_handicap_speed;
|
||||
|
||||
/** How are items going to be used? */
|
||||
ItemTactic m_item_tactic;
|
||||
|
||||
@@ -245,7 +245,8 @@ void NewAIController::update(float dt)
|
||||
// use the zipper instead
|
||||
if(m_controls->m_nitro &&
|
||||
m_kart->getPowerup()->getType()==PowerupManager::POWERUP_ZIPPER &&
|
||||
m_kart->getSpeed()>1.0f && m_kart->getZipperTimeLeft()<=0)
|
||||
m_kart->getSpeed()>1.0f &&
|
||||
m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0)
|
||||
{
|
||||
// Make sure that not all AI karts use the zipper at the same
|
||||
// time in time trial at start up, so during the first 5 seconds
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
Kart::Kart (const std::string& ident, int position,
|
||||
const btTransform& init_transform)
|
||||
: TerrainInfo(1),
|
||||
Moveable(), EmergencyAnimation(this), m_powerup(this)
|
||||
Moveable(), EmergencyAnimation(this), MaxSpeed(this), m_powerup(this)
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# pragma warning(1:4355)
|
||||
@@ -343,6 +343,23 @@ void Kart::adjustSpeed(float f)
|
||||
m_body->setAngularVelocity(m_body->getAngularVelocity()*f);
|
||||
} // adjustSpeed
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Caps the speed at a given value. If necessary the kart will
|
||||
* instantaneously change its speed.
|
||||
* \param max_speed Maximum speed of the kart.
|
||||
*/
|
||||
void Kart::capSpeed(float max_speed)
|
||||
{
|
||||
if ( m_speed > max_speed && isOnGround() )
|
||||
{
|
||||
const float velocity_ratio = max_speed/m_speed;
|
||||
btVector3 velocity = getBody()->getLinearVelocity();
|
||||
velocity *= velocity_ratio;
|
||||
getVehicle()->getRigidBody()->setLinearVelocity( velocity );
|
||||
}
|
||||
|
||||
} // capSpeed
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** 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).
|
||||
@@ -363,7 +380,7 @@ void Kart::updatedWeight()
|
||||
void Kart::reset()
|
||||
{
|
||||
EmergencyAnimation::reset();
|
||||
|
||||
MaxSpeed::reset();
|
||||
if (m_camera)
|
||||
{
|
||||
m_camera->reset();
|
||||
@@ -388,7 +405,6 @@ void Kart::reset()
|
||||
m_race_position = m_initial_position;
|
||||
m_finished_race = false;
|
||||
m_finish_time = 0.0f;
|
||||
m_zipper_time_left = 0.0f;
|
||||
m_collected_energy = 0;
|
||||
m_has_started = false;
|
||||
m_wheel_rotation = 0;
|
||||
@@ -574,17 +590,18 @@ void Kart::collectedItem(Item *item, int add_info)
|
||||
*/
|
||||
float Kart::getActualWheelForce()
|
||||
{
|
||||
float zipperF=(m_zipper_time_left>0.0f) ? stk_config->m_zipper_force : 0.0f;
|
||||
float time_left = MaxSpeed::getSpeedIncreaseTimeLeft(MS_INCREASE_ZIPPER);
|
||||
float zipper_force = time_left>0.0f ? m_kart_properties->getZipperForce(): 0.0f;
|
||||
const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio();
|
||||
for(unsigned int i=0; i<gear_ratio.size(); i++)
|
||||
{
|
||||
if(m_speed <= m_kart_properties->getMaxSpeed()*gear_ratio[i])
|
||||
{
|
||||
return getMaxPower()*m_kart_properties->getGearPowerIncrease()[i]
|
||||
+zipperF;
|
||||
+zipper_force;
|
||||
}
|
||||
}
|
||||
return getMaxPower()+zipperF;
|
||||
return getMaxPower()+zipper_force;
|
||||
|
||||
} // getActualWheelForce
|
||||
|
||||
@@ -648,7 +665,8 @@ void Kart::update(float dt)
|
||||
|
||||
// When really on air, free fly, when near ground, try to glide / adjust for landing
|
||||
// If zipped, be stable, so ramp+zipper can allow nice jumps without scripting the fly
|
||||
if(!isNearGround() && !(m_zipper_time_left > 0.0f))
|
||||
if(!isNearGround() &&
|
||||
MaxSpeed::getSpeedIncreaseTimeLeft(MS_INCREASE_ZIPPER)<=0.0f )
|
||||
m_uprightConstraint->setLimit(M_PI);
|
||||
else
|
||||
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
||||
@@ -670,8 +688,6 @@ void Kart::update(float dt)
|
||||
//m_body->setAngularVelocity(btVector3(0,0,0));
|
||||
}
|
||||
|
||||
m_zipper_time_left = m_zipper_time_left>0.0f ? m_zipper_time_left-dt : 0.0f;
|
||||
|
||||
//m_wheel_rotation gives the rotation around the X-axis, and since velocity's
|
||||
//timeframe is the delta time, we don't have to multiply it with dt.
|
||||
m_wheel_rotation += m_speed*dt / m_kart_properties->getWheelRadius();
|
||||
@@ -802,6 +818,9 @@ void Kart::update(float dt)
|
||||
else if(material->isZipper() && isOnGround()) handleZipper();
|
||||
else
|
||||
{
|
||||
MaxSpeed::setSlowdown(MaxSpeed::MS_DECREASE_TERRAIN,
|
||||
material->getMaxSpeedFraction(),
|
||||
material->getSlowDownTime() );
|
||||
// Normal driving on terrain. Adjust for maximum terrain speed
|
||||
// Gradually adjust the fraction of the maximum kart speed to
|
||||
// the amount specified for the terrain.
|
||||
@@ -841,13 +860,16 @@ void Kart::handleZipper()
|
||||
{
|
||||
// Ignore a zipper that's activated while braking
|
||||
if(m_controls.m_brake) return;
|
||||
m_zipper_time_left = stk_config->m_zipper_time;
|
||||
|
||||
btVector3 v = m_body->getLinearVelocity();
|
||||
float current_speed = v.length();
|
||||
float speed = std::min(current_speed+stk_config->m_zipper_speed_gain,
|
||||
getMaxSpeedOnTerrain() *
|
||||
(1 + stk_config->m_zipper_max_speed_fraction));
|
||||
MaxSpeed::increaseMaxSpeed(MaxSpeed::MS_INCREASE_ZIPPER,
|
||||
m_kart_properties->getZipperMaxSpeedIncrease(),
|
||||
m_kart_properties->getZipperTime(),
|
||||
/*fade_out_time*/ 3.0f);
|
||||
// This will result in all max speed settings updated, but no
|
||||
// changes to any slow downs since dt=0
|
||||
MaxSpeed::update(0);
|
||||
float speed = std::min(m_speed+m_kart_properties->getZipperSpeedGain(),
|
||||
MaxSpeed::getCurrentMaxSpeed() );
|
||||
|
||||
m_vehicle->activateZipper(speed);
|
||||
// Play custom character sound (weee!)
|
||||
@@ -988,7 +1010,7 @@ float Kart::handleSlipstream(float dt)
|
||||
if(m_slipstream_time>m_kart_properties->getSlipstreamCollectTime())
|
||||
{
|
||||
m_slipstream->setIntensity(1.0f, m_slipstream_target);
|
||||
return 0; // see below about abusing m_zipper_time_left without zipper
|
||||
return 0; // see below about abusing zipper without zipper
|
||||
//return m_kart_properties->getSlipstreamAddPower();
|
||||
}
|
||||
return 0;
|
||||
@@ -1128,9 +1150,10 @@ void Kart::updatePhysics(float dt)
|
||||
if(!m_has_started && m_controls.m_accel)
|
||||
{
|
||||
m_has_started = true;
|
||||
m_zipper_time_left = 5.0f;
|
||||
float f = m_kart_properties->getStartupBoost();
|
||||
m_vehicle->activateZipper(f);
|
||||
MaxSpeed::increaseMaxSpeed(MS_INCREASE_ZIPPER, +10,
|
||||
5.0f, 5.0f);
|
||||
|
||||
}
|
||||
|
||||
@@ -1267,33 +1290,8 @@ void Kart::updatePhysics(float dt)
|
||||
if (forwardW.dot(getVehicle()->getRigidBody()->getLinearVelocity()) < btScalar(0.))
|
||||
m_speed *= -1.f;
|
||||
|
||||
//cap at maximum velocity
|
||||
float max_speed = getMaxSpeedOnTerrain();
|
||||
if (m_zipper_time_left > 0.0f)
|
||||
{
|
||||
const float zipper_fade_time = 3.0f;
|
||||
if (m_zipper_time_left > zipper_fade_time)
|
||||
{
|
||||
max_speed *= (1.0f + stk_config->m_zipper_max_speed_fraction);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_speed *= (1.0f + (stk_config->m_zipper_max_speed_fraction * m_zipper_time_left * 1.0f/zipper_fade_time));
|
||||
}
|
||||
}
|
||||
if ( m_speed > max_speed && isOnGround())
|
||||
{
|
||||
const float velocity_ratio = max_speed/m_speed;
|
||||
m_speed = max_speed;
|
||||
btVector3 velocity = m_body->getLinearVelocity();
|
||||
|
||||
velocity.setZ( velocity.getZ() * velocity_ratio );
|
||||
velocity.setX( velocity.getX() * velocity_ratio );
|
||||
velocity.setY( velocity.getY() * velocity_ratio ); // Up-down too
|
||||
|
||||
getVehicle()->getRigidBody()->setLinearVelocity( velocity );
|
||||
|
||||
}
|
||||
// Cap speed if necessary
|
||||
MaxSpeed::update(dt);
|
||||
|
||||
// To avoid tunneling (which can happen on long falls), clamp the
|
||||
// velocity in Y direction. Tunneling can happen if the Y velocity
|
||||
@@ -1322,6 +1320,7 @@ void Kart::updatePhysics(float dt)
|
||||
{
|
||||
if(isOnGround())
|
||||
{
|
||||
float max_speed = MaxSpeed::getCurrentMaxSpeed();
|
||||
// Engine noise is based half in total speed, half in fake gears:
|
||||
// With a sawtooth graph like /|/|/| we get 3 even spaced gears,
|
||||
// ignoring the gear settings from stk_config, but providing a
|
||||
@@ -1378,7 +1377,7 @@ void Kart::loadData()
|
||||
m_smoke_system = new Smoke(this);
|
||||
m_water_splash_system = new WaterSplash(this);
|
||||
m_nitro = new Nitro(this);
|
||||
m_slipstream = new SlipStream(this);
|
||||
m_slipstream = new SlipStream(this);
|
||||
|
||||
if(m_kart_properties->hasSkidmarks())
|
||||
m_skidmarks = new SkidMarks(*this);
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
|
||||
#include "items/attachment.hpp"
|
||||
#include "items/powerup.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/controller/kart_control.hpp"
|
||||
#include "karts/emergency_animation.hpp"
|
||||
#include "karts/max_speed.hpp"
|
||||
#include "karts/moveable.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/controller/kart_control.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "tracks/terrain_info.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
@@ -60,7 +60,8 @@ class WaterSplash;
|
||||
* and TerrainInfo, which manages the terrain the kart is on.
|
||||
* \ingroup karts
|
||||
*/
|
||||
class Kart : public TerrainInfo, public Moveable, public EmergencyAnimation
|
||||
class Kart : public TerrainInfo, public Moveable, public EmergencyAnimation,
|
||||
public MaxSpeed
|
||||
{
|
||||
private:
|
||||
/** Reset position. */
|
||||
@@ -93,7 +94,6 @@ private:
|
||||
protected: // Used by the AI atm
|
||||
KartControl m_controls; // The kart controls (e.g. steering, fire, ...)
|
||||
Powerup m_powerup;
|
||||
float m_zipper_time_left; /**<Zipper time left. */
|
||||
Attachment *m_attachment;
|
||||
/** Easier access for player_kart. */
|
||||
Camera *m_camera;
|
||||
@@ -229,6 +229,7 @@ public:
|
||||
void resetBrakes ();
|
||||
void startEngineSFX ();
|
||||
void adjustSpeed (float f);
|
||||
void capSpeed (float max_speed);
|
||||
void updatedWeight ();
|
||||
virtual void collectedItem (Item *item, int random_attachment);
|
||||
virtual void reset ();
|
||||
@@ -292,9 +293,6 @@ public:
|
||||
/** Returns the number of powerups. */
|
||||
int getNumPowerup () const { return m_powerup.getNum(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time left for a zipper. */
|
||||
float getZipperTimeLeft () const { return m_zipper_time_left; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the remaining collected energy. */
|
||||
float getEnergy () const { return m_collected_energy; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -75,6 +75,8 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_rubber_band_max_length = m_rubber_band_force =
|
||||
m_rubber_band_duration = m_plunger_in_face_duration[0] =
|
||||
m_plunger_in_face_duration[1] = m_plunger_in_face_duration[2] =
|
||||
m_zipper_time = m_zipper_force = m_zipper_speed_gain =
|
||||
m_zipper_max_speed_increase = m_zipper_fade_out_time =
|
||||
m_time_till_max_skid =
|
||||
m_skid_decrease = m_skid_increase = m_skid_visual = m_skid_max =
|
||||
m_slipstream_length = m_slipstream_collect_time =
|
||||
@@ -405,6 +407,15 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
m_plunger_in_face_duration[2] = v[2];
|
||||
}
|
||||
|
||||
if(const XMLNode *zipper_node= root->getNode("zipper"))
|
||||
{
|
||||
zipper_node->get("time", &m_zipper_time );
|
||||
zipper_node->get("fade-out-time", &m_zipper_fade_out_time );
|
||||
zipper_node->get("force", &m_zipper_force );
|
||||
zipper_node->get("speed-gain", &m_zipper_speed_gain );
|
||||
zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase);
|
||||
}
|
||||
|
||||
if(const XMLNode *camera_node= root->getNode("camera"))
|
||||
{
|
||||
camera_node->get("distance", &m_camera_distance);
|
||||
@@ -522,11 +533,16 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
CHECK_NEG(m_upright_max_force, "upright max-force" );
|
||||
CHECK_NEG(m_track_connection_accel, "track-connection-accel" );
|
||||
CHECK_NEG(m_rubber_band_max_length, "rubber-band max-length" );
|
||||
CHECK_NEG(m_plunger_in_face_duration[0],"plunger: in-face-time[0]" );
|
||||
CHECK_NEG(m_plunger_in_face_duration[1],"plunger: in-face-time[1]" );
|
||||
CHECK_NEG(m_plunger_in_face_duration[2],"plunger: in-face-time[2]" );
|
||||
CHECK_NEG(m_plunger_in_face_duration[0],"plunger: in-face-time[0]" );
|
||||
CHECK_NEG(m_plunger_in_face_duration[1],"plunger: in-face-time[1]" );
|
||||
CHECK_NEG(m_plunger_in_face_duration[2],"plunger: in-face-time[2]" );
|
||||
CHECK_NEG(m_rubber_band_force, "rubber-band force" );
|
||||
CHECK_NEG(m_rubber_band_duration, "rubber-band duration" );
|
||||
CHECK_NEG(m_zipper_time, "zipper-time" );
|
||||
CHECK_NEG(m_zipper_fade_out_time, "zipper-fade-out-time" );
|
||||
CHECK_NEG(m_zipper_force, "zipper-force" );
|
||||
CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" );
|
||||
CHECK_NEG(m_zipper_max_speed_increase, "zipper-max-speed-increase" );
|
||||
CHECK_NEG(m_skid_decrease, "skid decrease" );
|
||||
CHECK_NEG(m_time_till_max_skid, "skid time-till-max" );
|
||||
CHECK_NEG(m_skid_increase, "skid increase" );
|
||||
|
||||
@@ -132,6 +132,21 @@ private:
|
||||
/** How far away from an explosion karts will still be affected. */
|
||||
float m_explosion_radius;
|
||||
|
||||
/** Duration a zipper is active. */
|
||||
float m_zipper_time;
|
||||
|
||||
/** Fade out time for a zipper. */
|
||||
float m_zipper_fade_out_time;
|
||||
|
||||
/** Additional force added to the acceleration. */
|
||||
float m_zipper_force;
|
||||
|
||||
/** Initial one time speed gain. */
|
||||
float m_zipper_speed_gain;
|
||||
|
||||
/** Absolute increase of the kart's maximum speed (in m/s). */
|
||||
float m_zipper_max_speed_increase;
|
||||
|
||||
/** Vertical offset after rescue. */
|
||||
float m_rescue_vert_offset;
|
||||
|
||||
@@ -403,6 +418,18 @@ public:
|
||||
/** Returns duration of a plunger in your face. */
|
||||
float getPlungerInFaceTime () const
|
||||
{return m_plunger_in_face_duration[race_manager->getDifficulty()];}
|
||||
/** Returns the time a zipper is active. */
|
||||
float getZipperTime () const {return m_zipper_time; }
|
||||
/** Returns the time a zipper is active. */
|
||||
float getZipperFadeOutTime () const {return m_zipper_fade_out_time; }
|
||||
/** Returns the additional force added applied to the kart. */
|
||||
float getZipperForce () const { return m_zipper_force; }
|
||||
/** Returns the initial zipper speed gain. */
|
||||
float getZipperSpeedGain () const { return m_zipper_speed_gain; }
|
||||
/** Returns the increase of the maximum speed of the kart
|
||||
* if a zipper is active. */
|
||||
float getZipperMaxSpeedIncrease () const { return m_zipper_max_speed_increase;}
|
||||
|
||||
|
||||
/** Returns additional rotation of 3d model when skidding. */
|
||||
float getSkidVisual () const {return m_skid_visual; }
|
||||
|
||||
176
src/karts/max_speed.cpp
Normal file
176
src/karts/max_speed.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
// $Id: max_speed.cpp 6306 2010-10-18 06:04:05Z hikerstk $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "karts/max_speed.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
#include "karts/kart.hpp"
|
||||
|
||||
/** This class handles maximum speed for karts. Several factors can influence
|
||||
* the maximum speed a kart can drive, some will decrease the maximum speed,
|
||||
* some will increase the maximum speed.
|
||||
* Slowdowns are specified in fraction of the (kart specific) maximum speed
|
||||
* of that kart. The following categories are defined:
|
||||
* - terrain-specific slow downs
|
||||
* - AI related slow down (low level AIs might drive slower than player)
|
||||
* - end controller related AI (end controller drives slower)
|
||||
* The largest slowdown of all those factors is applied to the maximum
|
||||
* speed of the kart.
|
||||
* Increase of maximum speed is given absolute, i.e. in m/s. The following
|
||||
* circumstances can increase the maximum speed:
|
||||
* - Use of a zipper
|
||||
* - Use of sliptstream
|
||||
* - Use of nitro
|
||||
* The speed increases for all those are added after applying the maximum
|
||||
* slowdown fraction.
|
||||
* At the end the maximum is capped by a value specified in stk_config
|
||||
* (to avoid issues with physics etc).
|
||||
*/
|
||||
MaxSpeed::MaxSpeed(Kart *kart)
|
||||
{
|
||||
m_kart = kart;
|
||||
} // MaxSpeed
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Reset to prepare for a restart. It just overwrites each entry with a
|
||||
* newly constructed values, i.e. values that don't cause any slowdown
|
||||
* or speedup.
|
||||
*/
|
||||
void MaxSpeed::reset()
|
||||
{
|
||||
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed();
|
||||
for(unsigned int i=MS_DECREASE_MIN; i<MS_DECREASE_MAX; i++)
|
||||
{
|
||||
SpeedDecrease sd;
|
||||
m_speed_decrease[i] = sd;
|
||||
}
|
||||
|
||||
// Then add the speed increase from each category
|
||||
// ----------------------------------------------
|
||||
for(unsigned int i=MS_INCREASE_MIN; i<MS_INCREASE_MAX; i++)
|
||||
{
|
||||
SpeedIncrease si;
|
||||
m_speed_increase[i] = si;
|
||||
}
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets an increased maximum speed for a category.
|
||||
* \param category The category for which to set the higher maximum speed.
|
||||
* \param add_speed How much speed (in m/s) is added to the maximum speed.
|
||||
* \param duration How long the speed increase will last.
|
||||
* \param fade_out_time How long the maximum speed will fade out linearly.
|
||||
*/
|
||||
void MaxSpeed::increaseMaxSpeed(unsigned int category, float add_speed,
|
||||
float duration, float fade_out_time)
|
||||
{
|
||||
assert(category>=MS_INCREASE_MIN && category <MS_INCREASE_MAX);
|
||||
m_speed_increase[category].m_duration = duration;
|
||||
m_speed_increase[category].m_fade_out_time = fade_out_time;
|
||||
m_speed_increase[category].m_max_add_speed = add_speed;
|
||||
m_speed_increase[category].m_current_speedup = add_speed;
|
||||
} // increaseMaxSpeed
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Handles the update of speed increase objects. The m_duration variable
|
||||
* contains the remaining time - as long as this variable is positibe,
|
||||
* the maximum speed increase applies, while when it is between
|
||||
* -m_fade_out_time and 0, the maximum speed will linearly decrease.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void MaxSpeed::SpeedIncrease::update(float dt)
|
||||
{
|
||||
m_duration -= dt;
|
||||
// ENd of increased max speed reached.
|
||||
if(m_duration < -m_fade_out_time)
|
||||
{
|
||||
m_current_speedup = 0;
|
||||
return;
|
||||
}
|
||||
// If we are still in main max speed increase time, do nothing
|
||||
if(m_duration >0) return;
|
||||
|
||||
// Now we are in the fade out period: decrease time linearly
|
||||
m_current_speedup -= dt*m_max_add_speed/m_fade_out_time;
|
||||
} // SpeedIncrease::update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MaxSpeed::setSlowdown(unsigned int category, float max_speed_fraction,
|
||||
float fade_in_time)
|
||||
{
|
||||
assert(category>=MS_DECREASE_MIN && category <MS_DECREASE_MAX);
|
||||
m_speed_decrease[category].m_max_speed_fraction = max_speed_fraction;
|
||||
m_speed_decrease[category].m_fade_in_time = fade_in_time;
|
||||
} // setSlowdown
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MaxSpeed::SpeedDecrease::update(float dt)
|
||||
{
|
||||
float diff = m_current_fraction - m_max_speed_fraction;
|
||||
if(diff > 0)
|
||||
{
|
||||
if (diff * m_fade_in_time > dt)
|
||||
m_current_fraction -= dt/m_fade_in_time;
|
||||
else
|
||||
m_current_fraction = m_max_speed_fraction;
|
||||
}
|
||||
else
|
||||
m_current_fraction = m_max_speed_fraction;
|
||||
} // SpeedDecrease::update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
float MaxSpeed::getSpeedIncreaseTimeLeft(unsigned int category)
|
||||
{
|
||||
return m_speed_increase[category].getTimeLeft();
|
||||
} // getSpeedIncreaseTimeLeft
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MaxSpeed::update(float dt)
|
||||
{
|
||||
|
||||
// First comput the minimum max-speed fraction, which
|
||||
// determines the overall decrease of maximum speed.
|
||||
// ---------------------------------------------------
|
||||
float f = 1.0f;
|
||||
for(unsigned int i=MS_DECREASE_MIN; i<MS_DECREASE_MAX; i++)
|
||||
{
|
||||
SpeedDecrease &slowdown = m_speed_decrease[i];
|
||||
slowdown.update(dt);
|
||||
f = std::min(f, slowdown.getSlowdownFraction());
|
||||
}
|
||||
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed() * f;
|
||||
|
||||
// Then add the speed increase from each category
|
||||
// ----------------------------------------------
|
||||
for(unsigned int i=MS_INCREASE_MIN; i<MS_INCREASE_MAX; i++)
|
||||
{
|
||||
SpeedIncrease &speedup = m_speed_increase[i];
|
||||
speedup.update(dt);
|
||||
m_current_max_speed += speedup.getSpeedIncrease();
|
||||
}
|
||||
|
||||
// Then cap the current speed of the kart
|
||||
// --------------------------------------
|
||||
m_kart->capSpeed(m_current_max_speed);
|
||||
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
138
src/karts/max_speed.hpp
Normal file
138
src/karts/max_speed.hpp
Normal file
@@ -0,0 +1,138 @@
|
||||
// $Id: max_speed.hpp 6307 2010-10-18 11:08:22Z hikerstk $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_MAX_SPEED_HPP
|
||||
#define HEADER_MAX_SPEED_HPP
|
||||
|
||||
/** \defgroup karts */
|
||||
|
||||
class Kart;
|
||||
|
||||
class MaxSpeed
|
||||
{
|
||||
public:
|
||||
/** The categories to use for increasing the speed of a kart:
|
||||
* Increase due to zipper, slipstream, nitro usage. */
|
||||
enum {MS_INCREASE_MIN,
|
||||
MS_INCREASE_ZIPPER = MS_INCREASE_MIN,
|
||||
MS_INCREASE_SLIPSTREAM,
|
||||
MS_INCREASE_NITRO,
|
||||
MS_INCREASE_MAX};
|
||||
|
||||
/** The categories to use for decreasing the speed of a kart:
|
||||
* Decrease due to terrain, different AI levels and end controller. */
|
||||
enum {MS_DECREASE_MIN,
|
||||
MS_DECREASE_TERRAIN = MS_DECREASE_MIN,
|
||||
MS_DECREASE_AI,
|
||||
MS_DECREASE_MAX};
|
||||
|
||||
private:
|
||||
/** A pointer to the kart to which this speed handling object belongs. */
|
||||
Kart *m_kart;
|
||||
|
||||
/** The current maximum speed. */
|
||||
float m_current_max_speed;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** An internal class to store and handle speed increase related data. */
|
||||
class SpeedIncrease
|
||||
{
|
||||
public:
|
||||
/** The maximum additional speed allowed. */
|
||||
float m_max_add_speed;
|
||||
/** How long this speed will apply. This is used as a timer internally,
|
||||
* to the duration will be decreased. When the duration is <0, the
|
||||
* fade out time starts, and duration will go down to
|
||||
* -m_fade_out_time before this speed increase stops. */
|
||||
float m_duration;
|
||||
/** The fadeout time. */
|
||||
float m_fade_out_time;
|
||||
/** The current max speed increase value. */
|
||||
float m_current_speedup;
|
||||
|
||||
/** The constructor initialised the values with a no-increase
|
||||
* entry, i.e. an entry that does affect top speed at all. */
|
||||
SpeedIncrease()
|
||||
{
|
||||
m_max_add_speed = 0;
|
||||
m_duration = -9999999;
|
||||
m_fade_out_time = 0;
|
||||
m_current_speedup = 0;
|
||||
} // SpeedIncrease
|
||||
void update(float dt);
|
||||
/** Returns the current speedup for this category. */
|
||||
float getSpeedIncrease() const {return m_current_speedup;}
|
||||
/** Returns the remaining time till the fade out time starts.
|
||||
* Note that this function will return a negative value if
|
||||
* the fade_out time has started or this speed increase has
|
||||
* expired. */
|
||||
float getTimeLeft() const {return m_duration; }
|
||||
}; // SpeedIncrease
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** An internal class to store and handle speed decrease related data. */
|
||||
class SpeedDecrease
|
||||
{
|
||||
public:
|
||||
/** The maximum slowdown to apply. */
|
||||
float m_max_speed_fraction;
|
||||
/** How long it should take for the full slowdown to take effect. */
|
||||
float m_fade_in_time;
|
||||
/** The current slowdown fraction, taking the fade-in time
|
||||
* into account. */
|
||||
float m_current_fraction;
|
||||
|
||||
/** The constructor initialises the data with data that won't
|
||||
* affect top speed at all. */
|
||||
SpeedDecrease()
|
||||
{
|
||||
m_max_speed_fraction = 1.0f;
|
||||
m_fade_in_time = 0.0f;
|
||||
m_current_fraction = 1.0f;
|
||||
} // SpeedDecrease
|
||||
void update(float dt);
|
||||
/** Returns the current slowdown fracftion, taking a 'fade in'
|
||||
* into account. */
|
||||
float getSlowdownFraction() const {return m_current_fraction;}
|
||||
}; // SpeedDecrease
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Stores all speed decrease related information
|
||||
* for each possible category. */
|
||||
SpeedDecrease m_speed_decrease[MS_DECREASE_MAX];
|
||||
|
||||
/** Stores all speed increase related information
|
||||
* for each possible category. */
|
||||
SpeedIncrease m_speed_increase[MS_INCREASE_MAX];
|
||||
|
||||
public:
|
||||
MaxSpeed(Kart *kart);
|
||||
|
||||
void increaseMaxSpeed(unsigned int category, float add_speed,
|
||||
float duration, float fade_out_time);
|
||||
void setSlowdown(unsigned int category, float max_speed_fraction,
|
||||
float fade_in_time);
|
||||
float getSpeedIncreaseTimeLeft(unsigned int category);
|
||||
void update(float dt);
|
||||
void reset();
|
||||
/** Returns the current maximum speed for this kart. */
|
||||
float getCurrentMaxSpeed() const { return m_current_max_speed; }
|
||||
|
||||
}; // MaxSpeed
|
||||
#endif
|
||||
Reference in New Issue
Block a user