diff --git a/data/stk_config.data b/data/stk_config.data index 7f88640a5..d3cff093c 100644 --- a/data/stk_config.data +++ b/data/stk_config.data @@ -96,6 +96,12 @@ (time-till-max-skid 0.4 ) ;; Time till maximum skidding is reached. (skid-visual 0.16) ;; Additional graphical rotation of kart. + (slipstream-length 5 ) ;; How far behind a kart slipstream works + (slipstream-time 5 ) ;; How many seconds of sstream give + ;; maximum benefit + (slipstream-add-power 3 ) ;; Additional power due to sstreaming. + ;; 1 = +100% + ;; Bullet physics attributes (brake-factor 11.0 ) ;; Defines the smallest turn radius at lowest speed (4.64 m at diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 00148a1c8..99d9e1632 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -71,6 +71,7 @@ Kart::Kart (const std::string& kart_name, int position, m_eliminated = false; m_finished_race = false; m_finish_time = 0.0f; + m_slipstream_time = 0.0f; m_shadow_enabled = false; m_shadow = NULL; m_smoke_system = NULL; @@ -111,6 +112,15 @@ Kart::Kart (const std::string& kart_name, int position, } loadData(); + float l = m_kart_properties->getSlipstreamLength(); + + Vec3 p0(-getKartWidth()*0.5f, -getKartLength()*0.5f, 0); + Vec3 p1(-getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0); + Vec3 p2( getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0); + Vec3 p3( getKartWidth()*0.5f, -getKartLength()*0.5f, 0); + m_slipstream_original_area = new Quad(p0, p1, p2, p3); + m_slipstream_area = new Quad(p0, p1, p2, p3); + reset(); } // Kart @@ -261,6 +271,8 @@ Kart::~Kart() { delete m_kart_chassis.getChildShape(i); } + delete m_slipstream_original_area; + delete m_slipstream_area; } // ~Kart //----------------------------------------------------------------------------- @@ -561,6 +573,7 @@ void Kart::update(float dt) m_water_splash_system->update(dt); m_nitro->update(dt); } // UserConfigParams::m_graphical_effects + updatePhysics(dt); Moveable::update(dt); @@ -723,6 +736,65 @@ float Kart::handleNitro(float dt) } // handleNitro +//----------------------------------------------------------------------------- +/** This function manages slipstreaming. It adds up the time a kart was + * slipstreaming, and returns the potential power boost due to coming + * out of slipstream. + */ +float Kart::handleSlipstream(float dt) +{ + m_slipstream_original_area->transform(getTrans(), m_slipstream_area); + + // Note: there is a slight inconsistency here: Karts are updated one + // after another. So if the position of this kart is compared with the + // slipstream area of a kart already updated, it will use the new + // slipstream area of that kart, but for karts not yet updated the + // old position will be used. The differences should not be noticable, + // and simplifies the update process (which would otherwise have to be + // done in two stages). + unsigned int n = race_manager->getNumKarts(); + bool is_sstreaming = false; + for(unsigned int i=0; igetKart(i); + // Don't test for slipstream with itself. + if(kart==this) continue; + + // Quick test: the kart must be not more than + // slipstream length+kart_length() away from the other kart + Vec3 delta = getXYZ() - kart->getXYZ(); + float l = kart->m_kart_properties->getSlipstreamLength() + kart->getKartLength()*0.5f; + if(delta.length2_2d() > l*l) continue; + + if(kart->m_slipstream_area->pointInQuad(getXYZ())) + { + is_sstreaming = true; + break; + } + } + + float add_power = 0; + + + if(m_slipstream_time >0 && !is_sstreaming) + { + // Kart is using slipstream advantage + add_power = getMaxPower() * m_kart_properties->getSlipstreamAddPower(); + m_slipstream_time = std::max(m_slipstream_time - dt, 0.0f); + printf("Add power %f, t=%f for '%s'\n", m_slipstream_time, add_power, getIdent().c_str()); + } + else if(is_sstreaming) + { + // Kart is collecting sliptstream advantage + m_slipstream_time = std::min(m_slipstream_time + dt, + m_kart_properties->getSlipstreamTime()); + + } + + return add_power; +} // handleSlipstream + + // ----------------------------------------------------------------------------- /** This function is called when the race starts. Up to then all brakes are braking (to avoid the kart from rolling downhill), but they need to be set @@ -766,8 +838,10 @@ void Kart::beep() // ----------------------------------------------------------------------------- void Kart::updatePhysics (float dt) { + m_bounce_back_time-=dt; - float engine_power = getActualWheelForce() + handleNitro(dt); + float engine_power = getActualWheelForce() + handleNitro(dt) + + handleSlipstream(dt); if(m_attachment.getType()==ATTACH_PARACHUTE) engine_power*=0.2f; if(m_controls.m_accel) // accelerating diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 5a420a81b..1c76a4501 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -41,6 +41,7 @@ class SFXBase; class btUprightConstraint; class btKart; class btRaycastVehicle::btVehicleTuning; +class Quad; class Kart : public TerrainInfo, public Moveable { @@ -49,14 +50,14 @@ private: unsigned int m_world_kart_id; // index of kart in world float m_skidding; ///< Accumulated skidding factor. -protected: - Attachment m_attachment; - Powerup m_powerup; - int m_race_position; // current race position (1-numKarts) int m_initial_position; // initial position of kart - - KartControl m_controls; // The position of the karts controls - + int m_race_position; // current race position (1-numKarts) +protected: // Used by the AI atm + KartControl m_controls; // The kart controls (e.g. steering, fire, ...) + Powerup m_powerup; + float m_zipper_time_left; /** 0; } void blockViewWithPlunger() { m_view_blocked_by_plunger = 10; } - /** - returns a bullet transform object located at the kart's position + /** Returns a bullet transform object located at the kart's position and oriented in the direction the kart is going. Can be useful e.g. to calculate the starting point and direction of projectiles */ - btTransform getKartHeading (const float customPitch=-1); + btTransform getKartHeading (const float customPitch=-1); // Functions to access the current kart properties (which might get changed, diff --git a/src/karts/kart_properties.cpp b/src/karts/kart_properties.cpp index be36c3523..687f0a502 100644 --- a/src/karts/kart_properties.cpp +++ b/src/karts/kart_properties.cpp @@ -65,7 +65,8 @@ KartProperties::KartProperties() : m_icon_material(0) m_rubber_band_duration = m_time_till_max_skid = m_skid_decrease = m_skid_increase = m_skid_visual = m_skid_max = m_camera_max_accel = m_camera_max_brake = - m_camera_distance = UNDEFINED; + m_slipstream_length = m_slipstream_time = m_slipstream_add_power = + m_camera_distance = UNDEFINED; m_gravity_center_shift = Vec3(UNDEFINED); m_has_skidmarks = true; m_version = 0; @@ -260,6 +261,9 @@ void KartProperties::getAllData(const lisp::Lisp* lisp) lisp->get("has-skidmarks", m_has_skidmarks ); lisp->get("skid-max", m_skid_max ); lisp->get("skid-visual", m_skid_visual ); + lisp->get("slipstream-length", m_slipstream_length ); + lisp->get("slipstream-time", m_slipstream_time ); + lisp->get("slipstream-add-power", m_slipstream_add_power ); lisp->getVector("groups", m_groups ); @@ -348,6 +352,9 @@ void KartProperties::checkAllSet(const std::string &filename) CHECK_NEG(m_skid_increase, "skid-increase" ); CHECK_NEG(m_skid_max, "skid-max" ); CHECK_NEG(m_skid_visual, "skid-visual" ); + CHECK_NEG(m_slipstream_length, "slipstream-length" ); + CHECK_NEG(m_slipstream_time, "slipstream-time" ); + CHECK_NEG(m_slipstream_add_power, "slipstream-add-power" ); CHECK_NEG(m_camera_max_accel, "camera-max-accel" ); CHECK_NEG(m_camera_max_brake, "camera-max-brake" ); diff --git a/src/karts/kart_properties.hpp b/src/karts/kart_properties.hpp index 6a60d9267..884e9595e 100644 --- a/src/karts/kart_properties.hpp +++ b/src/karts/kart_properties.hpp @@ -126,6 +126,11 @@ private: float m_skid_visual; /**< Additional rotation of 3d model * when skidding. */ + float m_slipstream_length; /**< How far behind a kart slipstreaming + * is effective. */ + float m_slipstream_time; /**< Time after which sstream has maxium + * benefit. */ + float m_slipstream_add_power; /**< Additional power due to sstreaming. */ float m_skid_max; /**< Maximal increase of steering when * skidding. */ float m_skid_increase; /**< Skidding is multiplied by this when @@ -217,6 +222,12 @@ public: float getRubberBandDuration () const {return m_rubber_band_duration; } /** Returns additional rotation of 3d model when skidding. */ float getSkidVisual () const {return m_skid_visual; } + /** Returns how far behind a kart slipstreaming works. */ + float getSlipstreamLength () const {return m_slipstream_length; } + /** Returns time after which slipstream has maximum effect. */ + float getSlipstreamTime () const {return m_slipstream_time; } + /** Returns additional power due to slipstreaming. */ + float getSlipstreamAddPower () const {return m_slipstream_add_power; } /** Returns the maximum factor by which the steering angle can be increased. */ float getMaxSkid () const {return m_skid_max; } /** Returns the factor by which m_skidding is multiplied when the kart is diff --git a/src/robots/default_robot.cpp b/src/robots/default_robot.cpp index 51897ed68..51f8688c4 100644 --- a/src/robots/default_robot.cpp +++ b/src/robots/default_robot.cpp @@ -621,7 +621,7 @@ void DefaultRobot::handleAcceleration( const float DELTA ) //Find if any player is ahead of this kart bool player_winning = false; for(unsigned int i = 0; i < race_manager->getNumPlayers(); ++i ) - if( m_race_position > RaceManager::getPlayerKart(i)->getPosition() ) + if( getPosition() > RaceManager::getPlayerKart(i)->getPosition() ) { player_winning = true; break; diff --git a/src/tracks/quad.cpp b/src/tracks/quad.cpp index 1b1bdea85..71a8cc24f 100644 --- a/src/tracks/quad.cpp +++ b/src/tracks/quad.cpp @@ -21,6 +21,8 @@ #include "irrlicht.h" +#include "LinearMath/btTransform.h" + /** Constructor, takes 4 points. */ Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3) { @@ -35,7 +37,7 @@ Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3) * \param v The vertex array in which to set the vertices. * \param color The color to use for this quad. */ -void Quad::setVertices(video::S3DVertex *v, const video::SColor &color) const +void Quad::getVertices(video::S3DVertex *v, const video::SColor &color) const { // Eps is used to raise the track debug quads a little bit higher than // the ground, so that they are actually visible. @@ -86,4 +88,20 @@ bool Quad::pointInQuad(const Vec3& p) const sideOfLine2D(m_p[3], m_p[0], p) >= 0.0; } } // pointInQuad +// ---------------------------------------------------------------------------- +/** Transforms a quad by a given transform (i.e. translation+rotation). This + * function does not modify this quad, the results are stored in the quad + * specified as parameter. These functions are used for slipstreaming to + * determine the slipstream area from the original value (kart at 0,0,0 and + * no rotation) to the current value. + * \param t The transform to apply. + * \param result The quad which stores the result. + */ +void Quad::transform(const btTransform &t, Quad *result) const +{ + result->m_p[0] = t(m_p[0]); + result->m_p[1] = t(m_p[1]); + result->m_p[2] = t(m_p[2]); + result->m_p[3] = t(m_p[3]); +} // transform diff --git a/src/tracks/quad.hpp b/src/tracks/quad.hpp index 204f09e08..033373959 100644 --- a/src/tracks/quad.hpp +++ b/src/tracks/quad.hpp @@ -26,6 +26,7 @@ #include "utils/vec3.hpp" +class btTransform; class Quad { private: @@ -43,9 +44,9 @@ private: public: Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3); - void setVertices(video::S3DVertex *v, const video::SColor &color) const; + void getVertices(video::S3DVertex *v, const video::SColor &color) const; bool pointInQuad(const Vec3& p) const; - + void transform(const btTransform &t, Quad *result) const; // ------------------------------------------------------------------------ /** Returns the i-th. point of a quad. */ const Vec3& operator[](int i) const {return m_p[i]; } @@ -54,6 +55,6 @@ public: const Vec3& getCenter () const {return m_center; } // ------------------------------------------------------------------------ /** Returns the minimum height of a quad. */ - float getMinHeight() const { return m_min_height; } + float getMinHeight() const { return m_min_height; } }; // class Quad #endif diff --git a/src/tracks/quad_graph.cpp b/src/tracks/quad_graph.cpp index fbeece944..a50c56691 100644 --- a/src/tracks/quad_graph.cpp +++ b/src/tracks/quad_graph.cpp @@ -187,7 +187,7 @@ void QuadGraph::createMesh() c.setRed (i%2 ? 255 : 0); c.setBlue(i%2 ? 0 : 255); // Transfer the 4 points of the current quad to the list of vertices - m_all_quads->getQuad(i).setVertices(new_v+4*i, c); + m_all_quads->getQuad(i).getVertices(new_v+4*i, c); // Set up the indices for the triangles // (note, afaik with opengl we could use quads directly, but the code