19
README.md
@ -64,13 +64,13 @@ mesa-common-dev pkg-config zlib1g-dev
|
|||||||
```
|
```
|
||||||
### In-game recorder
|
### 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).
|
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.
|
Compilation instruction is explained there. If you don't need this feature, pass `-DBUILD_RECORDER=off` to cmake.
|
||||||
|
|
||||||
### Compiling
|
### Compiling
|
||||||
|
|
||||||
Run the following commands inside `stk-code` directory to compile SuperTuxKart:
|
To compile SuperTuxKart, run the following commands inside `stk-code` directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir cmake_build
|
mkdir cmake_build
|
||||||
@ -80,6 +80,21 @@ make -j4
|
|||||||
```
|
```
|
||||||
STK can then be run from the build directory with `bin/supertuxkart`
|
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
|
### Further options
|
||||||
|
|
||||||
To create a debug version of STK, run:
|
To create a debug version of STK, run:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<challenge version="2">
|
<challenge version="2">
|
||||||
<track id="stk_enterprise" laps="3"/>
|
<track id="stk_enterprise" laps="3"/>
|
||||||
<mode major="single" minor="followtheleader"/>
|
<mode major="single" minor="quickrace"/>
|
||||||
<requirements trophies="110"/>
|
<requirements trophies="110"/>
|
||||||
|
|
||||||
<hard>
|
<hard>
|
||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 11 KiB |
@ -2,18 +2,21 @@
|
|||||||
<stkgui>
|
<stkgui>
|
||||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
|
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
|
||||||
|
|
||||||
<spacer height="2%" width="25"/>
|
<box width="100%" height="80%" padding="10" layout="vertical-row">
|
||||||
<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" word_wrap="true"/>
|
||||||
<bright width="100%" text="Select a type of control that you prefer" align="center" text_align="left" />
|
|
||||||
|
|
||||||
<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"
|
<icon-button id="accelerometer" width="fit" height="fit" icon="gui/difficulty_medium.png"
|
||||||
I18N="Control type" text="Accelerometer"/>
|
I18N="Control type" text="Accelerometer"/>
|
||||||
<icon-button id="steering_wheel" width="fit" height="fit" icon="gui/difficulty_hard.png"
|
<icon-button id="steering_wheel" width="fit" height="fit" icon="gui/difficulty_hard.png"
|
||||||
I18N="Control type" text="Steering wheel"/>
|
I18N="Control type" text="Steering wheel"/>
|
||||||
</ribbon>
|
</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>
|
</box>
|
||||||
|
|
||||||
<spacer height="7%" width="10"/>
|
<spacer height="7%" width="10"/>
|
||||||
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 73 KiB |
@ -312,21 +312,27 @@
|
|||||||
max-speed-increase="5" duration="1" fade-out-time="2" max="20" />
|
max-speed-increase="5" duration="1" fade-out-time="2" max="20" />
|
||||||
|
|
||||||
<!-- Slipstream
|
<!-- 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
|
length: How far behind a kart slipstream works
|
||||||
|
(note : this helps OTHER karts)
|
||||||
width: how wide slipstream works furthest away from the kart.
|
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
|
collect-time: How many seconds of sstream give maximum benefit
|
||||||
use-time: How long the benefit will last.
|
use-time: How long the benefit will last (obsolete, unused).
|
||||||
add-power: Additional power due to sstreaming. 1 = +100%
|
add-power: Additional power due to sstreaming.
|
||||||
min-speed: Minimum speed necessary for slipstream to take effect.
|
min-speed: Minimum speed necessary for slipstream to take effect.
|
||||||
max-speed-increase: How much the speed of the kart might exceed
|
max-speed-increase: How much the speed of the kart might exceed
|
||||||
its normal maximum speed.
|
its normal maximum speed.
|
||||||
duration: How long the higher speed lasts after slipstream stopped
|
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
|
fade-out-time: How long the slip stream speed increase will
|
||||||
gradually be reduced. -->
|
gradually be reduced. -->
|
||||||
<slipstream length="10" width="2" collect-time="2" use-time="5"
|
<slipstream base-speed="20" length="8" width="4" inner-factor="0.5"
|
||||||
add-power="3" min-speed="10" max-speed-increase="5"
|
collect-time="2" use-time="5" add-power="200" min-speed="8"
|
||||||
duration="1" fade-out-time="2" />
|
max-speed-increase="5" duration="1" fade-out-time="2" />
|
||||||
</characteristic>
|
</characteristic>
|
||||||
|
|
||||||
<!-- The different difficulties (like easy, medium, hard) -->
|
<!-- The different difficulties (like easy, medium, hard) -->
|
||||||
@ -360,9 +366,8 @@
|
|||||||
invulnerability-time="7" />
|
invulnerability-time="7" />
|
||||||
<nitro engine-force="350" max-speed-increase="4.5" duration="1.5"
|
<nitro engine-force="350" max-speed-increase="4.5" duration="1.5"
|
||||||
fade-out-time="2.5" />
|
fade-out-time="2.5" />
|
||||||
<slipstream length="11" collect-time="1.5" use-time="2.5" add-power="3.2"
|
<slipstream length="*0.9" collect-time="*0.9" add-power="*1.1"
|
||||||
min-speed="9" max-speed-increase="4" duration="1.2"
|
duration="*1.2" fade-out-time="*1.1" />
|
||||||
fade-out-time="2.3" />
|
|
||||||
</characteristic>
|
</characteristic>
|
||||||
<characteristic name="medium">
|
<characteristic name="medium">
|
||||||
<engine power="*0.63" max-speed="*1" brake-factor="*0.73"
|
<engine power="*0.63" max-speed="*1" brake-factor="*0.73"
|
||||||
@ -374,8 +379,7 @@
|
|||||||
<explosion time="1.8" radius="5"
|
<explosion time="1.8" radius="5"
|
||||||
invulnerability-time="6" />
|
invulnerability-time="6" />
|
||||||
<nitro engine-force="425" consumption="1.4" duration="1" />
|
<nitro engine-force="425" consumption="1.4" duration="1" />
|
||||||
<slipstream use-time="3.3" add-power="2.8" duration="0.9"
|
<slipstream add-power="*0.9" duration="*0.9" fade-out-time="*0.9" />
|
||||||
fade-out-time="1.6" />
|
|
||||||
</characteristic>
|
</characteristic>
|
||||||
<characteristic name="heavy">
|
<characteristic name="heavy">
|
||||||
<engine power="*1" max-speed="*1" brake-factor="*0.66"
|
<engine power="*1" max-speed="*1" brake-factor="*0.66"
|
||||||
@ -390,8 +394,8 @@
|
|||||||
invulnerability-time="6" />
|
invulnerability-time="6" />
|
||||||
<nitro engine-force="600" consumption="2" max-speed-increase="8"
|
<nitro engine-force="600" consumption="2" max-speed-increase="8"
|
||||||
duration="0.7" fade-out-time="1.3" />
|
duration="0.7" fade-out-time="1.3" />
|
||||||
<slipstream length="8.5" use-time="4" add-power="2.7" min-speed="10.5"
|
<slipstream length="*1.1" collect-time="*1.1" add-power="*0.8"
|
||||||
max-speed-increase="8" duration="0.7" fade-out-time="1" />
|
duration="*0.7" fade-out-time="*0.7" />
|
||||||
</characteristic>
|
</characteristic>
|
||||||
</kart-types>
|
</kart-types>
|
||||||
|
|
||||||
|
90
data/shaders/sp_road_blending.frag
Normal 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
|
||||||
|
}
|
17
data/shaders/sps_12_roadBlending.xml
Normal 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>
|
@ -36,17 +36,23 @@
|
|||||||
#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;
|
||||||
|
m_moving = NULL;
|
||||||
|
m_moving_fast = NULL;
|
||||||
|
|
||||||
#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 +65,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 +122,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 +151,27 @@ 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;
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
if (CVS->isGLSL())
|
||||||
|
{
|
||||||
|
delete m_moving;
|
||||||
|
delete m_moving_fast;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // ~SlipStream
|
} // ~SlipStream
|
||||||
|
|
||||||
@ -246,41 +303,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
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -303,7 +375,6 @@ void SlipStream::updateSlipstreamPower()
|
|||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
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,8 +391,11 @@ 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 (!inner)
|
||||||
{
|
{
|
||||||
if (!m_debug_dc)
|
if (!m_debug_dc)
|
||||||
{
|
{
|
||||||
@ -334,9 +408,143 @@ void SlipStream::setDebugColor(const video::SColor &color)
|
|||||||
v[i].m_color = color;
|
v[i].m_color = color;
|
||||||
}
|
}
|
||||||
m_debug_dc->setUpdateOffset(0);
|
m_debug_dc->setUpdateOffset(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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
|
} // 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,28 +558,49 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
if (CVS->isGLSL())
|
||||||
|
{
|
||||||
|
m_moving->update(dt);
|
||||||
|
m_moving_fast->update(dt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
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);
|
#ifndef SERVER_ONLY
|
||||||
|
if (CVS->isGLSL()) setIntensity(0, NULL);
|
||||||
|
#endif
|
||||||
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
|
||||||
@ -381,6 +610,7 @@ void SlipStream::update(float dt)
|
|||||||
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;
|
||||||
|
bool is_inner_sstreaming = false;
|
||||||
m_target_kart = NULL;
|
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
|
||||||
@ -389,6 +619,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 +627,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 +637,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)
|
||||||
{
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 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 &&
|
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, 128));
|
->setDebugColor(video::SColor(255, 0, 0, 255),true);
|
||||||
continue;
|
|
||||||
}
|
// Real test2: if in slipstream quad of other kart
|
||||||
// Real test: 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,48 +691,74 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_slipstream_time -=dt;
|
m_slipstream_time -=dt;
|
||||||
if(m_slipstream_time<0) m_slipstream_mode = SS_NONE;
|
if(m_slipstream_time<0) m_slipstream_mode = SS_NONE;
|
||||||
setIntensity(0, NULL);
|
#ifndef SERVER_ONLY
|
||||||
|
if (CVS->isGLSL()) setIntensity(0, NULL);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
} // 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()->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);
|
#ifndef SERVER_ONLY
|
||||||
|
if (CVS->isGLSL()) setIntensity(m_slipstream_time, m_target_kart);
|
||||||
|
#endif
|
||||||
m_slipstream_mode = SS_COLLECT;
|
m_slipstream_mode = SS_COLLECT;
|
||||||
if (m_slipstream_time > kp->getSlipstreamCollectTime())
|
|
||||||
{
|
|
||||||
setIntensity(1.0f, m_target_kart);
|
|
||||||
}
|
|
||||||
} // update
|
} // update
|
||||||
|
@ -44,18 +44,32 @@ class Material;
|
|||||||
/**
|
/**
|
||||||
* \ingroup graphics
|
* \ingroup graphics
|
||||||
*/
|
*/
|
||||||
class SlipStream : public MovingTexture
|
class SlipStream
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** The kart to which this smoke belongs. */
|
/** The kart to which this smoke belongs. */
|
||||||
AbstractKart *m_kart;
|
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. */
|
/** The scene node. */
|
||||||
scene::ISceneNode *m_node;
|
scene::ISceneNode *m_node;
|
||||||
|
|
||||||
|
/** The fast scene node. */
|
||||||
|
scene::ISceneNode *m_node_fast;
|
||||||
|
|
||||||
/** For debugging: a simple quad to display where slipstream works. */
|
/** For debugging: a simple quad to display where slipstream works. */
|
||||||
std::shared_ptr<SP::SPDynamicDrawCall> m_debug_dc;
|
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 length of the slipstream cylinder. This is used to scale
|
||||||
* the actual scene node correctly. */
|
* the actual scene node correctly. */
|
||||||
float m_length;
|
float m_length;
|
||||||
@ -70,12 +84,16 @@ private:
|
|||||||
/** This is slipstream area if the kart is at 0,0,0 without rotation. */
|
/** This is slipstream area if the kart is at 0,0,0 without rotation. */
|
||||||
Quad *m_slipstream_quad;
|
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
|
/** The kart from which this kart gets slipstream. Used by the AI to
|
||||||
** overtake the right kart. */
|
** overtake the right kart. */
|
||||||
AbstractKart* m_target_kart;
|
AbstractKart* m_target_kart;
|
||||||
|
|
||||||
SP::SPMesh* createMesh(Material* material);
|
SP::SPMesh* createMesh(Material* material);
|
||||||
void setDebugColor(const video::SColor &color);
|
void setDebugColor(const video::SColor &color, bool inner);
|
||||||
|
void updateQuad();
|
||||||
public:
|
public:
|
||||||
SlipStream (AbstractKart* kart);
|
SlipStream (AbstractKart* kart);
|
||||||
virtual ~SlipStream ();
|
virtual ~SlipStream ();
|
||||||
@ -97,4 +115,3 @@ public:
|
|||||||
bool inUse() const {return m_slipstream_mode==SS_USE; }
|
bool inUse() const {return m_slipstream_mode==SS_USE; }
|
||||||
}; // SlipStream
|
}; // SlipStream
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -215,10 +215,14 @@ AbstractCharacteristic::ValueType AbstractCharacteristic::getType(
|
|||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
case SLIPSTREAM_DURATION:
|
case SLIPSTREAM_DURATION:
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
|
case SLIPSTREAM_BASE_SPEED:
|
||||||
|
return TYPE_FLOAT;
|
||||||
case SLIPSTREAM_LENGTH:
|
case SLIPSTREAM_LENGTH:
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
case SLIPSTREAM_WIDTH:
|
case SLIPSTREAM_WIDTH:
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
|
case SLIPSTREAM_INNER_FACTOR:
|
||||||
|
return TYPE_FLOAT;
|
||||||
case SLIPSTREAM_COLLECT_TIME:
|
case SLIPSTREAM_COLLECT_TIME:
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
case SLIPSTREAM_USE_TIME:
|
case SLIPSTREAM_USE_TIME:
|
||||||
@ -447,10 +451,14 @@ std::string AbstractCharacteristic::getName(CharacteristicType type)
|
|||||||
return "NITRO_MAX";
|
return "NITRO_MAX";
|
||||||
case SLIPSTREAM_DURATION:
|
case SLIPSTREAM_DURATION:
|
||||||
return "SLIPSTREAM_DURATION";
|
return "SLIPSTREAM_DURATION";
|
||||||
|
case SLIPSTREAM_BASE_SPEED:
|
||||||
|
return "SLIPSTREAM_BASE_SPEED";
|
||||||
case SLIPSTREAM_LENGTH:
|
case SLIPSTREAM_LENGTH:
|
||||||
return "SLIPSTREAM_LENGTH";
|
return "SLIPSTREAM_LENGTH";
|
||||||
case SLIPSTREAM_WIDTH:
|
case SLIPSTREAM_WIDTH:
|
||||||
return "SLIPSTREAM_WIDTH";
|
return "SLIPSTREAM_WIDTH";
|
||||||
|
case SLIPSTREAM_INNER_FACTOR:
|
||||||
|
return "SLIPSTREAM_INNER_FACTOR";
|
||||||
case SLIPSTREAM_COLLECT_TIME:
|
case SLIPSTREAM_COLLECT_TIME:
|
||||||
return "SLIPSTREAM_COLLECT_TIME";
|
return "SLIPSTREAM_COLLECT_TIME";
|
||||||
case SLIPSTREAM_USE_TIME:
|
case SLIPSTREAM_USE_TIME:
|
||||||
@ -1471,6 +1479,18 @@ float AbstractCharacteristic::getSlipstreamDuration() const
|
|||||||
return result;
|
return result;
|
||||||
} // getSlipstreamDuration
|
} // 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
|
float AbstractCharacteristic::getSlipstreamLength() const
|
||||||
{
|
{
|
||||||
@ -1495,6 +1515,18 @@ float AbstractCharacteristic::getSlipstreamWidth() const
|
|||||||
return result;
|
return result;
|
||||||
} // getSlipstreamWidth
|
} // 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
|
float AbstractCharacteristic::getSlipstreamCollectTime() const
|
||||||
{
|
{
|
||||||
@ -1785,4 +1817,3 @@ bool AbstractCharacteristic::getSkidEnabled() const
|
|||||||
|
|
||||||
|
|
||||||
/* <characteristics-end acgetter> */
|
/* <characteristics-end acgetter> */
|
||||||
|
|
||||||
|
@ -194,8 +194,10 @@ public:
|
|||||||
|
|
||||||
// Slipstream
|
// Slipstream
|
||||||
SLIPSTREAM_DURATION,
|
SLIPSTREAM_DURATION,
|
||||||
|
SLIPSTREAM_BASE_SPEED,
|
||||||
SLIPSTREAM_LENGTH,
|
SLIPSTREAM_LENGTH,
|
||||||
SLIPSTREAM_WIDTH,
|
SLIPSTREAM_WIDTH,
|
||||||
|
SLIPSTREAM_INNER_FACTOR,
|
||||||
SLIPSTREAM_COLLECT_TIME,
|
SLIPSTREAM_COLLECT_TIME,
|
||||||
SLIPSTREAM_USE_TIME,
|
SLIPSTREAM_USE_TIME,
|
||||||
SLIPSTREAM_ADD_POWER,
|
SLIPSTREAM_ADD_POWER,
|
||||||
@ -360,8 +362,10 @@ public:
|
|||||||
float getNitroMax() const;
|
float getNitroMax() const;
|
||||||
|
|
||||||
float getSlipstreamDuration() const;
|
float getSlipstreamDuration() const;
|
||||||
|
float getSlipstreamBaseSpeed() const;
|
||||||
float getSlipstreamLength() const;
|
float getSlipstreamLength() const;
|
||||||
float getSlipstreamWidth() const;
|
float getSlipstreamWidth() const;
|
||||||
|
float getSlipstreamInnerFactor() const;
|
||||||
float getSlipstreamCollectTime() const;
|
float getSlipstreamCollectTime() const;
|
||||||
float getSlipstreamUseTime() const;
|
float getSlipstreamUseTime() const;
|
||||||
float getSlipstreamAddPower() const;
|
float getSlipstreamAddPower() const;
|
||||||
@ -392,4 +396,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -310,6 +310,23 @@ public:
|
|||||||
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
|
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
|
||||||
float engine_force, float duration,
|
float engine_force, float duration,
|
||||||
float fade_out_time) = 0;
|
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.
|
/** Defines a slowdown, which is in fraction of top speed.
|
||||||
* \param category The category for which the speed is increased.
|
* \param category The category for which the speed is increased.
|
||||||
@ -459,6 +476,9 @@ public:
|
|||||||
* defined even if the kart is flying. */
|
* defined even if the kart is flying. */
|
||||||
virtual const Vec3& getNormal() const = 0;
|
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 */
|
/** Returns the height of the terrain. we're currently above */
|
||||||
virtual float getHoT() const = 0;
|
virtual float getHoT() const = 0;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -494,4 +514,3 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
@ -147,6 +147,12 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
|
|||||||
m_boosted_ai = false;
|
m_boosted_ai = false;
|
||||||
m_type = RaceManager::KT_AI;
|
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_view_blocked_by_plunger = 0;
|
||||||
m_has_caught_nolok_bubblegum = false;
|
m_has_caught_nolok_bubblegum = false;
|
||||||
|
|
||||||
@ -370,6 +376,12 @@ void Kart::reset()
|
|||||||
m_has_caught_nolok_bubblegum = false;
|
m_has_caught_nolok_bubblegum = false;
|
||||||
m_is_jumping = 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
|
// In case that the kart was in the air, in which case its
|
||||||
// linear damping is 0
|
// linear damping is 0
|
||||||
if(m_body)
|
if(m_body)
|
||||||
@ -454,6 +466,15 @@ void Kart::increaseMaxSpeed(unsigned int category, float add_speed,
|
|||||||
fade_out_time);
|
fade_out_time);
|
||||||
} // increaseMaxSpeed
|
} // 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,
|
void Kart::setSlowdown(unsigned int category, float max_speed_fraction,
|
||||||
float fade_in_time)
|
float fade_in_time)
|
||||||
@ -1208,6 +1229,11 @@ void Kart::eliminate()
|
|||||||
m_stars_effect->update(1);
|
m_stars_effect->update(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_attachment)
|
||||||
|
{
|
||||||
|
m_attachment->clear();
|
||||||
|
}
|
||||||
|
|
||||||
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_TERRAIN, 0);
|
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_TERRAIN, 0);
|
||||||
m_kart_gfx->setGFXInvisible();
|
m_kart_gfx->setGFXInvisible();
|
||||||
if (m_engine_sound)
|
if (m_engine_sound)
|
||||||
@ -1278,9 +1304,22 @@ void Kart::update(float dt)
|
|||||||
{
|
{
|
||||||
m_kart_animation->update(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
|
// Update the position and other data taken from the physics (or
|
||||||
// an animation which calls setXYZ(), which also updates the kart
|
// an animation which calls setXYZ(), which also updates the kart
|
||||||
// physical position).
|
// physical position).
|
||||||
|
|
||||||
Moveable::update(dt);
|
Moveable::update(dt);
|
||||||
|
|
||||||
Vec3 front(0, 0, getKartLength()*0.5f);
|
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.
|
// when pressing the key, don't allow the min time to go under zero.
|
||||||
// If it went under zero, it would be reset
|
// 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)
|
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 (!increase_speed && m_min_nitro_time <= 0.0f)
|
||||||
{
|
{
|
||||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
|
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;
|
float nitro_frac = 0;
|
||||||
if ( (m_controls.getNitro() || m_min_nitro_time > 0.0f) &&
|
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
|
// fabs(speed) is important, otherwise the negative number will
|
||||||
// become a huge unsigned number in the particle scene node!
|
// become a huge unsigned number in the particle scene node!
|
||||||
@ -3050,6 +3091,14 @@ const Vec3& Kart::getNormal() const
|
|||||||
return m_terrain_info->getNormal();
|
return m_terrain_info->getNormal();
|
||||||
} // getNormal
|
} // getNormal
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns the position 0,25s before */
|
||||||
|
const Vec3& Kart::getPreviousXYZ() const
|
||||||
|
{
|
||||||
|
return m_previous_xyz[29];
|
||||||
|
} // getPreviousXYZ
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void Kart::playSound(SFXBuffer* buffer)
|
void Kart::playSound(SFXBuffer* buffer)
|
||||||
{
|
{
|
||||||
|
@ -74,6 +74,11 @@ protected:
|
|||||||
* new lap is triggered. */
|
* new lap is triggered. */
|
||||||
Vec3 m_xyz_front;
|
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 */
|
/** Is time flying activated */
|
||||||
bool m_is_jumping;
|
bool m_is_jumping;
|
||||||
|
|
||||||
@ -273,6 +278,9 @@ public:
|
|||||||
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
|
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
|
||||||
float engine_force, float duration,
|
float engine_force, float duration,
|
||||||
float fade_out_time);
|
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,
|
virtual void setSlowdown(unsigned int category, float max_speed_fraction,
|
||||||
float fade_in_time);
|
float fade_in_time);
|
||||||
virtual float getSpeedIncreaseTimeLeft(unsigned int category) const;
|
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
|
/** Returns the normal of the terrain the kart is over atm. This is
|
||||||
* defined even if the kart is flying. */
|
* defined even if the kart is flying. */
|
||||||
virtual const Vec3& getNormal() const;
|
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. */
|
/** For debugging only: check if a kart is flying. */
|
||||||
bool isFlying() const { return m_flying; }
|
bool isFlying() const { return m_flying; }
|
||||||
|
@ -1042,6 +1042,12 @@ float KartProperties::getSlipstreamDuration() const
|
|||||||
return m_cached_characteristic->getSlipstreamDuration();
|
return m_cached_characteristic->getSlipstreamDuration();
|
||||||
} // getSlipstreamDuration
|
} // getSlipstreamDuration
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float KartProperties::getSlipstreamBaseSpeed() const
|
||||||
|
{
|
||||||
|
return m_cached_characteristic->getSlipstreamBaseSpeed();
|
||||||
|
} // getSlipstreamBaseSpeed
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
float KartProperties::getSlipstreamLength() const
|
float KartProperties::getSlipstreamLength() const
|
||||||
{
|
{
|
||||||
@ -1054,6 +1060,12 @@ float KartProperties::getSlipstreamWidth() const
|
|||||||
return m_cached_characteristic->getSlipstreamWidth();
|
return m_cached_characteristic->getSlipstreamWidth();
|
||||||
} // getSlipstreamWidth
|
} // getSlipstreamWidth
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
float KartProperties::getSlipstreamInnerFactor() const
|
||||||
|
{
|
||||||
|
return m_cached_characteristic->getSlipstreamInnerFactor();
|
||||||
|
} // getSlipstreamInnerFactor
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
float KartProperties::getSlipstreamCollectTime() const
|
float KartProperties::getSlipstreamCollectTime() const
|
||||||
{
|
{
|
||||||
@ -1199,4 +1211,3 @@ bool KartProperties::getSkidEnabled() const
|
|||||||
} // getSkidEnabled
|
} // getSkidEnabled
|
||||||
|
|
||||||
/* <characteristics-end kpgetter> */
|
/* <characteristics-end kpgetter> */
|
||||||
|
|
||||||
|
@ -482,8 +482,10 @@ public:
|
|||||||
float getNitroMax() const;
|
float getNitroMax() const;
|
||||||
|
|
||||||
float getSlipstreamDuration() const;
|
float getSlipstreamDuration() const;
|
||||||
|
float getSlipstreamBaseSpeed() const;
|
||||||
float getSlipstreamLength() const;
|
float getSlipstreamLength() const;
|
||||||
float getSlipstreamWidth() const;
|
float getSlipstreamWidth() const;
|
||||||
|
float getSlipstreamInnerFactor() const;
|
||||||
float getSlipstreamCollectTime() const;
|
float getSlipstreamCollectTime() const;
|
||||||
float getSlipstreamUseTime() const;
|
float getSlipstreamUseTime() const;
|
||||||
float getSlipstreamAddPower() const;
|
float getSlipstreamAddPower() const;
|
||||||
|
@ -563,10 +563,14 @@ void XmlCharacteristic::load(const XMLNode *node)
|
|||||||
{
|
{
|
||||||
sub_node->get("duration",
|
sub_node->get("duration",
|
||||||
&m_values[SLIPSTREAM_DURATION]);
|
&m_values[SLIPSTREAM_DURATION]);
|
||||||
|
sub_node->get("base-speed",
|
||||||
|
&m_values[SLIPSTREAM_BASE_SPEED]);
|
||||||
sub_node->get("length",
|
sub_node->get("length",
|
||||||
&m_values[SLIPSTREAM_LENGTH]);
|
&m_values[SLIPSTREAM_LENGTH]);
|
||||||
sub_node->get("width",
|
sub_node->get("width",
|
||||||
&m_values[SLIPSTREAM_WIDTH]);
|
&m_values[SLIPSTREAM_WIDTH]);
|
||||||
|
sub_node->get("inner-factor",
|
||||||
|
&m_values[SLIPSTREAM_INNER_FACTOR]);
|
||||||
sub_node->get("collect-time",
|
sub_node->get("collect-time",
|
||||||
&m_values[SLIPSTREAM_COLLECT_TIME]);
|
&m_values[SLIPSTREAM_COLLECT_TIME]);
|
||||||
sub_node->get("use-time",
|
sub_node->get("use-time",
|
||||||
@ -624,4 +628,3 @@ void XmlCharacteristic::load(const XMLNode *node)
|
|||||||
|
|
||||||
/* <characteristics-end getXml> */
|
/* <characteristics-end getXml> */
|
||||||
} // load
|
} // load
|
||||||
|
|
||||||
|
10
src/main.cpp
@ -548,7 +548,8 @@ void cmdLineHelp()
|
|||||||
"./data/stk_config.xml\n"
|
"./data/stk_config.xml\n"
|
||||||
" -k, --numkarts=NUM Set number of karts on the racetrack.\n"
|
" -k, --numkarts=NUM Set number of karts on the racetrack.\n"
|
||||||
" --kart=NAME Use kart NAME.\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"
|
" --laps=N Define number of laps to N.\n"
|
||||||
" --mode=N N=1 Beginner, N=2 Intermediate, N=3 Expert, N=4 SuperTux.\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"
|
" --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);
|
race_manager->setNumKarts((int)l.size()+1);
|
||||||
} // --ai
|
} // --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))
|
if(CommandLine::has( "--mode", &s) || CommandLine::has( "--difficulty", &s))
|
||||||
{
|
{
|
||||||
int n = atoi(s.c_str());
|
int n = atoi(s.c_str());
|
||||||
|
@ -280,7 +280,9 @@ void RaceManager::computeRandomKartList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_ai_kart_list.clear();
|
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++)
|
for(unsigned int i=0; i<m; i++)
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ GUIEngine::EventPropagation GeneralTextFieldDialog::processEvent(const std::stri
|
|||||||
else if (eventSource == "ok")
|
else if (eventSource == "ok")
|
||||||
{
|
{
|
||||||
// If validation callback return true, dismiss the dialog
|
// 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;
|
m_self_destroy = true;
|
||||||
return GUIEngine::EVENT_BLOCK;
|
return GUIEngine::EVENT_BLOCK;
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ void GeneralTextFieldDialog::onEnterPressedInternal()
|
|||||||
return;
|
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;
|
m_self_destroy = true;
|
||||||
|
|
||||||
} // onEnterPressedInternal
|
} // onEnterPressedInternal
|
||||||
|
@ -387,18 +387,26 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a normal race, nothing was unlocked
|
|
||||||
// -------------------------------------------
|
|
||||||
StateManager::get()->popMenu();
|
StateManager::get()->popMenu();
|
||||||
if (name == "top") // Setup new race
|
if (name == "top") // Setup new race
|
||||||
{
|
{
|
||||||
race_manager->exitRace();
|
race_manager->exitRace();
|
||||||
race_manager->setAIKartOverride("");
|
race_manager->setAIKartOverride("");
|
||||||
|
|
||||||
|
//If pressing continue quickly in a losing challenge
|
||||||
|
if (race_manager->raceWasStartedFromOverworld())
|
||||||
|
{
|
||||||
|
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
|
||||||
|
OverWorld::enterOverWorld();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Screen* newStack[] = { MainMenuScreen::getInstance(),
|
Screen* newStack[] = { MainMenuScreen::getInstance(),
|
||||||
RaceSetupScreen::getInstance(),
|
RaceSetupScreen::getInstance(),
|
||||||
NULL };
|
NULL };
|
||||||
StateManager::get()->resetAndSetStack(newStack);
|
StateManager::get()->resetAndSetStack(newStack);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (name == "middle") // Restart
|
else if (name == "middle") // Restart
|
||||||
{
|
{
|
||||||
race_manager->rerunRace();
|
race_manager->rerunRace();
|
||||||
|
@ -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;
|
m_max_height_testing = Graph::MAX_HEIGHT_TESTING;
|
||||||
} // Quad
|
} // 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.
|
/** 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.
|
* \param v The vertex array in which to set the vertices.
|
||||||
|
@ -84,6 +84,9 @@ public:
|
|||||||
/** Returns the center of a quad. */
|
/** Returns the center of a quad. */
|
||||||
const Vec3& getCenter () const { return m_center; }
|
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)
|
void setHeightTesting(float min, float max)
|
||||||
{
|
{
|
||||||
m_min_height_testing = min;
|
m_min_height_testing = min;
|
||||||
|
@ -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
|
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"
|
echo "Testing $track"
|
||||||
$1 --log=0 -R \
|
$1 --log=0 -R \
|
||||||
--ai=nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok \
|
--aiNP=nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok,nolok \
|
||||||
--track=$track --difficulty=2 --type=1 --test-ai=2 \
|
--track=$track --difficulty=3 --type=1 --test-ai=2 \
|
||||||
--profile-laps=10 --no-graphics > stdout.$track
|
--profile-laps=10 --no-graphics > stdout.$track
|
||||||
done
|
done
|
||||||
|
@ -48,7 +48,7 @@ Startup: time(std::vector<float>/floatVector), boost(std::vector<float>/floatVec
|
|||||||
Rescue: duration, vertOffset, height
|
Rescue: duration, vertOffset, height
|
||||||
Explosion: duration, radius, invulnerabilityTime
|
Explosion: duration, radius, invulnerabilityTime
|
||||||
Nitro: duration, engineForce, consumption, smallContainer, bigContainer, maxSpeedIncrease, fadeOutTime, max
|
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)"""
|
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.
|
""" A GroupMember is an attribute of a group.
|
||||||
@ -283,4 +283,3 @@ Operations:""")
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|