diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index eec80719e..a3451e1e1 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -630,13 +630,18 @@ void Kart::handleZipper() // Ignore a zipper that's activated while braking if(m_controls.m_brake) return; m_zipper_time_left = stk_config->m_zipper_time; - const btVector3& v = m_body->getLinearVelocity(); + btVector3 v = m_body->getLinearVelocity(); float current_speed = v.length(); float speed = std::min(current_speed+stk_config->m_zipper_speed_gain, getMaxSpeed()); - // Avoid NAN problems, which can happen if e.g. a kart is rescued on - // top of zipper, and then dropped. - if(current_speed>0.00001) m_body->setLinearVelocity(v*(speed/current_speed)); + // If the speed is too low, very minor components of the velocity vector + // can become too big. E.g. each kart has a z component (to offset gravity + // I assume, around 0.16) --> if the karts are (nearly) at standstill, + // the z component is exaggerated, resulting in a jump. Even if Z + // is set to 0, minor left/right movements are then too strong. + // Therefore a zipper only adds the speed if the speed is at least 1 + // (experimentally found valud). It also avoids NAN problems (if v=0). + if(current_speed>1.0f) m_body->setLinearVelocity(v*(speed/current_speed)); } // handleZipper //----------------------------------------------------------------------------- #define sgn(x) ((x<0)?-1.0f:((x>0)?1.0f:0.0f)) diff --git a/src/robots/default_robot.cpp b/src/robots/default_robot.cpp index ec42f6322..8bb732bd6 100755 --- a/src/robots/default_robot.cpp +++ b/src/robots/default_robot.cpp @@ -174,10 +174,18 @@ void DefaultRobot::update(float dt) handleNitroAndZipper(); // If we are supposed to use nitro, but have a zipper, // use the zipper instead - if(m_controls.m_nitro && m_powerup.getType()==POWERUP_ZIPPER) + if(m_controls.m_nitro && m_powerup.getType()==POWERUP_ZIPPER && + getSpeed()>1.0f && m_zipper_time_left<=0) { - m_controls.m_nitro = false; - m_controls.m_fire = true; + // Make sure that not all AI karts use the zipper at the same + // time in time trial at start up, so during the first 5 seconds + // this is done at random only. + if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_TIME_TRIAL || + (m_world->getTime()<3.0f && rand()%50==1) ) + { + m_controls.m_nitro = false; + m_controls.m_fire = true; + } } /*And obviously general kart stuff*/