Moved explosion and rescue handling to EmergencyAnimation object
(previously called ExplosionAnimation). Updated vs project file for latest changes as well. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5239 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -332,6 +332,10 @@
|
||||
RelativePath="..\..\audio\music_information.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\audio\music_manager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\audio\music_ogg.cpp"
|
||||
>
|
||||
@@ -344,10 +348,6 @@
|
||||
RelativePath="..\..\audio\sfx_openal.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\audio\sound_manager.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="modes"
|
||||
@@ -465,7 +465,7 @@
|
||||
Name="karts"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\karts\explosion_animation.cpp"
|
||||
RelativePath="..\..\karts\emergency_animation.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@@ -1146,6 +1146,10 @@
|
||||
RelativePath="..\..\audio\music_information.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\audio\music_manager.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\audio\music_ogg.hpp"
|
||||
>
|
||||
@@ -1162,10 +1166,6 @@
|
||||
RelativePath="..\..\audio\sfx_openal.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\audio\sound_manager.hpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="modes"
|
||||
@@ -1291,7 +1291,7 @@
|
||||
Name="karts"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\karts\explosion_animation.hpp"
|
||||
RelativePath="..\..\karts\emergency_animation.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
||||
@@ -199,7 +199,7 @@ void Attachment::update(float dt)
|
||||
}
|
||||
break;
|
||||
case ATTACH_TINYTUX:
|
||||
if(m_time_left<=0.0) m_kart->endRescue();
|
||||
// Nothing to do for tiny tux, this is all handled in EmergencyAnimation
|
||||
break;
|
||||
} // switch
|
||||
|
||||
|
||||
@@ -174,7 +174,8 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
for(unsigned int i=0 ; i<world->getNumKarts(); i++ )
|
||||
{
|
||||
Kart *kart = world->getKart(i);
|
||||
if(kart->isEliminated() || kart == m_owner || kart->isRescue() ) continue;
|
||||
if(kart->isEliminated() || kart == m_owner ||
|
||||
kart->playingEmergencyAnimation() ) continue;
|
||||
btTransform t=kart->getTrans();
|
||||
|
||||
Vec3 delta = t.getOrigin()-tProjectile.getOrigin();
|
||||
|
||||
@@ -469,7 +469,8 @@ void DefaultAIController::handleSteering(float dt)
|
||||
void DefaultAIController::handleItems( const float DELTA, const int STEPS )
|
||||
{
|
||||
m_controls->m_fire = false;
|
||||
if(m_kart->isRescue() || m_kart->getPowerup()->getType() == POWERUP_NOTHING ) return;
|
||||
if(m_kart->playingEmergencyAnimation() ||
|
||||
m_kart->getPowerup()->getType() == POWERUP_NOTHING ) return;
|
||||
|
||||
m_time_since_last_shot += DELTA;
|
||||
|
||||
@@ -676,7 +677,8 @@ void DefaultAIController::handleRaceStart()
|
||||
void DefaultAIController::handleRescue(const float DELTA)
|
||||
{
|
||||
// check if kart is stuck
|
||||
if(m_kart->getSpeed()<2.0f && !m_kart->isRescue() && !m_world->isStartPhase())
|
||||
if(m_kart->getSpeed()<2.0f && !m_kart->playingEmergencyAnimation() &&
|
||||
!m_world->isStartPhase())
|
||||
{
|
||||
m_time_since_stuck += DELTA;
|
||||
if(m_time_since_stuck > 2.0f)
|
||||
|
||||
@@ -454,7 +454,8 @@ void NewAIController::handleSteering(float dt)
|
||||
void NewAIController::handleItems( const float DELTA, const int STEPS )
|
||||
{
|
||||
m_controls->m_fire = false;
|
||||
if(m_kart->isRescue() || m_kart->getPowerup()->getType() == POWERUP_NOTHING ) return;
|
||||
if(m_kart->playingEmergencyAnimation() ||
|
||||
m_kart->getPowerup()->getType() == POWERUP_NOTHING ) return;
|
||||
|
||||
m_time_since_last_shot += DELTA;
|
||||
|
||||
@@ -660,7 +661,8 @@ void NewAIController::handleRaceStart()
|
||||
void NewAIController::handleRescue(const float DELTA)
|
||||
{
|
||||
// check if kart is stuck
|
||||
if(m_kart->getSpeed()<2.0f && !m_kart->isRescue() && !m_world->isStartPhase())
|
||||
if(m_kart->getSpeed()<2.0f && !m_kart->playingEmergencyAnimation() &&
|
||||
!m_world->isStartPhase())
|
||||
{
|
||||
m_time_since_stuck += DELTA;
|
||||
if(m_time_since_stuck > 2.0f)
|
||||
|
||||
@@ -302,7 +302,7 @@ void PlayerController::update(float dt)
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_controls->m_fire && !m_kart->isRescue())
|
||||
if ( m_controls->m_fire && !m_kart->playingEmergencyAnimation())
|
||||
{
|
||||
if (m_kart->getPowerup()->getType()==POWERUP_NOTHING)
|
||||
m_kart->beep();
|
||||
@@ -324,7 +324,8 @@ void PlayerController::update(float dt)
|
||||
m_kart->forceRescue();
|
||||
m_controls->m_rescue=false;
|
||||
}
|
||||
if (m_kart->isRescue() && m_kart->getAttachment()->getType() != ATTACH_TINYTUX)
|
||||
if (m_kart->playingEmergencyAnimation() &&
|
||||
m_kart->getAttachment()->getType() != ATTACH_TINYTUX)
|
||||
{
|
||||
m_bzzt_sound->play();
|
||||
}
|
||||
|
||||
162
src/karts/emergency_animation.cpp
Normal file
162
src/karts/emergency_animation.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
// $Id$
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 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/emergency_animation.hpp"
|
||||
|
||||
#include "karts/kart.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "physics/btKart.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
|
||||
/** The constructor stores a pointer to the kart this object is animating,
|
||||
* and initialised the timer.
|
||||
* \param kart Pointer to the kart which is animated.
|
||||
*/
|
||||
EmergencyAnimation::EmergencyAnimation(Kart *kart)
|
||||
{
|
||||
m_kart = kart;
|
||||
// Setting kart mode here is important! If the mode should be rescue 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_kart_mode = EA_NONE;
|
||||
|
||||
}; // EmergencyAnimation
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Resets all data at the beginning of a race.
|
||||
*/
|
||||
void EmergencyAnimation::reset()
|
||||
{
|
||||
// If the kart was eliminated or rescued, the body was removed from the
|
||||
// physics world. Add it again.
|
||||
if(playingEmergencyAnimation())
|
||||
{
|
||||
World::getWorld()->getPhysics()->addKart(m_kart);
|
||||
}
|
||||
m_timer = 0;
|
||||
m_kart_mode = EA_NONE;
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the mode of the kart to being rescued, attaches the rescue model
|
||||
* and saves the current pitch and roll (for the rescue animation). It
|
||||
* also removes the kart from the physics world.
|
||||
*/
|
||||
void EmergencyAnimation::forceRescue()
|
||||
{
|
||||
if(playingEmergencyAnimation()) return;
|
||||
|
||||
m_kart_mode = EA_RESCUE;
|
||||
m_timer = m_kart->getKartProperties()->getRescueTime();
|
||||
m_up_velocity = m_kart->getKartProperties()->getRescueHeight() / m_timer;
|
||||
m_xyz = m_kart->getXYZ();
|
||||
|
||||
// FIXME: which version to use?
|
||||
m_curr_rotation.setHPR(m_kart->getRotation());
|
||||
|
||||
m_curr_rotation.setPitch(m_kart->getPitch());
|
||||
m_curr_rotation.setRoll(m_kart->getRoll() );
|
||||
m_curr_rotation.setHeading(0);
|
||||
m_add_rotation = -m_curr_rotation/m_timer;
|
||||
m_curr_rotation.setHeading(m_kart->getHeading());
|
||||
|
||||
World::getWorld()->getPhysics()->removeKart(m_kart);
|
||||
} // forceRescue
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Starts an explosion animation.
|
||||
* \param pos The coordinates of the explosion.
|
||||
* \param direct_hig True if the kart was hit directly --> maximal impact.
|
||||
*/
|
||||
void EmergencyAnimation::handleExplosion(const Vec3 &pos, bool direct_hit)
|
||||
{
|
||||
// Avoid doing another explosion while a kart is thrown around in the air.
|
||||
if(playingEmergencyAnimation()) return;
|
||||
|
||||
m_xyz = m_kart->getXYZ();
|
||||
// Ignore explosion that are too far away.
|
||||
float r = m_kart->getKartProperties()->getExplosionRadius();
|
||||
if(!direct_hit && pos.distance2(m_xyz)>r*r) return;
|
||||
|
||||
m_kart->playCustomSFX(SFXManager::CUSTOM_EXPLODE);
|
||||
m_kart_mode = EA_EXPLOSION;
|
||||
m_timer = m_kart->getKartProperties()->getExplosionTime();;
|
||||
|
||||
// Non-direct hits will be only affected half as much.
|
||||
if(!direct_hit) m_timer*=0.5f;
|
||||
|
||||
// Half of the overall time is spent in raising, so only use
|
||||
// half of the explosion time here.
|
||||
// Velocity after t seconds is:
|
||||
// v(t) = m_up_velocity + t*gravity
|
||||
// Since v(explosion_time*0.5) = 0, the following forumla computes
|
||||
// the right initial velocity for a kart to land back after
|
||||
// the specified time.
|
||||
m_up_velocity = 0.5f * m_timer * World::getWorld()->getTrack()->getGravity();
|
||||
World::getWorld()->getPhysics()->removeKart(m_kart);
|
||||
|
||||
m_curr_rotation.setHPR(m_kart->getRotation());
|
||||
const int max_rotation = direct_hit ? 2 : 1;
|
||||
// To get rotations in both directions for each axis we determine a random
|
||||
// number between -(max_rotation-1) and +(max_rotation-1)
|
||||
float f=2.0f*M_PI/m_timer;
|
||||
m_add_rotation.setHeading( (rand()%(2*max_rotation+1)-max_rotation)*f );
|
||||
m_add_rotation.setPitch( (rand()%(2*max_rotation+1)-max_rotation)*f );
|
||||
m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f );
|
||||
|
||||
} // handleExplosion
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates the explosion animation.
|
||||
* \param dt Time step size.
|
||||
* \return True if the explosion is still shown, false if it has finished.
|
||||
*/
|
||||
void EmergencyAnimation::update(float dt)
|
||||
{
|
||||
if(!playingEmergencyAnimation()) return;
|
||||
|
||||
// See if the timer expires, if so return the kart to normal game play
|
||||
m_timer -= dt;
|
||||
if(m_timer<0)
|
||||
{
|
||||
if(m_kart_mode==EA_RESCUE)
|
||||
World::getWorld()->moveKartAfterRescue(m_kart);
|
||||
World::getWorld()->getPhysics()->addKart(m_kart);
|
||||
m_kart->getBody()->setLinearVelocity(btVector3(0,0,0));
|
||||
m_kart->getBody()->setAngularVelocity(btVector3(0,0,0));
|
||||
m_kart_mode = EA_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Explosions change the upwards velocity:
|
||||
if ( m_kart_mode==EA_EXPLOSION)
|
||||
{
|
||||
m_up_velocity -= dt*World::getWorld()->getTrack()->getGravity();
|
||||
}
|
||||
|
||||
m_xyz.setY(m_xyz.getY()+dt*m_up_velocity);
|
||||
m_kart->setXYZ(m_xyz);
|
||||
m_curr_rotation += dt*m_add_rotation;
|
||||
btQuaternion q(m_curr_rotation.getHeading(), m_curr_rotation.getPitch(),
|
||||
m_curr_rotation.getRoll());
|
||||
m_kart->setRotation(q);
|
||||
} // update
|
||||
80
src/karts/emergency_animation.hpp
Normal file
80
src/karts/emergency_animation.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
// $Id$
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 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_EMERGENCY_ANIMATION_HPP
|
||||
#define HEADER_EMERGENCY_ANIMATION_HPP
|
||||
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
class Kart;
|
||||
|
||||
/** This class is a 'mixin' for kart, and handles the animated explosion.
|
||||
* I.e. it will throw the kart a certain amount in the air, rotate it
|
||||
* randomly, and after the specified time period let it land at the
|
||||
* same spot where it was hit, therefore avoiding any problems of
|
||||
* karts being pushed on wrong parts of the track, and making explosion
|
||||
* more 'fair' (it can't happen that one explosion give you actually
|
||||
* a benefit by pushing you forwards.
|
||||
* The object is a base class for kart, but will only be used if an
|
||||
* explosion happens.
|
||||
*/
|
||||
class EmergencyAnimation
|
||||
{
|
||||
private:
|
||||
/** The coordinates where the kart was hit originally. */
|
||||
Vec3 m_xyz;
|
||||
|
||||
/** The kart's current rotation. */
|
||||
Vec3 m_curr_rotation;
|
||||
|
||||
/** The artificial rotation to toss the kart around. It's in units
|
||||
* of rotation per second. */
|
||||
Vec3 m_add_rotation;
|
||||
|
||||
/** The upwards velocity. */
|
||||
float m_up_velocity;
|
||||
|
||||
/** Timer for the explosion. */
|
||||
float m_timer;
|
||||
|
||||
/** Duration for this explosion. This can potentially be set
|
||||
* with different values for different karts, or depending
|
||||
* on difficulty (so that on easy you can drive again earlier. */
|
||||
float m_duration;
|
||||
|
||||
/** A pointer to the class to which this object belongs. */
|
||||
Kart *m_kart;
|
||||
|
||||
/** Different kart modes: normal racing, being rescued, showing end
|
||||
* animation, explosions, kart eliminated. */
|
||||
enum {EA_NONE, EA_RESCUE, EA_EXPLOSION}
|
||||
m_kart_mode;
|
||||
public:
|
||||
EmergencyAnimation(Kart *kart);
|
||||
~EmergencyAnimation() {};
|
||||
void reset();
|
||||
void handleExplosion(const Vec3& pos, bool direct_hit);
|
||||
void forceRescue();
|
||||
void update(float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if an emergency animation is being played.
|
||||
*/
|
||||
bool playingEmergencyAnimation() const {return m_kart_mode!=EA_NONE; }
|
||||
}; // EmergencyAnimation
|
||||
#endif
|
||||
@@ -64,7 +64,7 @@
|
||||
Kart::Kart (const std::string& ident, int position,
|
||||
const btTransform& init_transform)
|
||||
: TerrainInfo(1),
|
||||
Moveable(), ExplosionAnimation(this), m_powerup(this)
|
||||
Moveable(), EmergencyAnimation(this), m_powerup(this)
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# pragma warning(1:4355)
|
||||
@@ -104,12 +104,6 @@ Kart::Kart (const std::string& ident, int position,
|
||||
m_max_speed_reverse_ratio = m_kart_properties->getMaxSpeedReverseRatio();
|
||||
m_speed = 0.0f;
|
||||
|
||||
// Re-setting kart mode is important! If the mode should be rescue 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_kart_mode = KM_RACE;
|
||||
m_wheel_rotation = 0;
|
||||
|
||||
// Create SFXBase for each custom sound (TODO: add back when properly done)
|
||||
@@ -333,11 +327,11 @@ Kart::~Kart()
|
||||
*/
|
||||
void Kart::eliminate()
|
||||
{
|
||||
if (m_kart_mode!=KM_RESCUE)
|
||||
if (!playingEmergencyAnimation())
|
||||
{
|
||||
World::getWorld()->getPhysics()->removeKart(this);
|
||||
}
|
||||
m_kart_mode = KM_ELIMINATED;
|
||||
m_eliminated = true;
|
||||
|
||||
getNode()->setVisible(false);
|
||||
} // eliminate
|
||||
@@ -380,13 +374,7 @@ void Kart::updatedWeight()
|
||||
*/
|
||||
void Kart::reset()
|
||||
{
|
||||
// If the kart was eliminated or rescued, the body was removed from the
|
||||
// physics world. Add it again.
|
||||
if(m_kart_mode==KM_ELIMINATED || m_kart_mode==KM_RESCUE)
|
||||
{
|
||||
World::getWorld()->getPhysics()->addKart(this);
|
||||
}
|
||||
|
||||
EmergencyAnimation::reset();
|
||||
if (m_camera)
|
||||
{
|
||||
m_camera->reset();
|
||||
@@ -408,8 +396,8 @@ void Kart::reset()
|
||||
m_powerup.reset();
|
||||
|
||||
m_race_position = 9;
|
||||
m_eliminated = false;
|
||||
m_finished_race = false;
|
||||
m_kart_mode = KM_RACE;
|
||||
m_finish_time = 0.0f;
|
||||
m_zipper_time_left = 0.0f;
|
||||
m_collected_energy = 0;
|
||||
@@ -474,7 +462,6 @@ void Kart::finishedRace(float time)
|
||||
if(m_finished_race) return;
|
||||
m_finished_race = true;
|
||||
m_finish_time = time;
|
||||
m_kart_mode = KM_END_ANIM;
|
||||
m_controller->finishedRace(time);
|
||||
race_manager->kartFinishedRace(this, time);
|
||||
|
||||
@@ -601,12 +588,12 @@ float Kart::getActualWheelForce()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** The kart is on ground if all 4 wheels touch the ground, and if no special
|
||||
* animation (rescue or explosion) is happening).
|
||||
* animation (rescue, explosion etc.) is happening).
|
||||
*/
|
||||
bool Kart::isOnGround() const
|
||||
{
|
||||
return (m_vehicle->getNumWheelsOnGround() == m_vehicle->getNumWheels()
|
||||
&& m_kart_mode!=KM_RESCUE && m_kart_mode!=KM_EXPLOSION);
|
||||
&& !playingEmergencyAnimation());
|
||||
} // isOnGround
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -622,70 +609,6 @@ bool Kart::isNearGround() const
|
||||
return ((getXYZ().getZ() - getHoT()) < stk_config->m_near_ground);
|
||||
} // isNearGround
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when an explosion happens.
|
||||
* \param pos Position of the explosion.
|
||||
* \param direct_hit True if this kart was hit directly (and should therefore
|
||||
* be more severly affected).
|
||||
*/
|
||||
void Kart::handleExplosion(const Vec3& pos, bool direct_hit)
|
||||
{
|
||||
int sign_bits = rand(); // To select plus or minus randomnly, assuming 15 bit at least
|
||||
if(direct_hit)
|
||||
{
|
||||
ExplosionAnimation::handleExplosion(pos, direct_hit);
|
||||
m_kart_mode = KM_EXPLOSION;
|
||||
// Play associated kart sound
|
||||
playCustomSFX(SFXManager::CUSTOM_EXPLODE);
|
||||
return;
|
||||
|
||||
float sign_a = (sign_bits & (0x1 << 8)) ? 1.0f : -1.0f;
|
||||
float sign_b = (sign_bits & (0x1 << 9)) ? 1.0f : -1.0f;
|
||||
float sign_c = (sign_bits & (0x1 << 10)) ? 1.0f : -1.0f;
|
||||
float sign_d = (sign_bits & (0x1 << 11)) ? 1.0f : -1.0f;
|
||||
float sign_e = (sign_bits & (0x1 << 12)) ? 1.0f : -1.0f;
|
||||
|
||||
btVector3 diff(sign_a * float(rand()%16) / 16.0f, 2.0f, sign_b * float(rand()%16) / 16.0f);
|
||||
diff.normalize();
|
||||
diff *= stk_config->m_explosion_impulse / 5.0f;
|
||||
m_uprightConstraint->setDisableTime(10.0f);
|
||||
getVehicle()->getRigidBody()->applyCentralImpulse(diff);
|
||||
|
||||
float torqueX = sign_c * (20.0f + float(rand()%32) * 5.0f);
|
||||
float torqueY = sign_d * (20.0f + float(rand()%32) * 5.0f);
|
||||
float torqueZ = sign_e * (20.0f + float(rand()%32) * 5.0f);
|
||||
|
||||
btVector3 torque(torqueX, torqueY, torqueZ);
|
||||
getVehicle()->getRigidBody()->applyTorqueImpulse(torque);
|
||||
|
||||
m_stars_effect->showFor(6.0f);
|
||||
}
|
||||
else // only affected by a distant explosion
|
||||
{
|
||||
btVector3 diff=getXYZ()-pos;
|
||||
// If the Y component is negative, the resulting impulse could push the
|
||||
// kart through the floor. So in this case ignore Y.
|
||||
if(diff.getY()<0.0f) diff.setY(0.0f);
|
||||
float len2=diff.length2();
|
||||
|
||||
// Protect against "near zero" distances
|
||||
len2 = (len2 > 0.5f) ? len2 : 0.5f;
|
||||
|
||||
// The correct formulae 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 :)
|
||||
diff *= stk_config->m_explosion_impulse/len2;
|
||||
getVehicle()->getRigidBody()->applyCentralImpulse(diff);
|
||||
// Even if just pushed, give some random rotation to simulate the lost of control by the shake
|
||||
float sign_a = (sign_bits & (0x1 << 8)) ? 1.0f : -1.0f;
|
||||
getVehicle()->getRigidBody()->applyTorqueImpulse(btVector3(0, sign_a * float(rand()%32*5)/sqrt(len2), 0));
|
||||
} // if direct_hit
|
||||
} // handleExplosion
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the kart in each time step. It updates the physics setting,
|
||||
* particle effects, camera position, etc.
|
||||
@@ -710,7 +633,7 @@ void Kart::update(float dt)
|
||||
|
||||
// On a client fiering is done upon receiving the command from the server.
|
||||
if ( m_controls.m_fire && network_manager->getMode()!=NetworkManager::NW_CLIENT
|
||||
&& !isRescue())
|
||||
&& !playingEmergencyAnimation())
|
||||
{
|
||||
// use() needs to be called even if there currently is no collecteable
|
||||
// since use() can test if something needs to be switched on/off.
|
||||
@@ -749,25 +672,7 @@ void Kart::update(float dt)
|
||||
m_wheel_rotation += m_speed*dt / m_kart_properties->getWheelRadius();
|
||||
m_wheel_rotation=fmodf(m_wheel_rotation, 2*M_PI);
|
||||
|
||||
if ( m_kart_mode==KM_RESCUE )
|
||||
{
|
||||
// Let the kart raise 2m in the 2 seconds of the rescue
|
||||
const float rescue_time = m_kart_properties->getRescueTime();
|
||||
const float rescue_height = 2.0f;
|
||||
btQuaternion q_roll (btVector3(0.0f, 0.0f, 1.0f),
|
||||
m_rescue_roll*dt/rescue_time);
|
||||
btQuaternion q_pitch(btVector3(1.f, 0.f, 0.f),
|
||||
m_rescue_pitch*dt/rescue_time);
|
||||
setXYZ(getXYZ()+Vec3(0,
|
||||
m_kart_properties->getRescueHeight()*dt/rescue_time,
|
||||
0));
|
||||
setRotation(getRotation()*q_roll*q_pitch);
|
||||
} // if rescue mode
|
||||
else if ( m_kart_mode==KM_EXPLOSION)
|
||||
{
|
||||
if(!ExplosionAnimation::update(dt))
|
||||
m_kart_mode = KM_RACE;
|
||||
}
|
||||
EmergencyAnimation::update(dt);
|
||||
|
||||
m_attachment->update(dt);
|
||||
|
||||
@@ -872,12 +777,12 @@ void Kart::update(float dt)
|
||||
// is rescued isOnGround might still be true, since the kart rigid
|
||||
// body was removed from the physics, but still retain the old
|
||||
// values for the raycasts).
|
||||
if( (!isOnGround() || m_kart_mode==KM_RESCUE) && m_shadow_enabled)
|
||||
if( (!isOnGround() || playingEmergencyAnimation()) && m_shadow_enabled)
|
||||
{
|
||||
m_shadow_enabled = false;
|
||||
m_shadow->disableShadow();
|
||||
}
|
||||
if(!m_shadow_enabled && isOnGround() && m_kart_mode!=KM_RESCUE)
|
||||
if(!m_shadow_enabled && isOnGround() && !playingEmergencyAnimation())
|
||||
{
|
||||
m_shadow->enableShadow();
|
||||
m_shadow_enabled = true;
|
||||
@@ -1338,46 +1243,6 @@ void Kart::updatePhysics(float dt)
|
||||
|
||||
} // updatePhysics
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the mode of the kart to being rescued, attaches the rescue model
|
||||
* and saves the current pitch and roll (for the rescue animation). It
|
||||
* also removes the kart from the physics world.
|
||||
*/
|
||||
void Kart::forceRescue()
|
||||
{
|
||||
m_kart_mode=KM_RESCUE;
|
||||
// Just in case that rescue is pressed while the kart is being rescued
|
||||
if(m_attachment->getType() != ATTACH_TINYTUX)
|
||||
{
|
||||
m_attachment->set( ATTACH_TINYTUX, m_kart_properties->getRescueTime());
|
||||
m_rescue_pitch = getPitch();
|
||||
m_rescue_roll = getRoll();
|
||||
//m_rescue_pitch = getHPR().getPitch();
|
||||
//m_rescue_roll = getHPR().getRoll();
|
||||
race_state->itemCollected(getWorldKartId(), -1, -1);
|
||||
World::getWorld()->getPhysics()->removeKart(this);
|
||||
}
|
||||
|
||||
} // forceRescue
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Drops a kart which was rescued back on the track.
|
||||
*/
|
||||
void Kart::endRescue()
|
||||
{
|
||||
m_kart_mode = KM_RACE;
|
||||
|
||||
World::getWorld()->getPhysics()->addKart(this);
|
||||
|
||||
m_body->setLinearVelocity (btVector3(0.0f,0.0f,0.0f));
|
||||
m_body->setAngularVelocity(btVector3(0.0f,0.0f,0.0f));
|
||||
|
||||
m_vehicle->deactivateZipper();
|
||||
|
||||
// let the mode decide where to put the kart
|
||||
World::getWorld()->moveKartAfterRescue(this, m_body);
|
||||
|
||||
} // endRescue
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Attaches the right model, creates the physics and loads all special
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "graphics/camera.hpp"
|
||||
#include "items/attachment.hpp"
|
||||
#include "items/powerup.hpp"
|
||||
#include "karts/explosion_animation.hpp"
|
||||
#include "karts/emergency_animation.hpp"
|
||||
#include "karts/moveable.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
@@ -56,7 +56,7 @@ class Stars;
|
||||
* is an object that is moved on the track, and has position and rotations)
|
||||
* and TerrainInfo, which manages the terrain the kart is on.
|
||||
*/
|
||||
class Kart : public TerrainInfo, public Moveable, public ExplosionAnimation
|
||||
class Kart : public TerrainInfo, public Moveable, public EmergencyAnimation
|
||||
{
|
||||
private:
|
||||
/** Reset position. */
|
||||
@@ -175,11 +175,9 @@ private:
|
||||
* > 0 the number it contains is the time left before removing plunger. */
|
||||
float m_view_blocked_by_plunger;
|
||||
float m_speed;
|
||||
/** Different kart modes: normal racing, being rescued, showing end
|
||||
* animation, explosions, kart eliminated. */
|
||||
enum {KM_RACE, KM_RESCUE, KM_END_ANIM, KM_EXPLOSION,
|
||||
KM_ELIMINATED}
|
||||
m_kart_mode;
|
||||
|
||||
/** True if this kart has been eliminated. */
|
||||
bool m_eliminated;
|
||||
|
||||
std::vector<SFXBase*> m_custom_sounds;
|
||||
SFXBase *m_beep_sound;
|
||||
@@ -193,7 +191,6 @@ private:
|
||||
void updatePhysics(float dt);
|
||||
|
||||
protected:
|
||||
float m_rescue_pitch, m_rescue_roll;
|
||||
const KartProperties *m_kart_properties;
|
||||
|
||||
|
||||
@@ -282,8 +279,6 @@ public:
|
||||
/** Returns true if this kart has finished the race. */
|
||||
bool hasFinishedRace () const { return m_finished_race; }
|
||||
// ------------------------------------------------------------------------
|
||||
void endRescue ();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the kart has a plunger attached to its face. */
|
||||
bool hasViewBlockedByPlunger() const
|
||||
{ return m_view_blocked_by_plunger > 0; }
|
||||
@@ -358,15 +353,11 @@ public:
|
||||
* the upright constraint to allow for more realistic explosions. */
|
||||
bool isNearGround () const;
|
||||
/** Returns true if the kart is eliminated. */
|
||||
bool isEliminated () const {return m_kart_mode==KM_ELIMINATED;}
|
||||
/** Returns true if the kart is being rescued. */
|
||||
bool isRescue () const {return m_kart_mode==KM_RESCUE;}
|
||||
bool isEliminated () const {return m_eliminated;}
|
||||
void eliminate ();
|
||||
void resetBrakes ();
|
||||
void adjustSpeed (float f);
|
||||
void updatedWeight ();
|
||||
void forceRescue ();
|
||||
void handleExplosion (const Vec3& pos, bool direct_hit);
|
||||
/** Returns a name to be displayed for this kart. */
|
||||
virtual const irr::core::stringw& getName() const {return m_kart_properties->getName();}
|
||||
const std::string& getIdent () const {return m_kart_properties->getIdent();}
|
||||
|
||||
@@ -73,7 +73,7 @@ KartProperties::KartProperties(const std::string &filename) : m_icon_material(0)
|
||||
m_slipstream_use_time = m_slipstream_add_power =
|
||||
m_slipstream_min_speed = m_camera_distance =
|
||||
m_rescue_time = m_rescue_height = m_explosion_time =
|
||||
m_explosion_height = UNDEFINED;
|
||||
m_explosion_radius = UNDEFINED;
|
||||
m_gravity_center_shift = Vec3(UNDEFINED);
|
||||
m_has_skidmarks = true;
|
||||
m_version = 0;
|
||||
@@ -218,7 +218,7 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
if(const XMLNode *explosion_node = root->getNode("explosion"))
|
||||
{
|
||||
explosion_node->get("time", &m_explosion_time );
|
||||
explosion_node->get("height", &m_explosion_height);
|
||||
explosion_node->get("radius", &m_explosion_radius);
|
||||
}
|
||||
|
||||
if(const XMLNode *skid_node = root->getNode("skid"))
|
||||
@@ -477,7 +477,7 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
CHECK_NEG(m_rescue_time, "rescue time" );
|
||||
CHECK_NEG(m_rescue_vert_offset, "rescue vert-offset" );
|
||||
CHECK_NEG(m_explosion_time, "explosion time" );
|
||||
CHECK_NEG(m_explosion_height, "explosion height" );
|
||||
CHECK_NEG(m_explosion_radius, "explosion radius" );
|
||||
|
||||
} // checkAllSet
|
||||
|
||||
|
||||
@@ -115,8 +115,8 @@ private:
|
||||
/** Time an animated explosion is shown. Longer = more delay for kart. */
|
||||
float m_explosion_time;
|
||||
|
||||
/** Height of an explosion animation. */
|
||||
float m_explosion_height;
|
||||
/** How far away from an explosion karts will still be affected. */
|
||||
float m_explosion_radius;
|
||||
|
||||
/** Vertical offset after rescue. */
|
||||
float m_rescue_vert_offset;
|
||||
@@ -256,7 +256,7 @@ public:
|
||||
/** Returns the time an explosion animation is shown. */
|
||||
float getExplosionTime () const {return m_explosion_time; }
|
||||
/** Returns the height of the explosion animation. */
|
||||
float getExplosionHeight () const {return m_explosion_height; }
|
||||
float getExplosionRadius () const {return m_explosion_radius; }
|
||||
/** Returns how much a kart can roll/pitch before the upright constraint
|
||||
* counteracts. */
|
||||
float getUprightTolerance () const {return m_upright_tolerance; }
|
||||
|
||||
@@ -159,7 +159,7 @@ void LinearWorld::update(float delta)
|
||||
Kart* kart = m_karts[n];
|
||||
|
||||
// Nothing to do for karts that are currently being rescued or eliminated
|
||||
if(kart->isRescue() || kart->isEliminated()) continue;
|
||||
if(kart->playingEmergencyAnimation()) continue;
|
||||
|
||||
// ---------- deal with sector data ---------
|
||||
|
||||
@@ -541,7 +541,7 @@ float LinearWorld::estimateFinishTimeForKart(Kart* kart)
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Decide where to drop a rescued kart
|
||||
*/
|
||||
void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
void LinearWorld::moveKartAfterRescue(Kart* kart)
|
||||
{
|
||||
KartInfo& info = m_kart_info[kart->getWorldKartId()];
|
||||
|
||||
@@ -581,7 +581,7 @@ void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
|
||||
m_track->getAngle(info.m_track_sector)));
|
||||
|
||||
body->setCenterOfMassTransform(pos);
|
||||
kart->getBody()->setCenterOfMassTransform(pos);
|
||||
|
||||
//project kart to surface of track
|
||||
bool kart_over_ground = m_physics->projectKartDownwards(kart);
|
||||
@@ -591,7 +591,7 @@ void LinearWorld::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
//add vertical offset so that the kart starts off above the track
|
||||
float vertical_offset = kart->getKartProperties()->getVertRescueOffset() *
|
||||
kart->getKartHeight();
|
||||
body->translate(btVector3(0, vertical_offset, 0));
|
||||
kart->getBody()->translate(btVector3(0, vertical_offset, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
|
||||
virtual RaceGUI::KartIconDisplayInfo*
|
||||
getKartsDisplayInfo();
|
||||
virtual void moveKartAfterRescue(Kart* kart, btRigidBody* body);
|
||||
virtual void moveKartAfterRescue(Kart* kart);
|
||||
|
||||
virtual void restartRace();
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ RaceGUI::KartIconDisplayInfo* ThreeStrikesBattle::getKartsDisplayInfo()
|
||||
} // getKartDisplayInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart)
|
||||
{
|
||||
// find closest point to drop kart on
|
||||
World *world = World::getWorld();
|
||||
@@ -286,7 +286,7 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0.5f*kart->getKartHeight(), 0.0f));
|
||||
pos.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 0 /* angle */) );
|
||||
|
||||
body->setCenterOfMassTransform(pos);
|
||||
kart->getBody()->setCenterOfMassTransform(pos);
|
||||
|
||||
//project kart to surface of track
|
||||
bool kart_over_ground = m_physics->projectKartDownwards(kart);
|
||||
@@ -296,7 +296,7 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
//add vertical offset so that the kart starts off above the track
|
||||
float vertical_offset = kart->getKartProperties()->getVertRescueOffset() *
|
||||
kart->getKartHeight();
|
||||
body->translate(btVector3(0, vertical_offset, 0));
|
||||
kart->getBody()->translate(btVector3(0, vertical_offset, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
virtual bool useFastMusicNearEnd() const { return false; }
|
||||
virtual RaceGUI::KartIconDisplayInfo* getKartsDisplayInfo();
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
virtual void moveKartAfterRescue(Kart* kart, btRigidBody* body);
|
||||
virtual void moveKartAfterRescue(Kart* kart);
|
||||
virtual bool acceptPowerup(const PowerupType type) const;
|
||||
|
||||
virtual std::string getIdent() const;
|
||||
|
||||
@@ -229,7 +229,7 @@ public:
|
||||
/** Since each mode will have a different way of deciding where a rescued
|
||||
* kart is dropped, this method will be called and each mode can implement it.
|
||||
*/
|
||||
virtual void moveKartAfterRescue(Kart* kart, btRigidBody* body) = 0;
|
||||
virtual void moveKartAfterRescue(Kart* kart) = 0;
|
||||
|
||||
/** Called when it is needed to know whether this kind of race involves counting laps.
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,6 @@ class btKart : public btRaycastVehicle
|
||||
{
|
||||
void defaultInit(const btVehicleTuning& tuning);
|
||||
btScalar m_track_connect_accel;
|
||||
btScalar m_skidding_factor;
|
||||
int m_num_wheels_on_ground;
|
||||
bool m_zipper_active;
|
||||
btScalar m_zipper_velocity;
|
||||
@@ -34,7 +33,6 @@ public:
|
||||
btScalar rayCast(btWheelInfo& wheel);
|
||||
btScalar rayCast(btWheelInfo& wheel, const btVector3& ray);
|
||||
bool projectVehicleToSurface(const btVector3& ray, bool translate_vehicle);
|
||||
void setSkidding(btScalar sf) { m_skidding_factor = sf; }
|
||||
virtual void updateVehicle(btScalar step);
|
||||
void resetSuspension();
|
||||
int getNumWheelsOnGround() const { return m_num_wheels_on_ground; }
|
||||
|
||||
Reference in New Issue
Block a user