diff --git a/data/kart_characteristics.xml b/data/kart_characteristics.xml
index 3407aa5ee..250b23a11 100644
--- a/data/kart_characteristics.xml
+++ b/data/kart_characteristics.xml
@@ -66,7 +66,7 @@
speed 10 the radius is 7.5 etc.
The actual turn radius is piece-wise linearly interpolated. This
allows for tighter turning at lower speeds, and also avoids that
- the kart becomes too hard to control at high speed (speeds of
+ the kart becomes too hard to control at high speed (speeds
higher than 25 can only be reached with powerups).
time-full-steer: This is the amount of change in steering depending
on current steering. So if the steering is between 0 and 0.5,
@@ -84,7 +84,8 @@
time-reset-steer="0.1" />
-
-
+
@@ -205,9 +207,9 @@
-
+
+ boost="8 4" />
-
+
-
+
+ min-collect-time="2.5" max-collect-time="8" add-power="300" min-speed="8"
+ max-speed-increase="3" duration-factor="1" fade-out-time="2" />
-
+
-
+
-
+
@@ -356,44 +360,40 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
-
-
-
-
+
+
+
diff --git a/src/karts/abstract_characteristic.cpp b/src/karts/abstract_characteristic.cpp
index af7ba896c..778812c0a 100644
--- a/src/karts/abstract_characteristic.cpp
+++ b/src/karts/abstract_characteristic.cpp
@@ -201,6 +201,8 @@ AbstractCharacteristic::ValueType AbstractCharacteristic::getType(
return TYPE_FLOAT;
case NITRO_ENGINE_FORCE:
return TYPE_FLOAT;
+ case NITRO_ENGINE_MULT:
+ return TYPE_FLOAT;
case NITRO_CONSUMPTION:
return TYPE_FLOAT;
case NITRO_SMALL_CONTAINER:
@@ -437,6 +439,8 @@ std::string AbstractCharacteristic::getName(CharacteristicType type)
return "NITRO_DURATION";
case NITRO_ENGINE_FORCE:
return "NITRO_ENGINE_FORCE";
+ case NITRO_ENGINE_MULT:
+ return "NITRO_ENGINE_MULT";
case NITRO_CONSUMPTION:
return "NITRO_CONSUMPTION";
case NITRO_SMALL_CONTAINER:
@@ -1395,6 +1399,18 @@ float AbstractCharacteristic::getNitroEngineForce() const
return result;
} // getNitroEngineForce
+// ----------------------------------------------------------------------------
+float AbstractCharacteristic::getNitroEngineMult() const
+{
+ float result;
+ bool is_set = false;
+ process(NITRO_ENGINE_MULT, &result, &is_set);
+ if (!is_set)
+ Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
+ getName(NITRO_ENGINE_MULT).c_str());
+ return result;
+} // getNitroEngineMult
+
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getNitroConsumption() const
{
diff --git a/src/karts/abstract_characteristic.hpp b/src/karts/abstract_characteristic.hpp
index f4fb2406c..23cbd60c7 100644
--- a/src/karts/abstract_characteristic.hpp
+++ b/src/karts/abstract_characteristic.hpp
@@ -185,6 +185,7 @@ public:
// Nitro
NITRO_DURATION,
NITRO_ENGINE_FORCE,
+ NITRO_ENGINE_MULT,
NITRO_CONSUMPTION,
NITRO_SMALL_CONTAINER,
NITRO_BIG_CONTAINER,
@@ -354,6 +355,7 @@ public:
float getNitroDuration() const;
float getNitroEngineForce() const;
+ float getNitroEngineMult() const;
float getNitroConsumption() const;
float getNitroSmallContainer() const;
float getNitroBigContainer() const;
diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp
index a7f330744..ab4300f74 100644
--- a/src/karts/kart.cpp
+++ b/src/karts/kart.cpp
@@ -2651,6 +2651,54 @@ void Kart::updateEngineSFX(float dt)
}
} // updateEngineSFX
+
+
+//-----------------------------------------------------------------------------
+/** Reduces the engine power according to speed
+ *
+ * TODO : find where the physics already apply a linear force decrease
+ * TODO : While this work fine, it should ideally be in physics
+ * However, the function use some kart properties and parachute
+ * effect needs to be applied, so keep both working if moving
+ * \param engine_power : the engine power on which to apply the decrease
+ */
+float Kart::applyAirFriction(float engine_power)
+{
+ //The physics already do that a certain amount of engine force is needed to keep going
+ //at a given speed (~39,33 engine force = 1 speed for a mass of 350)
+ //But it's either too slow to accelerate to a target speed or makes it
+ //too easy to accelerate farther.
+ //Instead of making increasing gears have enormous power gaps, apply friction
+
+ float mass_factor = m_kart_properties->getMass()/350.0f;
+ float compense_linear_slowdown = 39.33f*getSpeed()*mass_factor;
+
+ engine_power += compense_linear_slowdown;
+
+ // The result will always be a positive number
+ float friction_intensity = fabsf(getSpeed());
+
+ // Not a pure quadratic evolution as it would be too brutal
+ friction_intensity *= sqrt(friction_intensity)*5;
+
+ // Apply parachute physics
+ // Currently, all karts have the same base friction
+ // If this is changed, a compensation needs to be added here
+ if(m_attachment->getType()==Attachment::ATTACH_PARACHUTE)
+ friction_intensity *= m_kart_properties->getParachuteFriction();
+
+ if (friction_intensity < 0.0f) friction_intensity = 0.0f;
+
+ // We substract the friction from the engine power
+ // 1)This is the logical behavior
+ // 2)That way, engine boosts remain useful at high speed
+ // 3)It helps heavier karts, who have an higher engine power
+
+ engine_power-=friction_intensity;
+
+ return engine_power;
+} //applyAirFriction
+
//-----------------------------------------------------------------------------
/** Sets the engine power. It considers the engine specs, items that influence
* the available power, and braking/steering.
@@ -2661,9 +2709,11 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
updateNitro(ticks);
float engine_power = getActualWheelForce();
- // apply parachute physics if relevant
- if(m_attachment->getType()==Attachment::ATTACH_PARACHUTE)
- engine_power*=0.2f;
+ // apply nitro boost if relevant
+ if(getSpeedIncreaseTicksLeft(MaxSpeed::MS_INCREASE_NITRO) > 0)
+ {
+ engine_power*= m_kart_properties->getNitroEngineMult();
+ }
// apply bubblegum physics if relevant
if (m_bubblegum_ticks > 0)
@@ -2689,6 +2739,9 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
m_kart_properties->getSkidVisualTime() == 0)
engine_power *= 0.5f;
+ // This also applies parachute physics if relevant
+ engine_power = applyAirFriction(engine_power);
+
applyEngineForce(engine_power*m_controls.getAccel());
// Either all or no brake is set, so test only one to avoid
@@ -2698,14 +2751,20 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
m_vehicle->setAllBrakes(0);
m_brake_ticks = 0;
}
- else
- { // not accelerating
+ else // not accelerating
+ {
+ //The engine power is still guaranteed >= 0 at this point
+ float braking_power = engine_power;
+
+ // This also applies parachute physics if relevant
+ engine_power = applyAirFriction(engine_power);
+
if(m_controls.getBrake())
{ // check if the player is currently only slowing down
// or moving backwards
if(m_speed > 0.0f)
{ // Still going forward while braking
- applyEngineForce(-engine_power*2.5f);
+ applyEngineForce(engine_power-braking_power*3);
m_brake_ticks += ticks;
// Apply the brakes - include the time dependent brake increase
float f = 1.0f + stk_config->ticks2Time(m_brake_ticks)
@@ -2723,7 +2782,7 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
// The backwards acceleration is artificially increased to
// allow players to get "unstuck" quicker if they hit e.g.
// a wall.
- applyEngineForce(-engine_power*2.5f);
+ applyEngineForce(engine_power-braking_power*3);
}
else // -m_speed >= max speed on this terrain
{
@@ -2732,13 +2791,13 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
} // m_speed <00
}
- else // !m_brake
+ else // no braking and no acceleration
{
m_brake_ticks = 0;
- // lift the foot from throttle, brakes with 10% engine_power
+ // lift the foot from throttle, let friction slow it down
assert(!std::isnan(m_controls.getAccel()));
assert(!std::isnan(engine_power));
- applyEngineForce(-m_controls.getAccel()*engine_power*0.1f);
+ applyEngineForce(engine_power-braking_power);
// If not giving power (forward or reverse gear), and speed is low
// we are "parking" the kart, so in battle mode we can ambush people
@@ -2746,7 +2805,7 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
m_vehicle->setAllBrakes(20.0f);
else
m_vehicle->setAllBrakes(0);
- } // !m_brake
+ } // no braking and no acceleration
} // not accelerating
} // updateEnginePowerAndBrakes
diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp
index 569880fe2..6cc09be44 100644
--- a/src/karts/kart.hpp
+++ b/src/karts/kart.hpp
@@ -264,6 +264,7 @@ protected:
void updateEngineSFX(float dt);
void updateSpeed();
void updateNitro(int ticks);
+ float applyAirFriction (float engine_power);
float getActualWheelForce();
void playCrashSFX(const Material* m, AbstractKart *k);
void loadData(RaceManager::KartType type, bool animatedModel);
diff --git a/src/karts/kart_properties.cpp b/src/karts/kart_properties.cpp
index 5463c33ad..0b1763e94 100644
--- a/src/karts/kart_properties.cpp
+++ b/src/karts/kart_properties.cpp
@@ -1017,6 +1017,12 @@ float KartProperties::getNitroEngineForce() const
return m_cached_characteristic->getNitroEngineForce();
} // getNitroEngineForce
+// ----------------------------------------------------------------------------
+float KartProperties::getNitroEngineMult() const
+{
+ return m_cached_characteristic->getNitroEngineMult();
+} // getNitroEngineMult
+
// ----------------------------------------------------------------------------
float KartProperties::getNitroConsumption() const
{
diff --git a/src/karts/kart_properties.hpp b/src/karts/kart_properties.hpp
index 30ce89463..70fdce83b 100644
--- a/src/karts/kart_properties.hpp
+++ b/src/karts/kart_properties.hpp
@@ -469,6 +469,7 @@ public:
float getNitroDuration() const;
float getNitroEngineForce() const;
+ float getNitroEngineMult() const;
float getNitroConsumption() const;
float getNitroSmallContainer() const;
float getNitroBigContainer() const;
diff --git a/src/karts/skidding.cpp b/src/karts/skidding.cpp
index e81fc28f7..512210bea 100644
--- a/src/karts/skidding.cpp
+++ b/src/karts/skidding.cpp
@@ -545,7 +545,7 @@ void Skidding::update(int ticks, bool is_on_ground,
MaxSpeed::MS_INCREASE_RED_SKIDDING;
m_kart->m_max_speed->
instantSpeedIncrease(bonus_cat,
- bonus_speed, bonus_speed,
+ bonus_speed, bonus_speed/2,
bonus_force,
stk_config->time2Ticks(bonus_time),
/*fade-out-time*/ stk_config->time2Ticks(1.0f));
diff --git a/src/karts/xml_characteristic.cpp b/src/karts/xml_characteristic.cpp
index 2e9a34676..9a4e9f95e 100644
--- a/src/karts/xml_characteristic.cpp
+++ b/src/karts/xml_characteristic.cpp
@@ -545,6 +545,8 @@ void XmlCharacteristic::load(const XMLNode *node)
&m_values[NITRO_DURATION]);
sub_node->get("engine-force",
&m_values[NITRO_ENGINE_FORCE]);
+ sub_node->get("engine-mult",
+ &m_values[NITRO_ENGINE_MULT]);
sub_node->get("consumption",
&m_values[NITRO_CONSUMPTION]);
sub_node->get("small-container",