Merge pull request #5 from supertuxkart/master

Update fork
This commit is contained in:
Alayan-stk-2 2018-04-16 23:09:50 +02:00 committed by GitHub
commit e39735934b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 697 additions and 114 deletions

View File

@ -64,13 +64,13 @@ mesa-common-dev pkg-config zlib1g-dev
```
### In-game recorder
In order to build the in-game recorder for STK, you have to install
To build the in-game recorder for STK, you have to install
libopenglrecorder from your distribution, or compile it yourself from [here](https://github.com/Benau/libopenglrecorder).
Compilation instruction is explained there. If you don't need this feature, pass `-DBUILD_RECORDER=off` to cmake.
### Compiling
Run the following commands inside `stk-code` directory to compile SuperTuxKart:
To compile SuperTuxKart, run the following commands inside `stk-code` directory:
```bash
mkdir cmake_build
@ -80,6 +80,21 @@ make -j4
```
STK can then be run from the build directory with `bin/supertuxkart`
#### Keeping your build up to date
To recompile the latest code without redownloading the entire source, first run the ```svn up``` command inside the 'stk-assets' directory, then run the following commands inside the 'stk-code' directory:
```bash
git pull
cd cmake_build
cmake ..
make -j4
```
##### Build Speed Optimization
"-j4" is an example, for a faster build, use "-jx" instead, where "x" is the amount of CPU threads you have, minus one.
### Further options
To create a debug version of STK, run:

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<challenge version="2">
<track id="stk_enterprise" laps="3"/>
<mode major="single" minor="followtheleader"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="110"/>
<hard>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -2,18 +2,21 @@
<stkgui>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
<spacer height="2%" width="25"/>
<box width="100%" height="75%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a type of control that you prefer" align="center" text_align="left" />
<box width="100%" height="80%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a type of control that you prefer" align="center" text_align="left" word_wrap="true"/>
<spacer height="15%" width="10"/>
<spacer height="7%" width="10"/>
<ribbon id="control_type" height="60%" width="100%" align="center">
<ribbon id="control_type" proportion="1" width="100%" align="center">
<icon-button id="accelerometer" width="fit" height="fit" icon="gui/difficulty_medium.png"
I18N="Control type" text="Accelerometer"/>
<icon-button id="steering_wheel" width="fit" height="fit" icon="gui/difficulty_hard.png"
I18N="Control type" text="Steering wheel"/>
</ribbon>
<spacer height="12%" width="10"/>
<label width="100%" text="You can change it later in touch device settings." text_align="left" word_wrap="true"/>
</box>
<spacer height="7%" width="10"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -312,21 +312,27 @@
max-speed-increase="5" duration="1" fade-out-time="2" max="20" />
<!-- Slipstream
base-speed: the speed for which length and width are valid.
They are upscaled when faster and downscaled when slower.
length: How far behind a kart slipstream works
(note : this helps OTHER karts)
width: how wide slipstream works furthest away from the kart.
inner-factor: The proportion of the slipstreaming area with
twice faster slipstream "credits" collection.
collect-time: How many seconds of sstream give maximum benefit
use-time: How long the benefit will last.
add-power: Additional power due to sstreaming. 1 = +100%
use-time: How long the benefit will last (obsolete, unused).
add-power: Additional power due to sstreaming.
min-speed: Minimum speed necessary for slipstream to take effect.
max-speed-increase: How much the speed of the kart might exceed
its normal maximum speed.
duration: How long the higher speed lasts after slipstream stopped
working.
working (it works for at least collect-time more if the kart
don't go behind another kart to get further sstreaming time)
fade-out-time: How long the slip stream speed increase will
gradually be reduced. -->
<slipstream length="10" width="2" collect-time="2" use-time="5"
add-power="3" min-speed="10" max-speed-increase="5"
duration="1" fade-out-time="2" />
<slipstream base-speed="20" length="8" width="4" inner-factor="0.5"
collect-time="2" use-time="5" add-power="200" min-speed="8"
max-speed-increase="5" duration="1" fade-out-time="2" />
</characteristic>
<!-- The different difficulties (like easy, medium, hard) -->
@ -360,9 +366,8 @@
invulnerability-time="7" />
<nitro engine-force="350" max-speed-increase="4.5" duration="1.5"
fade-out-time="2.5" />
<slipstream length="11" collect-time="1.5" use-time="2.5" add-power="3.2"
min-speed="9" max-speed-increase="4" duration="1.2"
fade-out-time="2.3" />
<slipstream length="*0.9" collect-time="*0.9" add-power="*1.1"
duration="*1.2" fade-out-time="*1.1" />
</characteristic>
<characteristic name="medium">
<engine power="*0.63" max-speed="*1" brake-factor="*0.73"
@ -374,8 +379,7 @@
<explosion time="1.8" radius="5"
invulnerability-time="6" />
<nitro engine-force="425" consumption="1.4" duration="1" />
<slipstream use-time="3.3" add-power="2.8" duration="0.9"
fade-out-time="1.6" />
<slipstream add-power="*0.9" duration="*0.9" fade-out-time="*0.9" />
</characteristic>
<characteristic name="heavy">
<engine power="*1" max-speed="*1" brake-factor="*0.66"
@ -390,8 +394,8 @@
invulnerability-time="6" />
<nitro engine-force="600" consumption="2" max-speed-increase="8"
duration="0.7" fade-out-time="1.3" />
<slipstream length="8.5" use-time="4" add-power="2.7" min-speed="10.5"
max-speed-increase="8" duration="0.7" fade-out-time="1" />
<slipstream length="*1.1" collect-time="*1.1" add-power="*0.8"
duration="*0.7" fade-out-time="*0.7" />
</characteristic>
</kart-types>

View File

@ -0,0 +1,90 @@
in vec3 bitangent;
in vec4 color;
in float hue_change;
in vec3 normal;
in vec3 tangent;
in vec2 uv;
in vec4 world_position;
in float camdist;
layout(location = 0) out vec4 o_diffuse_color;
layout(location = 1) out vec4 o_normal_color;
#stk_include "utils/encode_normal.frag"
#stk_include "utils/rgb_conversion.frag"
#stk_include "utils/sp_texture_sampling.frag"
void main()
{
vec2 uuv = vec2(world_position.x, world_position.z);
uuv *= 0.2;
vec4 col = multi_sampleTextureLayer0(uv, camdist);
float mask = sampleTextureLayer4(uuv * 2.0).r;
//* (1.0 - color.g)
mask = mix(1.0, mask, color.r);
mask = mix(0.0, mask, 1.0 - color.g);
if(mask < 0.5)
{
discard;
}
// Adding some skidding marks to the road
float mask_2 = sampleTextureLayer4(uuv * 0.1).r;
float mask_3 = sampleTextureLayer4(uuv * 3.5).r;
mask_2 = pow(mask_2, 1.5);
mask_2 *= pow(mask_3, 0.5);
float skidding_marks = sampleTextureLayer5(uv * 10).g;
skidding_marks *= mask_2;
col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), skidding_marks);
float skidding_marks_2 = sampleTextureLayer5(uv * 15).g;
skidding_marks_2 *= mask_2;
col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), skidding_marks_2);
// Add some cracks
float cracks_marks = sampleTextureLayer5(uv * 11).b;
float crack_mask = sampleTextureLayer4(uuv * 0.5).r;
cracks_marks *= crack_mask;
col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), cracks_marks);
if (hue_change > 0.0)
{
float mask = col.a;
vec3 old_hsv = rgbToHsv(col.rgb);
float mask_step = step(mask, 0.5);
#if !defined(Advanced_Lighting_Enabled)
// For similar color
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
#else
float saturation = mask * 2.5;
#endif
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(hue_change,
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, 1.0);
}
vec3 final_color = col.xyz; // * color.xyz;
#if defined(Advanced_Lighting_Enabled)
vec4 layer_2 = multi_sampleTextureLayer2(uv, camdist);
vec4 layer_3 = multi_sampleTextureLayer3(uv, camdist);
o_diffuse_color = vec4(final_color, layer_2.z);
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
vec3 frag_tangent = normalize(tangent);
vec3 frag_bitangent = normalize(bitangent);
vec3 frag_normal = normalize(normal);
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
vec3 world_normal = t_b_n * tangent_space_normal;
o_normal_color.xy = 0.5 * EncodeNormal(normalize(world_normal)) + 0.5;
o_normal_color.zw = layer_2.xy;
#else
o_diffuse_color = vec4(final_color, 1.0);
#endif
}

View File

@ -0,0 +1,17 @@
<spshader>
<shader-info name="roadBlending" fallback-shader="solid" use-tangents="Y"/>
<first-pass vertex-shader="sp_pass.vert"
fragment-shader="sp_road_blending.frag"
skinned-mesh-shader="sp_skinning.vert">
</first-pass>
<!--
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="white.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"
function="shadowCascadeUniformAssigner"/>
</uniform-assigners>
-->
</spshader>

View File

@ -36,17 +36,23 @@
#include "utils/constants.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
* belongs to.
*/
SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
SlipStream::SlipStream(AbstractKart* kart)
{
m_node = NULL;
m_kart = kart;
m_moving = NULL;
m_moving_fast = NULL;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
m_moving = new MovingTexture(0.0f, 0.0f);
m_moving_fast = new MovingTexture(0.0f, 0.0f);
Material* material =
material_manager->getMaterialSPM("slipstream.png", "");
SP::SPMesh* mesh = createMesh(material);
@ -59,23 +65,42 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
m_node->setVisible(false);
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(m_node);
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
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 ew = m_kart->getKartProperties()->getSlipstreamWidth();
float ew = 0.0f;
float kl = m_kart->getKartLength();
//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[0]=Vec3(-kw*0.5f, 0, kl*0.5f );
p[1]=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]);
//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
if (UserConfigParams::m_slipstream_debug)
{
@ -97,6 +122,22 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
m_debug_dc->recalculateBoundingBox();
m_debug_dc->setParent(m_kart->getNode());
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
} // SlipStream
@ -110,11 +151,27 @@ SlipStream::~SlipStream()
{
irr_driver->removeNode(m_node);
}
if (m_node_fast)
{
irr_driver->removeNode(m_node_fast);
}
if (m_debug_dc)
{
m_debug_dc->removeFromSP();
}
if (m_debug_dc2)
{
m_debug_dc2->removeFromSP();
}
delete m_slipstream_quad;
delete m_slipstream_inner_quad;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
delete m_moving;
delete m_moving_fast;
}
#endif
} // ~SlipStream
@ -246,41 +303,56 @@ SP::SPMesh* SlipStream::createMesh(Material* material)
/** Sets the animation intensity (or speed).
* \param f Intensity: 0 = no slip stream,
* 1 = collecting
* 2 = using slip stream bonus
* 2 = bonus can be used
*/
void SlipStream::setIntensity(float f, const AbstractKart *kart)
{
if (!kart || !m_node)
if (!kart || !m_node || !m_node_fast)
{
if (m_node)
{
m_node->setVisible(false);
}
if (m_node_fast)
{
m_node_fast->setVisible(false);
}
return;
}
m_node->setVisible(true);
float ktf = m_kart->getKartProperties()->getSlipstreamCollectTime();
const float above_terrain = 0.2f;
core::vector3df my_pos = m_kart->getNode()->getPosition();
my_pos.Y = m_kart->getHoT()+above_terrain;
m_node->setPosition(my_pos);
core::vector3df other_pos = kart->getNode()->getPosition();
other_pos.Y = kart->getHoT()+above_terrain;
core::vector3df diff = other_pos - my_pos;
core::vector3df rotation = diff.getHorizontalAngle();
m_node->setRotation(rotation);
float fs = diff.getLength()/m_length;
m_node->setPosition(my_pos);
m_node->setRotation(rotation);
m_node->setScale(core::vector3df(1, 1, fs));
// For real testing in game: this needs some tuning!
m_node->setVisible(f!=0);
MovingTexture::setSpeed(f, 0);
m_node_fast->setPosition(my_pos);
m_node_fast->setRotation(rotation);
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;
// For debugging: make the slip stream effect visible all the time
m_node->setVisible(true);
MovingTexture::setSpeed(1.0f, 0.0f);
m_moving->setSpeed(1.0f, 0.0f);
} // setIntensity
//-----------------------------------------------------------------------------
@ -302,8 +374,7 @@ void SlipStream::updateSlipstreamPower()
// See if we are currently using accumulated slipstream credits:
// -------------------------------------------------------------
if(m_slipstream_mode==SS_USE)
{
setIntensity(2.0f, NULL);
{
const KartProperties *kp = m_kart->getKartProperties();
m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM,
kp->getSlipstreamMaxSpeedIncrease(),
@ -320,23 +391,160 @@ void SlipStream::updateSlipstreamPower()
* black: kart too slow
* red: not inside of slipstream area
* 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();
for (unsigned i = 0; i < 4; i++)
video::S3DVertexSkinnedMesh* v = m_debug_dc->getVerticesVector().data();
for (unsigned i = 0; i < 4; i++)
{
v[i].m_color = color;
}
m_debug_dc->setUpdateOffset(0);
}
else
{
v[i].m_color = color;
}
m_debug_dc->setUpdateOffset(0);
if (!m_debug_dc2)
{
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
//-----------------------------------------------------------------------------
/** 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.
* \param dt Time step size.
@ -350,38 +558,60 @@ void SlipStream::update(float dt)
|| m_kart->isGhostKart())
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();
}
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
m_moving->update(dt);
m_moving_fast->update(dt);
}
#endif
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;
}
updateSlipstreamPower();
// 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
// not moving. This is useful for debugging the graphics of SS-ing.
//#define 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);
#ifndef SERVER_ONLY
if (CVS->isGLSL()) setIntensity(0, NULL);
#endif
m_slipstream_mode = SS_NONE;
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;
}
#endif
// Then test if this kart is in the slipstream range of another kart:
// ------------------------------------------------------------------
World *world = World::getWorld();
unsigned int num_karts = world->getNumKarts();
bool is_sstreaming = false;
m_target_kart = NULL;
World *world = World::getWorld();
unsigned int num_karts = world->getNumKarts();
bool is_sstreaming = false;
bool is_inner_sstreaming = false;
m_target_kart = NULL;
// 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
@ -389,6 +619,7 @@ void SlipStream::update(float dt)
for(unsigned int i=0; i<num_karts; i++)
{
m_target_kart= world->getKart(i);
// Don't test for slipstream with itself, a kart that is being
// rescued or exploding, a ghost kart or an eliminated kart
if(m_target_kart==m_kart ||
@ -396,6 +627,8 @@ void SlipStream::update(float dt)
m_target_kart->isGhostKart() ||
m_target_kart->isEliminated() ) continue;
const KartProperties *kp_target = m_target_kart->getKartProperties();
// Transform this kart location into target kart point of view
Vec3 lc = m_target_kart->getTrans().inverse()(m_kart->getXYZ());
@ -404,37 +637,51 @@ void SlipStream::update(float dt)
if (fabsf(lc.y()) > 6.0f) continue;
// If the kart we are testing against is too slow, no need to test
// slipstreaming. Note: We compare the speed of the other kart
// 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.
// slipstreaming.
#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 &&
m_kart->getController()->isLocalPlayerController())
{
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;
}
#endif
// 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
// (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();
float l = kp->getSlipstreamLength()
+ 0.5f*( m_target_kart->getKartLength()
+m_kart->getKartLength() );
float l = kp_target->getSlipstreamLength();
float speed_factor = m_target_kart->getSpeed()
/kp_target->getSlipstreamBaseSpeed();
l = l*speed_factor + m_target_kart->getKartLength()
+ 0.5f*m_kart->getKartLength();
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;
}
// 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
->pointInside(lc))
{
@ -444,48 +691,74 @@ void SlipStream::update(float dt)
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 0, 255));
->setDebugColor(video::SColor(255, 0, 0, 255),false);
} // for i < num_karts
if(!is_sstreaming)
{
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
{
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())
{
// The first time slipstream is ready after collecting
// and you are leaving the slipstream area, you get a
// zipper bonus.
// and you are leaving the slipstream area, you get an
// instant speed_increase
if(m_slipstream_mode==SS_COLLECT)
{
m_slipstream_mode = SS_USE;
m_kart->handleZipper();
m_slipstream_time = kp->getSlipstreamCollectTime();
m_kart->instantSpeedIncrease(MaxSpeed::MS_INCREASE_SLIPSTREAM,
kp->getSlipstreamMaxSpeedIncrease(),
kp->getSlipstreamMaxSpeedIncrease(),
kp->getSlipstreamAddPower(),
kp->getSlipstreamDuration(),
kp->getSlipstreamFadeOutTime());
return;
}
}
m_slipstream_time -=dt;
if(m_slipstream_time<0) m_slipstream_mode = SS_NONE;
setIntensity(0, NULL);
#ifndef SERVER_ONLY
if (CVS->isGLSL()) setIntensity(0, NULL);
#endif
return;
} // if !is_sstreaming
if(UserConfigParams::m_slipstream_debug &&
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
m_slipstream_time = m_slipstream_mode==SS_NONE ? dt
: m_slipstream_time+dt;
//Twice as fast in the inner quad
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())
m_kart->setSlipstreamEffect(9.0f);
setIntensity(m_slipstream_time, m_target_kart);
#ifndef SERVER_ONLY
if (CVS->isGLSL()) setIntensity(m_slipstream_time, m_target_kart);
#endif
m_slipstream_mode = SS_COLLECT;
if (m_slipstream_time > kp->getSlipstreamCollectTime())
{
setIntensity(1.0f, m_target_kart);
}
} // update

View File

@ -44,18 +44,32 @@ class Material;
/**
* \ingroup graphics
*/
class SlipStream : public MovingTexture
class SlipStream
{
private:
/** The kart to which this smoke belongs. */
AbstractKart *m_kart;
/** The moving texture for the normal node */
MovingTexture *m_moving;
/** The moving texture for the fast node */
MovingTexture *m_moving_fast;
/** The scene node. */
scene::ISceneNode *m_node;
/** The fast scene node. */
scene::ISceneNode *m_node_fast;
/** For debugging: a simple quad to display where slipstream works. */
std::shared_ptr<SP::SPDynamicDrawCall> m_debug_dc;
/** For debugging: a simple quad to display where inner slipstream works. */
std::shared_ptr<SP::SPDynamicDrawCall> m_debug_dc2;
/** The length of the slipstream cylinder. This is used to scale
* the actual scene node correctly. */
float m_length;
@ -70,12 +84,16 @@ private:
/** This is slipstream area if the kart is at 0,0,0 without rotation. */
Quad *m_slipstream_quad;
/** This is the inner slipstream area if the kart is at 0,0,0 without rotation. */
Quad *m_slipstream_inner_quad;
/** The kart from which this kart gets slipstream. Used by the AI to
** overtake the right kart. */
AbstractKart* m_target_kart;
SP::SPMesh* createMesh(Material* material);
void setDebugColor(const video::SColor &color);
void setDebugColor(const video::SColor &color, bool inner);
void updateQuad();
public:
SlipStream (AbstractKart* kart);
virtual ~SlipStream ();
@ -97,4 +115,3 @@ public:
bool inUse() const {return m_slipstream_mode==SS_USE; }
}; // SlipStream
#endif

View File

@ -215,10 +215,14 @@ AbstractCharacteristic::ValueType AbstractCharacteristic::getType(
return TYPE_FLOAT;
case SLIPSTREAM_DURATION:
return TYPE_FLOAT;
case SLIPSTREAM_BASE_SPEED:
return TYPE_FLOAT;
case SLIPSTREAM_LENGTH:
return TYPE_FLOAT;
case SLIPSTREAM_WIDTH:
return TYPE_FLOAT;
case SLIPSTREAM_INNER_FACTOR:
return TYPE_FLOAT;
case SLIPSTREAM_COLLECT_TIME:
return TYPE_FLOAT;
case SLIPSTREAM_USE_TIME:
@ -447,10 +451,14 @@ std::string AbstractCharacteristic::getName(CharacteristicType type)
return "NITRO_MAX";
case SLIPSTREAM_DURATION:
return "SLIPSTREAM_DURATION";
case SLIPSTREAM_BASE_SPEED:
return "SLIPSTREAM_BASE_SPEED";
case SLIPSTREAM_LENGTH:
return "SLIPSTREAM_LENGTH";
case SLIPSTREAM_WIDTH:
return "SLIPSTREAM_WIDTH";
case SLIPSTREAM_INNER_FACTOR:
return "SLIPSTREAM_INNER_FACTOR";
case SLIPSTREAM_COLLECT_TIME:
return "SLIPSTREAM_COLLECT_TIME";
case SLIPSTREAM_USE_TIME:
@ -1471,6 +1479,18 @@ float AbstractCharacteristic::getSlipstreamDuration() const
return result;
} // getSlipstreamDuration
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamBaseSpeed() const
{
float result;
bool is_set = false;
process(SLIPSTREAM_BASE_SPEED, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName(SLIPSTREAM_BASE_SPEED).c_str());
return result;
} // getSlipstreamBaseSpeed
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamLength() const
{
@ -1495,6 +1515,18 @@ float AbstractCharacteristic::getSlipstreamWidth() const
return result;
} // getSlipstreamWidth
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamInnerFactor() const
{
float result;
bool is_set = false;
process(SLIPSTREAM_INNER_FACTOR, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName(SLIPSTREAM_INNER_FACTOR).c_str());
return result;
} // getSlipstreamInnerFactor
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamCollectTime() const
{
@ -1785,4 +1817,3 @@ bool AbstractCharacteristic::getSkidEnabled() const
/* <characteristics-end acgetter> */

View File

@ -194,8 +194,10 @@ public:
// Slipstream
SLIPSTREAM_DURATION,
SLIPSTREAM_BASE_SPEED,
SLIPSTREAM_LENGTH,
SLIPSTREAM_WIDTH,
SLIPSTREAM_INNER_FACTOR,
SLIPSTREAM_COLLECT_TIME,
SLIPSTREAM_USE_TIME,
SLIPSTREAM_ADD_POWER,
@ -360,8 +362,10 @@ public:
float getNitroMax() const;
float getSlipstreamDuration() const;
float getSlipstreamBaseSpeed() const;
float getSlipstreamLength() const;
float getSlipstreamWidth() const;
float getSlipstreamInnerFactor() const;
float getSlipstreamCollectTime() const;
float getSlipstreamUseTime() const;
float getSlipstreamAddPower() const;
@ -392,4 +396,3 @@ public:
};
#endif

View File

@ -310,6 +310,23 @@ public:
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
float engine_force, float duration,
float fade_out_time) = 0;
// ----------------------------------------------------------------------------
/** This adjusts the top speed using increaseMaxSpeed, but additionally
* causes an instant speed boost, which can be smaller than add-max-speed.
* (e.g. a zipper can give an instant boost of 5 m/s, but over time would
* allow the speed to go up by 10 m/s).
* \param category The category for which the speed is increased.
* \param add_max_speed Increase of the maximum allowed speed.
* \param speed_boost An instant speed increase for this kart.
* \param engine_force Additional engine force.
* \param duration Duration of the increased speed.
* \param fade_out_time How long the maximum speed will fade out linearly.
*/
virtual void instantSpeedIncrease(unsigned int category, float add_max_speed,
float speed_boost, float engine_force, float duration,
float fade_out_time) = 0;
// ------------------------------------------------------------------------
/** Defines a slowdown, which is in fraction of top speed.
* \param category The category for which the speed is increased.
@ -459,6 +476,9 @@ public:
* defined even if the kart is flying. */
virtual const Vec3& getNormal() const = 0;
// ------------------------------------------------------------------------
/** Returns the position 0,25s before */
virtual const Vec3& getPreviousXYZ() const = 0;
// ------------------------------------------------------------------------
/** Returns the height of the terrain. we're currently above */
virtual float getHoT() const = 0;
// ------------------------------------------------------------------------
@ -494,4 +514,3 @@ public:
#endif
/* EOF */

View File

@ -147,6 +147,12 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_boosted_ai = false;
m_type = RaceManager::KT_AI;
for (int i=0;i<30;i++)
{
m_previous_xyz[i] = getXYZ();
}
m_time_previous_counter = 0.0f;
m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false;
@ -370,6 +376,12 @@ void Kart::reset()
m_has_caught_nolok_bubblegum = false;
m_is_jumping = false;
for (int i=0;i<30;i++)
{
m_previous_xyz[i] = getXYZ();
}
m_time_previous_counter = 0.0f;
// In case that the kart was in the air, in which case its
// linear damping is 0
if(m_body)
@ -454,6 +466,15 @@ void Kart::increaseMaxSpeed(unsigned int category, float add_speed,
fade_out_time);
} // increaseMaxSpeed
// -----------------------------------------------------------------------------
void Kart::instantSpeedIncrease(unsigned int category, float add_max_speed,
float speed_boost, float engine_force, float duration,
float fade_out_time)
{
m_max_speed->instantSpeedIncrease(category, add_max_speed, speed_boost,
engine_force, duration, fade_out_time);
} // instantSpeedIncrease
// -----------------------------------------------------------------------------
void Kart::setSlowdown(unsigned int category, float max_speed_fraction,
float fade_in_time)
@ -1207,6 +1228,11 @@ void Kart::eliminate()
m_stars_effect->reset();
m_stars_effect->update(1);
}
if (m_attachment)
{
m_attachment->clear();
}
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_TERRAIN, 0);
m_kart_gfx->setGFXInvisible();
@ -1278,9 +1304,22 @@ void Kart::update(float dt)
{
m_kart_animation->update(dt);
}
m_time_previous_counter += dt;
while (m_time_previous_counter > (1.0f/120.0f))
{
m_previous_xyz[0] = getXYZ();
for (int i=29;i>0;i--)
{
m_previous_xyz[i] = m_previous_xyz[i-1];
}
m_time_previous_counter -= (1.0f/120.0f);
}
// Update the position and other data taken from the physics (or
// an animation which calls setXYZ(), which also updates the kart
// physical position).
Moveable::update(dt);
Vec3 front(0, 0, getKartLength()*0.5f);
@ -1996,11 +2035,13 @@ void Kart::updateNitro(float dt)
// when pressing the key, don't allow the min time to go under zero.
// If it went under zero, it would be reset
// As the time deduction happens before, it can be an arbitrarily
// small number > 0. Smaller means more responsive controls.
if (m_controls.getNitro() && m_min_nitro_time <= 0.0f)
m_min_nitro_time = 0.1f;
m_min_nitro_time = 0.005f;
}
bool increase_speed = (m_controls.getNitro() && isOnGround());
bool increase_speed = (m_min_nitro_time > 0 && isOnGround());
if (!increase_speed && m_min_nitro_time <= 0.0f)
{
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
@ -2863,7 +2904,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
// --------------------------------------------------------
float nitro_frac = 0;
if ( (m_controls.getNitro() || m_min_nitro_time > 0.0f) &&
isOnGround() && m_collected_energy > 0 )
m_collected_energy > 0 )
{
// fabs(speed) is important, otherwise the negative number will
// become a huge unsigned number in the particle scene node!
@ -3050,6 +3091,14 @@ const Vec3& Kart::getNormal() const
return m_terrain_info->getNormal();
} // getNormal
// ------------------------------------------------------------------------
/** Returns the position 0,25s before */
const Vec3& Kart::getPreviousXYZ() const
{
return m_previous_xyz[29];
} // getPreviousXYZ
// ------------------------------------------------------------------------
void Kart::playSound(SFXBuffer* buffer)
{

View File

@ -74,6 +74,11 @@ protected:
* new lap is triggered. */
Vec3 m_xyz_front;
/** The coordinates of the 30 previous positions */
Vec3 m_previous_xyz[30];
float m_time_previous_counter;
/** Is time flying activated */
bool m_is_jumping;
@ -273,6 +278,9 @@ public:
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
float engine_force, float duration,
float fade_out_time);
virtual void instantSpeedIncrease(unsigned int category, float add_max_speed,
float speed_boost, float engine_force, float duration,
float fade_out_time);
virtual void setSlowdown(unsigned int category, float max_speed_fraction,
float fade_in_time);
virtual float getSpeedIncreaseTimeLeft(unsigned int category) const;
@ -470,6 +478,10 @@ public:
/** Returns the normal of the terrain the kart is over atm. This is
* defined even if the kart is flying. */
virtual const Vec3& getNormal() const;
// ------------------------------------------------------------------------
/** Returns the position 0,25s before */
virtual const Vec3& getPreviousXYZ() const;
// ------------------------------------------------------------------------
/** For debugging only: check if a kart is flying. */
bool isFlying() const { return m_flying; }

View File

@ -1042,6 +1042,12 @@ float KartProperties::getSlipstreamDuration() const
return m_cached_characteristic->getSlipstreamDuration();
} // getSlipstreamDuration
// ----------------------------------------------------------------------------
float KartProperties::getSlipstreamBaseSpeed() const
{
return m_cached_characteristic->getSlipstreamBaseSpeed();
} // getSlipstreamBaseSpeed
// ----------------------------------------------------------------------------
float KartProperties::getSlipstreamLength() const
{
@ -1054,6 +1060,12 @@ float KartProperties::getSlipstreamWidth() const
return m_cached_characteristic->getSlipstreamWidth();
} // getSlipstreamWidth
// ----------------------------------------------------------------------------
float KartProperties::getSlipstreamInnerFactor() const
{
return m_cached_characteristic->getSlipstreamInnerFactor();
} // getSlipstreamInnerFactor
// ----------------------------------------------------------------------------
float KartProperties::getSlipstreamCollectTime() const
{
@ -1199,4 +1211,3 @@ bool KartProperties::getSkidEnabled() const
} // getSkidEnabled
/* <characteristics-end kpgetter> */

View File

@ -482,8 +482,10 @@ public:
float getNitroMax() const;
float getSlipstreamDuration() const;
float getSlipstreamBaseSpeed() const;
float getSlipstreamLength() const;
float getSlipstreamWidth() const;
float getSlipstreamInnerFactor() const;
float getSlipstreamCollectTime() const;
float getSlipstreamUseTime() const;
float getSlipstreamAddPower() const;

View File

@ -563,10 +563,14 @@ void XmlCharacteristic::load(const XMLNode *node)
{
sub_node->get("duration",
&m_values[SLIPSTREAM_DURATION]);
sub_node->get("base-speed",
&m_values[SLIPSTREAM_BASE_SPEED]);
sub_node->get("length",
&m_values[SLIPSTREAM_LENGTH]);
sub_node->get("width",
&m_values[SLIPSTREAM_WIDTH]);
sub_node->get("inner-factor",
&m_values[SLIPSTREAM_INNER_FACTOR]);
sub_node->get("collect-time",
&m_values[SLIPSTREAM_COLLECT_TIME]);
sub_node->get("use-time",
@ -624,4 +628,3 @@ void XmlCharacteristic::load(const XMLNode *node)
/* <characteristics-end getXml> */
} // load

View File

@ -548,7 +548,8 @@ void cmdLineHelp()
"./data/stk_config.xml\n"
" -k, --numkarts=NUM Set number of karts on the racetrack.\n"
" --kart=NAME Use kart NAME.\n"
" --ai=a,b,... Use the karts a, b, ... for the AI.\n"
" --ai=a,b,... Use the karts a, b, ... for the AI, and additional player kart.\n"
" --aiNP=a,b,... Use the karts a, b, ... for the AI, no additional player kart.\n"
" --laps=N Define number of laps to N.\n"
" --mode=N N=1 Beginner, N=2 Intermediate, N=3 Expert, N=4 SuperTux.\n"
" --type=N N=0 Normal, N=1 Time trial, N=2 Follow The Leader\n"
@ -1113,6 +1114,13 @@ int handleCmdLine()
race_manager->setNumKarts((int)l.size()+1);
} // --ai
if(CommandLine::has("--aiNP", &s))
{
const std::vector<std::string> l=StringUtils::split(std::string(s),',');
race_manager->setDefaultAIKartList(l);
race_manager->setNumKarts((int)l.size());
} // --aiNP
if(CommandLine::has( "--mode", &s) || CommandLine::has( "--difficulty", &s))
{
int n = atoi(s.c_str());

View File

@ -280,7 +280,9 @@ void RaceManager::computeRandomKartList()
}
m_ai_kart_list.clear();
unsigned int m = std::min( (unsigned) n, (unsigned)m_default_ai_list.size());
//Use the command line options AI list.
unsigned int m = std::min( (unsigned) m_num_karts, (unsigned)m_default_ai_list.size());
for(unsigned int i=0; i<m; i++)
{

View File

@ -69,7 +69,7 @@ GUIEngine::EventPropagation GeneralTextFieldDialog::processEvent(const std::stri
else if (eventSource == "ok")
{
// If validation callback return true, dismiss the dialog
if (m_val_cb(m_title, m_text_field))
if (!m_self_destroy && m_val_cb(m_title, m_text_field))
m_self_destroy = true;
return GUIEngine::EVENT_BLOCK;
}
@ -88,7 +88,7 @@ void GeneralTextFieldDialog::onEnterPressedInternal()
return;
}
if (m_val_cb(m_title, m_text_field))
if (!m_self_destroy && m_val_cb(m_title, m_text_field))
m_self_destroy = true;
} // onEnterPressedInternal

View File

@ -387,17 +387,25 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
return;
}
// This is a normal race, nothing was unlocked
// -------------------------------------------
StateManager::get()->popMenu();
if (name == "top") // Setup new race
{
race_manager->exitRace();
race_manager->setAIKartOverride("");
Screen* newStack[] = { MainMenuScreen::getInstance(),
RaceSetupScreen::getInstance(),
NULL };
StateManager::get()->resetAndSetStack(newStack);
//If pressing continue quickly in a losing challenge
if (race_manager->raceWasStartedFromOverworld())
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
OverWorld::enterOverWorld();
}
else
{
Screen* newStack[] = { MainMenuScreen::getInstance(),
RaceSetupScreen::getInstance(),
NULL };
StateManager::get()->resetAndSetStack(newStack);
}
}
else if (name == "middle") // Restart
{

View File

@ -42,6 +42,20 @@ Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3,
m_max_height_testing = Graph::MAX_HEIGHT_TESTING;
} // Quad
/** Takes 4 points. */
void Quad::setQuad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3)
{
m_p[0]=p0; m_p[1]=p1; m_p[2]=p2; m_p[3]=p3;
m_center = 0.25f*(p0+p1+p2+p3);
m_min_height = std::min ( std::min(p0.getY(), p1.getY()),
std::min(p2.getY(), p3.getY()) );
m_max_height = std::max ( std::max(p0.getY(), p1.getY()),
std::max(p2.getY(), p3.getY()) );
m_min_height_testing = Graph::MIN_HEIGHT_TESTING;
m_max_height_testing = Graph::MAX_HEIGHT_TESTING;
} // setQuad
// ----------------------------------------------------------------------------
/** Sets the vertices in a irrlicht vertex array to the 4 points of this quad.
* \param v The vertex array in which to set the vertices.

View File

@ -84,6 +84,9 @@ public:
/** Returns the center of a quad. */
const Vec3& getCenter () const { return m_center; }
// ------------------------------------------------------------------------
/** Set new quad coordinates. */
void setQuad (const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3);
// ------------------------------------------------------------------------
void setHeightTesting(float min, float max)
{
m_min_height_testing = min;

View File

@ -3,7 +3,7 @@
for track in abyss candela_city cocoa_temple cornfield_crossing fortmagma gran_paradiso_island greenvalley hacienda lighthouse mansion mines minigolf olivermath sandtrack scotland snowmountain snowtuxpeak stk_enterprise volcano_island xr591 zengarden; do
echo "Testing $track"
$1 --log=0 -R \
--ai=nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok \
--track=$track --difficulty=2 --type=1 --test-ai=2 \
--aiNP=nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok \
--track=$track --difficulty=3 --type=1 --test-ai=2 \
--profile-laps=10 --no-graphics > stdout.$track
done

View File

@ -48,7 +48,7 @@ Startup: time(std::vector<float>/floatVector), boost(std::vector<float>/floatVec
Rescue: duration, vertOffset, height
Explosion: duration, radius, invulnerabilityTime
Nitro: duration, engineForce, consumption, smallContainer, bigContainer, maxSpeedIncrease, fadeOutTime, max
Slipstream: duration, length, width, collectTime, useTime, addPower, minSpeed, maxSpeedIncrease, fadeOutTime
Slipstream: duration, baseSpeed, length, width, innerFactor, collectTime, useTime, addPower, minSpeed, maxSpeedIncrease, fadeOutTime
Skid: increase, decrease, max, timeTillMax, visual, visualTime, revertVisualTime, minSpeed, timeTillBonus(std::vector<float>/floatVector), bonusSpeed(std::vector<float>/floatVector), bonusTime(std::vector<float>/floatVector), bonusForce(std::vector<float>/floatVector), physicalJumpTime, graphicalJumpTime, postSkidRotateFactor, reduceTurnMin, reduceTurnMax, enabled(bool)"""
""" A GroupMember is an attribute of a group.
@ -283,4 +283,3 @@ Operations:""")
if __name__ == '__main__':
main()