Implement dynamic basket ball speed, fix #2783
This commit is contained in:
parent
6f50c234a3
commit
073708c97e
@ -87,6 +87,9 @@
|
|||||||
power: The power of the kart (the engine power needed to accelerate
|
power: The power of the kart (the engine power needed to accelerate
|
||||||
at a given pace is proportional to mass)
|
at a given pace is proportional to mass)
|
||||||
max-speed: The base maximum speed of the kart in m/s
|
max-speed: The base maximum speed of the kart in m/s
|
||||||
|
generic-max-speed: Must have the same value as max-speed. This
|
||||||
|
is the max speed independently of kart type and
|
||||||
|
of handicap, which is used by basket balls.
|
||||||
brake-factor: Value used when braking.
|
brake-factor: Value used when braking.
|
||||||
brake-time-increase: The brake force is multiplied by
|
brake-time-increase: The brake force is multiplied by
|
||||||
(1 + brake_time) * brake_time_increase - i.e. the longer the
|
(1 + brake_time) * brake_time_increase - i.e. the longer the
|
||||||
@ -94,7 +97,7 @@
|
|||||||
max-speed-reverse-ratio is the percentage of max speed for reverse
|
max-speed-reverse-ratio is the percentage of max speed for reverse
|
||||||
gear.
|
gear.
|
||||||
-->
|
-->
|
||||||
<engine power="950" max-speed="25" brake-factor="15"
|
<engine power="950" max-speed="25" generic-max-speed="25" brake-factor="15"
|
||||||
brake-time-increase="6" max-speed-reverse-ratio="0.65" />
|
brake-time-increase="6" max-speed-reverse-ratio="0.65" />
|
||||||
|
|
||||||
<!-- Simulated gears
|
<!-- Simulated gears
|
||||||
@ -342,15 +345,15 @@
|
|||||||
<!-- The different difficulties (like easy, medium, hard) -->
|
<!-- The different difficulties (like easy, medium, hard) -->
|
||||||
<difficulties>
|
<difficulties>
|
||||||
<characteristic name="easy">
|
<characteristic name="easy">
|
||||||
<engine power="*0.7" max-speed="*0.6" />
|
<engine power="*0.7" max-speed="*0.6" generic-max-speed="*0.6" />
|
||||||
<plunger in-face-time="3" />
|
<plunger in-face-time="3" />
|
||||||
</characteristic>
|
</characteristic>
|
||||||
<characteristic name="medium">
|
<characteristic name="medium">
|
||||||
<engine power="*0.83" max-speed="*0.8" />
|
<engine power="*0.83" max-speed="*0.8" generic-max-speed="*0.8" />
|
||||||
<plunger in-face-time="4" />
|
<plunger in-face-time="4" />
|
||||||
</characteristic>
|
</characteristic>
|
||||||
<characteristic name="hard">
|
<characteristic name="hard">
|
||||||
<engine power="*0.92" max-speed="*0.92" />
|
<engine power="*0.92" max-speed="*0.92" generic-max-speed="*0.92" />
|
||||||
</characteristic>
|
</characteristic>
|
||||||
<!-- This doesn't need to be changed because the most fast/heavy/extreme
|
<!-- This doesn't need to be changed because the most fast/heavy/extreme
|
||||||
values should also be the default ones. -->
|
values should also be the default ones. -->
|
||||||
|
@ -16,6 +16,22 @@
|
|||||||
<item name="switch" icon="swap-icon.png" />
|
<item name="switch" icon="swap-icon.png" />
|
||||||
<item name="swatter" icon="swatter-icon.png" />
|
<item name="swatter" icon="swatter-icon.png" />
|
||||||
<!-- interval: How long a single bounce takes.
|
<!-- interval: How long a single bounce takes.
|
||||||
|
min-speed-offset: The speed of the ball is calculated
|
||||||
|
by adding the speed-offset to the difficulty's
|
||||||
|
max-speed. min-speed-offset is used when the
|
||||||
|
ball is closer than min-offset-distance
|
||||||
|
to the target.
|
||||||
|
max-speed-offset: The additional speed of the ball when
|
||||||
|
farther than max-offset-distance.
|
||||||
|
speed : defines the initial speed. Mainly kept for
|
||||||
|
compatibility with flyable class
|
||||||
|
min-offset-distance: The distance under which the ball is
|
||||||
|
at minimal speed.
|
||||||
|
max-offset-distance: The distance over which the ball is
|
||||||
|
at maximal speed. If it is not equal to
|
||||||
|
min-offset-distance, the ball speeds between
|
||||||
|
both is a weighted average of the min and
|
||||||
|
max speed.
|
||||||
max-height: The maximum height of a bounce.
|
max-height: The maximum height of a bounce.
|
||||||
min-height: Unused mostly, but defines implicitly
|
min-height: Unused mostly, but defines implicitly
|
||||||
the starting height (as average of
|
the starting height (as average of
|
||||||
@ -57,7 +73,12 @@
|
|||||||
tunneling.
|
tunneling.
|
||||||
-->
|
-->
|
||||||
<item name="rubber-ball" icon="rubber_ball-icon.png"
|
<item name="rubber-ball" icon="rubber_ball-icon.png"
|
||||||
model="rubber_ball.spm" speed="35.0"
|
model="rubber_ball.spm"
|
||||||
|
speed="40.0"
|
||||||
|
min-speed-offset="9.0"
|
||||||
|
max-speed-offset="29.0"
|
||||||
|
min-offset-distance="50.0"
|
||||||
|
max-offset-distance="250.0"
|
||||||
interval="1"
|
interval="1"
|
||||||
max-height="4.0" min-height="0"
|
max-height="4.0" min-height="0"
|
||||||
fast-ping-distance="50"
|
fast-ping-distance="50"
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "items/attachment.hpp"
|
#include "items/attachment.hpp"
|
||||||
#include "items/projectile_manager.hpp"
|
#include "items/projectile_manager.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
|
#include "karts/kart_properties.hpp"
|
||||||
#include "modes/linear_world.hpp"
|
#include "modes/linear_world.hpp"
|
||||||
#include "network/network_string.hpp"
|
#include "network/network_string.hpp"
|
||||||
#include "network/rewind_info.hpp"
|
#include "network/rewind_info.hpp"
|
||||||
@ -49,6 +50,10 @@ int RubberBall::m_st_delete_ticks;
|
|||||||
float RubberBall::m_st_max_height_difference;
|
float RubberBall::m_st_max_height_difference;
|
||||||
float RubberBall::m_st_fast_ping_distance;
|
float RubberBall::m_st_fast_ping_distance;
|
||||||
float RubberBall::m_st_early_target_factor;
|
float RubberBall::m_st_early_target_factor;
|
||||||
|
float RubberBall::m_st_min_speed_offset;
|
||||||
|
float RubberBall::m_st_max_speed_offset;
|
||||||
|
float RubberBall::m_st_min_offset_distance;
|
||||||
|
float RubberBall::m_st_max_offset_distance;
|
||||||
int RubberBall::m_next_id = 0;
|
int RubberBall::m_next_id = 0;
|
||||||
|
|
||||||
|
|
||||||
@ -305,16 +310,21 @@ void RubberBall::getNextControlPoint()
|
|||||||
*/
|
*/
|
||||||
void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
||||||
{
|
{
|
||||||
m_st_interval = 1.0f;
|
m_st_interval = 1.0f;
|
||||||
m_st_squash_duration = 3.0f;
|
m_st_squash_duration = 3.0f;
|
||||||
m_st_squash_slowdown = 0.5f;
|
m_st_squash_slowdown = 0.5f;
|
||||||
m_st_min_interpolation_distance = 30.0f;
|
m_st_min_interpolation_distance = 30.0f;
|
||||||
m_st_target_distance = 50.0f;
|
m_st_target_distance = 50.0f;
|
||||||
m_st_target_max_angle = 25.0f;
|
m_st_target_max_angle = 25.0f;
|
||||||
m_st_delete_ticks = stk_config->time2Ticks(10.0f);
|
m_st_delete_ticks = stk_config->time2Ticks(10.0f);
|
||||||
m_st_max_height_difference = 10.0f;
|
m_st_max_height_difference = 10.0f;
|
||||||
m_st_fast_ping_distance = 50.0f;
|
m_st_fast_ping_distance = 50.0f;
|
||||||
m_st_early_target_factor = 1.0f;
|
m_st_early_target_factor = 1.0f;
|
||||||
|
m_st_min_speed_offset = 8.0f;
|
||||||
|
m_st_max_speed_offset = 28.0f;
|
||||||
|
m_st_min_offset_distance = 50.0f;
|
||||||
|
m_st_max_offset_distance = 250.0f;
|
||||||
|
|
||||||
|
|
||||||
if(!node.get("interval", &m_st_interval))
|
if(!node.get("interval", &m_st_interval))
|
||||||
Log::warn("powerup", "No interval specified for basket ball.");
|
Log::warn("powerup", "No interval specified for basket ball.");
|
||||||
@ -350,6 +360,28 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
|||||||
if(!node.get("early-target-factor", &m_st_early_target_factor))
|
if(!node.get("early-target-factor", &m_st_early_target_factor))
|
||||||
Log::warn("powerup",
|
Log::warn("powerup",
|
||||||
"No early-target-factor specified for basket ball.");
|
"No early-target-factor specified for basket ball.");
|
||||||
|
if(!node.get("min-speed-offset", &m_st_min_speed_offset))
|
||||||
|
Log::warn("powerup", "No min-speed-offset specified for basket ball.");
|
||||||
|
if(!node.get("max-speed-offset", &m_st_max_speed_offset))
|
||||||
|
Log::warn("powerup", "No max-speed-offset specified for basket ball.");
|
||||||
|
if(!node.get("min-offset-distance", &m_st_min_offset_distance))
|
||||||
|
Log::warn("powerup", "No min-offset-distance specified for basket ball.");
|
||||||
|
if(!node.get("max-offset-distance", &m_st_max_offset_distance))
|
||||||
|
Log::warn("powerup", "No max-offset-distance specified for basket ball.");
|
||||||
|
|
||||||
|
|
||||||
|
//sanity checks
|
||||||
|
if (m_st_min_speed_offset < 10.0f)
|
||||||
|
m_st_min_speed_offset = 10.0f;
|
||||||
|
if (m_st_min_speed_offset > m_st_max_speed_offset)
|
||||||
|
{
|
||||||
|
m_st_max_speed_offset = m_st_min_speed_offset;
|
||||||
|
}
|
||||||
|
if (m_st_max_offset_distance <= (m_st_min_offset_distance + 10.0f))
|
||||||
|
{
|
||||||
|
m_st_max_offset_distance = m_st_min_offset_distance + 10.0f;
|
||||||
|
}
|
||||||
|
|
||||||
Flyable::init(node, rubberball, PowerupManager::POWERUP_RUBBERBALL);
|
Flyable::init(node, rubberball, PowerupManager::POWERUP_RUBBERBALL);
|
||||||
} // init
|
} // init
|
||||||
|
|
||||||
@ -395,6 +427,9 @@ bool RubberBall::updateAndDelete(int ticks)
|
|||||||
computeTarget();
|
computeTarget();
|
||||||
updateDistanceToTarget();
|
updateDistanceToTarget();
|
||||||
|
|
||||||
|
//Update the speed
|
||||||
|
updateWeightedSpeed(ticks);
|
||||||
|
|
||||||
// Determine the new position. This new position is only temporary,
|
// Determine the new position. This new position is only temporary,
|
||||||
// since it still needs to be adjusted for the height of the terrain.
|
// since it still needs to be adjusted for the height of the terrain.
|
||||||
Vec3 next_xyz;
|
Vec3 next_xyz;
|
||||||
@ -507,6 +542,67 @@ void RubberBall::moveTowardsTarget(Vec3 *next_xyz, int ticks)
|
|||||||
|
|
||||||
} // moveTowardsTarget
|
} // moveTowardsTarget
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Calculates the current speed of the basket ball.
|
||||||
|
* The base basket ball speed is the target's normal max speed.
|
||||||
|
* Then an offset is applied.
|
||||||
|
* If closer than m_st_min_offset_distance ; it is m_st_min_speed_offset
|
||||||
|
* If farther than m_st_max_offset_distance ; it is m_st_max_speed_offset
|
||||||
|
* Else, it is a weighted average.
|
||||||
|
* It takes up to 5 seconds to fully change its speed
|
||||||
|
* (to avoid sudden big speed changes when the distance change suddenly
|
||||||
|
* at ball throwing, because of paths, shortcuts, etc.)
|
||||||
|
* If there is no target, it will keep its current speed
|
||||||
|
*/
|
||||||
|
void RubberBall::updateWeightedSpeed(int ticks)
|
||||||
|
{
|
||||||
|
// Don't change the speed if there is no target
|
||||||
|
if (m_delete_ticks >= 10)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const KartProperties *kp = m_target->getKartProperties();
|
||||||
|
// Get the speed depending on difficulty but not on kart type/handicap
|
||||||
|
float targeted_speed = kp->getEngineGenericMaxSpeed();
|
||||||
|
|
||||||
|
float dt = stk_config->ticks2Time(ticks);
|
||||||
|
|
||||||
|
//Calculate the targeted weighted speed
|
||||||
|
if (m_distance_to_target <= m_st_min_offset_distance)
|
||||||
|
{
|
||||||
|
targeted_speed += m_st_min_speed_offset;
|
||||||
|
}
|
||||||
|
else if (m_distance_to_target > m_st_max_offset_distance)
|
||||||
|
{
|
||||||
|
targeted_speed += m_st_max_speed_offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float weight = 1.0f;
|
||||||
|
float offset = 0.0f;
|
||||||
|
weight = (m_st_max_offset_distance - m_distance_to_target)
|
||||||
|
/(m_st_max_offset_distance - m_st_min_offset_distance);
|
||||||
|
offset = weight * m_st_min_speed_offset + (1-weight) * m_st_max_speed_offset;
|
||||||
|
targeted_speed += offset;
|
||||||
|
}
|
||||||
|
//Update the real speed
|
||||||
|
//Always >= 0
|
||||||
|
float max_change = (m_st_max_speed_offset - m_st_min_speed_offset)*dt/(5.0f);
|
||||||
|
if (m_speed-targeted_speed <= max_change && m_speed-targeted_speed >= -max_change)
|
||||||
|
{
|
||||||
|
m_speed = targeted_speed;
|
||||||
|
}
|
||||||
|
else if (m_speed < targeted_speed)
|
||||||
|
{
|
||||||
|
m_speed += max_change;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_speed -= max_change;
|
||||||
|
}
|
||||||
|
} // updateWeightedSpeed
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Uses Hermite splines (Catmull-Rom) to interpolate the position of the
|
/** Uses Hermite splines (Catmull-Rom) to interpolate the position of the
|
||||||
* ball between the control points. If the next point would be outside of
|
* ball between the control points. If the next point would be outside of
|
||||||
|
@ -82,6 +82,20 @@ private:
|
|||||||
* ball will be deleted. */
|
* ball will be deleted. */
|
||||||
static int m_st_delete_ticks;
|
static int m_st_delete_ticks;
|
||||||
|
|
||||||
|
/** If the ball is closer to its target than min_offset_distance, the speed
|
||||||
|
* in addition to the difficulty's default max speed. */
|
||||||
|
static float m_st_min_speed_offset;
|
||||||
|
|
||||||
|
/** If the ball is farther to its target than max_offset_distance, the speed
|
||||||
|
* in addition to the difficulty's default max speed. */
|
||||||
|
static float m_st_max_speed_offset;
|
||||||
|
|
||||||
|
/** The distance to target under which the ball is the slowest */
|
||||||
|
static float m_st_min_offset_distance;
|
||||||
|
|
||||||
|
/** The distance to target over which the ball is the fastest */
|
||||||
|
static float m_st_max_offset_distance;
|
||||||
|
|
||||||
/** This factor is used to influence how much the rubber ball should aim
|
/** This factor is used to influence how much the rubber ball should aim
|
||||||
* at its target early. It used the 'distance to center of track' of its
|
* at its target early. It used the 'distance to center of track' of its
|
||||||
* target, and adjusts the interpolation control points to be more or
|
* target, and adjusts the interpolation control points to be more or
|
||||||
@ -195,6 +209,7 @@ private:
|
|||||||
float updateHeight();
|
float updateHeight();
|
||||||
void interpolate(Vec3 *next_xyz, int ticks);
|
void interpolate(Vec3 *next_xyz, int ticks);
|
||||||
void moveTowardsTarget(Vec3 *next_xyz, int ticks);
|
void moveTowardsTarget(Vec3 *next_xyz, int ticks);
|
||||||
|
void updateWeightedSpeed(int ticks);
|
||||||
void initializeControlPoints(const Vec3 &xyz);
|
void initializeControlPoints(const Vec3 &xyz);
|
||||||
float getTunnelHeight(const Vec3 &next_xyz,
|
float getTunnelHeight(const Vec3 &next_xyz,
|
||||||
const float vertical_offset) const;
|
const float vertical_offset) const;
|
||||||
|
@ -89,6 +89,8 @@ AbstractCharacteristic::ValueType AbstractCharacteristic::getType(
|
|||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
case ENGINE_MAX_SPEED:
|
case ENGINE_MAX_SPEED:
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
|
case ENGINE_GENERIC_MAX_SPEED:
|
||||||
|
return TYPE_FLOAT;
|
||||||
case ENGINE_BRAKE_FACTOR:
|
case ENGINE_BRAKE_FACTOR:
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
case ENGINE_BRAKE_TIME_INCREASE:
|
case ENGINE_BRAKE_TIME_INCREASE:
|
||||||
@ -727,6 +729,18 @@ float AbstractCharacteristic::getEngineMaxSpeed() const
|
|||||||
return result;
|
return result;
|
||||||
} // getEngineMaxSpeed
|
} // getEngineMaxSpeed
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float AbstractCharacteristic::getEngineGenericMaxSpeed() const
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
bool is_set = false;
|
||||||
|
process(ENGINE_GENERIC_MAX_SPEED, &result, &is_set);
|
||||||
|
if (!is_set)
|
||||||
|
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
|
||||||
|
getName(ENGINE_GENERIC_MAX_SPEED).c_str());
|
||||||
|
return result;
|
||||||
|
} // getEngineGenericMaxSpeed
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
float AbstractCharacteristic::getEngineBrakeFactor() const
|
float AbstractCharacteristic::getEngineBrakeFactor() const
|
||||||
{
|
{
|
||||||
|
@ -95,6 +95,7 @@ public:
|
|||||||
// Engine
|
// Engine
|
||||||
ENGINE_POWER,
|
ENGINE_POWER,
|
||||||
ENGINE_MAX_SPEED,
|
ENGINE_MAX_SPEED,
|
||||||
|
ENGINE_GENERIC_MAX_SPEED,
|
||||||
ENGINE_BRAKE_FACTOR,
|
ENGINE_BRAKE_FACTOR,
|
||||||
ENGINE_BRAKE_TIME_INCREASE,
|
ENGINE_BRAKE_TIME_INCREASE,
|
||||||
ENGINE_MAX_SPEED_REVERSE_RATIO,
|
ENGINE_MAX_SPEED_REVERSE_RATIO,
|
||||||
@ -282,6 +283,7 @@ public:
|
|||||||
|
|
||||||
float getEnginePower() const;
|
float getEnginePower() const;
|
||||||
float getEngineMaxSpeed() const;
|
float getEngineMaxSpeed() const;
|
||||||
|
float getEngineGenericMaxSpeed() const;
|
||||||
float getEngineBrakeFactor() const;
|
float getEngineBrakeFactor() const;
|
||||||
float getEngineBrakeTimeIncrease() const;
|
float getEngineBrakeTimeIncrease() const;
|
||||||
float getEngineMaxSpeedReverseRatio() const;
|
float getEngineMaxSpeedReverseRatio() const;
|
||||||
|
@ -59,7 +59,7 @@ AbstractKart::AbstractKart(const std::string& ident,
|
|||||||
// Technically the mesh in m_kart_model needs to be grab'ed and
|
// Technically the mesh in m_kart_model needs to be grab'ed and
|
||||||
// released when the kart is deleted, but since the original
|
// released when the kart is deleted, but since the original
|
||||||
// kart_model is stored in the kart_properties all the time,
|
// kart_model is stored in the kart_properties all the time,
|
||||||
// there is no risk of a mesh being deleted to early.
|
// there is no risk of a mesh being deleted too early.
|
||||||
m_kart_model = m_kart_properties->getKartModelCopy(ri);
|
m_kart_model = m_kart_properties->getKartModelCopy(ri);
|
||||||
m_kart_width = m_kart_model->getWidth();
|
m_kart_width = m_kart_model->getWidth();
|
||||||
m_kart_height = m_kart_model->getHeight();
|
m_kart_height = m_kart_model->getHeight();
|
||||||
|
@ -679,6 +679,12 @@ float KartProperties::getEngineMaxSpeed() const
|
|||||||
return m_cached_characteristic->getEngineMaxSpeed();
|
return m_cached_characteristic->getEngineMaxSpeed();
|
||||||
} // getEngineMaxSpeed
|
} // getEngineMaxSpeed
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float KartProperties::getEngineGenericMaxSpeed() const
|
||||||
|
{
|
||||||
|
return m_cached_characteristic->getEngineGenericMaxSpeed();
|
||||||
|
} // getEngineMaxSpeed
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
float KartProperties::getEngineBrakeFactor() const
|
float KartProperties::getEngineBrakeFactor() const
|
||||||
{
|
{
|
||||||
|
@ -396,6 +396,7 @@ public:
|
|||||||
|
|
||||||
float getEnginePower() const;
|
float getEnginePower() const;
|
||||||
float getEngineMaxSpeed() const;
|
float getEngineMaxSpeed() const;
|
||||||
|
float getEngineGenericMaxSpeed() const;
|
||||||
float getEngineBrakeFactor() const;
|
float getEngineBrakeFactor() const;
|
||||||
float getEngineBrakeTimeIncrease() const;
|
float getEngineBrakeTimeIncrease() const;
|
||||||
float getEngineMaxSpeedReverseRatio() const;
|
float getEngineMaxSpeedReverseRatio() const;
|
||||||
|
@ -365,6 +365,8 @@ void XmlCharacteristic::load(const XMLNode *node)
|
|||||||
&m_values[ENGINE_POWER]);
|
&m_values[ENGINE_POWER]);
|
||||||
sub_node->get("max-speed",
|
sub_node->get("max-speed",
|
||||||
&m_values[ENGINE_MAX_SPEED]);
|
&m_values[ENGINE_MAX_SPEED]);
|
||||||
|
sub_node->get("generic-max-speed",
|
||||||
|
&m_values[ENGINE_GENERIC_MAX_SPEED]);
|
||||||
sub_node->get("brake-factor",
|
sub_node->get("brake-factor",
|
||||||
&m_values[ENGINE_BRAKE_FACTOR]);
|
&m_values[ENGINE_BRAKE_FACTOR]);
|
||||||
sub_node->get("brake-time-increase",
|
sub_node->get("brake-time-increase",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user