From 921c2621dc04fb04fc85afe4929e039c623614b5 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Tue, 21 Aug 2007 14:50:45 +0000 Subject: [PATCH] 1) Fixed incorrect pitch of rockets when firing. 2) The 'unlimited rocket' cheat is now bound to F7 (before it was a clear key, which isn't available on all keyboards - at least not on mine). Bullet only: 3) Gear parameters are now configureable and can be specified in stk_config.data and separately for each kart. 4) An explosion will somewhat push other karts that are close by away (some feedback on this feature is welcome - the impulse can be set in the stk_config file). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1214 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- configure.ac | 2 +- data/stk_config.data | 9 +++++++ data/tuxkart.tkkf | 1 - src/gui/race_gui.cpp | 2 +- src/kart.cpp | 60 ++++++++++++++++++++++++----------------- src/kart.hpp | 2 +- src/kart_properties.cpp | 11 ++++++++ src/kart_properties.hpp | 14 ++++++++++ src/moveable.hpp | 1 + src/projectile.cpp | 42 ++++++++++++++++++++++------- src/projectile.hpp | 4 +-- src/stk_config.cpp | 25 ++++++++++++++--- src/stk_config.hpp | 1 + 13 files changed, 132 insertions(+), 42 deletions(-) diff --git a/configure.ac b/configure.ac index 7e31ef6be..e16cad87b 100644 --- a/configure.ac +++ b/configure.ac @@ -138,7 +138,7 @@ case "${host}" in # include # define MIN_ALUT_VERSION 1 int main() { - if(alutGetMajorVersion() gear 1, + ;; 0.5 means: if speed <=0.5 *maxSpeed --> gear 2 + ;; The next vector contains the increase in max power (to simulate different + ;; gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1 + (gear-switch-ratio 0.25 0.5 0.75) + (gear-power-increase 2.5 1.8 1.4 ) ) ;; end kart-defaults ) diff --git a/data/tuxkart.tkkf b/data/tuxkart.tkkf index 2525a3ea3..c70838686 100644 --- a/data/tuxkart.tkkf +++ b/data/tuxkart.tkkf @@ -9,6 +9,5 @@ (red 0.7) (green 0.0) (blue 0.0) - ) ;; EOF ;; diff --git a/src/gui/race_gui.cpp b/src/gui/race_gui.cpp index 1aaed5c91..98570c10c 100644 --- a/src/gui/race_gui.cpp +++ b/src/gui/race_gui.cpp @@ -168,7 +168,7 @@ void RaceGUI::inputKeyboard(int key, int pressed) static int isWireframe = false ; switch ( key ) { - case 0x12: // TODO: Which key is that? + case SDLK_F7: if(world->m_race_setup.getNumPlayers()==1) { // ctrl-r Kart* kart = world->getPlayerKart(0); diff --git a/src/kart.cpp b/src/kart.cpp index a458fee0f..b74b7d89d 100644 --- a/src/kart.cpp +++ b/src/kart.cpp @@ -571,41 +571,53 @@ void Kart::doZipperProcessing (float delta) //----------------------------------------------------------------------------- float Kart::getActualWheelForce() { - if ( m_speed <= m_max_speed*0.25f ) + const std::vector& gear_ratio=m_kart_properties->getGearSwitchRatio(); + for(unsigned int i=0; igetGearPowerIncrease()[i]; } - else if ( m_speed > m_max_speed*0.25f && m_speed <= m_max_speed*0.5f ) - { - return( getMaxPower() * 1.8f ); // gear 2 - } - else if ( m_speed > m_max_speed*0.5f && m_speed <= m_max_speed*0.75f ) - { - return( getMaxPower() * 1.4f ); // gear 3 - } - else if ( m_speed > m_max_speed*0.75f ) - { - return( getMaxPower() ); // gear 4 - } - return(0.0f); -} + return getMaxPower(); + +} // getActualWheelForce #endif //----------------------------------------------------------------------------- -void Kart::getsProjectile () +void Kart::handleExplosion(const sgVec3& pos, bool direct_hit) { #ifdef BULLET - btVector3 velocity = m_kart_body->getLinearVelocity(); + if(direct_hit) { + btVector3 velocity = m_kart_body->getLinearVelocity(); - velocity.setX( 0.0f ); - velocity.setY( 0.0f ); - velocity.setZ( 3.5f ); + velocity.setX( 0.0f ); + velocity.setY( 0.0f ); + velocity.setZ( 3.5f ); + + getVehicle()->getRigidBody()->setLinearVelocity( velocity ); + } + else // only affected by a distant explosion + { + sgVec3 diff; + sgSubVec3(diff, getCoord()->xyz, pos); + float len2=sgLengthSquaredVec3(diff); + + // The correct forumale would be to first normalise diff, + // then apply the impulse (which decreases 1/r^2 depending + // on the distance r), so: + // diff/len(diff) * impulseSize/len(diff)^2 + // = diff*impulseSize/len(diff)^3 + // We use diff*impulseSize/len(diff)^2 here, this makes the impulse + // somewhat larger, which is actually more fun :) + sgScaleVec3(diff,stk_config->m_explosion_impulse/len2); + btVector3 impulse(diff[0],diff[1], diff[2]); + getVehicle()->getRigidBody()->applyCentralImpulse(impulse); + } - getVehicle()->getRigidBody()->setLinearVelocity( velocity ); #else - forceCrash(); + // only the kart hit directly is affected. + if(direct_hit) forceCrash(); #endif -} +} // handleExplosion //----------------------------------------------------------------------------- void Kart::forceCrash () diff --git a/src/kart.hpp b/src/kart.hpp index ac5fc1fbe..f3d164a09 100644 --- a/src/kart.hpp +++ b/src/kart.hpp @@ -244,6 +244,7 @@ public: #endif void adjustSpeedWeight(float f); void forceRescue (); + void handleExplosion (const sgVec3& pos, bool direct_hit); const std::string& getName () const {return m_kart_properties->getName();} virtual int isPlayerKart () const {return 0; } // addMessages gets called by world to add messages to the gui @@ -257,7 +258,6 @@ public: virtual void doCollisionAnalysis(float dt, float hot ); virtual void doObjectInteractions(); virtual void OutsideTrack (int isReset) {m_rescue=true;} - virtual void getsProjectile (); }; class TrafficDriver : public Kart diff --git a/src/kart_properties.cpp b/src/kart_properties.cpp index f717a9f15..6a1fad1a2 100644 --- a/src/kart_properties.cpp +++ b/src/kart_properties.cpp @@ -160,6 +160,15 @@ void KartProperties::getAllData(const lisp::Lisp* lisp) lisp->get("maximum-speed", m_maximum_speed ); lisp->get("gravity-center-shift", m_gravity_center_shift ); lisp->get("suspension-rest", m_suspension_rest ); +#ifdef BULLET + // getVector appends to existing vectors, so a new one must be used to load + std::vector temp; + lisp->getVector("gear-switch-ratio", temp); + if(temp.size()>0) m_gear_switch_ratio = temp; + temp.clear(); + lisp->getVector("gear-power-increase", temp); + if(temp.size()>0) m_gear_power_increase = temp; +#endif } // getAllData @@ -215,6 +224,8 @@ void KartProperties::init_defaults() m_max_speed_reverse_ratio = stk_config->m_max_speed_reverse_ratio; m_gravity_center_shift = stk_config->m_gravity_center_shift; m_suspension_rest = stk_config->m_suspension_rest; + m_gear_switch_ratio = stk_config->m_gear_switch_ratio; + m_gear_power_increase = stk_config->m_gear_power_increase; } // init_defaults diff --git a/src/kart_properties.hpp b/src/kart_properties.hpp index d020d20be..5ac06de64 100644 --- a/src/kart_properties.hpp +++ b/src/kart_properties.hpp @@ -21,6 +21,7 @@ #define HEADER_KARTPROPERTIES_H #include +#include #include "lisp/lisp.hpp" #include "no_copy.hpp" @@ -89,6 +90,15 @@ protected: float m_max_speed_reverse_ratio; float m_gravity_center_shift; float m_suspension_rest; + // The following two vectors define at what ratio of the maximum speed what + // gear is selected, e.g. 0.25 means: if speed <=0.25*maxSpeed --> gear 1, + // 0.5 means: if speed <=0.5 *maxSpeed --> gear 2 + // The next vector contains the increase in max power (to simulate different + // gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1 + std::vector m_gear_switch_ratio; + std::vector m_gear_power_increase; + + public: KartProperties (); virtual ~KartProperties (); @@ -145,6 +155,10 @@ public: float getMaximumSpeed () const {return m_maximum_speed; } float getGravityCenterShift () const {return m_gravity_center_shift; } float getSuspensionRest () const {return m_suspension_rest; } + const std::vector& + getGearSwitchRatio () const {return m_gear_switch_ratio; } + const std::vector& + getGearPowerIncrease () const {return m_gear_power_increase; } }; #endif diff --git a/src/moveable.hpp b/src/moveable.hpp index a57f9196c..087acf1a0 100644 --- a/src/moveable.hpp +++ b/src/moveable.hpp @@ -68,6 +68,7 @@ public: int isOnGround () {return m_on_ground; } sgCoord* getVelocity () {return & m_velocity; } sgCoord* getCoord () {return &m_curr_pos; } + const sgVec4* getNormalHOT () const {return m_normal_hot; } void setCoord (sgCoord* pos) {sgCopyCoord ( &m_curr_pos,pos); } virtual void placeModel () {m_model->setTransform(&m_curr_pos); } virtual void handleZipper () {}; diff --git a/src/projectile.cpp b/src/projectile.cpp index a3857a3d3..84ce9d6d0 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -42,7 +42,28 @@ void Projectile::init(Kart *kart, int collectable_) m_speed = collectable_manager->getSpeed(m_type); ssgTransform *m = getModel(); m->addKid(collectable_manager->getModel(m_type)); - setCoord(kart->getCoord()); + + sgCoord c; + sgCopyCoord(&c, kart->getCoord()); + const float angle_terrain = c.hpr[0]*M_PI/180.0f; + // The projectile should have the pitch of the terrain on which the kart + // is - while this is not really realistic, it plays much better this way + const sgVec4* normal = kart->getNormalHOT(); + if(normal) + { + const float X = -sin(angle_terrain); + const float Y = cos(angle_terrain); + // Compute the angle between the normal of the plane and the line to + // (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane, + // simplifying the computation of the scalar product. + float pitch = ( (*normal)[0]*X + (*normal)[1]*Y ); // use ( x,y,0) + + // The actual angle computed above is between the normal and the (x,y,0) + // line, so to compute the actual angles 90 degrees must be subtracted. + c.hpr[1] = acosf(pitch)/M_PI*180.0f-90.0f; + } + + setCoord(&c); scene->add(m); } // init @@ -80,12 +101,7 @@ void Projectile::doObjectInteractions () if ( D < 2.0f ) { - explode(); -#ifdef BULLET - kart -> getsProjectile () ; -#else - kart -> forceCrash () ; -#endif + explode(kart); return; } else if ( D < ndist ) @@ -176,13 +192,13 @@ void Projectile::doCollisionAnalysis ( float dt, float hot ) } else if ( m_type != COLLECT_NOTHING ) { - explode(); + explode(NULL); // no kart was hit directly } } // if m_collided||m_crashed } // doCollisionAnalysis //----------------------------------------------------------------------------- -void Projectile::explode() +void Projectile::explode(Kart *kart_hit) { m_has_hit_something=true; m_curr_pos.xyz[2] += 1.2f ; @@ -196,6 +212,14 @@ void Projectile::explode() ssgTransform *m = getModel(); m->removeAllKids(); scene->remove(m); + + for ( unsigned int i = 0 ; i < world->getNumKarts() ; i++ ) + { + Kart *kart = world -> getKart(i); + // handle the actual explosion. Set a flag it if was a direct hit. + kart->handleExplosion(m_curr_pos.xyz, kart==kart_hit); + } + } // explode /* EOF */ diff --git a/src/projectile.hpp b/src/projectile.hpp index 8607c714f..a2ea9b87f 100644 --- a/src/projectile.hpp +++ b/src/projectile.hpp @@ -41,14 +41,14 @@ public: void update (float); void doCollisionAnalysis (float dt, float hot); void doObjectInteractions(); - void explode (); + void explode (Kart* kart); bool hasHit () {return m_has_hit_something;} void reset () { Moveable::reset(); sgCopyCoord(&m_last_pos,&m_reset_pos ); } - void OutsideTrack (int isReset) {explode();} + void OutsideTrack (int isReset) {explode(NULL);} } ; diff --git a/src/stk_config.cpp b/src/stk_config.cpp index d70fb4503..19e2388f1 100644 --- a/src/stk_config.cpp +++ b/src/stk_config.cpp @@ -34,7 +34,25 @@ void STKConfig::load(const std::string filename) fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \ strA,filename.c_str());exit(-1); \ } - +#ifdef BULLET + if(m_gear_switch_ratio.size()==0) + { + fprintf(stderr,"Missing default value for 'gear-switch-ratio' in '%s'.\n", + filename.c_str()); + exit(-1); + } + if(m_gear_power_increase.size()==0) + { + fprintf(stderr,"Missing default value for 'gear-power-increase' in '%s'.\n", + filename.c_str()); + exit(-1); + } + if(m_gear_switch_ratio.size()!=m_gear_power_increase.size()) { + fprintf(stderr,"Number of entries for 'gear-switch-ratio' and 'gear-power-increase"); + fprintf(stderr,"in '%s' must be equal.\n", filename.c_str()); + exit(-1); + } +#endif CHECK_NEG(m_corn_r, "m_corn_r" ); CHECK_NEG(m_corn_f, "m_corn_f" ); @@ -91,7 +109,7 @@ void STKConfig::load(const std::string filename) CHECK_NEG(m_max_road_distance, "shortcut-road-distance" ); CHECK_NEG(m_shortcut_segments, "shortcut-skipped-segments" ); CHECK_NEG(m_suspension_rest, "suspension-rest" ); - + CHECK_NEG(m_explosion_impulse, "explosion-impulse" ); // Precompute some handy values to reduce work later m_magnet_range_sq = m_magnet_range_sq * m_magnet_range_sq; @@ -119,7 +137,7 @@ void STKConfig::init_defaults() m_wheelie_lean_recovery = m_wheelie_step = m_wheelie_balance_recovery = m_wheelie_power_boost = m_chassis_linear_damping = m_chassis_angular_damping = m_maximum_speed = m_brake_force = m_gravity_center_shift = m_suspension_rest = - m_max_speed_reverse_ratio = -99.9f; + m_max_speed_reverse_ratio = m_explosion_impulse = -99.9f; m_air_res_reduce[0] = 1.0f; } // init_defaults @@ -146,6 +164,7 @@ void STKConfig::getAllData(const lisp::Lisp* lisp) lisp->get("bomb-time", m_bomb_time ); lisp->get("bomb-time-increase", m_bomb_time_increase ); lisp->get("anvil-time", m_anvil_time ); + lisp->get("explosion-impulse", m_explosion_impulse ); // Get the default KartProperties // ------------------------------ diff --git a/src/stk_config.hpp b/src/stk_config.hpp index f8d1af425..d42fc20ee 100644 --- a/src/stk_config.hpp +++ b/src/stk_config.hpp @@ -42,6 +42,7 @@ public: float m_max_road_distance; // max distance from road to be still ON road float m_shortcut_segments; // skipping more than this number of segments is // considered to be a shortcut + float m_explosion_impulse; // impulse affecting each non-hit kart STKConfig() : KartProperties() {}; void init_defaults ();