Refactored skidding to use a new base class SkiddingProperties.

This patch reduces the dependencies between KartProperties and
skidding core (and especially reduces compile time when skidding
core changes).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10926 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-03-06 11:28:04 +00:00
parent 3404d4cf46
commit 65c73e9186
10 changed files with 395 additions and 203 deletions

View File

@ -184,7 +184,7 @@
<skid increase="1.05" decrease="0.95" max="2.5" time-till-max="0.5" <skid increase="1.05" decrease="0.95" max="2.5" time-till-max="0.5"
visual="1.0" visual-time="0" visual="1.0" visual-time="0"
time-till-bonus="1.5 2.5" time-till-bonus="1.5 2.5"
bonus-force="100 200" bonus-time="3.0 4.0" bonus-speed="100 200" bonus-time="3.0 4.0"
post-skid-rotate-factor="1" reduce-turn-min="0.6" post-skid-rotate-factor="1" reduce-turn-min="0.6"
reduce-turn-max="0.8"/> reduce-turn-max="0.8"/>

View File

@ -872,6 +872,10 @@
RelativePath="..\..\karts\skidding.cpp" RelativePath="..\..\karts\skidding.cpp"
> >
</File> </File>
<File
RelativePath="..\..\karts\skidding_properties.cpp"
>
</File>
<Filter <Filter
Name="controller" Name="controller"
> >
@ -2014,6 +2018,10 @@
RelativePath="..\..\karts\skidding.hpp" RelativePath="..\..\karts\skidding.hpp"
> >
</File> </File>
<File
RelativePath="..\..\karts\skidding_properties.hpp"
>
</File>
<Filter <Filter
Name="controller" Name="controller"
> >

View File

@ -22,6 +22,7 @@
#include <assert.h> #include <assert.h>
#include "karts/kart.hpp" #include "karts/kart.hpp"
#include "karts/skidding_properties.hpp"
#include "modes/linear_world.hpp" #include "modes/linear_world.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "utils/constants.hpp" #include "utils/constants.hpp"
@ -312,7 +313,7 @@ void AIBaseController::setSteering(float angle, float dt)
// FIXME: Disable skidding for now if the new skidding // FIXME: Disable skidding for now if the new skidding
// code is activated, since the AI can not handle this // code is activated, since the AI can not handle this
// properly. // properly.
if(m_kart->getKartProperties()->getSkidVisualTime()>0) if(m_kart->getKartProperties()->getSkiddingProperties()->getSkidVisualTime()>0)
m_controls->m_skid = false; m_controls->m_skid = false;
float old_steer = m_controls->m_steer; float old_steer = m_controls->m_steer;

View File

@ -187,7 +187,8 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
loadData(type, is_first_kart, animations); loadData(type, is_first_kart, animations);
m_kart_gfx = new KartGFX(this); m_kart_gfx = new KartGFX(this);
m_skidding = new Skidding(this); m_skidding = new Skidding(this,
m_kart_properties->getSkiddingProperties());
reset(); reset();
} // Kart } // Kart
@ -455,6 +456,7 @@ Kart::~Kart()
delete m_kart_chassis.getChildShape(i); delete m_kart_chassis.getChildShape(i);
} }
delete m_kart_model; delete m_kart_model;
delete m_skidding;
if(m_controller) if(m_controller)
delete m_controller; delete m_controller;
if(m_saved_controller) if(m_saved_controller)
@ -1006,7 +1008,7 @@ void Kart::update(float dt)
static video::SColor pink(255, 255, 133, 253); static video::SColor pink(255, 255, 133, 253);
// draw skidmarks if relevant (we force pink skidmarks on when hitting a bubblegum) // draw skidmarks if relevant (we force pink skidmarks on when hitting a bubblegum)
if(m_kart_properties->hasSkidmarks()) if(m_kart_properties->getSkiddingProperties()->hasSkidmarks())
{ {
m_skidmarks->update(dt, m_skidmarks->update(dt,
m_bubblegum_time > 0, m_bubblegum_time > 0,
@ -1612,14 +1614,15 @@ void Kart::updatePhysics(float dt)
float steering = getMaxSteerAngle() * m_controls.m_steer; float steering = getMaxSteerAngle() * m_controls.m_steer;
// FIXME: Misuse (for now) the skid visual time to disable the new // FIXME: Misuse (for now) the skid visual time to disable the new
// skidding code // skidding code
if(m_kart_properties->getSkidVisualTime()==0) if(m_kart_properties->getSkiddingProperties()->getSkidVisualTime()==0)
{ {
steering *= m_skidding->getSkidFactor(); steering *= m_skidding->getSkidFactor();
} }
else if(m_controls.m_skid) else if(m_controls.m_skid)
{ {
steering *= m_kart_properties->getSkidReduceTurnMin() steering *= m_kart_properties->getSkiddingProperties()
* sqrt(m_kart_properties->getMaxSkid() ->getSkidReduceTurnMin()
* sqrt(m_kart_properties->getSkiddingProperties()->getMaxSkid()
/ m_skidding->getSkidFactor()); / m_skidding->getSkidFactor());
} }
else else
@ -1753,7 +1756,7 @@ void Kart::updateEnginePowerAndBrakes(float dt)
else if(m_speed < 0.0f) else if(m_speed < 0.0f)
engine_power *= 5.0f; engine_power *= 5.0f;
// Lose some traction when skidding, to balance the adventage // Lose some traction when skidding, to balance the advantage
if(m_controls.m_skid) if(m_controls.m_skid)
engine_power *= 0.5f; engine_power *= 0.5f;
@ -1959,7 +1962,7 @@ void Kart::loadData(RaceManager::KartType type, bool is_first_kart,
m_slipstream = new SlipStream(this); m_slipstream = new SlipStream(this);
if(m_kart_properties->hasSkidmarks()) if(m_kart_properties->getSkiddingProperties()->hasSkidmarks())
{ {
m_skidmarks = new SkidMarks(*this); m_skidmarks = new SkidMarks(*this);
m_skidmarks->adjustFog( m_skidmarks->adjustFog(

View File

@ -28,6 +28,7 @@
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/kart_model.hpp" #include "karts/kart_model.hpp"
#include "karts/skidding_properties.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "utils/constants.hpp" #include "utils/constants.hpp"
@ -82,11 +83,8 @@ KartProperties::KartProperties(const std::string &filename)
m_rubber_band_fade_out_time = m_plunger_in_face_duration[0] = m_rubber_band_fade_out_time = m_plunger_in_face_duration[0] =
m_plunger_in_face_duration[1] = m_plunger_in_face_duration[2] = m_plunger_in_face_duration[1] = m_plunger_in_face_duration[2] =
m_zipper_time = m_zipper_force = m_zipper_speed_gain = m_zipper_time = m_zipper_force = m_zipper_speed_gain =
m_zipper_max_speed_increase = m_zipper_fade_out_time = m_zipper_max_speed_increase = m_zipper_fade_out_time =
m_time_till_max_skid = m_post_skid_rotate_factor = m_slipstream_length = m_slipstream_collect_time =
m_skid_reduce_turn_min = m_skid_reduce_turn_max =
m_skid_decrease = m_skid_increase = m_skid_visual = m_skid_max =
m_skid_visual_time = m_slipstream_length = m_slipstream_collect_time =
m_slipstream_use_time = m_slipstream_add_power = m_slipstream_use_time = m_slipstream_add_power =
m_slipstream_min_speed = m_slipstream_max_speed_increase = m_slipstream_min_speed = m_slipstream_max_speed_increase =
m_slipstream_duration = m_slipstream_fade_out_time = m_slipstream_duration = m_slipstream_fade_out_time =
@ -97,14 +95,9 @@ KartProperties::KartProperties(const std::string &filename)
m_swatter_distance2 = m_swatter_duration = m_squash_slowdown = m_swatter_distance2 = m_swatter_duration = m_squash_slowdown =
m_squash_duration = m_downward_impulse_factor = UNDEFINED; m_squash_duration = m_downward_impulse_factor = UNDEFINED;
m_skid_bonus_time.clear();
m_skid_bonus_force.clear();
m_skid_time_till_bonus.clear();
m_gravity_center_shift = Vec3(UNDEFINED); m_gravity_center_shift = Vec3(UNDEFINED);
m_bevel_factor = Vec3(UNDEFINED); m_bevel_factor = Vec3(UNDEFINED);
m_exp_spring_response = false; m_exp_spring_response = false;
m_has_skidmarks = true;
m_version = 0; m_version = 0;
m_color = video::SColor(255, 0, 0, 0); m_color = video::SColor(255, 0, 0, 0);
m_shape = 32; // close enough to a circle. m_shape = 32; // close enough to a circle.
@ -112,7 +105,15 @@ KartProperties::KartProperties(const std::string &filename)
m_kart_model = NULL; m_kart_model = NULL;
m_has_rand_wheels = false; m_has_rand_wheels = false;
// The default constructor for stk_config uses filename="" // The default constructor for stk_config uses filename=""
if (filename != "") load(filename, "kart"); if (filename != "")
{
m_skidding_properties = NULL;
load(filename, "kart");
}
else
{
m_skidding_properties = new SkiddingProperties();
}
} // KartProperties } // KartProperties
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -120,8 +121,30 @@ KartProperties::KartProperties(const std::string &filename)
KartProperties::~KartProperties() KartProperties::~KartProperties()
{ {
delete m_kart_model; delete m_kart_model;
if(m_skidding_properties)
delete m_skidding_properties;
} // ~KartProperties } // ~KartProperties
//-----------------------------------------------------------------------------
/** Copies this KartProperties to another one. Importnat: if you add any
* pointers to kart_properties, the data structure they are pointing to
* need to be copied here explicitely!
* \param source The source kart properties from which to copy this objects'
* values.
*/
void KartProperties::copyFrom(const KartProperties *source)
{
*this = *source;
// After the memcpy the two skidding properties will share pointers.
// So all pointer variables need to be separately allocated and assigned.
m_skidding_properties = new SkiddingProperties();
assert(m_skidding_properties);
*m_skidding_properties = *source->m_skidding_properties;
//m_skidding_properties->copyFrom(source->m_skidding_properties);
} // copy
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Loads the kart properties from a file. /** Loads the kart properties from a file.
* \param filename Filename to load. * \param filename Filename to load.
@ -129,8 +152,9 @@ KartProperties::~KartProperties()
*/ */
void KartProperties::load(const std::string &filename, const std::string &node) void KartProperties::load(const std::string &filename, const std::string &node)
{ {
// Get the default values from STKConfig: // Get the default values from STKConfig. This will also allocate any
*this = stk_config->getDefaultKartProperties(); // pointers used in KartProperties
copyFrom(&stk_config->getDefaultKartProperties());
// m_kart_model must be initialised after assigning the default // m_kart_model must be initialised after assigning the default
// values from stk_config (otherwise all kart_properties will // values from stk_config (otherwise all kart_properties will
// share the same KartModel // share the same KartModel
@ -295,19 +319,7 @@ void KartProperties::getAllData(const XMLNode * root)
} }
if(const XMLNode *skid_node = root->getNode("skid")) if(const XMLNode *skid_node = root->getNode("skid"))
{ {
skid_node->get("increase", &m_skid_increase ); m_skidding_properties->load(skid_node);
skid_node->get("decrease", &m_skid_decrease );
skid_node->get("max", &m_skid_max );
skid_node->get("time-till-max", &m_time_till_max_skid );
skid_node->get("visual", &m_skid_visual );
skid_node->get("visual-time", &m_skid_visual_time );
skid_node->get("enable", &m_has_skidmarks );
skid_node->get("time-till-bonus", &m_skid_time_till_bonus );
skid_node->get("bonus-force", &m_skid_bonus_force );
skid_node->get("bonus-time", &m_skid_bonus_time );
skid_node->get("post-skid-rotate-factor",&m_post_skid_rotate_factor);
skid_node->get("reduce-turn-min", &m_skid_reduce_turn_min );
skid_node->get("reduce-turn-max", &m_skid_reduce_turn_max );
} }
if(const XMLNode *slipstream_node = root->getNode("slipstream")) if(const XMLNode *slipstream_node = root->getNode("slipstream"))
@ -629,15 +641,6 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_zipper_force, "zipper-force" ); CHECK_NEG(m_zipper_force, "zipper-force" );
CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" ); CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" );
CHECK_NEG(m_zipper_max_speed_increase, "zipper-max-speed-increase" ); 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" );
CHECK_NEG(m_skid_max, "skid max" );
CHECK_NEG(m_skid_visual, "skid visual" );
CHECK_NEG(m_skid_visual_time, "skid visual-time" );
CHECK_NEG(m_post_skid_rotate_factor, "skid post-skid-rotate-factor" );
CHECK_NEG(m_skid_reduce_turn_min, "skid reduce-turn-min" );
CHECK_NEG(m_skid_reduce_turn_max, "skid reduce-turn-max" );
CHECK_NEG(m_slipstream_length, "slipstream length" ); CHECK_NEG(m_slipstream_length, "slipstream length" );
CHECK_NEG(m_slipstream_collect_time, "slipstream collect-time" ); CHECK_NEG(m_slipstream_collect_time, "slipstream collect-time" );
CHECK_NEG(m_slipstream_use_time, "slipstream use-time" ); CHECK_NEG(m_slipstream_use_time, "slipstream use-time" );
@ -671,29 +674,7 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_explosion_radius, "explosion radius" ); CHECK_NEG(m_explosion_radius, "explosion radius" );
CHECK_NEG(m_ai_steering_variation, "ai steering-variation" ); CHECK_NEG(m_ai_steering_variation, "ai steering-variation" );
if(m_skid_time_till_bonus.size()==0) m_skidding_properties->checkAllSet(filename);
fprintf(stderr, "Warning: no skid time declared, can be ignored.\n");
if(m_skid_time_till_bonus.size()!=m_skid_bonus_force.size())
{
fprintf(stderr, "Warning: skid time-till-bonus and bonus-force\n");
fprintf(stderr, " must have same number of elements.\n");
exit(-1);
}
if(m_skid_time_till_bonus.size()!=m_skid_bonus_time.size())
{
fprintf(stderr, "Warning: skid time-till-bonus and bonus-time must\n");
fprintf(stderr, " have same number of elements.\n");
exit(-1);
}
for(unsigned int i=0; i<m_skid_time_till_bonus.size()-1; i++)
{
if(m_skid_time_till_bonus[i]>=m_skid_time_till_bonus[i+1])
{
fprintf(stderr, "Warning: skid time-till-bonus not sorted.\n");
exit(-1);
}
} // for i
} // checkAllSet } // checkAllSet
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -717,26 +698,6 @@ float KartProperties::getMaxSteerAngle(float speed) const
return 0; // avoid compiler warning return 0; // avoid compiler warning
} // getMaxSteerAngle } // getMaxSteerAngle
// ----------------------------------------------------------------------------
/** Determines the bonus force to be applied to a kart which has skidded for
* the specified amount of time. It returns which level of skid bonus to use.
* \param t Time the kart has skidded.
* \return The 'level' of skid bonus: 0=no bonus, 1=level 1, 2=level 2 etc.
*/
unsigned int KartProperties::getSkidBonus(float t, float *bonus_time,
float *bonus_force) const
{
*bonus_time = 0;
*bonus_force = 0;
for(unsigned int i=0; i<m_skid_bonus_force.size(); i++)
{
if(t<=m_skid_time_till_bonus[i]) return i;
*bonus_force = m_skid_bonus_force[i];
*bonus_time= m_skid_bonus_time[i];
}
return m_skid_bonus_force.size();
} // getSkidBonusForce
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Called the first time a kart accelerates after 'ready-set-go'. It searches /** Called the first time a kart accelerates after 'ready-set-go'. It searches
* through m_startup_times to find the appropriate slot, and returns the * through m_startup_times to find the appropriate slot, and returns the

View File

@ -34,10 +34,10 @@ using namespace irr;
#include "karts/kart_model.hpp" #include "karts/kart_model.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
#include "utils/no_copy.hpp"
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
class Material; class Material;
class SkiddingProperties;
class XMLNode; class XMLNode;
/** /**
@ -56,6 +56,11 @@ private:
/** Base directory for this kart. */ /** Base directory for this kart. */
std::string m_root; std::string m_root;
/** The skididing properties for this kart, as a separate object in order
* to reduce dependencies (and therefore compile time) when changing
* any skidding property. */
SkiddingProperties *m_skidding_properties;
/** The absolute path of the icon texture to use. */ /** The absolute path of the icon texture to use. */
Material *m_icon_material; Material *m_icon_material;
@ -285,47 +290,6 @@ private:
/** How long the slip stream speed increase will gradually be reduced. */ /** How long the slip stream speed increase will gradually be reduced. */
float m_slipstream_fade_out_time; float m_slipstream_fade_out_time;
/** Maximal increase of steering when skidding. */
float m_skid_max;
/** Skidding is multiplied by this when skidding
* to increase to m_skid_increase. */
float m_skid_increase;
/** Skidding is multiplied by this when not skidding to decrease to 1.0. */
float m_skid_decrease;
/** Time till maximum skidding is reached. */
float m_time_till_max_skid;
/** Additional rotation of 3d model when skidding. */
float m_skid_visual;
/** How long it takes for visual skid to reach maximum. */
float m_skid_visual_time;
/** This factor is used to determine how much the chassis of a kart
* should rotate to match the graphical view. A factor of 1 is
* identical, a smaller factor will rotate the kart less (which might
* feel better). */
float m_post_skid_rotate_factor;
/** A factor is used to reduce the amount of steering while skidding. This
* is the minimum factor used (i.e. resulting in the largest turn
* radius). */
float m_skid_reduce_turn_min;
/** A factor is used to reduce the amount of steering while skidding. This
* is the maximum factor used (i.e. resulting in the smallest turn
* radius). */
float m_skid_reduce_turn_max;
/** Kart leaves skid marks. */
bool m_has_skidmarks;
/** Time of skidding before you get a bonus boost. It's possible to
* define more than one time, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_time_till_bonus;
/** How much additional speed a kart gets when skidding. It's possible to
* define more than one force, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_bonus_force;
/** How long the bonus will last. It's possible to define more than one
* time, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_bonus_time;
/** Make the AI to steer at slightly different points to make it less /** Make the AI to steer at slightly different points to make it less
* likely that the AI creates 'trains' - the kart behind getting * likely that the AI creates 'trains' - the kart behind getting
@ -367,14 +331,13 @@ private:
public: public:
KartProperties (const std::string &filename=""); KartProperties (const std::string &filename="");
~KartProperties (); ~KartProperties ();
void copyFrom (const KartProperties *source);
void getAllData (const XMLNode * root); void getAllData (const XMLNode * root);
void checkAllSet (const std::string &filename); void checkAllSet (const std::string &filename);
float getStartupBoost () const; float getStartupBoost () const;
/** Returns the maximum steering angle (depending on speed). */ /** Returns the maximum steering angle (depending on speed). */
float getMaxSteerAngle (float speed) const; float getMaxSteerAngle (float speed) const;
unsigned int getSkidBonus(float t, float *bonus_time,
float *bonus_force) const;
/** Returns the material for the kart icons. */ /** Returns the material for the kart icons. */
Material* getIconMaterial () const {return m_icon_material; } Material* getIconMaterial () const {return m_icon_material; }
@ -651,41 +614,9 @@ public:
* had to be set. */ * had to be set. */
float getShadowYOffset () const {return m_shadow_y_offset; } float getShadowYOffset () const {return m_shadow_y_offset; }
/** Returns the maximum factor by which the steering angle /** Returns a pointer to the skidding properties. */
* can be increased. */ const SkiddingProperties *getSkiddingProperties() const
float getMaxSkid () const {return m_skid_max; } { return m_skidding_properties; }
/** Returns the factor by which m_skidding is multiplied when the kart is
* skidding to increase it to the maximum. */
float getSkidIncrease () const {return m_skid_increase; }
/** Returns the factor by which m_skidding is multiplied when the kart is
* not skidding to decrease the current skidding amount back to 1.0f . */
float getSkidDecrease () const {return m_skid_decrease; }
/** Returns the time (in seconds) of drifting till the maximum skidding
* is reached. */
float getTimeTillMaxSkid () const {return m_time_till_max_skid; }
/** Returns additional rotation of 3d model when skidding. */
float getSkidVisual () const {return m_skid_visual; }
/** Returns the time for the visual skid to reach maximum. */
float getSkidVisualTime () const {return m_skid_visual_time; }
/** Returns a factor to be used to determine how much the chassis of a
* kart should rotate to match the graphical view. A factor of 1 is
* identical, a smaller factor will rotate the kart less (which might
* feel better). */
float getPostSkidRotateFactor () const {return m_post_skid_rotate_factor;}
/** Returns the factor by which to recude the amount of steering while
skidding. */
float getSkidReduceTurnMin () const { return m_skid_reduce_turn_min; }
float getSkidReduceTurnMax () const { return m_skid_reduce_turn_max; }
/** Returns if the kart leaves skidmarks or not. */
bool hasSkidmarks () const {return m_has_skidmarks; }
/** Returns ratio of current speed to max speed at which the gear will /** Returns ratio of current speed to max speed at which the gear will
* change (for our simualated gears = simple change of engine power). */ * change (for our simualated gears = simple change of engine power). */

View File

@ -25,9 +25,10 @@
/** Constructor of the skidding object. /** Constructor of the skidding object.
*/ */
Skidding::Skidding(Kart *kart) Skidding::Skidding(Kart *kart, const SkiddingProperties *sp)
{ {
m_kart = kart; m_kart = kart;
copyFrom(sp);
reset(); reset();
} // Skidding } // Skidding
@ -37,7 +38,7 @@ Skidding::Skidding(Kart *kart)
void Skidding::reset() void Skidding::reset()
{ {
m_skid_time = 0.0f; m_skid_time = 0.0f;
m_skid_state = SKID_NONE; m_skid_state = m_skid_visual_time<=0 ? SKID_OLD : SKID_NONE;
m_skid_factor = 1.0f; m_skid_factor = 1.0f;
} // reset } // reset
@ -56,12 +57,11 @@ void Skidding::update(float dt, bool is_on_ground,
{ {
if((fabs(steering) > 0.001f) && skidding) if((fabs(steering) > 0.001f) && skidding)
{ {
m_skid_factor += m_kart->getKartProperties()->getSkidIncrease() m_skid_factor += m_skid_increase *dt/m_time_till_max_skid;
*dt/m_kart->getKartProperties()->getTimeTillMaxSkid();
} }
else if(m_skid_factor>1.0f) else if(m_skid_factor>1.0f)
{ {
m_skid_factor *= m_kart->getKartProperties()->getSkidDecrease(); m_skid_factor *= m_skid_decrease;
} }
} }
else else
@ -69,13 +69,13 @@ void Skidding::update(float dt, bool is_on_ground,
m_skid_factor = 1.0f; // Lose any skid factor as soon as we fly m_skid_factor = 1.0f; // Lose any skid factor as soon as we fly
} }
if(m_skid_factor>m_kart->getKartProperties()->getMaxSkid()) if(m_skid_factor>m_skid_max)
m_skid_factor = m_kart->getKartProperties()->getMaxSkid(); m_skid_factor = m_skid_max;
else else
if(m_skid_factor<1.0f) m_skid_factor = 1.0f; if(m_skid_factor<1.0f) m_skid_factor = 1.0f;
// FIXME hiker: remove once the new skidding code is finished. // FIXME hiker: remove once the new skidding code is finished.
if(m_kart->getKartProperties()->getSkidVisualTime()<=0) if(m_skid_state == SKID_OLD)
return; return;
// This is only reached if the new skidding is enabled // This is only reached if the new skidding is enabled
@ -113,10 +113,8 @@ void Skidding::update(float dt, bool is_on_ground,
{ {
m_skid_time += dt; m_skid_time += dt;
float bonus_time, bonus_force; float bonus_time, bonus_force;
unsigned int level = unsigned int level = getSkidBonus(&bonus_time,
m_kart->getKartProperties()->getSkidBonus(m_skid_time, &bonus_force);
&bonus_time,
&bonus_force);
// If at least level 1 bonus is reached, show appropriate gfx // If at least level 1 bonus is reached, show appropriate gfx
if(level>0) m_kart->getKartGFX()->setSkidLevel(level); if(level>0) m_kart->getKartGFX()->setSkidLevel(level);
// If player stops skidding, trigger bonus, and change state to // If player stops skidding, trigger bonus, and change state to
@ -124,15 +122,11 @@ void Skidding::update(float dt, bool is_on_ground,
if(!skidding) if(!skidding)
{ {
m_skid_state = SKID_SHOW_GFX; m_skid_state = SKID_SHOW_GFX;
float t = (m_skid_time <= m_kart->getKartProperties() float t = (m_skid_time <= m_skid_visual_time)
->getSkidVisualTime())
? m_skid_time ? m_skid_time
: m_kart->getKartProperties()->getSkidVisualTime(); : m_skid_visual_time;
float vso = getVisualSkidOffset(); float vso = getVisualSkidOffset();
btVector3 rot(0, btVector3 rot(0, vso*m_post_skid_rotate_factor, 0);
vso*m_kart->getKartProperties()
->getPostSkidRotateFactor(),
0);
m_kart->getVehicle()->setTimedRotation(t, rot); m_kart->getVehicle()->setTimedRotation(t, rot);
// skid_time is used to count backwards for the GFX // skid_time is used to count backwards for the GFX
m_skid_time = t; m_skid_time = t;
@ -161,7 +155,28 @@ void Skidding::update(float dt, bool is_on_ground,
m_skid_state = SKID_NONE; m_skid_state = SKID_NONE;
} }
} // switch } // switch
} // updateSkidding } // update
// ----------------------------------------------------------------------------
/** Determines the bonus time and speed given the currently accumulated
* m_skid_time.
* \param bonus_time On return contains how long the bonus should be active.
* \param bonus_speed How much additional speed the kart should get.
* \return The bonus level: 0 = no bonus, 1 = first entry in bonus array etc.
*/
unsigned int Skidding::getSkidBonus(float *bonus_time,
float *bonus_speed) const
{
*bonus_time = 0;
*bonus_speed = 0;
for(unsigned int i=0; i<m_skid_bonus_speed.size(); i++)
{
if(m_skid_time<=m_skid_time_till_bonus[i]) return i;
*bonus_speed = m_skid_bonus_speed[i];
*bonus_time= m_skid_bonus_time[i];
}
return m_skid_bonus_speed.size();
} // getSkidBonusForce
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Determines how much the graphics model of the kart should be rotated /** Determines how much the graphics model of the kart should be rotated
@ -171,22 +186,24 @@ void Skidding::update(float dt, bool is_on_ground,
*/ */
float Skidding::getVisualSkidOffset() const float Skidding::getVisualSkidOffset() const
{ {
if(m_kart->getKartProperties()->getSkidVisualTime()==0) float speed = m_kart->getSpeed();
float steer_percent = m_kart->getSteerPercent();
float current_max_speed = m_kart->getCurrentMaxSpeed();
if(m_skid_visual_time==0)
{ {
float speed_ratio = m_kart->getSpeed() float speed_ratio = speed / current_max_speed;
/ m_kart->MaxSpeed::getCurrentMaxSpeed(); float r = m_skid_factor / m_skid_max;
float r = m_skid_factor / m_kart->getKartProperties()->getMaxSkid(); return steer_percent * speed_ratio * r;
return m_kart->getSteerPercent() * speed_ratio * r;
} }
// New skidding code // New skidding code
float f = m_kart->getKartProperties()->getSkidVisual() float f = m_skid_visual * steer_percent;
* m_kart->getSteerPercent(); //if(m_kart->getSpeed() < m_kart->getKartProperties()->getMaxSpeed())
if(m_kart->getSpeed() < m_kart->getKartProperties()->getMaxSpeed()) // f *= m_kart->getSpeed()/m_kart->getKartProperties()->getMaxSpeed();
f *= m_kart->getSpeed()/m_kart->getKartProperties()->getMaxSpeed();
float st = fabsf(m_skid_time); float st = fabsf(m_skid_time);
if(st<m_kart->getKartProperties()->getSkidVisualTime()) if(st<m_skid_visual_time)
f *= st/m_kart->getKartProperties()->getSkidVisualTime(); f *= st/m_skid_visual_time;
return f; return f;

View File

@ -19,15 +19,22 @@
#ifndef HEADER_SKIDDING_HPP #ifndef HEADER_SKIDDING_HPP
#define HEADER_SKIDDING_HPP #define HEADER_SKIDDING_HPP
#include "skidding_properties.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
class Kart; class Kart;
#include <vector>
/** /**
* \ingroup karts * \ingroup karts
*/ */
class Skidding : public NoCopy class Skidding : public SkiddingProperties
{ {
public:
LEAK_CHECK();
private: private:
/** Accumulated skidding factor. */ /** Accumulated skidding factor. */
float m_skid_factor; float m_skid_factor;
@ -36,20 +43,29 @@ private:
* trigger the skidding bonus. */ * trigger the skidding bonus. */
float m_skid_time; float m_skid_time;
enum {SKID_NONE, SKID_ACCUMULATE_LEFT, SKID_ACCUMULATE_RIGHT, /** SKID_OLD: old skidding, will be removed. */
SKID_TRIGGER_BONUS, SKID_SHOW_GFX} /** SKID_NONE: Kart is currently not skidding.
* SKID_ACCUMULATE_LEFT: Kart is skidding to the left and accumulating
* for bonus.
* SKID_ACCUMULATE_RIGHT: Similar for turning right
* SKID_SHOW_GFX: Shows the gfx, while the bonus is actibe. */
enum {SKID_OLD, SKID_NONE, SKID_ACCUMULATE_LEFT, SKID_ACCUMULATE_RIGHT,
SKID_SHOW_GFX}
m_skid_state; m_skid_state;
/** A read-only pointer to the kart's properties. */ /** A read-only pointer to the kart's properties. */
Kart *m_kart; Kart *m_kart;
unsigned int Skidding::getSkidBonus(float *bonus_time,
float *bonus_speed) const;
public: public:
Skidding(Kart *kart); Skidding(Kart *kart, const SkiddingProperties *sp);
~Skidding();
void reset(); void reset();
void update(float dt, bool is_on_ground, float steer, void update(float dt, bool is_on_ground, float steer,
bool skidding); bool skidding);
float getVisualSkidOffset() const; float getVisualSkidOffset() const;
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Returns the current skid factor in [1, skid_max_for_this_kart]. */ /** Returns the current skid factor in [1, skid_max_for_this_kart]. */
float getSkidFactor() const { return m_skid_factor; } float getSkidFactor() const { return m_skid_factor; }

View File

@ -0,0 +1,115 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2012 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/skidding_properties.hpp"
#include "io/xml_node.hpp"
#include <string.h>
float SkiddingProperties::UNDEFINED = -99.9f;
SkiddingProperties::SkiddingProperties()
{
m_skid_increase = UNDEFINED;
m_skid_decrease = UNDEFINED;
m_skid_max = UNDEFINED;
m_time_till_max_skid = UNDEFINED;
m_skid_visual = UNDEFINED;
m_skid_visual_time = UNDEFINED;
m_post_skid_rotate_factor = UNDEFINED;
m_skid_reduce_turn_min = UNDEFINED;
m_skid_reduce_turn_max = UNDEFINED;
m_has_skidmarks = true;
m_skid_bonus_time.clear();
m_skid_bonus_speed.clear();
m_skid_time_till_bonus.clear();
} // SkiddingProperties
// ----------------------------------------------------------------------------
void SkiddingProperties::load(const XMLNode *skid_node)
{
skid_node->get("increase", &m_skid_increase );
skid_node->get("decrease", &m_skid_decrease );
skid_node->get("max", &m_skid_max );
skid_node->get("time-till-max", &m_time_till_max_skid );
skid_node->get("visual", &m_skid_visual );
skid_node->get("visual-time", &m_skid_visual_time );
skid_node->get("post-skid-rotate-factor",&m_post_skid_rotate_factor);
skid_node->get("reduce-turn-min", &m_skid_reduce_turn_min );
skid_node->get("reduce-turn-max", &m_skid_reduce_turn_max );
skid_node->get("enable", &m_has_skidmarks );
skid_node->get("bonus-time", &m_skid_bonus_time );
skid_node->get("bonus-speed", &m_skid_bonus_speed );
skid_node->get("time-till-bonus", &m_skid_time_till_bonus );
} // load
// ----------------------------------------------------------------------------
void SkiddingProperties::checkAllSet(const std::string &filename) const
{
#define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \
fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \
strA,filename.c_str());exit(-1); \
}
CHECK_NEG(m_skid_increase, "skid increase" );
CHECK_NEG(m_skid_decrease, "skid decrease" );
CHECK_NEG(m_skid_max, "skid max" );
CHECK_NEG(m_time_till_max_skid, "skid time-till-max" );
CHECK_NEG(m_skid_visual, "skid visual" );
CHECK_NEG(m_skid_visual_time, "skid visual-time" );
CHECK_NEG(m_post_skid_rotate_factor, "skid post-skid-rotate-factor" );
CHECK_NEG(m_skid_reduce_turn_min, "skid reduce-turn-min" );
CHECK_NEG(m_skid_reduce_turn_max, "skid reduce-turn-max" );
if(m_skid_time_till_bonus.size()==0)
fprintf(stderr, "Warning: no skid time declared, can be ignored.\n");
if(m_skid_time_till_bonus.size()!=m_skid_bonus_speed.size())
{
fprintf(stderr, "Warning: skid time-till-bonus and bonus-force\n");
fprintf(stderr, " must have same number of elements.\n");
exit(-1);
}
if(m_skid_time_till_bonus.size()!=m_skid_bonus_time.size())
{
fprintf(stderr, "Warning: skid time-till-bonus and bonus-time must\n");
fprintf(stderr, " have same number of elements.\n");
exit(-1);
}
for(unsigned int i=0; i<m_skid_time_till_bonus.size()-1; i++)
{
if(m_skid_time_till_bonus[i]>=m_skid_time_till_bonus[i+1])
{
fprintf(stderr, "Warning: skid time-till-bonus not sorted.\n");
exit(-1);
}
} // for i
} // check
// ----------------------------------------------------------------------------
void SkiddingProperties::copyFrom(const SkiddingProperties *destination)
{
//memcpy(this, destination, sizeof(SkiddingProperties));
*this = *destination;
} // copyFrom
// ----------------------------------------------------------------------------
/* EOF */

View File

@ -0,0 +1,140 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2012 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_SKIDDING_PROPERTIES_HPP
#define HEADER_SKIDDING_PROPERTIES_HPP
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
class Kart;
class XMLNode;
#include <vector>
/** A simple class that stores all skidding related properties. It acts as
* interface between kart_properties and Skidding (to avoid either passing
* very many individual variables, or making KartProperties a dependency
* of Skidding.
* \ingroup karts
*/
class SkiddingProperties
{
public:
// LEAK_CHECK();
protected:
/** Skidding is multiplied by this when skidding
* to increase to m_skid_increase. */
float m_skid_increase;
/** Skidding is multiplied by this when not skidding to decrease to 1.0. */
float m_skid_decrease;
/** How long it takes for visual skid to reach maximum. */
float m_skid_visual_time;
/** Time till maximum skidding is reached. */
float m_time_till_max_skid;
/** Maximal increase of steering when skidding. */
float m_skid_max;
/** Additional rotation of 3d model when skidding. */
float m_skid_visual;
/** This factor is used to determine how much the chassis of a kart
* should rotate to match the graphical view. A factor of 1 is
* identical, a smaller factor will rotate the kart less (which might
* feel better). */
float m_post_skid_rotate_factor;
/** Time of skidding before you get a bonus boost. It's possible to
* define more than one time, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_time_till_bonus;
/** How much additional speed a kart gets when skidding. It's possible to
* define more than one speed, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_bonus_speed;
/** How long the bonus will last. It's possible to define more than one
* time, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_bonus_time;
/** A factor is used to reduce the amount of steering while skidding. This
* is the minimum factor used (i.e. resulting in the largest turn
* radius). */
float m_skid_reduce_turn_min;
/** A factor is used to reduce the amount of steering while skidding. This
* is the maximum factor used (i.e. resulting in the smallest turn
* radius). */
float m_skid_reduce_turn_max;
/** Kart leaves skid marks. */
bool m_has_skidmarks;
/** Used to check that all values are defined in the xml file. */
static float UNDEFINED;
public:
SkiddingProperties();
void load(const XMLNode *skid_node);
void copyFrom(const SkiddingProperties *destination);
void SkiddingProperties::checkAllSet(const std::string &filename) const;
// ------------------------------------------------------------------------
/** Returns if the kart leaves skidmarks or not. */
bool hasSkidmarks() const { return m_has_skidmarks; }
// ------------------------------------------------------------------------
/** Returns the maximum factor by which the steering angle
* can be increased. */
float getMaxSkid() const {return m_skid_max; }
// ------------------------------------------------------------------------
/** Returns additional rotation of 3d model when skidding. */
float getSkidVisual () const {return m_skid_visual; }
// ------------------------------------------------------------------------
/** Returns the time for the visual skid to reach maximum. */
float getSkidVisualTime () const {return m_skid_visual_time; }
// ------------------------------------------------------------------------
/** Returns a factor to be used to determine how much the chassis of a
* kart should rotate to match the graphical view. A factor of 1 is
* identical, a smaller factor will rotate the kart less (which might
* feel better). */
float getPostSkidRotateFactor () const {return m_post_skid_rotate_factor;}
// ------------------------------------------------------------------------
/** Returns the factor by which to recude the amount of steering while
skidding. */
float getSkidReduceTurnMin () const { return m_skid_reduce_turn_min; }
// ------------------------------------------------------------------------
float getSkidReduceTurnMax () const { return m_skid_reduce_turn_max; }
}; // SkiddingProperties
#endif
/* EOF */