Completely revamps slipstreaming
This commit is contained in:
parent
b2bdd49931
commit
f41b537477
@ -36,17 +36,21 @@
|
|||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
#include "utils/mini_glm.hpp"
|
#include "utils/mini_glm.hpp"
|
||||||
|
|
||||||
/** Creates the slip stream object using a moving texture.
|
/** Creates the slip stream object
|
||||||
* \param kart Pointer to the kart to which the slip stream
|
* \param kart Pointer to the kart to which the slip stream
|
||||||
* belongs to.
|
* belongs to.
|
||||||
*/
|
*/
|
||||||
SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
SlipStream::SlipStream(AbstractKart* kart)
|
||||||
{
|
{
|
||||||
m_node = NULL;
|
m_node = NULL;
|
||||||
|
m_kart = kart;
|
||||||
|
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
if (CVS->isGLSL())
|
if (CVS->isGLSL())
|
||||||
{
|
{
|
||||||
|
m_moving = new MovingTexture(0.0f, 0.0f);
|
||||||
|
m_moving_fast = new MovingTexture(0.0f, 0.0f);
|
||||||
|
|
||||||
Material* material =
|
Material* material =
|
||||||
material_manager->getMaterialSPM("slipstream.png", "");
|
material_manager->getMaterialSPM("slipstream.png", "");
|
||||||
SP::SPMesh* mesh = createMesh(material);
|
SP::SPMesh* mesh = createMesh(material);
|
||||||
@ -59,23 +63,42 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
|||||||
m_node->setVisible(false);
|
m_node->setVisible(false);
|
||||||
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(m_node);
|
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(m_node);
|
||||||
assert(spmn);
|
assert(spmn);
|
||||||
setSPTM(spmn->getTextureMatrix(0).data());
|
m_moving->setSPTM(spmn->getTextureMatrix(0).data());
|
||||||
|
|
||||||
|
material = material_manager->getMaterialSPM("slipstream2.png", "");
|
||||||
|
mesh = createMesh(material);
|
||||||
|
m_node_fast = irr_driver->addMesh(mesh, "slipstream2");
|
||||||
|
mesh->drop();
|
||||||
|
debug_name = m_kart->getIdent()+" (slip-stream2)";
|
||||||
|
m_node_fast->setName(debug_name.c_str());
|
||||||
|
m_node_fast->setPosition(core::vector3df(0, 0 * 0.25f + 2.5f,
|
||||||
|
m_kart->getKartLength()));
|
||||||
|
m_node_fast->setVisible(false);
|
||||||
|
spmn = dynamic_cast<SP::SPMeshNode*>(m_node_fast);
|
||||||
|
assert(spmn);
|
||||||
|
m_moving_fast->setSPTM(spmn->getTextureMatrix(0).data());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_slipstream_time = 0.0f;
|
m_slipstream_time = 0.0f;
|
||||||
|
|
||||||
float length = m_kart->getKartProperties()->getSlipstreamLength();
|
//The kart starts at 0 speed anyway
|
||||||
|
float length = 0.0f;
|
||||||
float kw = m_kart->getKartWidth();
|
float kw = m_kart->getKartWidth();
|
||||||
float ew = m_kart->getKartProperties()->getSlipstreamWidth();
|
float ew = 0.0f;
|
||||||
float kl = m_kart->getKartLength();
|
float kl = m_kart->getKartLength();
|
||||||
|
|
||||||
|
//making the slipstream quad start at the kart front
|
||||||
|
//allows better results when the kart turns
|
||||||
Vec3 p[4];
|
Vec3 p[4];
|
||||||
p[0]=Vec3(-kw*0.5f, 0, -kl*0.5f );
|
p[0]=Vec3(-kw*0.5f, 0, kl*0.5f );
|
||||||
p[1]=Vec3(-ew*0.5f, 0, -kl*0.5f-length);
|
p[1]=Vec3(-ew*0.5f, 0, -kl*0.5f-length);
|
||||||
p[2]=Vec3( ew*0.5f, 0, -kl*0.5f-length);
|
p[2]=Vec3( ew*0.5f, 0, -kl*0.5f-length);
|
||||||
p[3]=Vec3( kw*0.5f, 0, -kl*0.5f );
|
p[3]=Vec3( kw*0.5f, 0, kl*0.5f );
|
||||||
|
|
||||||
m_slipstream_quad = new Quad(p[0], p[1], p[2], p[3]);
|
m_slipstream_quad = new Quad(p[0], p[1], p[2], p[3]);
|
||||||
|
//The position will be corrected in the update anyway
|
||||||
|
m_slipstream_inner_quad = new Quad(p[0], p[1], p[2], p[3]);
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
if (UserConfigParams::m_slipstream_debug)
|
if (UserConfigParams::m_slipstream_debug)
|
||||||
{
|
{
|
||||||
@ -97,6 +120,22 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
|||||||
m_debug_dc->recalculateBoundingBox();
|
m_debug_dc->recalculateBoundingBox();
|
||||||
m_debug_dc->setParent(m_kart->getNode());
|
m_debug_dc->setParent(m_kart->getNode());
|
||||||
SP::addDynamicDrawCall(m_debug_dc);
|
SP::addDynamicDrawCall(m_debug_dc);
|
||||||
|
|
||||||
|
m_debug_dc2 = std::make_shared<SP::SPDynamicDrawCall>
|
||||||
|
(scene::EPT_TRIANGLE_STRIP,
|
||||||
|
SP::SPShaderManager::get()->getSPShader("additive"),
|
||||||
|
material_manager->getDefaultSPMaterial("additive"));
|
||||||
|
m_debug_dc2->getVerticesVector().resize(4);
|
||||||
|
v = m_debug_dc2->getVerticesVector().data();
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
v[i].m_position = p[idx[i]].toIrrVector();
|
||||||
|
v[i].m_normal = 0x1FF << 10;
|
||||||
|
v[i].m_color = red;
|
||||||
|
}
|
||||||
|
m_debug_dc2->recalculateBoundingBox();
|
||||||
|
m_debug_dc2->setParent(m_kart->getNode());
|
||||||
|
SP::addDynamicDrawCall(m_debug_dc2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} // SlipStream
|
} // SlipStream
|
||||||
@ -110,11 +149,22 @@ SlipStream::~SlipStream()
|
|||||||
{
|
{
|
||||||
irr_driver->removeNode(m_node);
|
irr_driver->removeNode(m_node);
|
||||||
}
|
}
|
||||||
|
if (m_node_fast)
|
||||||
|
{
|
||||||
|
irr_driver->removeNode(m_node_fast);
|
||||||
|
}
|
||||||
if (m_debug_dc)
|
if (m_debug_dc)
|
||||||
{
|
{
|
||||||
m_debug_dc->removeFromSP();
|
m_debug_dc->removeFromSP();
|
||||||
}
|
}
|
||||||
|
if (m_debug_dc2)
|
||||||
|
{
|
||||||
|
m_debug_dc2->removeFromSP();
|
||||||
|
}
|
||||||
delete m_slipstream_quad;
|
delete m_slipstream_quad;
|
||||||
|
delete m_slipstream_inner_quad;
|
||||||
|
delete m_moving;
|
||||||
|
delete m_moving_fast;
|
||||||
|
|
||||||
} // ~SlipStream
|
} // ~SlipStream
|
||||||
|
|
||||||
@ -246,41 +296,56 @@ SP::SPMesh* SlipStream::createMesh(Material* material)
|
|||||||
/** Sets the animation intensity (or speed).
|
/** Sets the animation intensity (or speed).
|
||||||
* \param f Intensity: 0 = no slip stream,
|
* \param f Intensity: 0 = no slip stream,
|
||||||
* 1 = collecting
|
* 1 = collecting
|
||||||
* 2 = using slip stream bonus
|
* 2 = bonus can be used
|
||||||
*/
|
*/
|
||||||
void SlipStream::setIntensity(float f, const AbstractKart *kart)
|
void SlipStream::setIntensity(float f, const AbstractKart *kart)
|
||||||
{
|
{
|
||||||
if (!kart || !m_node)
|
if (!kart || !m_node || !m_node_fast)
|
||||||
{
|
{
|
||||||
if (m_node)
|
if (m_node)
|
||||||
{
|
{
|
||||||
m_node->setVisible(false);
|
m_node->setVisible(false);
|
||||||
}
|
}
|
||||||
|
if (m_node_fast)
|
||||||
|
{
|
||||||
|
m_node_fast->setVisible(false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_node->setVisible(true);
|
float ktf = m_kart->getKartProperties()->getSlipstreamCollectTime();
|
||||||
|
|
||||||
const float above_terrain = 0.2f;
|
const float above_terrain = 0.2f;
|
||||||
core::vector3df my_pos = m_kart->getNode()->getPosition();
|
core::vector3df my_pos = m_kart->getNode()->getPosition();
|
||||||
my_pos.Y = m_kart->getHoT()+above_terrain;
|
my_pos.Y = m_kart->getHoT()+above_terrain;
|
||||||
m_node->setPosition(my_pos);
|
|
||||||
|
|
||||||
core::vector3df other_pos = kart->getNode()->getPosition();
|
core::vector3df other_pos = kart->getNode()->getPosition();
|
||||||
other_pos.Y = kart->getHoT()+above_terrain;
|
other_pos.Y = kart->getHoT()+above_terrain;
|
||||||
core::vector3df diff = other_pos - my_pos;
|
core::vector3df diff = other_pos - my_pos;
|
||||||
core::vector3df rotation = diff.getHorizontalAngle();
|
core::vector3df rotation = diff.getHorizontalAngle();
|
||||||
m_node->setRotation(rotation);
|
|
||||||
float fs = diff.getLength()/m_length;
|
float fs = diff.getLength()/m_length;
|
||||||
|
|
||||||
|
m_node->setPosition(my_pos);
|
||||||
|
m_node->setRotation(rotation);
|
||||||
m_node->setScale(core::vector3df(1, 1, fs));
|
m_node->setScale(core::vector3df(1, 1, fs));
|
||||||
|
|
||||||
// For real testing in game: this needs some tuning!
|
m_node_fast->setPosition(my_pos);
|
||||||
m_node->setVisible(f!=0);
|
m_node_fast->setRotation(rotation);
|
||||||
MovingTexture::setSpeed(f, 0);
|
m_node_fast->setScale(core::vector3df(1, 1, fs));
|
||||||
|
|
||||||
|
m_node->setVisible(f>0.0f && f<ktf);
|
||||||
|
m_node_fast->setVisible(f>=ktf);
|
||||||
|
|
||||||
|
//specify the texture speed movement
|
||||||
|
if (f > 8.0f) f = 8.0f;
|
||||||
|
f = f/2;
|
||||||
|
|
||||||
|
m_moving->setSpeed(f, 0);
|
||||||
|
m_moving_fast->setSpeed(f, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
// For debugging: make the slip stream effect visible all the time
|
// For debugging: make the slip stream effect visible all the time
|
||||||
m_node->setVisible(true);
|
m_node->setVisible(true);
|
||||||
MovingTexture::setSpeed(1.0f, 0.0f);
|
m_moving->setSpeed(1.0f, 0.0f);
|
||||||
} // setIntensity
|
} // setIntensity
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -302,8 +367,7 @@ void SlipStream::updateSlipstreamPower()
|
|||||||
// See if we are currently using accumulated slipstream credits:
|
// See if we are currently using accumulated slipstream credits:
|
||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
if(m_slipstream_mode==SS_USE)
|
if(m_slipstream_mode==SS_USE)
|
||||||
{
|
{
|
||||||
setIntensity(2.0f, NULL);
|
|
||||||
const KartProperties *kp = m_kart->getKartProperties();
|
const KartProperties *kp = m_kart->getKartProperties();
|
||||||
m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM,
|
m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM,
|
||||||
kp->getSlipstreamMaxSpeedIncrease(),
|
kp->getSlipstreamMaxSpeedIncrease(),
|
||||||
@ -320,23 +384,160 @@ void SlipStream::updateSlipstreamPower()
|
|||||||
* black: kart too slow
|
* black: kart too slow
|
||||||
* red: not inside of slipstream area
|
* red: not inside of slipstream area
|
||||||
* green: slipstream is being accumulated.
|
* green: slipstream is being accumulated.
|
||||||
|
* \param inner : bool to know if we apply the color to the inner quad or to the main one
|
||||||
*/
|
*/
|
||||||
void SlipStream::setDebugColor(const video::SColor &color)
|
void SlipStream::setDebugColor(const video::SColor &color, bool inner)
|
||||||
{
|
{
|
||||||
if (!m_debug_dc)
|
if (!inner)
|
||||||
{
|
{
|
||||||
return;
|
if (!m_debug_dc)
|
||||||
}
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
video::S3DVertexSkinnedMesh* v = m_debug_dc->getVerticesVector().data();
|
video::S3DVertexSkinnedMesh* v = m_debug_dc->getVerticesVector().data();
|
||||||
for (unsigned i = 0; i < 4; i++)
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
v[i].m_color = color;
|
||||||
|
}
|
||||||
|
m_debug_dc->setUpdateOffset(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
v[i].m_color = color;
|
if (!m_debug_dc2)
|
||||||
}
|
{
|
||||||
m_debug_dc->setUpdateOffset(0);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::S3DVertexSkinnedMesh* v = m_debug_dc2->getVerticesVector().data();
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
v[i].m_color = color;
|
||||||
|
}
|
||||||
|
m_debug_dc2->setUpdateOffset(0);
|
||||||
|
}
|
||||||
} // setDebugColor
|
} // setDebugColor
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** UpdateQuad
|
||||||
|
*/
|
||||||
|
void SlipStream::updateQuad()
|
||||||
|
{
|
||||||
|
|
||||||
|
//Change the quad form to counteract the mismatch between
|
||||||
|
//kart orientation and real direction
|
||||||
|
|
||||||
|
//Computations are contrieved by the fact we have several
|
||||||
|
//different 3D vector, one for each library.
|
||||||
|
Vec3 moving_xyz = m_kart->getPreviousXYZ() - m_kart->getXYZ();
|
||||||
|
|
||||||
|
//retrieve a vector rotated to kart direction
|
||||||
|
btScalar bx,by,bz;//a btScalar is a float or a double
|
||||||
|
bx = 1.0f;
|
||||||
|
by = bz = 0.0f;
|
||||||
|
btVector3 rotated_base;
|
||||||
|
rotated_base.setValue(bx,by,bz);
|
||||||
|
btQuaternion rotation = m_kart->getRotation();
|
||||||
|
rotated_base = quatRotate(rotation,rotated_base);
|
||||||
|
Vec3 direction_vector;
|
||||||
|
//Z and X need to be inverted and X multiplied by -1 to match moving_xyz
|
||||||
|
direction_vector = Vec3(rotated_base.getZ(), rotated_base.getY(), -rotated_base.getX());
|
||||||
|
|
||||||
|
//normalize the moving vector
|
||||||
|
float vec_length = moving_xyz.x()*moving_xyz.x()
|
||||||
|
+ moving_xyz.y()*moving_xyz.y()
|
||||||
|
+ moving_xyz.z()*moving_xyz.z();
|
||||||
|
if (vec_length != 0)
|
||||||
|
{
|
||||||
|
vec_length = core::reciprocal_squareroot(vec_length);
|
||||||
|
float x,y,z;
|
||||||
|
x = moving_xyz.x() * vec_length;
|
||||||
|
y = moving_xyz.y() * vec_length;
|
||||||
|
z = moving_xyz.z() * vec_length;
|
||||||
|
moving_xyz = Vec3(x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
//This vector gives us the change to apply in absolute coordinates
|
||||||
|
Vec3 noffset = moving_xyz - direction_vector;
|
||||||
|
|
||||||
|
//But the quad position is in the kart coordinate space
|
||||||
|
//So we rotate it back
|
||||||
|
rotated_base.setValue(-noffset.z(),noffset.y(),noffset.x());
|
||||||
|
rotation = rotation.inverse();
|
||||||
|
rotated_base = quatRotate(rotation,rotated_base);
|
||||||
|
noffset = Vec3(rotated_base.getZ(), rotated_base.getY(), -rotated_base.getX());
|
||||||
|
|
||||||
|
float speed_factor = m_kart->getSpeed()/m_kart->getKartProperties()->getSlipstreamBaseSpeed();
|
||||||
|
float length = m_kart->getKartProperties()->getSlipstreamLength()*speed_factor;
|
||||||
|
float kw = m_kart->getKartWidth();
|
||||||
|
float ew = m_kart->getKartProperties()->getSlipstreamWidth()*speed_factor;
|
||||||
|
float kl = m_kart->getKartLength();
|
||||||
|
float offx = (kl*0.5f+length)*noffset.x();
|
||||||
|
float offz = (kl*0.5f+length)*noffset.z();
|
||||||
|
|
||||||
|
//making the slipstream quad start at the kart front
|
||||||
|
//allows better results when the kart turns
|
||||||
|
Vec3 p[4];
|
||||||
|
p[0]=Vec3(-kw*0.5f, 0, kl*0.5f );
|
||||||
|
p[1]=Vec3(-ew*0.5f+offx, 0, -kl*0.5f-length+offz);
|
||||||
|
p[2]=Vec3( ew*0.5f+offx, 0, -kl*0.5f-length+offz);
|
||||||
|
p[3]=Vec3( kw*0.5f, 0, kl*0.5f );
|
||||||
|
|
||||||
|
//Update the slipstreaming quad
|
||||||
|
m_slipstream_quad->setQuad(p[0], p[1], p[2], p[3]);
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
//recalculate quad position for debug drawing
|
||||||
|
if (UserConfigParams::m_slipstream_debug)
|
||||||
|
{
|
||||||
|
video::S3DVertexSkinnedMesh* v =
|
||||||
|
m_debug_dc->getVerticesVector().data();
|
||||||
|
unsigned idx[] = { 0, 3, 1, 2 };
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
v[i].m_position = p[idx[i]].toIrrVector();
|
||||||
|
}
|
||||||
|
m_debug_dc->recalculateBoundingBox();
|
||||||
|
m_debug_dc->setParent(m_kart->getNode());
|
||||||
|
SP::addDynamicDrawCall(m_debug_dc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
float inner_factor = m_kart->getKartProperties()->getSlipstreamInnerFactor()*sqrt(speed_factor);
|
||||||
|
length = length*inner_factor;
|
||||||
|
ew = ew*inner_factor;
|
||||||
|
if (ew > 0.5f) ew -= 0.5f;
|
||||||
|
else ew = 0;
|
||||||
|
|
||||||
|
offx = (kl*0.5f+length)*noffset.x();
|
||||||
|
offz = (kl*0.5f+length)*noffset.z();
|
||||||
|
|
||||||
|
p[0]=Vec3(-kw*0.5f, 0, kl*0.5f );
|
||||||
|
p[1]=Vec3(-ew*0.5f+offx, 0, -kl*0.5f-length+offz);
|
||||||
|
p[2]=Vec3( ew*0.5f+offx, 0, -kl*0.5f-length+offz);
|
||||||
|
p[3]=Vec3( kw*0.5f, 0, kl*0.5f );
|
||||||
|
|
||||||
|
//Update the slipstreaming inner quad
|
||||||
|
m_slipstream_inner_quad->setQuad(p[0], p[1], p[2], p[3]);
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
//recalculate inner quad position for debug drawing
|
||||||
|
if (UserConfigParams::m_slipstream_debug)
|
||||||
|
{
|
||||||
|
video::S3DVertexSkinnedMesh* v =
|
||||||
|
m_debug_dc2->getVerticesVector().data();
|
||||||
|
unsigned idx[] = { 0, 3, 1, 2 };
|
||||||
|
for (unsigned i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
v[i].m_position = p[idx[i]].toIrrVector();
|
||||||
|
}
|
||||||
|
m_debug_dc2->recalculateBoundingBox();
|
||||||
|
m_debug_dc2->setParent(m_kart->getNode());
|
||||||
|
SP::addDynamicDrawCall(m_debug_dc2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //updateQuad
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Update, called once per timestep.
|
/** Update, called once per timestep.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
@ -350,38 +551,53 @@ void SlipStream::update(float dt)
|
|||||||
|| m_kart->isGhostKart())
|
|| m_kart->isGhostKart())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MovingTexture::update(dt);
|
//there is no slipstreaming at low speed
|
||||||
|
//and the quad may do weird things if going in reverse
|
||||||
|
if(m_kart->getSpeed() > 1.0f)
|
||||||
|
{
|
||||||
|
updateQuad();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_moving->update(dt);
|
||||||
|
m_moving_fast->update(dt);
|
||||||
|
|
||||||
if(m_slipstream_mode==SS_USE)
|
if(m_slipstream_mode==SS_USE)
|
||||||
{
|
{
|
||||||
m_slipstream_time -= dt;
|
m_slipstream_time -= dt;//This makes slipstream_time decrease twice faster
|
||||||
if(m_slipstream_time<0) m_slipstream_mode=SS_NONE;
|
if(m_slipstream_time<0) m_slipstream_mode=SS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSlipstreamPower();
|
updateSlipstreamPower();
|
||||||
|
|
||||||
// If this kart is too slow for slipstreaming taking effect, do nothing
|
// If this kart is too slow for slipstreaming taking effect, do nothing
|
||||||
|
// Use a margin because what really matters is the target's speed
|
||||||
|
// If this kart is much slower than the minSpeed, then either its
|
||||||
|
// targets are slower too, or it won't stay long enough behind them
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// Define this to get slipstream effect shown even when the karts are
|
// Define this to get slipstream effect shown even when the karts are
|
||||||
// not moving. This is useful for debugging the graphics of SS-ing.
|
// not moving. This is useful for debugging the graphics of SS-ing.
|
||||||
//#define DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
//#define DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
||||||
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
||||||
if(m_kart->getSpeed() < kp->getSlipstreamMinSpeed())
|
if(m_kart->getSpeed() < kp->getSlipstreamMinSpeed() - 2.0f)
|
||||||
{
|
{
|
||||||
setIntensity(0, NULL);
|
setIntensity(0, NULL);
|
||||||
m_slipstream_mode = SS_NONE;
|
m_slipstream_mode = SS_NONE;
|
||||||
if(UserConfigParams::m_slipstream_debug)
|
if(UserConfigParams::m_slipstream_debug)
|
||||||
setDebugColor(video::SColor(255, 0, 0, 0));
|
{
|
||||||
|
setDebugColor(video::SColor(255, 0, 0, 0),false);
|
||||||
|
setDebugColor(video::SColor(255, 0, 0, 0),true);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Then test if this kart is in the slipstream range of another kart:
|
// Then test if this kart is in the slipstream range of another kart:
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
World *world = World::getWorld();
|
World *world = World::getWorld();
|
||||||
unsigned int num_karts = world->getNumKarts();
|
unsigned int num_karts = world->getNumKarts();
|
||||||
bool is_sstreaming = false;
|
bool is_sstreaming = false;
|
||||||
m_target_kart = NULL;
|
bool is_inner_sstreaming = false;
|
||||||
|
m_target_kart = NULL;
|
||||||
|
|
||||||
// Note that this loop can not be simply replaced with a shorter loop
|
// Note that this loop can not be simply replaced with a shorter loop
|
||||||
// using only the karts with a better position - since a kart might
|
// using only the karts with a better position - since a kart might
|
||||||
@ -389,6 +605,7 @@ void SlipStream::update(float dt)
|
|||||||
for(unsigned int i=0; i<num_karts; i++)
|
for(unsigned int i=0; i<num_karts; i++)
|
||||||
{
|
{
|
||||||
m_target_kart= world->getKart(i);
|
m_target_kart= world->getKart(i);
|
||||||
|
|
||||||
// Don't test for slipstream with itself, a kart that is being
|
// Don't test for slipstream with itself, a kart that is being
|
||||||
// rescued or exploding, a ghost kart or an eliminated kart
|
// rescued or exploding, a ghost kart or an eliminated kart
|
||||||
if(m_target_kart==m_kart ||
|
if(m_target_kart==m_kart ||
|
||||||
@ -396,6 +613,8 @@ void SlipStream::update(float dt)
|
|||||||
m_target_kart->isGhostKart() ||
|
m_target_kart->isGhostKart() ||
|
||||||
m_target_kart->isEliminated() ) continue;
|
m_target_kart->isEliminated() ) continue;
|
||||||
|
|
||||||
|
const KartProperties *kp_target = m_target_kart->getKartProperties();
|
||||||
|
|
||||||
// Transform this kart location into target kart point of view
|
// Transform this kart location into target kart point of view
|
||||||
Vec3 lc = m_target_kart->getTrans().inverse()(m_kart->getXYZ());
|
Vec3 lc = m_target_kart->getTrans().inverse()(m_kart->getXYZ());
|
||||||
|
|
||||||
@ -404,37 +623,51 @@ void SlipStream::update(float dt)
|
|||||||
if (fabsf(lc.y()) > 6.0f) continue;
|
if (fabsf(lc.y()) > 6.0f) continue;
|
||||||
|
|
||||||
// If the kart we are testing against is too slow, no need to test
|
// If the kart we are testing against is too slow, no need to test
|
||||||
// slipstreaming. Note: We compare the speed of the other kart
|
// slipstreaming.
|
||||||
// against the minimum slipstream speed kart of this kart - not
|
|
||||||
// entirely sure if this makes sense, but it makes it easier to
|
|
||||||
// give karts different slipstream properties.
|
|
||||||
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
||||||
if (m_target_kart->getSpeed() < kp->getSlipstreamMinSpeed())
|
if (m_target_kart->getSpeed() < kp_target->getSlipstreamMinSpeed())
|
||||||
{
|
{
|
||||||
if(UserConfigParams::m_slipstream_debug &&
|
if(UserConfigParams::m_slipstream_debug &&
|
||||||
m_kart->getController()->isLocalPlayerController())
|
m_kart->getController()->isLocalPlayerController())
|
||||||
|
{
|
||||||
m_target_kart->getSlipstream()
|
m_target_kart->getSlipstream()
|
||||||
->setDebugColor(video::SColor(255, 0, 0, 0));
|
->setDebugColor(video::SColor(255, 0, 0, 0), false);
|
||||||
|
m_target_kart->getSlipstream()
|
||||||
|
->setDebugColor(video::SColor(255, 0, 0, 0), true);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Quick test: the kart must be not more than
|
// Quick test: the kart must be not more than
|
||||||
// slipstream length+0.5*kart_length()+0.5*target_kart_length
|
// slipstream length+0.5*kart_length()+target_kart_length
|
||||||
// away from the other kart
|
// away from the other kart
|
||||||
|
// (additional target_kart_length because that kart's center
|
||||||
|
// is not the center of rotation of the slipstreaming quad)
|
||||||
Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ();
|
Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ();
|
||||||
float l = kp->getSlipstreamLength()
|
float l = kp_target->getSlipstreamLength();
|
||||||
+ 0.5f*( m_target_kart->getKartLength()
|
float speed_factor = m_target_kart->getSpeed()
|
||||||
+m_kart->getKartLength() );
|
/kp_target->getSlipstreamBaseSpeed();
|
||||||
|
l = l*speed_factor + m_target_kart->getKartLength()
|
||||||
|
+ 0.5f*m_kart->getKartLength();
|
||||||
if(delta.length2() > l*l)
|
if(delta.length2() > l*l)
|
||||||
{
|
{
|
||||||
if(UserConfigParams::m_slipstream_debug &&
|
|
||||||
m_kart->getController()->isLocalPlayerController())
|
|
||||||
m_target_kart->getSlipstream()
|
|
||||||
->setDebugColor(video::SColor(255, 0, 0, 128));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Real test: if in slipstream quad of other kart
|
// Real test 1: if in inner slipstream quad of other kart
|
||||||
|
if(m_target_kart->getSlipstream()->m_slipstream_inner_quad
|
||||||
|
->pointInside(lc))
|
||||||
|
{
|
||||||
|
is_inner_sstreaming = true;
|
||||||
|
is_sstreaming = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(UserConfigParams::m_slipstream_debug &&
|
||||||
|
m_kart->getController()->isLocalPlayerController())
|
||||||
|
m_target_kart->getSlipstream()
|
||||||
|
->setDebugColor(video::SColor(255, 0, 0, 255),true);
|
||||||
|
|
||||||
|
// Real test2: if in slipstream quad of other kart
|
||||||
if(m_target_kart->getSlipstream()->m_slipstream_quad
|
if(m_target_kart->getSlipstream()->m_slipstream_quad
|
||||||
->pointInside(lc))
|
->pointInside(lc))
|
||||||
{
|
{
|
||||||
@ -444,26 +677,36 @@ void SlipStream::update(float dt)
|
|||||||
if(UserConfigParams::m_slipstream_debug &&
|
if(UserConfigParams::m_slipstream_debug &&
|
||||||
m_kart->getController()->isLocalPlayerController())
|
m_kart->getController()->isLocalPlayerController())
|
||||||
m_target_kart->getSlipstream()
|
m_target_kart->getSlipstream()
|
||||||
->setDebugColor(video::SColor(255, 0, 0, 255));
|
->setDebugColor(video::SColor(255, 0, 0, 255),false);
|
||||||
} // for i < num_karts
|
} // for i < num_karts
|
||||||
|
|
||||||
if(!is_sstreaming)
|
if(!is_sstreaming)
|
||||||
{
|
{
|
||||||
if(UserConfigParams::m_slipstream_debug &&
|
if(UserConfigParams::m_slipstream_debug &&
|
||||||
m_kart->getController()->isLocalPlayerController())
|
m_kart->getController()->isLocalPlayerController())
|
||||||
|
{
|
||||||
m_target_kart->getSlipstream()
|
m_target_kart->getSlipstream()
|
||||||
->setDebugColor(video::SColor(255, 255, 0, 0));
|
->setDebugColor(video::SColor(255, 255, 0, 0),false);
|
||||||
|
|
||||||
|
m_target_kart->getSlipstream()
|
||||||
|
->setDebugColor(video::SColor(255, 0, 255, 0),true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if(isSlipstreamReady())
|
if(isSlipstreamReady())
|
||||||
{
|
{
|
||||||
// The first time slipstream is ready after collecting
|
// The first time slipstream is ready after collecting
|
||||||
// and you are leaving the slipstream area, you get a
|
// and you are leaving the slipstream area, you get an
|
||||||
// zipper bonus.
|
// instant speed_increase
|
||||||
if(m_slipstream_mode==SS_COLLECT)
|
if(m_slipstream_mode==SS_COLLECT)
|
||||||
{
|
{
|
||||||
m_slipstream_mode = SS_USE;
|
m_slipstream_mode = SS_USE;
|
||||||
m_kart->handleZipper();
|
m_kart->instantSpeedIncrease(MaxSpeed::MS_INCREASE_SLIPSTREAM,
|
||||||
m_slipstream_time = kp->getSlipstreamCollectTime();
|
kp->getSlipstreamMaxSpeedIncrease(),
|
||||||
|
kp->getSlipstreamMaxSpeedIncrease(),
|
||||||
|
kp->getSlipstreamAddPower(),
|
||||||
|
kp->getSlipstreamDuration(),
|
||||||
|
kp->getSlipstreamFadeOutTime());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -475,17 +718,30 @@ void SlipStream::update(float dt)
|
|||||||
|
|
||||||
if(UserConfigParams::m_slipstream_debug &&
|
if(UserConfigParams::m_slipstream_debug &&
|
||||||
m_kart->getController()->isLocalPlayerController())
|
m_kart->getController()->isLocalPlayerController())
|
||||||
m_target_kart->getSlipstream()->setDebugColor(video::SColor(255, 0, 255, 0));
|
m_target_kart->getSlipstream()->setDebugColor(video::SColor(255, 128, 255, 0),false);
|
||||||
|
|
||||||
// Accumulate slipstream credits now
|
// Accumulate slipstream credits now
|
||||||
m_slipstream_time = m_slipstream_mode==SS_NONE ? dt
|
//Twice as fast in the inner quad
|
||||||
: m_slipstream_time+dt;
|
if (is_inner_sstreaming)
|
||||||
|
{
|
||||||
|
m_slipstream_time = m_slipstream_mode==SS_NONE ? 2*dt : m_slipstream_time+2*dt;
|
||||||
|
|
||||||
|
if(UserConfigParams::m_slipstream_debug &&
|
||||||
|
m_kart->getController()->isLocalPlayerController())
|
||||||
|
m_target_kart->getSlipstream()->setDebugColor(video::SColor(255, 0, 255, 128),true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_slipstream_time = m_slipstream_mode==SS_NONE ? dt : m_slipstream_time+dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cap the possible credits. Keep this similar to the animation speed cap.
|
||||||
|
if (m_slipstream_time > 8.0f)
|
||||||
|
m_slipstream_time = 8.0f;
|
||||||
|
|
||||||
if(isSlipstreamReady())
|
if(isSlipstreamReady())
|
||||||
m_kart->setSlipstreamEffect(9.0f);
|
m_kart->setSlipstreamEffect(9.0f);
|
||||||
setIntensity(m_slipstream_time, m_target_kart);
|
setIntensity(m_slipstream_time, m_target_kart);
|
||||||
|
|
||||||
m_slipstream_mode = SS_COLLECT;
|
m_slipstream_mode = SS_COLLECT;
|
||||||
if (m_slipstream_time > kp->getSlipstreamCollectTime())
|
|
||||||
{
|
|
||||||
setIntensity(1.0f, m_target_kart);
|
|
||||||
}
|
|
||||||
} // update
|
} // update
|
||||||
|
Loading…
Reference in New Issue
Block a user