2007-05-27 16:01:53 +00:00
|
|
|
// $Id$
|
|
|
|
//
|
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
|
|
|
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
|
|
|
|
// Copyright (C) 2006 SuperTuxKart-Team, Joerg Henrichs, Steve Baker
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
2008-06-13 00:53:52 +00:00
|
|
|
// as published by the Free Software Foundation; either version 3
|
2007-05-27 16:01:53 +00:00
|
|
|
// 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.
|
2008-09-07 14:55:05 +00:00
|
|
|
|
2008-11-07 04:34:01 +00:00
|
|
|
#include "karts/kart.hpp"
|
|
|
|
|
2008-01-25 01:29:12 +00:00
|
|
|
#include <math.h>
|
2007-05-27 16:01:53 +00:00
|
|
|
#include <iostream>
|
2008-09-18 03:24:19 +00:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
# define snprintf _snprintf
|
|
|
|
#endif
|
|
|
|
|
2008-09-07 14:42:37 +00:00
|
|
|
#define _WINSOCKAPI_
|
2007-05-27 16:01:53 +00:00
|
|
|
#include <plib/ssg.h>
|
|
|
|
|
2008-09-07 14:55:05 +00:00
|
|
|
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 13:52:48 +00:00
|
|
|
#include "loader.hpp"
|
2008-10-29 01:45:29 +00:00
|
|
|
#include "items/item_manager.hpp"
|
2008-03-01 03:18:53 +00:00
|
|
|
#include "file_manager.hpp"
|
2007-05-27 16:01:53 +00:00
|
|
|
#include "user_config.hpp"
|
|
|
|
#include "constants.hpp"
|
|
|
|
#include "shadow.hpp"
|
|
|
|
#include "track.hpp"
|
|
|
|
#include "translation.hpp"
|
2008-04-18 06:26:36 +00:00
|
|
|
#include "material_manager.hpp"
|
2008-09-18 03:24:19 +00:00
|
|
|
#include "audio/sound_manager.hpp"
|
|
|
|
#include "audio/sfx_manager.hpp"
|
|
|
|
#include "audio/sfx_base.hpp"
|
2008-12-01 09:26:25 +00:00
|
|
|
#include "graphics/nitro.hpp"
|
2008-12-02 13:01:39 +00:00
|
|
|
#include "graphics/skid_marks.hpp"
|
2008-12-01 22:56:57 +00:00
|
|
|
#include "graphics/smoke.hpp"
|
2008-11-07 01:05:52 +00:00
|
|
|
#include "gui/menu_manager.hpp"
|
|
|
|
#include "gui/race_gui.hpp"
|
|
|
|
#include "karts/kart_model.hpp"
|
2008-11-07 04:34:01 +00:00
|
|
|
#include "karts/kart_properties_manager.hpp"
|
2008-09-07 14:42:37 +00:00
|
|
|
#include "network/race_state.hpp"
|
2008-09-07 14:55:05 +00:00
|
|
|
#include "network/network_manager.hpp"
|
2008-11-07 01:05:52 +00:00
|
|
|
#include "physics/physics.hpp"
|
2008-12-01 22:43:50 +00:00
|
|
|
#include "utils/coord.hpp"
|
2008-09-19 06:07:29 +00:00
|
|
|
#include "utils/ssg_help.hpp"
|
2008-11-08 20:35:45 +00:00
|
|
|
#include "audio/sfx_manager.hpp"
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2007-12-11 02:48:10 +00:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
// Disable warning for using 'this' in base member initializer list
|
|
|
|
# pragma warning(disable:4355)
|
|
|
|
#endif
|
2008-10-06 13:40:11 +00:00
|
|
|
|
|
|
|
Kart::Kart (const std::string& kart_name, int position,
|
|
|
|
const btTransform& init_transform)
|
|
|
|
: TerrainInfo(1),
|
2008-10-30 02:02:56 +00:00
|
|
|
Moveable(), m_attachment(this), m_powerup(this)
|
2008-10-06 13:40:11 +00:00
|
|
|
|
2007-12-11 02:48:10 +00:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
# pragma warning(1:4355)
|
|
|
|
#endif
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 13:52:48 +00:00
|
|
|
m_kart_properties = kart_properties_manager->getKart(kart_name);
|
2008-06-20 09:34:35 +00:00
|
|
|
m_initial_position = position;
|
2008-11-24 23:19:47 +00:00
|
|
|
m_collected_energy = 0;
|
2008-04-15 13:57:18 +00:00
|
|
|
m_eliminated = false;
|
2007-05-27 16:01:53 +00:00
|
|
|
m_finished_race = false;
|
|
|
|
m_finish_time = 0.0f;
|
2009-01-16 00:37:31 +00:00
|
|
|
m_shadow_enabled = false;
|
|
|
|
m_shadow = NULL;
|
2007-05-27 16:01:53 +00:00
|
|
|
m_smoke_system = NULL;
|
2008-12-01 09:26:25 +00:00
|
|
|
m_nitro = NULL;
|
2008-12-02 13:01:39 +00:00
|
|
|
m_skidmarks = NULL;
|
2008-06-20 09:34:35 +00:00
|
|
|
|
2008-12-26 20:45:56 +00:00
|
|
|
m_view_blocked_by_plunger = 0;
|
2008-12-26 20:12:57 +00:00
|
|
|
|
2008-06-20 09:34:35 +00:00
|
|
|
// Set position and heading:
|
|
|
|
m_reset_transform = init_transform;
|
2008-05-20 03:33:48 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
// Neglecting the roll resistance (which is small for high speeds compared
|
|
|
|
// to the air resistance), maximum speed is reached when the engine
|
|
|
|
// power equals the air resistance force, resulting in this formula:
|
2008-12-11 10:47:16 +00:00
|
|
|
m_max_speed = m_kart_properties->getMaxSpeed();
|
2007-08-17 17:07:12 +00:00
|
|
|
m_max_speed_reverse_ratio = m_kart_properties->getMaxSpeedReverseRatio();
|
|
|
|
m_speed = 0.0f;
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-02-12 00:10:05 +00:00
|
|
|
// Setting rescue to false is important! If rescue is set when reset() is
|
|
|
|
// called, it is assumed that this was triggered by a restart, and that
|
|
|
|
// the vehicle must be added back to the physics world. Since reset() is
|
|
|
|
// also called at the very start, it must be guaranteed that rescue is
|
|
|
|
// not set.
|
|
|
|
m_rescue = false;
|
|
|
|
m_wheel_rotation = 0;
|
|
|
|
|
2008-11-20 09:11:27 +00:00
|
|
|
m_engine_sound = sfx_manager->newSFX(m_kart_properties->getEngineSfxType());
|
|
|
|
m_beep_sound = sfx_manager->newSFX( SFXManager::SOUND_BEEP );
|
|
|
|
m_crash_sound = sfx_manager->newSFX( SFXManager::SOUND_CRASH );
|
|
|
|
m_skid_sound = sfx_manager->newSFX( SFXManager::SOUND_SKID );
|
2008-12-30 01:07:22 +00:00
|
|
|
m_goo_sound = sfx_manager->newSFX( SFXManager::SOUND_GOO );
|
|
|
|
|
2008-09-18 03:24:19 +00:00
|
|
|
if(!m_engine_sound)
|
|
|
|
{
|
|
|
|
fprintf(stdout, "Error: Could not allocate a sfx object for the kart. Further errors may ensue!\n");
|
|
|
|
}
|
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
loadData();
|
2008-06-20 09:34:35 +00:00
|
|
|
reset();
|
2007-05-27 16:01:53 +00:00
|
|
|
} // Kart
|
|
|
|
|
2008-07-21 01:55:41 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
2008-09-01 15:39:17 +00:00
|
|
|
btTransform Kart::getKartHeading(const float customPitch)
|
2008-07-21 01:55:41 +00:00
|
|
|
{
|
|
|
|
btTransform trans = this->getTrans();
|
|
|
|
|
|
|
|
// get heading=trans.getBasis*(0,1,0) ... so save the multiplication:
|
|
|
|
btVector3 direction(trans.getBasis()[0][1],
|
|
|
|
trans.getBasis()[1][1],
|
|
|
|
trans.getBasis()[2][1]);
|
|
|
|
float heading=atan2(-direction.getX(), direction.getY());
|
|
|
|
|
|
|
|
TerrainInfo::update(this->getXYZ());
|
2008-09-01 15:39:17 +00:00
|
|
|
float pitch = (customPitch == -1 ? getTerrainPitch(heading) : customPitch);
|
2008-07-21 01:55:41 +00:00
|
|
|
|
|
|
|
btMatrix3x3 m;
|
|
|
|
m.setEulerZYX(pitch, 0.0f, heading);
|
|
|
|
trans.setBasis(m);
|
|
|
|
|
|
|
|
return trans;
|
2008-09-20 14:23:20 +00:00
|
|
|
} // getKartHeading
|
2008-07-21 01:55:41 +00:00
|
|
|
|
2008-09-20 14:23:20 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-11-07 01:05:52 +00:00
|
|
|
void Kart::createPhysics()
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
|
|
|
// First: Create the chassis of the kart
|
|
|
|
// -------------------------------------
|
2008-11-07 01:05:52 +00:00
|
|
|
const KartModel *km = m_kart_properties->getKartModel();
|
|
|
|
float kart_width = km->getWidth();
|
|
|
|
float kart_length = km->getLength();
|
|
|
|
float kart_height = km->getHeight();
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2007-11-03 13:13:26 +00:00
|
|
|
btBoxShape *shape = new btBoxShape(btVector3(0.5f*kart_width,
|
2008-04-29 03:29:28 +00:00
|
|
|
0.5f*kart_length,
|
|
|
|
0.5f*kart_height));
|
2007-05-27 16:01:53 +00:00
|
|
|
btTransform shiftCenterOfGravity;
|
|
|
|
shiftCenterOfGravity.setIdentity();
|
|
|
|
// Shift center of gravity downwards, so that the kart
|
2008-07-17 01:33:49 +00:00
|
|
|
// won't topple over too easy.
|
|
|
|
shiftCenterOfGravity.setOrigin(getGravityCenterShift());
|
2007-11-08 22:40:15 +00:00
|
|
|
m_kart_chassis.addChildShape(shiftCenterOfGravity, shape);
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
// Set mass and inertia
|
|
|
|
// --------------------
|
|
|
|
float mass=getMass();
|
|
|
|
|
|
|
|
// Position the chassis
|
|
|
|
// --------------------
|
|
|
|
btTransform trans;
|
|
|
|
trans.setIdentity();
|
2008-01-30 05:30:10 +00:00
|
|
|
createBody(mass, trans, &m_kart_chassis);
|
2008-02-05 11:56:21 +00:00
|
|
|
m_user_pointer.set(this);
|
2007-09-30 14:17:28 +00:00
|
|
|
m_body->setDamping(m_kart_properties->getChassisLinearDamping(),
|
|
|
|
m_kart_properties->getChassisAngularDamping() );
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
// Reset velocities
|
|
|
|
// ----------------
|
2007-09-30 14:17:28 +00:00
|
|
|
m_body->setLinearVelocity (btVector3(0.0f,0.0f,0.0f));
|
|
|
|
m_body->setAngularVelocity(btVector3(0.0f,0.0f,0.0f));
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
// Create the actual vehicle
|
|
|
|
// -------------------------
|
|
|
|
m_vehicle_raycaster =
|
2008-09-21 16:07:56 +00:00
|
|
|
new btDefaultVehicleRaycaster(RaceManager::getWorld()->getPhysics()->getPhysicsWorld());
|
2008-10-16 00:20:49 +00:00
|
|
|
m_tuning = new btKart::btVehicleTuning();
|
2008-11-28 03:44:41 +00:00
|
|
|
m_tuning->m_maxSuspensionTravelCm = m_kart_properties->getSuspensionTravelCM();
|
2008-10-16 23:49:27 +00:00
|
|
|
m_vehicle = new btKart(*m_tuning, m_body, m_vehicle_raycaster,
|
|
|
|
m_kart_properties->getTrackConnectionAccel());
|
2007-11-03 13:13:26 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
// never deactivate the vehicle
|
2007-09-30 14:17:28 +00:00
|
|
|
m_body->setActivationState(DISABLE_DEACTIVATION);
|
2007-05-27 16:01:53 +00:00
|
|
|
m_vehicle->setCoordinateSystem(/*right: */ 0, /*up: */ 2, /*forward: */ 1);
|
|
|
|
|
|
|
|
// Add wheels
|
|
|
|
// ----------
|
2008-07-17 01:33:49 +00:00
|
|
|
float wheel_radius = m_kart_properties->getWheelRadius();
|
2007-08-16 07:09:26 +00:00
|
|
|
float suspension_rest = m_kart_properties->getSuspensionRest();
|
2008-11-07 01:05:52 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
btVector3 wheel_direction(0.0f, 0.0f, -1.0f);
|
|
|
|
btVector3 wheel_axle(1.0f,0.0f,0.0f);
|
|
|
|
|
2008-11-07 01:05:52 +00:00
|
|
|
for(unsigned int i=0; i<4; i++)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2008-11-07 01:05:52 +00:00
|
|
|
bool is_front_wheel = i<2;
|
2008-11-10 04:34:22 +00:00
|
|
|
btWheelInfo& wheel = m_vehicle->addWheel(
|
|
|
|
m_kart_properties->getKartModel()->getWheelPhysicsPosition(i),
|
2008-11-07 01:05:52 +00:00
|
|
|
wheel_direction, wheel_axle, suspension_rest,
|
|
|
|
wheel_radius, *m_tuning, is_front_wheel);
|
2007-05-27 16:01:53 +00:00
|
|
|
wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness();
|
|
|
|
wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelDampingRelaxation();
|
|
|
|
wheel.m_wheelsDampingCompression = m_kart_properties->getWheelDampingCompression();
|
|
|
|
wheel.m_frictionSlip = m_kart_properties->getFrictionSlip();
|
|
|
|
wheel.m_rollInfluence = m_kart_properties->getRollInfluence();
|
|
|
|
}
|
2008-04-22 14:20:52 +00:00
|
|
|
// Obviously these allocs have to be properly managed/freed
|
2008-04-29 03:50:08 +00:00
|
|
|
btTransform t;
|
|
|
|
t.setIdentity();
|
|
|
|
m_uprightConstraint=new btUprightConstraint(*m_body, t);
|
2008-04-29 03:29:28 +00:00
|
|
|
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
2008-04-22 14:20:52 +00:00
|
|
|
m_uprightConstraint->setBounce(0.0f);
|
2008-04-29 03:29:28 +00:00
|
|
|
m_uprightConstraint->setMaxLimitForce(m_kart_properties->getUprightMaxForce());
|
2008-04-22 14:20:52 +00:00
|
|
|
m_uprightConstraint->setErp(1.0f);
|
|
|
|
m_uprightConstraint->setLimitSoftness(1.0f);
|
|
|
|
m_uprightConstraint->setDamping(0.0f);
|
2008-09-21 16:07:56 +00:00
|
|
|
RaceManager::getWorld()->getPhysics()->addKart(this, m_vehicle);
|
2008-09-18 03:24:19 +00:00
|
|
|
|
|
|
|
//create the engine sound
|
|
|
|
if(m_engine_sound)
|
|
|
|
{
|
2008-10-27 01:38:10 +00:00
|
|
|
m_engine_sound->speed(0.6f);
|
2008-09-18 03:24:19 +00:00
|
|
|
m_engine_sound->loop();
|
|
|
|
m_engine_sound->play();
|
|
|
|
}
|
2007-05-27 16:01:53 +00:00
|
|
|
} // createPhysics
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
Kart::~Kart()
|
|
|
|
{
|
2008-09-18 03:24:19 +00:00
|
|
|
//stop the engine sound
|
|
|
|
if(m_engine_sound)
|
|
|
|
{
|
|
|
|
m_engine_sound->stop();
|
|
|
|
}
|
2008-11-08 11:30:50 +00:00
|
|
|
sfx_manager->deleteSFX(m_engine_sound );
|
|
|
|
sfx_manager->deleteSFX(m_beep_sound );
|
|
|
|
sfx_manager->deleteSFX(m_crash_sound );
|
|
|
|
sfx_manager->deleteSFX(m_skid_sound );
|
2008-12-30 01:07:22 +00:00
|
|
|
sfx_manager->deleteSFX(m_goo_sound );
|
|
|
|
|
2008-12-01 04:17:17 +00:00
|
|
|
if(m_smoke_system) ssgDeRefDelete(m_smoke_system);
|
2008-12-01 09:26:25 +00:00
|
|
|
if(m_nitro) ssgDeRefDelete(m_nitro);
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
ssgDeRefDelete(m_shadow);
|
|
|
|
|
2008-12-02 13:01:39 +00:00
|
|
|
if(m_skidmarks) delete m_skidmarks ;
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-09-21 16:07:56 +00:00
|
|
|
RaceManager::getWorld()->getPhysics()->removeKart(this);
|
2007-11-08 22:40:15 +00:00
|
|
|
delete m_vehicle;
|
2007-05-27 16:01:53 +00:00
|
|
|
delete m_tuning;
|
|
|
|
delete m_vehicle_raycaster;
|
2008-04-22 14:20:52 +00:00
|
|
|
delete m_uprightConstraint;
|
2007-11-08 22:40:15 +00:00
|
|
|
for(int i=0; i<m_kart_chassis.getNumChildShapes(); i++)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2007-11-08 22:40:15 +00:00
|
|
|
delete m_kart_chassis.getChildShape(i);
|
2007-05-27 16:01:53 +00:00
|
|
|
}
|
|
|
|
} // ~Kart
|
|
|
|
|
2008-04-15 13:57:18 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Kart::eliminate()
|
|
|
|
{
|
|
|
|
m_eliminated = true;
|
2008-09-21 16:07:56 +00:00
|
|
|
RaceManager::getWorld()->getPhysics()->removeKart(this);
|
2008-04-15 13:57:18 +00:00
|
|
|
|
|
|
|
// make the kart invisible by placing it way under the track
|
|
|
|
sgVec3 hell; hell[0]=0.0f; hell[1]=0.0f; hell[2] = -10000.0f;
|
|
|
|
getModelTransform()->setTransform(hell);
|
|
|
|
} // eliminate
|
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Returns true if the kart is 'resting'
|
|
|
|
*
|
|
|
|
* Returns true if the kart is 'resting', i.e. (nearly) not moving.
|
|
|
|
*/
|
2008-01-16 00:09:05 +00:00
|
|
|
bool Kart::isInRest() const
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2007-09-30 14:17:28 +00:00
|
|
|
return fabs(m_body->getLinearVelocity ().z())<0.2;
|
2007-05-27 16:01:53 +00:00
|
|
|
} // isInRest
|
2007-12-17 13:16:09 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-11-28 03:44:41 +00:00
|
|
|
/** Multiplies the velocity of the kart by a factor f (both linear
|
|
|
|
* and angular). This is used by anvils, which suddenly slow down the kart
|
|
|
|
* when they are attached.
|
2007-05-27 16:01:53 +00:00
|
|
|
*/
|
2008-11-28 03:44:41 +00:00
|
|
|
void Kart::adjustSpeed(float f)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2007-09-30 14:17:28 +00:00
|
|
|
m_body->setLinearVelocity(m_body->getLinearVelocity()*f);
|
2008-11-28 03:44:41 +00:00
|
|
|
m_body->setAngularVelocity(m_body->getAngularVelocity()*f);
|
|
|
|
} // adjustSpeed
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** This method is to be called every time the mass of the kart is updated,
|
|
|
|
* which includes attaching an anvil to the kart (and detaching).
|
|
|
|
*/
|
|
|
|
void Kart::updatedWeight()
|
|
|
|
{
|
2007-05-27 16:01:53 +00:00
|
|
|
// getMass returns the mass increased by the attachment
|
|
|
|
btVector3 inertia;
|
|
|
|
float m=getMass();
|
2007-11-08 22:40:15 +00:00
|
|
|
m_kart_chassis.calculateLocalInertia(m, inertia);
|
2007-09-30 14:17:28 +00:00
|
|
|
m_body->setMassProps(m, inertia);
|
2008-11-28 03:44:41 +00:00
|
|
|
} // updatedWeight
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Kart::reset()
|
|
|
|
{
|
2008-12-20 00:21:15 +00:00
|
|
|
// If the kart was eliminated or rescued, the body was removed from the
|
2009-01-07 01:32:49 +00:00
|
|
|
// physics world. Add it again.
|
2008-12-20 00:21:15 +00:00
|
|
|
if(m_eliminated || m_rescue)
|
2008-04-15 13:57:18 +00:00
|
|
|
{
|
2008-09-21 16:07:56 +00:00
|
|
|
RaceManager::getWorld()->getPhysics()->addKart(this, m_vehicle);
|
2008-04-15 13:57:18 +00:00
|
|
|
}
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
m_attachment.clear();
|
2008-10-30 02:02:56 +00:00
|
|
|
m_powerup.reset();
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
m_race_position = 9;
|
|
|
|
m_finished_race = false;
|
2008-04-15 13:57:18 +00:00
|
|
|
m_eliminated = false;
|
2008-12-20 00:21:15 +00:00
|
|
|
m_rescue = false;
|
2007-05-27 16:01:53 +00:00
|
|
|
m_finish_time = 0.0f;
|
|
|
|
m_zipper_time_left = 0.0f;
|
2009-01-05 23:17:00 +00:00
|
|
|
m_collected_energy = 0;
|
2008-01-25 01:29:12 +00:00
|
|
|
m_wheel_rotation = 0;
|
2008-09-07 14:42:37 +00:00
|
|
|
m_bounce_back_time = 0.0f;
|
2008-11-24 00:47:55 +00:00
|
|
|
m_skidding = 1.0f;
|
2008-12-11 23:45:13 +00:00
|
|
|
m_time_last_crash = 0.0f;
|
2009-01-05 22:55:25 +00:00
|
|
|
m_max_speed_reduction = 0.0f;
|
|
|
|
m_power_reduction = 50.0f;
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-12-21 21:40:00 +00:00
|
|
|
m_controls.m_steer = 0.0f;
|
|
|
|
m_controls.m_accel = 0.0f;
|
|
|
|
m_controls.m_brake = false;
|
|
|
|
m_controls.m_nitro = false;
|
|
|
|
m_controls.m_drift = false;
|
|
|
|
m_controls.m_fire = false;
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-02-11 02:20:51 +00:00
|
|
|
// Set the brakes so that karts don't slide downhill
|
|
|
|
for(int i=0; i<4; i++) m_vehicle->setBrake(5.0f, i);
|
|
|
|
|
2008-06-24 06:29:35 +00:00
|
|
|
setTrans(m_reset_transform);
|
2008-06-20 09:34:35 +00:00
|
|
|
|
2008-01-15 11:38:54 +00:00
|
|
|
m_vehicle->applyEngineForce (0.0f, 2);
|
|
|
|
m_vehicle->applyEngineForce (0.0f, 3);
|
2008-06-20 09:34:35 +00:00
|
|
|
|
|
|
|
Moveable::reset();
|
2008-12-08 01:07:16 +00:00
|
|
|
m_skidmarks->reset();
|
2007-05-27 16:01:53 +00:00
|
|
|
for(int j=0; j<m_vehicle->getNumWheels(); j++)
|
|
|
|
{
|
|
|
|
m_vehicle->updateWheelTransform(j, true);
|
|
|
|
}
|
|
|
|
|
2008-06-20 09:34:35 +00:00
|
|
|
TerrainInfo::update(getXYZ());
|
2007-05-27 16:01:53 +00:00
|
|
|
} // reset
|
2008-09-29 02:29:33 +00:00
|
|
|
|
2008-05-20 03:33:48 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Kart::raceFinished(float time)
|
|
|
|
{
|
|
|
|
m_finished_race = true;
|
|
|
|
m_finish_time = time;
|
|
|
|
race_manager->RaceFinished(this, time);
|
|
|
|
} // raceFinished
|
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-10-29 15:55:54 +00:00
|
|
|
void Kart::collectedItem(const Item &item, int add_info)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2008-10-29 15:55:54 +00:00
|
|
|
const ItemType type = item.getType();
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-09-07 14:42:37 +00:00
|
|
|
switch (type)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2008-11-24 23:19:47 +00:00
|
|
|
case ITEM_BANANA : m_attachment.hitBanana(item, add_info); break;
|
|
|
|
case ITEM_SILVER_COIN : m_collected_energy++ ; break;
|
|
|
|
case ITEM_GOLD_COIN : m_collected_energy += 3 ; break;
|
|
|
|
case ITEM_BONUS_BOX :
|
|
|
|
{
|
|
|
|
// In wheelie style, karts get more items depending on energy,
|
|
|
|
// in nitro mode it's only one item.
|
2008-12-21 21:40:00 +00:00
|
|
|
int n = 1;
|
2008-11-24 23:19:47 +00:00
|
|
|
m_powerup.hitBonusBox(n, item,add_info);
|
|
|
|
break;
|
|
|
|
}
|
2008-11-07 01:18:04 +00:00
|
|
|
case ITEM_BUBBLEGUM:
|
2008-11-07 04:54:38 +00:00
|
|
|
// slow down
|
|
|
|
m_body->setLinearVelocity(m_body->getLinearVelocity()*0.3f);
|
2008-12-30 01:07:22 +00:00
|
|
|
m_goo_sound->position(getXYZ());
|
|
|
|
m_goo_sound->play();
|
2008-11-07 01:18:04 +00:00
|
|
|
break;
|
2008-09-19 14:41:23 +00:00
|
|
|
default : break;
|
2007-05-27 16:01:53 +00:00
|
|
|
} // switch TYPE
|
|
|
|
|
2008-10-30 02:02:56 +00:00
|
|
|
// Attachments and powerups are stored in the corresponding
|
2008-10-29 15:55:54 +00:00
|
|
|
// functions (hit{Red,Green}Item), so only coins need to be
|
2008-09-07 14:42:37 +00:00
|
|
|
// stored here.
|
|
|
|
if(network_manager->getMode()==NetworkManager::NW_SERVER &&
|
2008-10-29 15:55:54 +00:00
|
|
|
(type==ITEM_SILVER_COIN || type==ITEM_GOLD_COIN) )
|
2008-09-07 14:42:37 +00:00
|
|
|
{
|
2008-10-29 15:55:54 +00:00
|
|
|
race_state->itemCollected(getWorldKartId(), item.getItemId());
|
2008-09-07 14:42:37 +00:00
|
|
|
}
|
|
|
|
|
2008-11-24 23:19:47 +00:00
|
|
|
if ( m_collected_energy > MAX_ITEMS_COLLECTED )
|
|
|
|
m_collected_energy = MAX_ITEMS_COLLECTED;
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-10-29 15:55:54 +00:00
|
|
|
} // collectedItem
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2007-08-18 14:26:11 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2007-12-20 04:37:35 +00:00
|
|
|
// Simulates gears
|
2007-08-18 14:26:11 +00:00
|
|
|
float Kart::getActualWheelForce()
|
|
|
|
{
|
2008-01-01 14:30:39 +00:00
|
|
|
float zipperF=(m_zipper_time_left>0.0f) ? stk_config->m_zipper_force : 0.0f;
|
2007-08-21 14:50:45 +00:00
|
|
|
const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio();
|
|
|
|
for(unsigned int i=0; i<gear_ratio.size(); i++)
|
2007-08-18 14:26:11 +00:00
|
|
|
{
|
2009-01-05 22:55:25 +00:00
|
|
|
if(m_speed <= getMaxSpeed()*gear_ratio[i])
|
2008-09-18 03:24:19 +00:00
|
|
|
{
|
|
|
|
m_current_gear_ratio = gear_ratio[i];
|
2008-01-01 14:30:39 +00:00
|
|
|
return getMaxPower()*m_kart_properties->getGearPowerIncrease()[i]+zipperF;
|
2008-09-18 03:24:19 +00:00
|
|
|
}
|
2007-08-18 14:26:11 +00:00
|
|
|
}
|
2008-01-01 14:30:39 +00:00
|
|
|
return getMaxPower()+zipperF;
|
2007-08-21 14:50:45 +00:00
|
|
|
|
|
|
|
} // getActualWheelForce
|
2007-08-18 14:26:11 +00:00
|
|
|
|
2007-11-08 12:31:54 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-02-11 02:20:51 +00:00
|
|
|
/** The kart is on ground if all 4 wheels touch the ground
|
|
|
|
*/
|
|
|
|
bool Kart::isOnGround() const
|
2007-11-08 12:31:54 +00:00
|
|
|
{
|
|
|
|
return m_vehicle->getWheelInfo(0).m_raycastInfo.m_isInContact &&
|
|
|
|
m_vehicle->getWheelInfo(1).m_raycastInfo.m_isInContact &&
|
|
|
|
m_vehicle->getWheelInfo(2).m_raycastInfo.m_isInContact &&
|
|
|
|
m_vehicle->getWheelInfo(3).m_raycastInfo.m_isInContact;
|
|
|
|
} // isOnGround
|
2007-05-27 16:01:53 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2009-01-14 23:36:30 +00:00
|
|
|
/** The kart is near the ground, but not necesarily on it (small jumps). This
|
|
|
|
* is used to determine when to switch off the upright constraint, so that
|
|
|
|
* explosions can be more violent, while still
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Kart::isNearGround() const
|
|
|
|
{
|
|
|
|
if(getHoT()==Track::NOHIT)
|
|
|
|
return false;
|
|
|
|
else
|
|
|
|
return ((getXYZ().getZ() - getHoT()) < stk_config->m_near_ground);
|
|
|
|
} // isNearGround
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-06-20 09:34:35 +00:00
|
|
|
void Kart::handleExplosion(const Vec3& pos, bool direct_hit)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2008-05-13 04:32:37 +00:00
|
|
|
if(direct_hit)
|
|
|
|
{
|
2008-05-14 00:53:59 +00:00
|
|
|
btVector3 diff((float)(rand()%16/16), (float)(rand()%16/16), 2.0f);
|
2008-05-13 04:32:37 +00:00
|
|
|
diff.normalize();
|
|
|
|
diff*=stk_config->m_explosion_impulse/5.0f;
|
2008-10-16 00:20:49 +00:00
|
|
|
m_uprightConstraint->setDisableTime(10.0f);
|
2008-05-13 04:32:37 +00:00
|
|
|
getVehicle()->getRigidBody()->applyCentralImpulse(diff);
|
2008-05-14 00:53:59 +00:00
|
|
|
getVehicle()->getRigidBody()->applyTorqueImpulse(btVector3(float(rand()%32*5),
|
|
|
|
float(rand()%32*5),
|
|
|
|
float(rand()%32*5)));
|
2007-08-21 14:50:45 +00:00
|
|
|
}
|
2007-12-17 13:16:09 +00:00
|
|
|
else // only affected by a distant explosion
|
2007-08-21 14:50:45 +00:00
|
|
|
{
|
2008-06-20 09:34:35 +00:00
|
|
|
btVector3 diff=getXYZ()-pos;
|
2008-04-20 23:28:37 +00:00
|
|
|
//if the z component is negative, the resulting impulse could push the
|
|
|
|
// kart through the floor. So in this case ignore z.
|
2008-05-02 03:01:25 +00:00
|
|
|
if(diff.getZ()<0) diff.setZ(0.0f);
|
|
|
|
float len2=diff.length2();
|
2007-08-21 14:50:45 +00:00
|
|
|
|
2007-12-17 13:16:09 +00:00
|
|
|
// The correct formhale would be to first normalise diff,
|
2007-08-21 14:50:45 +00:00
|
|
|
// 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 :)
|
2008-05-02 03:01:25 +00:00
|
|
|
diff *= stk_config->m_explosion_impulse/len2;
|
|
|
|
getVehicle()->getRigidBody()->applyCentralImpulse(diff);
|
2007-08-21 14:50:45 +00:00
|
|
|
}
|
|
|
|
} // handleExplosion
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-04-16 09:57:50 +00:00
|
|
|
void Kart::update(float dt)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2009-01-14 23:36:30 +00:00
|
|
|
if(m_body->getAngularVelocity().getZ()>1.9f)
|
|
|
|
dt=1.0f*dt;
|
2008-12-26 20:45:56 +00:00
|
|
|
// if its view is blocked by plunger, decrease remaining time
|
|
|
|
if(m_view_blocked_by_plunger > 0) m_view_blocked_by_plunger -= dt;
|
|
|
|
|
2008-09-08 10:53:29 +00:00
|
|
|
// Store the actual kart controls at the start of update in the server
|
|
|
|
// state. This makes it easier to reset some fields when they are not used
|
|
|
|
// anymore (e.g. controls.fire).
|
|
|
|
if(network_manager->getMode()==NetworkManager::NW_SERVER)
|
|
|
|
{
|
|
|
|
race_state->storeKartControls(*this);
|
|
|
|
}
|
|
|
|
|
2008-09-07 14:55:05 +00:00
|
|
|
// On a client fiering is done upon receiving the command from the server.
|
2008-12-21 21:40:00 +00:00
|
|
|
if ( m_controls.m_fire && network_manager->getMode()!=NetworkManager::NW_CLIENT
|
2008-09-07 14:55:05 +00:00
|
|
|
&& !isRescue())
|
|
|
|
{
|
|
|
|
// use() needs to be called even if there currently is no collecteable
|
|
|
|
// since use() can test if something needs to be switched on/off.
|
2008-10-30 02:02:56 +00:00
|
|
|
m_powerup.use() ;
|
2008-12-21 21:40:00 +00:00
|
|
|
m_controls.m_fire = false;
|
2008-09-07 14:55:05 +00:00
|
|
|
}
|
|
|
|
|
2009-01-14 23:36:30 +00:00
|
|
|
// When really on air, free fly, when near ground, try to glide / adjust for landing
|
|
|
|
if(!isNearGround())
|
2008-10-16 00:20:49 +00:00
|
|
|
m_uprightConstraint->setLimit(M_PI);
|
|
|
|
else
|
|
|
|
m_uprightConstraint->setLimit(m_kart_properties->getUprightTolerance());
|
|
|
|
|
|
|
|
|
2008-01-01 14:30:39 +00:00
|
|
|
m_zipper_time_left = m_zipper_time_left>0.0f ? m_zipper_time_left-dt : 0.0f;
|
|
|
|
|
2008-01-25 01:29:12 +00:00
|
|
|
//m_wheel_rotation gives the rotation around the X-axis, and since velocity's
|
2007-05-27 16:01:53 +00:00
|
|
|
//timeframe is the delta time, we don't have to multiply it with dt.
|
2008-06-10 02:35:10 +00:00
|
|
|
m_wheel_rotation += m_speed*dt / m_kart_properties->getWheelRadius();
|
|
|
|
m_wheel_rotation=fmodf(m_wheel_rotation, 2*M_PI);
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
if ( m_rescue )
|
|
|
|
{
|
|
|
|
// Let the kart raise 2m in the 2 seconds of the rescue
|
|
|
|
const float rescue_time = 2.0f;
|
|
|
|
const float rescue_height = 2.0f;
|
|
|
|
if(m_attachment.getType() != ATTACH_TINYTUX)
|
|
|
|
{
|
|
|
|
m_attachment.set( ATTACH_TINYTUX, rescue_time ) ;
|
2008-06-20 09:34:35 +00:00
|
|
|
m_rescue_pitch = getHPR().getPitch();
|
|
|
|
m_rescue_roll = getHPR().getRoll();
|
2008-09-21 16:07:56 +00:00
|
|
|
RaceManager::getWorld()->getPhysics()->removeKart(this);
|
2008-10-29 15:55:54 +00:00
|
|
|
race_state->itemCollected(getWorldKartId(), -1, -1);
|
2007-05-27 16:01:53 +00:00
|
|
|
}
|
2007-11-03 13:13:26 +00:00
|
|
|
btQuaternion q_roll (btVector3(0.f, 1.f, 0.f),
|
|
|
|
-m_rescue_roll*dt/rescue_time*M_PI/180.0f);
|
|
|
|
btQuaternion q_pitch(btVector3(1.f, 0.f, 0.f),
|
|
|
|
-m_rescue_pitch*dt/rescue_time*M_PI/180.0f);
|
2008-06-20 09:34:35 +00:00
|
|
|
setXYZRotation(getXYZ()+Vec3(0, 0, rescue_height*dt/rescue_time),
|
|
|
|
getRotation()*q_roll*q_pitch);
|
2007-05-27 16:01:53 +00:00
|
|
|
} // if m_rescue
|
2008-01-01 14:30:39 +00:00
|
|
|
m_attachment.update(dt);
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-09-27 19:43:57 +00:00
|
|
|
//smoke drawing control point
|
2008-12-01 09:26:25 +00:00
|
|
|
if ( user_config->m_graphical_effects )
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2008-12-01 09:26:25 +00:00
|
|
|
m_smoke_system->update(dt);
|
|
|
|
m_nitro->update(dt);
|
|
|
|
} // user_config->m_graphical_effects
|
2007-05-27 16:01:53 +00:00
|
|
|
updatePhysics(dt);
|
|
|
|
|
2008-09-27 19:43:57 +00:00
|
|
|
//kart_info.m_last_track_coords = kart_info.m_curr_track_coords;
|
2008-06-20 09:34:35 +00:00
|
|
|
|
2007-12-17 13:16:09 +00:00
|
|
|
Moveable::update(dt);
|
2008-01-16 00:09:05 +00:00
|
|
|
|
2008-11-08 11:30:50 +00:00
|
|
|
m_engine_sound->position ( getXYZ() );
|
|
|
|
m_beep_sound->position ( getXYZ() );
|
|
|
|
m_crash_sound->position ( getXYZ() );
|
|
|
|
m_skid_sound->position ( getXYZ() );
|
2008-10-09 22:24:19 +00:00
|
|
|
|
2008-01-16 00:09:05 +00:00
|
|
|
// Check if a kart is (nearly) upside down and not moving much --> automatic rescue
|
2008-06-20 09:34:35 +00:00
|
|
|
if((fabs(getHPR().getRoll())>60 && fabs(getSpeed())<3.0f) )
|
2008-01-16 00:09:05 +00:00
|
|
|
{
|
|
|
|
forceRescue();
|
|
|
|
}
|
|
|
|
|
2008-01-01 14:30:39 +00:00
|
|
|
btTransform trans=getTrans();
|
2008-12-09 21:23:18 +00:00
|
|
|
// Add a certain epsilon (0.3) to the height of the kart. This avoids
|
2008-03-04 03:37:42 +00:00
|
|
|
// problems of the ray being cast from under the track (which happened
|
2008-12-09 21:23:18 +00:00
|
|
|
// e.g. on tux tollway when jumping down from the ramp, when the chassis
|
|
|
|
// partly tunnels through the track). While tunneling should not be
|
|
|
|
// happening (since Z velocity is clamped), the epsilon is left in place
|
|
|
|
// just to be on the safe side (it will not hit the chassis itself).
|
|
|
|
Vec3 pos_plus_epsilon = trans.getOrigin()+btVector3(0,0,0.3f);
|
2008-12-09 10:58:01 +00:00
|
|
|
// These values cause the track not to be hit in tuxtrack. I leave
|
|
|
|
// them in as a test case if additional debugging should be needed.
|
|
|
|
// Note: it might be that the kart chassis is actually 'in' the track,
|
|
|
|
// i.e. it's a tunneling problem!
|
|
|
|
//btVector3 pos_plus_epsilon (-54.449902, -139.99402, -3.4524240);
|
|
|
|
// motionstate: -52.449902, -139.99402, -3.6524241
|
|
|
|
// collision object -52.221024, -139.99614, -3.5276926
|
2008-04-18 06:26:36 +00:00
|
|
|
|
2009-01-08 00:12:41 +00:00
|
|
|
// Make sure that the ray doesn't hit the kart. This is done by
|
|
|
|
// resetting the collision filter group, so that this collision
|
|
|
|
// object is ignored during raycasting.
|
|
|
|
short int old_group = 0;
|
|
|
|
if(m_body->getBroadphaseHandle())
|
|
|
|
{
|
|
|
|
old_group = m_body->getBroadphaseHandle()->m_collisionFilterGroup;
|
|
|
|
m_body->getBroadphaseHandle()->m_collisionFilterGroup = 0;
|
|
|
|
}
|
|
|
|
TerrainInfo::update(pos_plus_epsilon);
|
|
|
|
if(m_body->getBroadphaseHandle())
|
|
|
|
{
|
|
|
|
m_body->getBroadphaseHandle()->m_collisionFilterGroup = old_group;
|
|
|
|
}
|
2008-04-18 06:26:36 +00:00
|
|
|
const Material* material=getMaterial();
|
2009-01-05 22:55:25 +00:00
|
|
|
m_power_reduction = 50.0f;
|
2008-04-18 06:26:36 +00:00
|
|
|
if (getHoT()==Track::NOHIT) // kart falling off the track
|
2008-01-01 14:30:39 +00:00
|
|
|
{
|
2008-12-16 21:28:33 +00:00
|
|
|
// let kart fall a bit before rescuing
|
2008-12-16 21:31:02 +00:00
|
|
|
if( RaceManager::getTrack()->m_left_driveline.size() > 0 &&
|
2008-12-31 00:36:23 +00:00
|
|
|
fabs( getXYZ().getZ() - RaceManager::getTrack()->m_left_driveline[0].getZ() ) > 17)
|
2008-12-16 21:28:33 +00:00
|
|
|
forceRescue();
|
2008-04-18 06:26:36 +00:00
|
|
|
}
|
|
|
|
else if(material)
|
2007-12-17 13:16:09 +00:00
|
|
|
{
|
2008-04-18 06:26:36 +00:00
|
|
|
// Sometimes the material can be 0. This can happen if a kart is above
|
|
|
|
// another kart (e.g. mass collision, or one kart falling on another
|
|
|
|
// kart). Bullet does not have any triangle information in this case,
|
|
|
|
// and so material can not be set. In this case it is simply ignored
|
|
|
|
// since it can't hurt (material is only used for friction, zipper and
|
|
|
|
// rescue, so those things are not triggered till the kart is on the
|
|
|
|
// track again)
|
|
|
|
if (material->isReset() && isOnGround()) forceRescue();
|
|
|
|
else if(material->isZipper() && isOnGround()) handleZipper();
|
2009-01-05 22:55:25 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_power_reduction = material->getSlowDown();
|
|
|
|
// Normal driving on terrain. Adjust for maximum terrain speed
|
2009-01-14 23:36:30 +00:00
|
|
|
float max_speed_here = material->getMaxSpeedFraction()*getMaxSpeed();
|
2009-01-05 22:55:25 +00:00
|
|
|
// If the speed is too fast, reduce the maximum speed gradually.
|
|
|
|
// The actual capping happens in updatePhysics
|
|
|
|
if(max_speed_here<m_speed)
|
|
|
|
m_max_speed_reduction += dt*material->getSlowDown();
|
|
|
|
else
|
|
|
|
m_max_speed_reduction = 0.0f;
|
|
|
|
}
|
2008-04-18 06:26:36 +00:00
|
|
|
} // if there is material
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-10-29 15:55:54 +00:00
|
|
|
// Check if any item was hit.
|
|
|
|
item_manager->hitItem(this);
|
2008-12-02 13:01:39 +00:00
|
|
|
m_skidmarks->update(dt);
|
2009-01-16 00:37:31 +00:00
|
|
|
|
|
|
|
// Remove the shadow if the kart is not on the ground
|
|
|
|
if(!isOnGround() && m_shadow_enabled)
|
|
|
|
{
|
|
|
|
m_shadow_enabled = false;
|
|
|
|
m_model_transform->removeKid(m_shadow);
|
|
|
|
}
|
|
|
|
if(isOnGround() && !m_shadow_enabled)
|
|
|
|
{
|
|
|
|
m_shadow_enabled = true;
|
|
|
|
m_model_transform->addKid(m_shadow);
|
|
|
|
}
|
2008-11-07 01:05:52 +00:00
|
|
|
} // update
|
2008-10-16 00:20:49 +00:00
|
|
|
|
2008-01-01 14:30:39 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-11-24 23:19:47 +00:00
|
|
|
/** Sets zipper time, and apply one time additional speed boost.
|
|
|
|
*/
|
2008-01-01 14:30:39 +00:00
|
|
|
void Kart::handleZipper()
|
|
|
|
{
|
2008-05-14 00:56:06 +00:00
|
|
|
// Ignore a zipper that's activated while braking
|
2008-12-21 21:40:00 +00:00
|
|
|
if(m_controls.m_brake) return;
|
2008-03-05 13:22:00 +00:00
|
|
|
m_zipper_time_left = stk_config->m_zipper_time;
|
2009-01-12 01:28:55 +00:00
|
|
|
btVector3 v = m_body->getLinearVelocity();
|
2008-03-05 13:22:00 +00:00
|
|
|
float current_speed = v.length();
|
|
|
|
float speed = std::min(current_speed+stk_config->m_zipper_speed_gain,
|
2009-01-14 23:36:30 +00:00
|
|
|
getMaxSpeedOnTerrain());
|
2009-01-12 01:28:55 +00:00
|
|
|
// 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));
|
2008-01-01 14:30:39 +00:00
|
|
|
} // handleZipper
|
2007-05-27 16:01:53 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define sgn(x) ((x<0)?-1.0f:((x>0)?1.0f:0.0f))
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void Kart::draw()
|
|
|
|
{
|
|
|
|
float m[16];
|
2008-01-01 14:30:39 +00:00
|
|
|
btTransform t=getTrans();
|
2007-05-27 16:01:53 +00:00
|
|
|
t.getOpenGLMatrix(m);
|
|
|
|
|
|
|
|
btVector3 wire_color(0.5f, 0.5f, 0.5f);
|
2008-11-07 01:05:52 +00:00
|
|
|
//RaceManager::getWorld()->getPhysics()->debugDraw(m, m_body->getCollisionShape(),
|
|
|
|
// wire_color);
|
2008-08-01 01:25:03 +00:00
|
|
|
btCylinderShapeX wheelShape( btVector3(0.1f,
|
2007-05-27 16:01:53 +00:00
|
|
|
m_kart_properties->getWheelRadius(),
|
2007-11-08 22:40:15 +00:00
|
|
|
m_kart_properties->getWheelRadius()));
|
2007-05-27 16:01:53 +00:00
|
|
|
btVector3 wheelColor(1,0,0);
|
|
|
|
for(int i=0; i<m_vehicle->getNumWheels(); i++)
|
|
|
|
{
|
|
|
|
m_vehicle->updateWheelTransform(i, true);
|
|
|
|
float m[16];
|
|
|
|
m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m);
|
2008-09-21 16:07:56 +00:00
|
|
|
RaceManager::getWorld()->getPhysics()->debugDraw(m, &wheelShape, wheelColor);
|
2007-05-27 16:01:53 +00:00
|
|
|
}
|
|
|
|
} // draw
|
2007-12-17 13:16:09 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
2008-12-11 10:47:16 +00:00
|
|
|
/** Returned an additional engine power boost when using nitro.
|
2008-11-24 23:19:47 +00:00
|
|
|
* \param dt Time step size.
|
|
|
|
*/
|
2008-12-11 10:47:16 +00:00
|
|
|
float Kart::handleNitro(float dt)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2008-12-21 21:40:00 +00:00
|
|
|
if(!m_controls.m_nitro) return 0.0;
|
2008-12-11 10:47:16 +00:00
|
|
|
m_collected_energy -= dt;
|
|
|
|
if(m_collected_energy<0)
|
2008-11-24 23:19:47 +00:00
|
|
|
{
|
2008-12-11 10:47:16 +00:00
|
|
|
m_collected_energy = 0;
|
|
|
|
return 0.0;
|
2008-04-22 14:20:52 +00:00
|
|
|
}
|
2008-12-11 10:47:16 +00:00
|
|
|
return m_kart_properties->getNitroPowerBoost() * getMaxPower();
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-12-11 10:47:16 +00:00
|
|
|
} // handleNitro
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-02-11 02:20:51 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
/** 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
|
|
|
|
to zero (otherwise the brakes will be braking whenever no engine force
|
|
|
|
is set, i.e. the kart is not accelerating).
|
|
|
|
*/
|
|
|
|
void Kart::resetBrakes()
|
|
|
|
{
|
|
|
|
for(int i=0; i<4; i++) m_vehicle->setBrake(0.0f, i);
|
|
|
|
} // resetBrakes
|
2007-05-27 16:01:53 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
2008-09-07 14:42:37 +00:00
|
|
|
void Kart::crashed(Kart *k)
|
|
|
|
{
|
2008-12-11 23:45:13 +00:00
|
|
|
/** If a kart is crashing against the track, the collision is often
|
|
|
|
* reported more than once, resulting in a machine gun effect, and too
|
|
|
|
* long disabling of the engine. Therefore, this reaction is disabled
|
|
|
|
* for 0.5 seconds after a crash.
|
|
|
|
*/
|
|
|
|
if(RaceManager::getWorld()->getTime()-m_time_last_crash < 0.5f) return;
|
|
|
|
|
|
|
|
m_time_last_crash = RaceManager::getWorld()->getTime();
|
2008-09-07 14:42:37 +00:00
|
|
|
// After a collision disable the engine for a short time so that karts
|
|
|
|
// can 'bounce back' a bit (without this the engine force will prevent
|
|
|
|
// karts from bouncing back, they will instead stuck towards the obstable).
|
2008-10-09 22:24:19 +00:00
|
|
|
if(m_bounce_back_time<=0.0f)
|
|
|
|
{
|
2008-12-11 23:45:13 +00:00
|
|
|
// In case that the sfx is longer than 0.5 seconds, only play it if
|
|
|
|
// it's not already playing.
|
2008-12-13 13:00:06 +00:00
|
|
|
if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING)
|
2008-12-11 23:45:13 +00:00
|
|
|
m_crash_sound->play();
|
2008-12-11 22:57:40 +00:00
|
|
|
m_bounce_back_time = 0.1f;
|
2008-10-09 22:24:19 +00:00
|
|
|
}
|
2008-09-07 14:42:37 +00:00
|
|
|
} // crashed
|
2008-10-09 22:24:19 +00:00
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void Kart::beep()
|
|
|
|
{
|
|
|
|
m_beep_sound->play();
|
|
|
|
} // beep
|
|
|
|
|
2008-09-07 14:42:37 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
2007-05-27 16:01:53 +00:00
|
|
|
void Kart::updatePhysics (float dt)
|
|
|
|
{
|
2008-09-07 14:42:37 +00:00
|
|
|
m_bounce_back_time-=dt;
|
2008-12-11 10:47:16 +00:00
|
|
|
float engine_power = getActualWheelForce() + handleNitro(dt);
|
2007-11-03 13:13:26 +00:00
|
|
|
if(m_attachment.getType()==ATTACH_PARACHUTE) engine_power*=0.2f;
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-12-21 21:40:00 +00:00
|
|
|
if(m_controls.m_accel) // accelerating
|
2008-09-07 14:42:37 +00:00
|
|
|
{ // For a short time after a collision disable the engine,
|
|
|
|
// so that the karts can bounce back a bit from the obstacle.
|
2008-12-28 19:29:08 +00:00
|
|
|
if(m_bounce_back_time>0.0f)
|
|
|
|
engine_power = 0.0f;
|
|
|
|
// let a player going backwards accelerate quickly (e.g. if a player hits a
|
|
|
|
// wall, he needs to be able to start again quickly after going backwards)
|
|
|
|
else if(m_speed < 0.0f)
|
|
|
|
engine_power *= 5.0f;
|
2009-01-05 22:55:25 +00:00
|
|
|
// Engine slow down due to terrain (see m_power_reduction is set in
|
|
|
|
// update() depending on terrain type.
|
2009-01-06 02:39:30 +00:00
|
|
|
engine_power *= m_power_reduction/stk_config->m_slowdown_factor;
|
2007-08-17 17:07:12 +00:00
|
|
|
m_vehicle->applyEngineForce(engine_power, 2);
|
|
|
|
m_vehicle->applyEngineForce(engine_power, 3);
|
2008-12-28 19:29:08 +00:00
|
|
|
// Either all or no brake is set, so test only one to avoid
|
|
|
|
// resetting all brakes most of the time.
|
|
|
|
if(m_vehicle->getWheelInfo(0).m_brake &&
|
|
|
|
!RaceManager::getWorld()->isStartPhase())
|
|
|
|
resetBrakes();
|
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
}
|
|
|
|
else
|
2007-08-17 17:07:12 +00:00
|
|
|
{ // not accelerating
|
2008-12-21 21:40:00 +00:00
|
|
|
if(m_controls.m_brake)
|
2008-11-08 20:35:45 +00:00
|
|
|
{ // check if the player is currently only slowing down or moving backwards
|
2008-11-30 16:42:56 +00:00
|
|
|
if(m_speed > 0.0f)
|
2008-11-08 23:20:23 +00:00
|
|
|
{ // going forward
|
|
|
|
m_vehicle->applyEngineForce(0.f, 2);//engine off
|
|
|
|
m_vehicle->applyEngineForce(0.f, 3);
|
|
|
|
|
|
|
|
//apply the brakes
|
|
|
|
for(int i=0; i<4; i++) m_vehicle->setBrake(getBrakeFactor() * 4.0f, i);
|
2008-11-25 21:05:35 +00:00
|
|
|
m_skidding*= 1.08f;//skid a little when the brakes are hit (just enough to make the skiding sound)
|
2008-12-26 20:05:41 +00:00
|
|
|
if(m_skidding>m_kart_properties->getMaxSkid())
|
|
|
|
m_skidding=m_kart_properties->getMaxSkid();
|
2007-08-17 17:07:12 +00:00
|
|
|
}
|
|
|
|
else
|
2008-11-08 20:35:45 +00:00
|
|
|
{
|
2008-11-30 16:42:56 +00:00
|
|
|
resetBrakes();
|
2008-12-16 21:00:56 +00:00
|
|
|
// going backward, apply reverse gear ratio (unless he goes too fast backwards)
|
2009-01-14 23:36:30 +00:00
|
|
|
if ( fabs(m_speed) < getMaxSpeedOnTerrain()*m_max_speed_reverse_ratio )
|
2007-08-17 17:07:12 +00:00
|
|
|
{
|
2008-12-28 19:29:08 +00:00
|
|
|
// the backwards acceleration is artificially increased to allow
|
|
|
|
// players to get "unstuck" quicker if they hit e.g. a wall
|
|
|
|
m_vehicle->applyEngineForce(-engine_power*2.5f, 2);
|
|
|
|
m_vehicle->applyEngineForce(-engine_power*2.5f, 3);
|
2008-11-30 16:42:56 +00:00
|
|
|
}
|
2007-08-17 17:07:12 +00:00
|
|
|
else
|
|
|
|
{
|
2008-11-30 16:42:56 +00:00
|
|
|
m_vehicle->applyEngineForce(0.f, 2);
|
|
|
|
m_vehicle->applyEngineForce(0.f, 3);
|
2008-12-16 21:00:56 +00:00
|
|
|
}
|
|
|
|
|
2007-08-17 17:07:12 +00:00
|
|
|
}
|
2007-06-15 02:06:26 +00:00
|
|
|
}
|
|
|
|
else
|
2008-11-08 20:35:45 +00:00
|
|
|
{
|
|
|
|
// lift the foot from throttle, brakes with 10% engine_power
|
2008-12-21 21:40:00 +00:00
|
|
|
m_vehicle->applyEngineForce(-m_controls.m_accel*engine_power*0.1f, 2);
|
|
|
|
m_vehicle->applyEngineForce(-m_controls.m_accel*engine_power*0.1f, 3);
|
2008-11-08 23:20:23 +00:00
|
|
|
|
2008-11-09 22:02:34 +00:00
|
|
|
if(!RaceManager::getWorld()->isStartPhase())
|
|
|
|
resetBrakes();
|
2007-06-15 02:06:26 +00:00
|
|
|
}
|
2007-05-27 16:01:53 +00:00
|
|
|
}
|
2008-11-24 00:47:55 +00:00
|
|
|
#ifdef ENABLE_JUMP
|
2008-07-12 01:20:29 +00:00
|
|
|
if(m_controls.jump && isOnGround())
|
2007-09-23 14:52:39 +00:00
|
|
|
{
|
|
|
|
//Vector3 impulse(0.0f, 0.0f, 10.0f);
|
|
|
|
// getVehicle()->getRigidBody()->applyCentralImpulse(impulse);
|
2007-09-30 14:17:28 +00:00
|
|
|
btVector3 velocity = m_body->getLinearVelocity();
|
2007-11-18 13:44:53 +00:00
|
|
|
velocity.setZ( m_kart_properties->getJumpVelocity() );
|
2007-09-23 14:52:39 +00:00
|
|
|
|
2007-11-03 13:13:26 +00:00
|
|
|
getBody()->setLinearVelocity( velocity );
|
2007-09-23 14:52:39 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
}
|
2008-11-24 00:47:55 +00:00
|
|
|
#endif
|
2009-01-06 21:16:27 +00:00
|
|
|
if (isOnGround()){
|
|
|
|
if((fabs(m_controls.m_steer) > 0.001f) && m_controls.m_drift)
|
|
|
|
{
|
|
|
|
m_skidding += m_kart_properties->getSkidIncrease()
|
|
|
|
*dt/m_kart_properties->getTimeTillMaxSkid();
|
|
|
|
if(m_skidding>m_kart_properties->getMaxSkid())
|
|
|
|
m_skidding=m_kart_properties->getMaxSkid();
|
|
|
|
}
|
|
|
|
else if(m_skidding>1.0f)
|
|
|
|
{
|
|
|
|
m_skidding *= m_kart_properties->getSkidDecrease();
|
|
|
|
if(m_skidding<1.0f) m_skidding=1.0f;
|
|
|
|
}
|
2008-12-21 21:40:00 +00:00
|
|
|
}
|
2009-01-06 21:16:27 +00:00
|
|
|
else
|
2008-12-21 21:40:00 +00:00
|
|
|
{
|
2009-01-06 21:16:27 +00:00
|
|
|
m_skidding = 1.0f; // Lose any skid factor as soon as we fly
|
2008-12-21 21:40:00 +00:00
|
|
|
}
|
|
|
|
if(m_skidding>1.0f)
|
|
|
|
{
|
2008-12-30 01:01:56 +00:00
|
|
|
if(m_skid_sound->getStatus() != SFXManager::SFX_PLAYING)
|
2008-12-21 21:40:00 +00:00
|
|
|
m_skid_sound->play();
|
|
|
|
}
|
|
|
|
else if(m_skid_sound->getStatus() == SFXManager::SFX_PLAYING)
|
2008-05-02 06:26:07 +00:00
|
|
|
{
|
2008-12-21 21:40:00 +00:00
|
|
|
m_skid_sound->stop();
|
2008-05-02 06:26:07 +00:00
|
|
|
}
|
2008-12-21 21:40:00 +00:00
|
|
|
float steering = getMaxSteerAngle() * m_controls.m_steer*m_skidding;
|
|
|
|
|
|
|
|
m_vehicle->setSteeringValue(steering, 0);
|
|
|
|
m_vehicle->setSteeringValue(steering, 1);
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-09-08 10:01:48 +00:00
|
|
|
// Only compute the current speed if this is not the client. On a client the
|
|
|
|
// speed is actually received from the server.
|
|
|
|
if(network_manager->getMode()!=NetworkManager::NW_CLIENT)
|
|
|
|
m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length();
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2007-08-17 17:07:12 +00:00
|
|
|
// calculate direction of m_speed
|
|
|
|
const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform();
|
|
|
|
btVector3 forwardW (
|
|
|
|
chassisTrans.getBasis()[0][1],
|
|
|
|
chassisTrans.getBasis()[1][1],
|
|
|
|
chassisTrans.getBasis()[2][1]);
|
|
|
|
|
|
|
|
if (forwardW.dot(getVehicle()->getRigidBody()->getLinearVelocity()) < btScalar(0.))
|
|
|
|
m_speed *= -1.f;
|
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
//cap at maximum velocity
|
2009-01-14 23:36:30 +00:00
|
|
|
const float max_speed = getMaxSpeedOnTerrain();
|
2007-05-27 16:01:53 +00:00
|
|
|
if ( m_speed > max_speed )
|
|
|
|
{
|
|
|
|
const float velocity_ratio = max_speed/m_speed;
|
|
|
|
m_speed = max_speed;
|
2007-09-30 14:17:28 +00:00
|
|
|
btVector3 velocity = m_body->getLinearVelocity();
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
velocity.setY( velocity.getY() * velocity_ratio );
|
|
|
|
velocity.setX( velocity.getX() * velocity_ratio );
|
|
|
|
|
|
|
|
getVehicle()->getRigidBody()->setLinearVelocity( velocity );
|
|
|
|
|
|
|
|
}
|
2008-12-09 10:58:01 +00:00
|
|
|
|
|
|
|
// To avoid tunneling (which can happen on long falls), clamp the
|
|
|
|
// velocity in Z direction. Tunneling can happen if the Z velocity
|
|
|
|
// is larger than the maximum suspension travel (per frame), since then
|
|
|
|
// the wheel suspension can not stop/slow down the fall (though I am
|
|
|
|
// not sure if this is enough in all cases!). So the speed is limited
|
|
|
|
// to suspensionTravel / dt with dt = 1/60 (since this is the dt
|
|
|
|
// bullet is using).
|
|
|
|
const Vec3 &v = m_body->getLinearVelocity();
|
|
|
|
if(v.getZ() < - m_kart_properties->getSuspensionTravelCM()*0.01f*60)
|
|
|
|
{
|
|
|
|
Vec3 v_clamped = v;
|
|
|
|
// clamp the speed to 99% of the maxium falling speed.
|
|
|
|
v_clamped.setZ(-m_kart_properties->getSuspensionTravelCM()*0.01f*60 * 0.99f);
|
|
|
|
m_body->setLinearVelocity(v_clamped);
|
|
|
|
}
|
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
//at low velocity, forces on kart push it back and forth so we ignore this
|
2007-08-18 14:26:11 +00:00
|
|
|
if(fabsf(m_speed) < 0.2f) // quick'n'dirty workaround for bug 1776883
|
2007-05-27 16:01:53 +00:00
|
|
|
m_speed = 0;
|
|
|
|
|
2008-10-27 01:38:10 +00:00
|
|
|
// when going faster, use higher pitch for engine
|
2008-09-20 14:23:20 +00:00
|
|
|
if(m_engine_sound && sfx_manager->sfxAllowed())
|
2008-09-18 03:24:19 +00:00
|
|
|
{
|
2008-11-07 01:05:52 +00:00
|
|
|
m_engine_sound->speed(0.6f + (float)(m_speed / max_speed)*0.7f);
|
2008-10-09 22:24:19 +00:00
|
|
|
m_engine_sound->position(getXYZ());
|
2008-09-18 03:24:19 +00:00
|
|
|
}
|
2008-11-19 22:43:21 +00:00
|
|
|
#ifdef XX
|
|
|
|
printf("forward %f %f %f %f side %f %f %f %f angVel %f %f %f heading %f\n"
|
|
|
|
,m_vehicle->m_forwardImpulse[0]
|
|
|
|
,m_vehicle->m_forwardImpulse[1]
|
|
|
|
,m_vehicle->m_forwardImpulse[2]
|
|
|
|
,m_vehicle->m_forwardImpulse[3]
|
|
|
|
,m_vehicle->m_sideImpulse[0]
|
|
|
|
,m_vehicle->m_sideImpulse[1]
|
|
|
|
,m_vehicle->m_sideImpulse[2]
|
|
|
|
,m_vehicle->m_sideImpulse[3]
|
|
|
|
,m_body->getAngularVelocity().getX()
|
|
|
|
,m_body->getAngularVelocity().getY()
|
|
|
|
,m_body->getAngularVelocity().getZ()
|
|
|
|
,getHPR().getHeading()
|
|
|
|
);
|
|
|
|
#endif
|
2008-09-18 03:24:19 +00:00
|
|
|
} // updatePhysics
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-09-27 19:43:57 +00:00
|
|
|
void Kart::forceRescue()
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
|
|
|
m_rescue=true;
|
|
|
|
} // forceRescue
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Drops a kart which was rescued back on the track.
|
|
|
|
*/
|
|
|
|
void Kart::endRescue()
|
|
|
|
{
|
|
|
|
m_rescue = false ;
|
2007-12-12 14:07:26 +00:00
|
|
|
|
2007-09-30 14:17:28 +00:00
|
|
|
m_body->setLinearVelocity (btVector3(0.0f,0.0f,0.0f));
|
|
|
|
m_body->setAngularVelocity(btVector3(0.0f,0.0f,0.0f));
|
2008-09-27 20:32:07 +00:00
|
|
|
|
|
|
|
// let the mode decide where to put the kart
|
|
|
|
RaceManager::getWorld()->moveKartAfterRescue(this, m_body);
|
|
|
|
|
2008-09-21 16:07:56 +00:00
|
|
|
RaceManager::getWorld()->getPhysics()->addKart(this, m_vehicle);
|
2007-05-27 16:01:53 +00:00
|
|
|
} // endRescue
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-12-08 01:07:16 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
void Kart::loadData()
|
|
|
|
{
|
|
|
|
float r [ 2 ] = { -10.0f, 100.0f } ;
|
|
|
|
|
|
|
|
|
2008-11-07 01:05:52 +00:00
|
|
|
ssgEntity *obj = m_kart_properties->getKartModel()->getRoot();
|
|
|
|
createPhysics();
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-09-19 06:07:29 +00:00
|
|
|
SSGHelp::createDisplayLists(obj); // create all display lists
|
2007-05-27 16:01:53 +00:00
|
|
|
ssgRangeSelector *lod = new ssgRangeSelector ;
|
|
|
|
|
|
|
|
lod -> addKid ( obj ) ;
|
|
|
|
lod -> setRanges ( r, 2 ) ;
|
|
|
|
|
2008-11-07 01:05:52 +00:00
|
|
|
getModelTransform() -> addKid ( lod ) ;
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
// Attach Particle System
|
2008-12-01 04:17:17 +00:00
|
|
|
m_smoke_system = new Smoke(this);
|
|
|
|
m_smoke_system->ref();
|
2008-12-01 09:26:25 +00:00
|
|
|
m_nitro = new Nitro(this);
|
|
|
|
m_nitro->ref();
|
2008-12-01 04:17:17 +00:00
|
|
|
|
2008-12-02 13:01:39 +00:00
|
|
|
m_skidmarks = new SkidMarks(*this);
|
2007-05-27 16:01:53 +00:00
|
|
|
|
|
|
|
m_shadow = createShadow(m_kart_properties->getShadowFile(), -1, 1, -1, 1);
|
|
|
|
m_shadow->ref();
|
2007-12-08 13:04:56 +00:00
|
|
|
m_model_transform->addKid ( m_shadow );
|
2009-01-16 00:37:31 +00:00
|
|
|
m_shadow_enabled = true;
|
2007-05-27 16:01:53 +00:00
|
|
|
} // loadData
|
|
|
|
|
2008-11-07 01:05:52 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Stores the current suspension length. This function is called from world
|
|
|
|
* after all karts are in resting position (see World::resetAllKarts), so
|
|
|
|
* that the default suspension rest length can be stored. This is then used
|
|
|
|
* later to move the wheels depending on actual suspension, so that when
|
|
|
|
* a kart is in rest, the wheels are at the position at which they were
|
|
|
|
* modelled.
|
|
|
|
*/
|
|
|
|
void Kart::setSuspensionLength()
|
|
|
|
{
|
|
|
|
for(unsigned int i=0; i<4; i++)
|
|
|
|
{
|
|
|
|
m_default_suspension_length[i] =
|
|
|
|
m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
|
|
|
|
} // for i
|
|
|
|
} // setSuspensionLength
|
2008-12-01 22:05:25 +00:00
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-06-20 09:34:35 +00:00
|
|
|
void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
|
2007-05-27 16:01:53 +00:00
|
|
|
{
|
2008-11-07 01:05:52 +00:00
|
|
|
float wheel_z_axis[4];
|
|
|
|
KartModel *kart_model = m_kart_properties->getKartModel();
|
|
|
|
for(unsigned int i=0; i<4; i++)
|
|
|
|
{
|
2008-11-10 04:34:22 +00:00
|
|
|
// Set the suspension length
|
|
|
|
wheel_z_axis[i] = m_default_suspension_length[i]
|
|
|
|
- m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
|
2008-11-07 01:05:52 +00:00
|
|
|
}
|
2009-01-04 01:14:59 +00:00
|
|
|
#define AUTO_SKID_VISUAL 1.7f
|
|
|
|
float auto_skid;
|
|
|
|
if (m_skidding>AUTO_SKID_VISUAL) // Above a limit, start counter rotating the wheels to get drifting look
|
|
|
|
auto_skid = m_controls.m_steer*30.0f*((AUTO_SKID_VISUAL - m_skidding) / 0.8f); // divisor comes from max_skid - AUTO_SKID_VISUAL
|
|
|
|
else
|
|
|
|
auto_skid = m_controls.m_steer*30.0f;
|
|
|
|
kart_model->adjustWheels(m_wheel_rotation, auto_skid,
|
2008-11-07 01:05:52 +00:00
|
|
|
wheel_z_axis);
|
2007-05-27 16:01:53 +00:00
|
|
|
|
2008-07-17 01:33:49 +00:00
|
|
|
Vec3 center_shift = getGravityCenterShift();
|
2008-11-10 04:34:22 +00:00
|
|
|
float X = m_vehicle->getWheelInfo(0).m_chassisConnectionPointCS.getZ()
|
|
|
|
- m_default_suspension_length[0]
|
|
|
|
- m_vehicle->getWheelInfo(0).m_wheelsRadius
|
|
|
|
- (kart_model->getWheelGraphicsRadius(0)
|
2008-12-21 21:40:00 +00:00
|
|
|
-kart_model->getWheelGraphicsPosition(0).getZ() );
|
2008-11-10 04:34:22 +00:00
|
|
|
center_shift.setZ(X);
|
2008-11-24 00:47:55 +00:00
|
|
|
|
2008-12-01 04:17:17 +00:00
|
|
|
if(m_smoke_system)
|
2008-12-08 01:07:16 +00:00
|
|
|
{
|
2008-12-21 21:40:00 +00:00
|
|
|
float f = fabsf(m_controls.m_steer) > 0.8 ? 50.0f : 0.0f;
|
2008-12-08 01:07:16 +00:00
|
|
|
m_smoke_system->setCreationRate((m_skidding-1)*f);
|
|
|
|
}
|
2008-12-01 09:26:25 +00:00
|
|
|
if(m_nitro)
|
2008-12-21 21:40:00 +00:00
|
|
|
m_nitro->setCreationRate(m_controls.m_nitro && m_collected_energy>0
|
2008-12-04 05:07:20 +00:00
|
|
|
? getSpeed()*5.0f : 0);
|
2008-11-24 00:47:55 +00:00
|
|
|
|
|
|
|
float speed_ratio = getSpeed()/getMaxSpeed();
|
2008-12-15 03:56:54 +00:00
|
|
|
float offset_heading = getSteerPercent()*m_kart_properties->getSkidVisual()
|
|
|
|
* speed_ratio * m_skidding*m_skidding;
|
2008-12-21 21:40:00 +00:00
|
|
|
Moveable::updateGraphics(center_shift, Vec3(offset_heading, 0, 0));
|
2008-06-20 09:34:35 +00:00
|
|
|
} // updateGraphics
|
|
|
|
|
2007-05-27 16:01:53 +00:00
|
|
|
/* EOF */
|