Merged master

This commit is contained in:
Sachith Hasaranga Seneviratne 2014-07-05 06:58:43 +05:30
commit 6af28141a4
23 changed files with 1327 additions and 387 deletions

View File

@ -145,7 +145,7 @@
<!-- Default values for all karts
============================ -->
<general-kart-defaults>
<!-- Camera: Distance between kart and camera.
forward-up-angle: Angle between camera and plane of kart (pitch)
when the camera is pointing forward
@ -162,57 +162,6 @@
shown. -->
<jump animation-time="0.5" />
<!-- If a kart starts within the specified time after 'go',
it receives the corresponding bonus from 'boost'. Those
fields must have the same size, and must be sorted by
increasing times. -->
<startup time = "0.3 0.5"
boost = "6 3" />
<!-- Rescue: time: How long it takes the kart to be raised.
height: how height the kart will be raised before it is
dropped back onto the track.
vert rescue offset: used to raise karts a bit higher before
releasing them on the ground after a rescue. Used to avoid
resetting karts into the track. Not sure if this is still
necessary. -->
<rescue vert-offset="0.0" time="1.2" height="2"/>
<!-- Nitro: engine-force: additional engine power
consumption: nitro consumption - heavier characters can be set
to need more nitro than lighter character.
small-container: how much energy a small container gives.
big-container: how much energy a big container gives.
max-speed-increase: How much the speed of a kart might exceed
its maximum speed (in m/s).
duration: How long the increased speed will be valid after
the kart stops using nitro (and the fade-out-time starts).
fade-out-time: Duration during which the increased maximum
speed due to nitro fades out.
max: How much nitro a kart can store.
-->
<nitro engine-force="500" consumption="1" small-container="1" big-container="3"
max-speed-increase="5" duration="1" fade-out-time="2" max="20"/>
<!-- Bubble gum data:
time: How long the bubblegum lasts.
speed-fraction: To what fraction of top-speed the speed is reduced.
torque: To rotate the kart somewhat.
fade-in-time: How quick the slowdown takes effect.
-->
<bubblegum time="1" speed-fraction="0.3" torque="500" fade-in-time="0.01"/>
<!-- time: Time a zipper is active.
force: Additional zipper force.
speed-gain: One time additional speed.
max-speed-increase: Additional speed allowed on top of the
kart-specific maximum kart speed.
fade-out-time: determines how long it takes for a zipper
to fade out (after 'time').
-->
<zipper time="3.5" force="250.0" speed-gain="4.5" max-speed-increase="15"
fade-out-time="1.0" />
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
decrease: multiplicative decrease of skidding factor in each frame.
max: maximum skidding factor = maximum increase of steering angle.
@ -246,15 +195,6 @@
of the turn the kart is doing somewhat by steering to the left and right,
but you will always keep on doing a left turn, just more or less. -->
<skid increase="1.05" decrease="0.95" max="2.5" time-till-max="0.5"
visual="1.25" visual-time="0.7" revert-visual-time="0.7"
min-speed="10" time-till-bonus="1.0 3.0"
bonus-speed="4.5 6.5" bonus-time="3.0 4.0"
bonus-force="250 350"
physical-jump-time="0" graphical-jump-time="0.4"
post-skid-rotate-factor="1"
reduce-turn-min="0.2" reduce-turn-max="0.8"/>
<!-- Kart-specific settings used by the AI.
use-slipstream: if the AI should try to overtake karts using slipstream.
disable-slipstream-usage: even if the AI is not trying to use slipstream,
@ -394,81 +334,7 @@
skidding-threshold="2.0"
/>
</ai>
<!-- Slipstream: length: How far behind a kart slipstream works
width: how wide slipstream works furthest away from the kart.
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%
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.
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"/>
<!-- Kart-specific settings for the swatter:
duration: how long can the swatter be active.
distance: How close a kart or an item must be before it can be hit.
squash-duration: How long a kart will remain squashed.
squash-slowdown: percentage of max speed that a kart is
restricted to. -->
<swatter duration="10" distance="3" squash-duration="5"
squash-slowdown="0.5"/>
<!-- Leaning related parameters, i.e. slightly leaning the karts when
driving a fast curve.
max: maximum leaning (i.e. when steering as much as possible at highest
speed), in degrees.
sped: Speed with which the leaning changes (in degree/second). -->
<lean max="8.6" speed="5.0" />
<!-- turn-radius defines the turn radius of the kart at
a given speed. The actual steering angle is dependent on the
wheel base of the kart: radius = wheel_base/sin(steering_angle).
The values below define that at speed 0 the turn radius is 2, at
speed 10 the radius is 7.5 etc.
The actual turn radius is piece-wise linearly interpolated. This
allows for tighter turning at lower speeds, and also avoids that
the kart becomes too hard to control at high speed (speeds of higher
than 23 can only be reached with powerups).
time-full-steer: This is the amount of change in steering depending
on current steering. So if the steering is between 0 and 0.5,
the time-for-steering-change is 0.15. If the current steering is
between 0.5 and 1.0, the time-for-steering-change is 0.25.
The speed is used as dt/time-for-steering-change.
In short: steering at less than halfway is somewhat faster,
which should avoid oversteering (by pressing the key for too long),
but slower when you want to steer more. Overwall with the current
settings the expected time-to-full-steer is:
0.5 * 0.25 + 0.5 * 0.15 = 0.2 ... which is overall the same
time we had previously.
-->
<turn turn-radius="0:2.0 10:7.5 25:15 45:30"
time-full-steer ="0:0.15 0.5:0.15 0.5:0.25 1.0:0.25"
time-reset-steer="0.1" />
<!-- Speed and acceleration related values: power and max-speed (in m/s)
have 3 values, one for low, medium, and hard.
brake-factor: Value used when braking. max-speed-reverse-ratio is
the percentage of max speed for reverse gear. -->
<engine power="450 475 500 510" max-speed="17 21 23 25" brake-factor="11.0"
max-speed-reverse-ratio="0.3"/>
<!-- Simulated gears: switch-ratio defines at what ratio of the maximum
speed what gear is selected, e.g. 0.25 means that if the speed is
bigger or equal to 0.25 x maxSpeed then use gear 1, 0.5 means if
the speed is bigger or equal to 0.5 x maxSpeed then gear 2.
gear-power-increase contains the increase in max power (to simulate
different gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1
| first | second | third | . -->
<gear switch-ratio="0.25 0.7 1.0" power-increase="2.2 1.7 1.3"/>
<!-- mass -->
<mass value="225"/>
<!-- Suspension related values. stiffness: kart's suspension stiffness.
rest: Length of suspension when at rest.
travel-cm: maximum movement of suspension - in cm!!
@ -549,26 +415,280 @@
<collision impulse-type="normal"
impulse="3000" impulse-time="0.1" terrain-impulse="8000"
restitution="1.0" bevel-factor="0.5 0.0 0.5" />
<!-- If a kart starts within the specified time after 'go',
it receives the corresponding bonus from 'boost'. Those
fields must have the same size, and must be sorted by
increasing times. -->
<startup time = "0.3 0.5"
boost = "6 3" />
<!-- Rescue: time: How long it takes the kart to be raised.
height: how height the kart will be raised before it is
dropped back onto the track.
vert rescue offset: used to raise karts a bit higher before
releasing them on the ground after a rescue. Used to avoid
resetting karts into the track. Not sure if this is still
necessary. -->
<rescue vert-offset="0.0" time="1.2" height="2"/>
<!-- Nitro: engine-force: additional engine power
consumption: nitro consumption - heavier characters can be set
to need more nitro than lighter character.
small-container: how much energy a small container gives.
big-container: how much energy a big container gives.
max-speed-increase: How much the speed of a kart might exceed
its maximum speed (in m/s).
duration: How long the increased speed will be valid after
the kart stops using nitro (and the fade-out-time starts).
fade-out-time: Duration during which the increased maximum
speed due to nitro fades out.
max: How much nitro a kart can store.
-->
<nitro engine-force="500" consumption="1" small-container="1" big-container="3"
max-speed-increase="5" duration="1" fade-out-time="2" max="20"/>
<!-- Bubble gum data:
time: How long the bubblegum lasts.
speed-fraction: To what fraction of top-speed the speed is reduced.
torque: To rotate the kart somewhat.
fade-in-time: How quick the slowdown takes effect.
-->
<bubblegum time="1" speed-fraction="0.3" torque="500" fade-in-time="0.01"/>
<!-- time: Time a zipper is active.
force: Additional zipper force.
speed-gain: One time additional speed.
max-speed-increase: Additional speed allowed on top of the
kart-specific maximum kart speed.
fade-out-time: determines how long it takes for a zipper
to fade out (after 'time').
-->
<zipper time="3.5" force="250.0" speed-gain="4.5" max-speed-increase="15"
fade-out-time="1.0" />
<!-- Kart-specific plunger and rubber band handling: max-length is
the maximum length of rubber band before it snaps. force is
the force a plunger/rubber band applies to the kart(s).
duration is the duration a rubber band acts.
in-face-time determines how long it takes before a plunger
in your face is removed. -->
<plunger band-max-length="50" band-force="1500" band-duration="1"
band-speed-increase="7" band-fade-out-time="3"
in-face-time="3 4 4.5 4.5"/>
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
decrease: multiplicative decrease of skidding factor in each frame.
max: maximum skidding factor = maximum increase of steering angle.
time-till-max: Time till maximum skidding is reached.
visual: Additional graphical rotation of kart. The graphical rotation
of the kart also determines the direction the kart is driving to
when skidding is stopped.
visual-time: How long it takes for the visual skid to reach maximum.
revert-visual-time: how long it takes when stopping a skid to revert
the visual skid and bring visuals and physics in sync again.
angular-velocity: Angular velocity to be used for the kart when skidding.
min-speed: Minimum speed a kart must have before it can skid. Must be
>0, otherwise the kart can skid at the start of the race.
time-till-bonus: How long a kart needs to skid in order to get a bonus.
bonus-force: A speedup applied to the kart whick skidded for a while.
bonus-time: How long the bonus-force is applied.
bonus-force: Additional engine force (this is used to offset the fact
that turning after skidding (e.g. to correct direction) often uses
up the skid bonus).
post-skid-rotate-factor: a factor to be used to determine how much
the chassis of a kart should rotate to match the graphical view.
A factor of 1 is identical, a smaller factor will rotate the kart
less (which might feel better).
physical-jump-time: Time for a physical jump at the beginning of a skid.
graphical-jump-time: Time for a graphics-only jump at the beginning
of a skid.
reduce-turn-min/max: The steering done by the controller (which is in
[-1,1]) is mapped to [reduce-turn-min, reduce-turn-max] when skidding
is active (for left turn, right turn will use [-max, -min]). The
effect is that while you skid (say left) you can adjust the direction
of the turn the kart is doing somewhat by steering to the left and right,
but you will always keep on doing a left turn, just more or less. -->
<skid increase="1.05" decrease="0.95" max="2.5" time-till-max="0.5"
visual="1.25" visual-time="0.7" revert-visual-time="0.7"
min-speed="10" time-till-bonus="1.0 3.0"
bonus-speed="4.5 6.5" bonus-time="3.0 4.0"
bonus-force="250 350"
physical-jump-time="0" graphical-jump-time="0.4"
post-skid-rotate-factor="1"
reduce-turn-min="0.2" reduce-turn-max="0.8"/>
<!-- Slipstream: length: How far behind a kart slipstream works
width: how wide slipstream works furthest away from the kart.
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%
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.
fade-out-time: How long the slip stream speed increase will
gradually be reduced. -->
<!-- Kart-specific explosion parameters.
Time: how long it takes before the kart can drive again (this
determines how height the kart is being thrown).
Invulnerability-time: how long a kart will be invulnerable
after being hit by an explosion.
radius: Kart closer to this value will be affected by
an explosion as well. -->
<explosion time="2" radius="5"
invulnerability-time="6" />
<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"/>
<!-- Kart-specific settings for the swatter:
duration: how long can the swatter be active.
distance: How close a kart or an item must be before it can be hit.
squash-duration: How long a kart will remain squashed.
squash-slowdown: percentage of max speed that a kart is
restricted to. -->
<swatter duration="10" distance="3" squash-duration="5"
squash-slowdown="0.5"/>
<!-- Leaning related parameters, i.e. slightly leaning the karts when
driving a fast curve.
max: maximum leaning (i.e. when steering as much as possible at highest
speed), in degrees.
sped: Speed with which the leaning changes (in degree/second). -->
<lean max="8.6" speed="5.0" />
<!-- turn-radius defines the turn radius of the kart at
a given speed. The actual steering angle is dependent on the
wheel base of the kart: radius = wheel_base/sin(steering_angle).
The values below define that at speed 0 the turn radius is 2, at
speed 10 the radius is 7.5 etc.
The actual turn radius is piece-wise linearly interpolated. This
allows for tighter turning at lower speeds, and also avoids that
the kart becomes too hard to control at high speed (speeds of higher
than 23 can only be reached with powerups).
time-full-steer: This is the amount of change in steering depending
on current steering. So if the steering is between 0 and 0.5,
the time-for-steering-change is 0.15. If the current steering is
between 0.5 and 1.0, the time-for-steering-change is 0.25.
The speed is used as dt/time-for-steering-change.
In short: steering at less than halfway is somewhat faster,
which should avoid oversteering (by pressing the key for too long),
but slower when you want to steer more. Overwall with the current
settings the expected time-to-full-steer is:
0.5 * 0.25 + 0.5 * 0.15 = 0.2 ... which is overall the same
time we had previously.
-->
<turn turn-radius="0:2.0 10:7.5 25:15 45:30"
time-full-steer ="0:0.15 0.5:0.15 0.5:0.25 1.0:0.25"
time-reset-steer="0.1" />
<!-- Speed and acceleration related values: power and max-speed (in m/s)
have 3 values, one for low, medium, and hard.
brake-factor: Value used when braking. max-speed-reverse-ratio is
the percentage of max speed for reverse gear. -->
<engine power="450 475 500 510" max-speed="17 21 23 25" brake-factor="11.0"
max-speed-reverse-ratio="0.3"/>
<!-- Simulated gears: switch-ratio defines at what ratio of the maximum
speed what gear is selected, e.g. 0.25 means that if the speed is
bigger or equal to 0.25 x maxSpeed then use gear 1, 0.5 means if
the speed is bigger or equal to 0.5 x maxSpeed then gear 2.
gear-power-increase contains the increase in max power (to simulate
different gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1
| first | second | third | . -->
<gear switch-ratio="0.25 0.7 1.0" power-increase="2.2 1.7 1.3"/>
<!-- mass -->
<mass value="225"/>
<!-- Kart-specific plunger and rubber band handling: max-length is
the maximum length of rubber band before it snaps. force is
the force a plunger/rubber band applies to the kart(s).
duration is the duration a rubber band acts.
in-face-time determines how long it takes before a plunger
in your face is removed. -->
<plunger band-max-length="50" band-force="1500" band-duration="1"
band-speed-increase="7" band-fade-out-time="3"
in-face-time="3 4 4.5 4.5"/>
<!-- Kart-specific explosion parameters.
Time: how long it takes before the kart can drive again (this
determines how height the kart is being thrown).
Invulnerability-time: how long a kart will be invulnerable
after being hit by an explosion.
radius: Kart closer to this value will be affected by
an explosion as well. -->
<explosion time="2" radius="5"
invulnerability-time="6" />
<kart-type>
<light>
<startup time = "0.3 0.5"
boost = "8.5 4.5" />
<nitro engine-force="350" consumption="1" small-container="1" big-container="3"
max-speed-increase="4.5" duration="1.5" fade-out-time="2.5" max="20"/>
<slipstream length="11" width="2" 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"/>
<turn turn-radius="0:3.0 10:10.0 25:20.0 45:40.0"
time-full-steer ="0:0.15 0.5:0.15 0.5:0.25 1.0:0.25"
time-reset-steer="0.1"/>
<engine power="250 300 350 400" max-speed="15.8 18.8 23.85 30.0" brake-factor="15.0"
max-speed-reverse-ratio="0.3"/>
<gear switch-ratio="0.20 0.55 1" power-increase="5 4 3"/>
<mass value="195"/>
<explosion time="2.1" radius="5.5"
invulnerability-time="7" />
</light>
<medium>
<startup time = "0.3 0.5"
boost = "4.2 2.6" />
<nitro engine-force="425" consumption="1.4" small-container="1" big-container="3"
max-speed-increase="5" duration="1.2" fade-out-time="2" max="20"/>
<slipstream length="10" width="2" collect-time="2" use-time="3.3"
add-power="2.8" min-speed="10"
max-speed-increase="5" duration="0.9" fade-out-time="1.6"/>
<turn turn-radius="0:4.5 10:16.0 25:30.0 45:60.0"
time-full-steer ="0:0.17 0.5:0.17 0.5:0.28 1.0:0.28"
time-reset-steer="0.1"/>
<engine power="425 500 575 600" max-speed="15 20 23.2 27" brake-factor="11.0"
max-speed-reverse-ratio="0.4"/>
<gear switch-ratio="0.30 0.7 1.0" power-increase="2.2 2.2 2.5"/>
<mass value="250"/>
<explosion time="1.8" radius="5"
invulnerability-time="6" />
</medium>
<heavy>
<startup time = "0.3 0.5"
boost = "3.8 2" />
<nitro engine-force="600" consumption="2" small-container="1" big-container="3"
max-speed-increase="8" duration="0.7" fade-out-time="1.3" max="20"/>
<slipstream length="8.5" width="2" collect-time="2" use-time="4"
add-power="2.7" min-speed="10.5"
max-speed-increase="8" duration="0.7" fade-out-time="1"/>
<swatter duration="10" distance="3" squash-duration="5"
squash-slowdown="0.5"/>
<turn turn-radius="0:4.0 10:18.5 25:43.0 45:72.5"
time-full-steer ="0:0.23 0.5:0.23 0.5:0.41 1.0:0.41"
time-reset-steer="0.1"/>
<engine power="600 700 800 900" max-speed="15 20 23 25" brake-factor="10"
max-speed-reverse-ratio="0.65"/>
<gear switch-ratio="0.45 0.70 1" power-increase="1.5 1.7 2.5"/>
<mass value="350"/>
<explosion time="1.5" radius="4"
invulnerability-time="6" />
</heavy>
</kart-type>
</general-kart-defaults>
</config>

View File

@ -1,6 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -50,6 +50,13 @@ STKConfig::~STKConfig()
if(m_default_kart_properties)
delete m_default_kart_properties;
for(std::map<std::string, KartProperties*>::iterator it = m_kart_properties.begin();
it != m_kart_properties.end(); ++it)
{
if (it->second)
delete it->second;
}
} // ~STKConfig
//-----------------------------------------------------------------------------
@ -380,6 +387,15 @@ void STKConfig::getAllData(const XMLNode * root)
throw std::runtime_error(msg.str());
}
m_default_kart_properties->getAllData(node);
const XMLNode *types = node->getNode("kart-type");
for (unsigned int i = 0; i < types->getNumNodes(); ++i)
{
const XMLNode* type = types->getNode(i);
m_kart_properties[type->getName()] = new KartProperties();
m_kart_properties[type->getName()]->copyFrom(m_default_kart_properties);
m_kart_properties[type->getName()]->getAllData(type);
}
} // getAllData

View File

@ -30,6 +30,7 @@
#include <vector>
#include <string>
#include <map>
class KartProperties;
class MusicInformation;
@ -47,6 +48,7 @@ class STKConfig : public NoCopy
protected:
/** Default kart properties. */
KartProperties *m_default_kart_properties;
std::map<std::string, KartProperties*> m_kart_properties;
public:
/** What to do if a kart already has a powerup when it hits a bonus box:
@ -170,6 +172,9 @@ public:
/** Returns the default kart properties for each kart. */
const KartProperties &
getDefaultKartProperties() const {return *m_default_kart_properties; }
const KartProperties &
getKartProperties(std::string type) { return *m_kart_properties[type]; }
}
; // STKConfig

View File

@ -99,7 +99,7 @@ const int MIN_SUPPORTED_WIDTH = 800;
* So we create a dummy device here to begin with, which is then later (once
* the real device exists) changed in initDevice().
*/
IrrDriver::IrrDriver()
IrrDriver::IrrDriver() : object_count{}
{
m_resolution_changing = RES_CHANGE_NONE;
m_phase = SOLID_NORMAL_AND_DEPTH_PASS;
@ -110,8 +110,8 @@ IrrDriver::IrrDriver()
m_post_processing = NULL;
m_wind = new Wind();
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = 0;
SkyboxCubeMap = 0;
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false;
SkyboxCubeMap = m_last_light_bucket_distance = 0;
} // IrrDriver
// ----------------------------------------------------------------------------
@ -1657,8 +1657,14 @@ void IrrDriver::displayFPS()
if (UserConfigParams::m_artist_debug_mode)
{
sprintf(buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
min, fps, max, object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[TRANSPARENT_PASS], m_last_light_bucket_distance);
sprintf(
buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
min, fps, max,
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
object_count[TRANSPARENT_PASS],
m_last_light_bucket_distance
);
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
object_count[TRANSPARENT_PASS] = 0;

View File

@ -821,7 +821,9 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
core::aabbox3df trackbox(vmin->toIrrVector(), vmax->toIrrVector() -
core::vector3df(0, 30, 0));
if (trackbox.MinEdge.X != trackbox.MaxEdge.X &&
trackbox.MinEdge.Y != trackbox.MaxEdge.Y)
trackbox.MinEdge.Y != trackbox.MaxEdge.Y &&
// Cover the case where SunCamViewMatrix is null
SunCamViewMatrix.getScale() != core::vector3df(0., 0., 0.))
{
SunCamViewMatrix.transformBoxEx(trackbox);
core::matrix4 tmp_matrix;

View File

@ -0,0 +1,170 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "guiengine/engine.hpp"
#include "guiengine/widgets/kart_stats_widget.hpp"
#include "utils/string_utils.hpp"
#include <string.h>
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include "config/user_config.hpp"
#include <IGUIEnvironment.h>
#include <IGUIElement.h>
#include <IGUIButton.h>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr;
// -----------------------------------------------------------------------------
KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
std::string kart_group,
bool multiplayer) : Widget(WTYPE_DIV)
{
m_player_id = player_id;
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
area.getWidth(), area.getHeight() );
const std::string default_kart = UserConfigParams::m_default_kart;
const KartProperties* props =
kart_properties_manager->getKart(default_kart);
if(!props)
{
// If the default kart can't be found (e.g. previously a addon
// kart was used, but the addon package was removed), use the
// first kart as a default. This way we don't have to hardcode
// any kart names.
int id = kart_properties_manager->getKartByGroup(kart_group, 0);
if (id == -1)
{
props = kart_properties_manager->getKartById(0);
}
else
{
props = kart_properties_manager->getKartById(id);
}
if(!props)
{
fprintf(stderr,
"[KartSelectionScreen] WARNING: Can't find default "
"kart '%s' nor any other kart.\n",
default_kart.c_str());
exit(-1);
}
}
const int offset = (m_h - (SKILL_COUNT*m_skill_bar_h)) / 2;
for (int i = 0; i < SKILL_COUNT; ++i)
{
irr::core::recti skillArea(m_skill_bar_x, m_skill_bar_y + offset*i,
m_skill_bar_x + m_skill_bar_w,
m_skill_bar_y + m_skill_bar_h + offset*i);
SkillLevelWidget* skill_bar = NULL;
skill_bar = new SkillLevelWidget(skillArea, m_player_id, multiplayer);
m_skills.push_back(skill_bar);
m_children.push_back(skill_bar);
}
m_skills[SKILL_MASS]->setValue((int)(props->getMass()/5));
m_skills[SKILL_MASS]->setLabel("WEIGHT");
m_skills[SKILL_MASS]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_mass", m_player_id);
m_skills[SKILL_SPEED]->setValue((int)((props->getAbsMaxSpeed()-20)*20));
m_skills[SKILL_SPEED]->setLabel("SPEED");
m_skills[SKILL_SPEED]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_speed", m_player_id);
m_skills[SKILL_POWER]->setValue((int)(props->getAvgPower()));
m_skills[SKILL_POWER]->setLabel("POWER");
m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id);
} // KartStatsWidget
// -----------------------------------------------------------------------------
void KartStatsWidget::add()
{
for (int i = 0; i < SKILL_COUNT; ++i) {
m_skills[i]->add();
}
}
void KartStatsWidget::move(int x, int y, int w, int h)
{
Widget::move(x,y,w,h);
setSize(m_x, m_y, m_w, m_h);
int offset = (m_h - (SKILL_COUNT*m_skill_bar_h)) / 2;
for (int i = 0; i < SKILL_COUNT; ++i)
{
m_skills[i]->move(m_skill_bar_x,
m_y + offset + m_skill_bar_h*i,
m_skill_bar_w,
m_skill_bar_h);
}
} //move
// -----------------------------------------------------------------------------
// ---- set value for given type
void KartStatsWidget::setValue(Stats type, int value)
{
m_skills[type]->setValue(value);
} //setValue
// -----------------------------------------------------------------------------
// ---- get value for given type
int KartStatsWidget::getValue(Stats type)
{
return m_skills[type]->getValue();
} // getVAlue
// ---- set size for widgets inside KartStatsWidget
void KartStatsWidget::setSize(const int x, const int y, const int w, const int h)
{
m_x = x;
m_y = y;
m_w = w;
m_h = h;
// -- sizes
m_skill_bar_w = w;
m_skill_bar_h = GUIEngine::getTitleFontHeight();
// for shrinking effect
if (h < 175)
{
const float factor = h / 175.0f;
m_skill_bar_h = (int)(m_skill_bar_h*factor);
}
m_skill_bar_x = x;
m_skill_bar_y = y + h/2 - m_skill_bar_h/2;
} // setSize
// -----------------------------------------------------------------------------

View File

@ -0,0 +1,104 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_KART_STATS_HPP
#define HEADER_KART_STATS_HPP
#include <irrString.h>
#include "guiengine/widget.hpp"
#include "utils/leak_check.hpp"
#include "utils/ptr_vector.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/progress_bar_widget.hpp"
#include "guiengine/widgets/skill_level_widget.hpp"
namespace GUIEngine
{
/**
* \brief A progress bar widget.
* \ingroup widgetsgroup
*/
class KartStatsWidget : public Widget
{
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getWidthNeededAroundLabel() const { return 35; }
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getHeightNeededAroundLabel() const { return 4; }
/** widget coordinates */
int m_skill_bar_x, m_skill_bar_y, m_skill_bar_h, m_skill_bar_w;
int m_player_id;
std::vector<SkillLevelWidget*> m_skills;
public:
enum Stats
{
SKILL_MASS,
SKILL_SPEED,
SKILL_POWER,
SKILL_COUNT
};
LEAK_CHECK()
KartStatsWidget(core::recti area, const int player_id,
std::string kart_group,
bool multiplayer);
virtual ~KartStatsWidget() {};
// ------------------------------------------------------------------------
/** Add the widgets to the current screen */
virtual void add();
/** Move the widget and its children */
virtual void move(const int x, const int y, const int w, const int h);
// -------------------------------------------------------------------------
/** Updates the animation (moving/shrinking/etc.) */
void onUpdate(float delta);
// -------------------------------------------------------------------------
/** Event callback */
// -------------------------------------------------------------------------
/** Sets the size of the widget as a whole, and placed children widgets
* inside itself */
void setSize(const int x, const int y, const int w, const int h);
/** Change the value of the widget, it must be a percent. */
void setValue(Stats type, int value);
/** Get the current values of the widget. */
int getValue(Stats type);
};
}
#endif

View File

@ -33,7 +33,7 @@ using namespace irr::core;
using namespace irr::gui;
ModelViewWidget::ModelViewWidget() :
IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false, false)
IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false, false)
{
m_frame_buffer = NULL;
m_rtt_main_node = NULL;
@ -42,17 +42,17 @@ ModelViewWidget::ModelViewWidget() :
m_type = WTYPE_MODEL_VIEW;
m_rtt_provider = NULL;
m_rotation_mode = ROTATE_OFF;
// so that the base class doesn't complain there is no icon defined
m_properties[PROP_ICON]="gui/main_help.png";
m_rtt_unsupported = false;
}
// -----------------------------------------------------------------------------
ModelViewWidget::~ModelViewWidget()
{
GUIEngine::needsUpdate.remove(this);
delete m_rtt_provider;
m_rtt_provider = NULL;
}
@ -61,18 +61,18 @@ void ModelViewWidget::add()
{
// so that the base class doesn't complain there is no icon defined
m_properties[PROP_ICON]="gui/main_help.png";
IconButtonWidget::add();
/*
FIXME: remove this unclean thing, I think irrlicht provides this feature:
virtual void IGUIElement::OnPostRender (u32 timeMs)
\brief animate the element and its children.
virtual void IGUIElement::OnPostRender (u32 timeMs)
\brief animate the element and its children.
*/
GUIEngine::needsUpdate.push_back(this);
angle = 0;
} // add
// -----------------------------------------------------------------------------
@ -82,11 +82,11 @@ void ModelViewWidget::clearModels()
m_model_location.clear();
m_model_scale.clear();
m_model_frames.clear();
if (m_rtt_main_node != NULL) m_rtt_main_node->remove();
if (m_light != NULL) m_light->remove();
if (m_camera != NULL) m_camera->remove();
m_rtt_main_node = NULL;
m_camera = NULL;
m_light = NULL;
@ -98,7 +98,7 @@ void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location,
const Vec3& scale, const int frame)
{
if(!mesh) return;
m_models.push_back(mesh);
m_model_location.push_back(location);
m_model_scale.push_back(scale);
@ -109,7 +109,7 @@ void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location,
void ModelViewWidget::update(float delta)
{
if (m_rtt_unsupported) return;
if (m_rotation_mode == ROTATE_CONTINUOUSLY)
{
angle += delta*m_rotation_speed;
@ -121,10 +121,10 @@ void ModelViewWidget::update(float delta)
// (taking wrap-arounds into account)
const int angle_distance_from_end = (int)(360 - angle);
const int target_distance_from_end = (int)(360 - angle);
int distance_with_positive_rotation;
int distance_with_negative_rotation;
if (angle < m_rotation_target)
{
distance_with_positive_rotation = (int)(m_rotation_target - angle);
@ -135,10 +135,10 @@ void ModelViewWidget::update(float delta)
distance_with_positive_rotation = (int)(angle_distance_from_end + m_rotation_target);
distance_with_negative_rotation = (int)(angle - m_rotation_target);
}
//std::cout << "distance_with_positive_rotation=" << distance_with_positive_rotation <<
//" distance_with_negative_rotation=" << distance_with_negative_rotation << " angle="<< angle <<std::endl;
if (distance_with_positive_rotation < distance_with_negative_rotation)
{
angle += m_rotation_speed * delta*(3.0f + std::min(distance_with_positive_rotation, distance_with_negative_rotation)*2.0f);
@ -149,27 +149,27 @@ void ModelViewWidget::update(float delta)
}
if (angle > 360) angle -= 360;
if (angle < 0) angle += 360;
// stop rotating when target reached
if (fabsf(angle - m_rotation_target) < 2.0f) m_rotation_mode = ROTATE_OFF;
}
if (!irr_driver->isGLSL())
return;
if (m_rtt_provider == NULL)
{
std::string name = "model view ";
name += m_properties[PROP_ID].c_str();
m_rtt_provider = new RTT(512, 512);
}
if (m_rtt_main_node == NULL)
{
setupRTTScene(m_models, m_model_location, m_model_scale, m_model_frames);
}
m_rtt_main_node->setRotation(core::vector3df(0.0f, angle, 0.0f));
m_rtt_main_node->setVisible(true);
@ -180,22 +180,22 @@ void ModelViewWidget::update(float delta)
}
void ModelViewWidget::setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
AlignedArray<Vec3>& mesh_location,
AlignedArray<Vec3>& mesh_scale,
const std::vector<int>& model_frames)
AlignedArray<Vec3>& mesh_location,
AlignedArray<Vec3>& mesh_scale,
const std::vector<int>& model_frames)
{
irr_driver->suppressSkyBox();
if (m_rtt_main_node != NULL) m_rtt_main_node->remove();
if (m_light != NULL) m_light->remove();
if (m_camera != NULL) m_camera->remove();
m_rtt_main_node = NULL;
m_camera = NULL;
m_light = NULL;
irr_driver->clearLights();
if (model_frames[0] == -1)
{
scene::ISceneNode* node = irr_driver->addMesh(mesh.get(0), NULL);
@ -207,27 +207,27 @@ void ModelViewWidget::setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
else
{
scene::IAnimatedMeshSceneNode* node =
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(0), NULL);
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(0), NULL);
node->setPosition(mesh_location[0].toIrrVector());
node->setFrameLoop(model_frames[0], model_frames[0]);
node->setAnimationSpeed(0);
node->setScale(mesh_scale[0].toIrrVector());
node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_rtt_main_node = node;
}
assert(m_rtt_main_node != NULL);
assert(mesh.size() == mesh_location.size());
assert(mesh.size() == model_frames.size());
const int mesh_amount = mesh.size();
for (int n = 1; n<mesh_amount; n++)
{
if (model_frames[n] == -1)
{
scene::ISceneNode* node =
irr_driver->addMesh(mesh.get(n), m_rtt_main_node);
irr_driver->addMesh(mesh.get(n), m_rtt_main_node);
node->setPosition(mesh_location[n].toIrrVector());
node->updateAbsolutePosition();
node->setScale(mesh_scale[n].toIrrVector());
@ -235,8 +235,8 @@ void ModelViewWidget::setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
else
{
scene::IAnimatedMeshSceneNode* node =
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(n),
m_rtt_main_node);
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(n),
m_rtt_main_node);
node->setPosition(mesh_location[n].toIrrVector());
node->setFrameLoop(model_frames[n], model_frames[n]);
node->setAnimationSpeed(0);
@ -245,32 +245,32 @@ void ModelViewWidget::setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
//std::cout << "(((( set frame " << model_frames[n] << " ))))\n";
}
}
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 35, 35, 35));
const core::vector3df &spot_pos = core::vector3df(0, 30, 40);
m_light = irr_driver->addLight(spot_pos, 0.3f /* energy */, 10 /* distance */, 1.0f /* r */, 1.0f /* g */, 1.0f /* g*/, true, NULL);
m_rtt_main_node->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
m_rtt_main_node->setMaterialFlag(video::EMF_LIGHTING, true);
const int materials = m_rtt_main_node->getMaterialCount();
for (int n = 0; n<materials; n++)
{
m_rtt_main_node->getMaterial(n).setFlag(video::EMF_LIGHTING, true);
// set size of specular highlights
m_rtt_main_node->getMaterial(n).Shininess = 100.0f;
m_rtt_main_node->getMaterial(n).SpecularColor.set(255, 50, 50, 50);
m_rtt_main_node->getMaterial(n).DiffuseColor.set(255, 150, 150, 150);
m_rtt_main_node->getMaterial(n).setFlag(video::EMF_GOURAUD_SHADING,
true);
true);
}
m_camera = irr_driver->getSceneManager()->addCameraSceneNode();
m_camera->setAspectRatio(1.0f);
m_camera->setPosition(core::vector3df(0.0, 20.0f, 70.0f));
m_camera->setUpVector(core::vector3df(0.0, 1.0, 0.0));
m_camera->setTarget(core::vector3df(0, 10, 0.0f));

View File

@ -30,9 +30,10 @@ using namespace irr;
// -----------------------------------------------------------------------------
ProgressBarWidget::ProgressBarWidget() : Widget(WTYPE_PROGRESS)
ProgressBarWidget::ProgressBarWidget(bool show_label) : Widget(WTYPE_PROGRESS)
{
m_value = 0;
m_show_label = show_label;
}
// -----------------------------------------------------------------------------
@ -52,7 +53,10 @@ void ProgressBarWidget::add()
void ProgressBarWidget::setValue(int value)
{
m_value = value;
setLabel(std::string(StringUtils::toString(value) + "%").c_str());
if (m_show_label)
{
setLabel(std::string(StringUtils::toString(value) + "%").c_str());
}
}
// -----------------------------------------------------------------------------

View File

@ -45,12 +45,12 @@ namespace GUIEngine
/** Change the label on the widget */
void setLabel(const irr::core::stringw label);
int m_value;
bool m_show_label;
public:
LEAK_CHECK()
ProgressBarWidget();
ProgressBarWidget(bool show_label = true);
virtual ~ProgressBarWidget() {}
/** Change the value of the widget, it must be a percent. */

View File

@ -0,0 +1,152 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "guiengine/engine.hpp"
#include "guiengine/widgets/skill_level_widget.hpp"
#include "utils/string_utils.hpp"
#include <string.h>
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include "config/user_config.hpp"
#include <IGUIEnvironment.h>
#include <IGUIElement.h>
#include <IGUIButton.h>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr;
// -----------------------------------------------------------------------------
SkillLevelWidget::SkillLevelWidget(core::recti area, const int player_id,
bool multiplayer, const int value,
const stringw& label) : Widget(WTYPE_DIV)
{
m_player_id = player_id;
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
area.getWidth(), area.getHeight() );
// ---- Mass skill level widget
m_bar = NULL;
m_bar = new ProgressBarWidget(false);
m_bar->setValue(value);
m_bar->m_x = m_bar_x;
m_bar->m_y = m_bar_y;
m_bar->m_w = m_bar_w;
m_bar->m_h = m_bar_h;
m_bar->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_skill_bar", m_player_id);
m_label = NULL;
m_label = new LabelWidget(!multiplayer, true);
m_label->setText(label,false);
m_label->m_x = m_label_x;
m_label->m_y = m_label_y;
m_label->m_w = m_label_w;
m_label->m_h = m_label_h;
m_label->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_skill_label", m_player_id);
m_children.push_back(m_bar);
m_children.push_back(m_label);
} // KartStatsWidget
// -----------------------------------------------------------------------------
void SkillLevelWidget::add()
{
m_bar->add();
m_label->add();
}
// -----------------------------------------------------------------------------
void SkillLevelWidget::move(const int x, const int y, const int w, const int h)
{
Widget::move(x,y,w,h);
setSize(m_x, m_y, m_w, m_h);
if (m_bar != NULL)
{
m_bar->move(m_bar_x,
m_bar_y,
m_bar_w,
m_bar_h );
}
if (m_label != NULL)
{
m_label->move(m_label_x,
m_label_y,
m_label_w,
m_label_h);
}
}
// -------------------------------------------------------------------------
void SkillLevelWidget::setSize(const int x, const int y, const int w, const int h)
{
m_x = x;
m_y = y;
m_w = w;
m_h = h;
// -- sizes
m_bar_w = 3*(w/2)/4;
m_bar_h = h;
m_label_w = w/2;
m_label_h = h;
// for shrinking effect
if (h < 175)
{
const float factor = h / 175.0f;
m_bar_h = (int)(m_bar_h*factor);
m_label_h = (int)(m_label_h*factor);
}
m_bar_x = x + w/2;
m_bar_y = y + m_h/2 - m_bar_h/2;
m_label_x = x;
m_label_y = y + m_h/2 - m_label_h/2;
} // setSize
// -----------------------------------------------------------------------------
void SkillLevelWidget::setValue(const int value)
{
m_bar->setValue(value);
}
// -----------------------------------------------------------------------------
void SkillLevelWidget::setLabel(const irr::core::stringw& label)
{
m_label->setText(label, false);
}

View File

@ -0,0 +1,102 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_SKILL_LEVEL_HPP
#define HEADER_SKILL_LEVEL_HPP
#include <irrString.h>
#include "guiengine/widget.hpp"
#include "utils/leak_check.hpp"
#include "utils/ptr_vector.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/progress_bar_widget.hpp"
namespace GUIEngine
{
/**
* \brief A skill level widget.
* \ingroup widgetsgroup
*/
class SkillLevelWidget : public Widget
{
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getWidthNeededAroundLabel() const { return 35; }
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getHeightNeededAroundLabel() const { return 4; }
/** widget coordinates */
int m_bar_x, m_bar_y, m_bar_h, m_bar_w;
int m_label_x, m_label_y, m_label_h, m_label_w;
std::string m_label_name;
int m_player_id;
public:
LEAK_CHECK()
LabelWidget* m_label;
ProgressBarWidget* m_bar;
SkillLevelWidget(core::recti area, const int player_id, bool multiplayer,
const int value = 0, const irr::core::stringw& label = "default");
virtual ~SkillLevelWidget() {};
// ------------------------------------------------------------------------
/** Add the widgets to the current screen */
virtual void add();
// -------------------------------------------------------------------------
virtual void move(const int x, const int y, const int w, const int h);
// -------------------------------------------------------------------------
/** Sets the size of the widget as a whole, and placed children widgets
* inside itself */
void setSize(const int x, const int y, const int w, const int h);
/** Change the value of the widget, it must be a percent. */
void setValue(const int value);
/** Get the current values of the widget. */
int getValue() {return m_bar->getValue(); };
/** Change the label of the widget */
void setLabel(const irr::core::stringw& label);
/** Get the current label of the widget. */
const irr::core::stringw& getLabel()
{
return m_label->getText();
}
};
}
#endif

View File

@ -74,15 +74,16 @@ bool DeviceManager::initialize()
}
const int keyboard_amount = m_keyboard_configs.size();
for (int n=0; n<keyboard_amount; n++)
for (int n = 0; n < keyboard_amount; n++)
{
m_keyboards.push_back(new KeyboardDevice(m_keyboard_configs.get(n)));
}
if(UserConfigParams::logMisc())
Log::info("Device manager","Initializing gamepad support.");
Log::info("Device manager","Initializing gamepad support.");
irr_driver->getDevice()->activateJoysticks(m_irrlicht_gamepads);
int num_gamepads = m_irrlicht_gamepads.size();
if(UserConfigParams::logMisc())
{
@ -90,8 +91,6 @@ bool DeviceManager::initialize()
num_gamepads);
}
// Create GamePadDevice for each physical gamepad and find a GamepadConfig to match
for (int id = 0; id < num_gamepads; id++)
{
@ -112,6 +111,7 @@ bool DeviceManager::initialize()
{
Log::info("Device manager","#%d: %s detected...", id, name.c_str());
}
// Returns true if new configuration was created
if (getConfigForGamepad(id, name, &gamepadConfig) == true)
{
@ -135,6 +135,7 @@ bool DeviceManager::initialize()
} // end for
if (created) serialize();
return created;
} // initialize

View File

@ -172,13 +172,19 @@ void KartProperties::load(const std::string &filename, const std::string &node)
{
// Get the default values from STKConfig. This will also allocate any
// pointers used in KartProperties
copyFrom(&stk_config->getDefaultKartProperties());
const XMLNode* root = new XMLNode(filename);
std::string kart_type;
if (root->get("type", &kart_type))
copyFrom(&stk_config->getKartProperties(kart_type));
else
copyFrom(&stk_config->getDefaultKartProperties());
// m_kart_model must be initialised after assigning the default
// values from stk_config (otherwise all kart_properties will
// share the same KartModel
m_kart_model = new KartModel(/*is_master*/true);
const XMLNode * root = 0;
m_root = StringUtils::getPath(filename)+"/";
m_ident = StringUtils::getBasename(StringUtils::getPath(filename));
// If this is an addon kart, add "addon_" to the identifier - just in
@ -188,7 +194,6 @@ void KartProperties::load(const std::string &filename, const std::string &node)
m_ident = Addon::createAddonId(m_ident);
try
{
root = new XMLNode(filename);
if(!root || root->getName()!="kart")
{
std::ostringstream msg;
@ -286,7 +291,7 @@ void KartProperties::load(const std::string &filename, const std::string &node)
*/
void KartProperties::getAllData(const XMLNode * root)
{
root->get("version", &m_version);
root->get("version", &m_version);
root->get("name", &m_name );
@ -307,50 +312,11 @@ void KartProperties::getAllData(const XMLNode * root)
root->get("shadow-x-offset", &m_shadow_x_offset );
root->get("shadow-y-offset", &m_shadow_y_offset );
root->get("type", &m_kart_type );
if(const XMLNode *dimensions_node = root->getNode("center"))
dimensions_node->get("gravity-shift", &m_gravity_center_shift);
if(const XMLNode *nitro_node = root->getNode("nitro"))
{
nitro_node->get("consumption", &m_nitro_consumption );
nitro_node->get("small-container", &m_nitro_small_container );
nitro_node->get("big-container", &m_nitro_big_container );
nitro_node->get("max-speed-increase", &m_nitro_max_speed_increase);
nitro_node->get("engine-force", &m_nitro_engine_force );
nitro_node->get("duration", &m_nitro_duration );
nitro_node->get("fade-out-time", &m_nitro_fade_out_time );
nitro_node->get("max", &m_nitro_max );
nitro_node->get("min-consumption-time", &m_nitro_min_consumption );
}
if(const XMLNode *bubble_node = root->getNode("bubblegum"))
{
bubble_node->get("time", &m_bubblegum_time );
bubble_node->get("speed-fraction", &m_bubblegum_speed_fraction);
bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time );
bubble_node->get("torque", &m_bubblegum_torque );
}
if(const XMLNode *rescue_node = root->getNode("rescue"))
{
rescue_node->get("vert-offset", &m_rescue_vert_offset);
rescue_node->get("time", &m_rescue_time );
rescue_node->get("height", &m_rescue_height );
}
if(const XMLNode *explosion_node = root->getNode("explosion"))
{
explosion_node->get("time", &m_explosion_time );
explosion_node->get("radius", &m_explosion_radius);
explosion_node->get("invulnerability-time",
&m_explosion_invulnerability_time);
}
if(const XMLNode *skid_node = root->getNode("skid"))
{
m_skidding_properties->load(skid_node);
}
if(const XMLNode *ai_node = root->getNode("ai"))
{
const XMLNode *easy = ai_node->getNode("easy");
@ -363,59 +329,6 @@ void KartProperties::getAllData(const XMLNode * root)
m_ai_properties[RaceManager::DIFFICULTY_BEST]->load(best);
}
if(const XMLNode *slipstream_node = root->getNode("slipstream"))
{
slipstream_node->get("length", &m_slipstream_length );
slipstream_node->get("width", &m_slipstream_width );
slipstream_node->get("collect-time", &m_slipstream_collect_time );
slipstream_node->get("use-time", &m_slipstream_use_time );
slipstream_node->get("add-power", &m_slipstream_add_power );
slipstream_node->get("min-speed", &m_slipstream_min_speed );
slipstream_node->get("max-speed-increase",
&m_slipstream_max_speed_increase);
slipstream_node->get("duration", &m_slipstream_duration );
slipstream_node->get("fade-out-time",&m_slipstream_fade_out_time );
}
if(const XMLNode *turn_node = root->getNode("turn"))
{
turn_node->get("time-full-steer", &m_time_full_steer );
turn_node->get("time-reset-steer", &m_time_reset_steer );
turn_node->get("turn-radius", &m_turn_angle_at_speed );
// For now store the turn radius in turn angle, the correct
// value can only be determined later in ::load
}
if(const XMLNode *engine_node = root->getNode("engine"))
{
engine_node->get("brake-factor", &m_brake_factor);
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
engine_node->get("power", &m_engine_power);
if(m_engine_power.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("[KartProperties]",
"Incorrect engine-power specifications for kart '%s'",
getIdent().c_str());
}
engine_node->get("max-speed", &m_max_speed);
if(m_max_speed.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("[KartProperties]",
"Incorrect max-speed specifications for kart '%s'",
getIdent().c_str());
}
} // if getNode("engine")
if(const XMLNode *gear_node = root->getNode("gear"))
{
gear_node->get("switch-ratio", &m_gear_switch_ratio );
gear_node->get("power-increase", &m_gear_power_increase);
}
if(const XMLNode *mass_node = root->getNode("mass"))
mass_node->get("value", &m_mass);
if(const XMLNode *suspension_node = root->getNode("suspension"))
{
suspension_node->get("stiffness", &m_suspension_stiffness);
@ -488,50 +401,6 @@ void KartProperties::getAllData(const XMLNode * root)
//TODO: listed as an attribute in the xml file after wheel-radius
//TODO: same goes for their rear equivalents
if(const XMLNode *plunger_node= root->getNode("plunger"))
{
plunger_node->get("band-max-length", &m_rubber_band_max_length );
plunger_node->get("band-force", &m_rubber_band_force );
plunger_node->get("band-duration", &m_rubber_band_duration );
plunger_node->get("band-speed-increase",&m_rubber_band_speed_increase);
plunger_node->get("band-fade-out-time", &m_rubber_band_fade_out_time );
plunger_node->get("in-face-time", &m_plunger_in_face_duration);
if(m_plunger_in_face_duration.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("KartProperties",
"Invalid plunger in-face-time specification.");
}
}
if(const XMLNode *zipper_node= root->getNode("zipper"))
{
zipper_node->get("time", &m_zipper_time );
zipper_node->get("fade-out-time", &m_zipper_fade_out_time );
zipper_node->get("force", &m_zipper_force );
zipper_node->get("speed-gain", &m_zipper_speed_gain );
zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase);
}
if(const XMLNode *swatter_node= root->getNode("swatter"))
{
swatter_node->get("duration", &m_swatter_duration );
swatter_node->get("squash-duration", &m_squash_duration );
swatter_node->get("squash-slowdown", &m_squash_slowdown );
if(swatter_node->get("distance", &m_swatter_distance2) )
{
// Avoid squaring if distance is not defined, so that
// distance2 remains UNDEFINED (which is a negative value)
m_swatter_distance2 *= m_swatter_distance2;
}
}
if(const XMLNode *lean_node= root->getNode("lean"))
{
lean_node->get("max", &m_max_lean );
lean_node->get("speed", &m_lean_speed);
m_max_lean *= DEGREE_TO_RAD;
m_lean_speed *= DEGREE_TO_RAD;
}
if(const XMLNode *jump_node= root->getNode("jump"))
{
@ -547,12 +416,6 @@ void KartProperties::getAllData(const XMLNode * root)
m_camera_backward_up_angle *= DEGREE_TO_RAD;
}
if(const XMLNode *startup_node= root->getNode("startup"))
{
startup_node->get("time", &m_startup_times);
startup_node->get("boost", &m_startup_boost);
}
if(const XMLNode *sounds_node= root->getNode("sounds"))
{
std::string s;
@ -598,6 +461,151 @@ void KartProperties::getAllData(const XMLNode * root)
#endif
} // if sounds-node exist
if(const XMLNode *nitro_node = root->getNode("nitro"))
{
nitro_node->get("consumption", &m_nitro_consumption );
nitro_node->get("small-container", &m_nitro_small_container );
nitro_node->get("big-container", &m_nitro_big_container );
nitro_node->get("max-speed-increase", &m_nitro_max_speed_increase);
nitro_node->get("engine-force", &m_nitro_engine_force );
nitro_node->get("duration", &m_nitro_duration );
nitro_node->get("fade-out-time", &m_nitro_fade_out_time );
nitro_node->get("max", &m_nitro_max );
nitro_node->get("min-consumption-time", &m_nitro_min_consumption );
}
if(const XMLNode *bubble_node = root->getNode("bubblegum"))
{
bubble_node->get("time", &m_bubblegum_time );
bubble_node->get("speed-fraction", &m_bubblegum_speed_fraction);
bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time );
bubble_node->get("torque", &m_bubblegum_torque );
}
if(const XMLNode *rescue_node = root->getNode("rescue"))
{
rescue_node->get("vert-offset", &m_rescue_vert_offset);
rescue_node->get("time", &m_rescue_time );
rescue_node->get("height", &m_rescue_height );
}
if(const XMLNode *explosion_node = root->getNode("explosion"))
{
explosion_node->get("time", &m_explosion_time );
explosion_node->get("radius", &m_explosion_radius);
explosion_node->get("invulnerability-time",
&m_explosion_invulnerability_time);
}
if(const XMLNode *skid_node = root->getNode("skid"))
{
m_skidding_properties->load(skid_node);
}
if(const XMLNode *slipstream_node = root->getNode("slipstream"))
{
slipstream_node->get("length", &m_slipstream_length );
slipstream_node->get("width", &m_slipstream_width );
slipstream_node->get("collect-time", &m_slipstream_collect_time );
slipstream_node->get("use-time", &m_slipstream_use_time );
slipstream_node->get("add-power", &m_slipstream_add_power );
slipstream_node->get("min-speed", &m_slipstream_min_speed );
slipstream_node->get("max-speed-increase",
&m_slipstream_max_speed_increase);
slipstream_node->get("duration", &m_slipstream_duration );
slipstream_node->get("fade-out-time",&m_slipstream_fade_out_time );
}
if(const XMLNode *turn_node = root->getNode("turn"))
{
turn_node->get("time-full-steer", &m_time_full_steer );
turn_node->get("time-reset-steer", &m_time_reset_steer );
turn_node->get("turn-radius", &m_turn_angle_at_speed );
// For now store the turn radius in turn angle, the correct
// value can only be determined later in ::load
}
if(const XMLNode *engine_node = root->getNode("engine"))
{
engine_node->get("brake-factor", &m_brake_factor);
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
engine_node->get("power", &m_engine_power);
if(m_engine_power.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("[KartProperties]",
"Incorrect engine-power specifications for kart '%s'",
getIdent().c_str());
}
engine_node->get("max-speed", &m_max_speed);
if(m_max_speed.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("[KartProperties]",
"Incorrect max-speed specifications for kart '%s'",
getIdent().c_str());
}
} // if getNode("engine")
if(const XMLNode *gear_node = root->getNode("gear"))
{
gear_node->get("switch-ratio", &m_gear_switch_ratio );
gear_node->get("power-increase", &m_gear_power_increase);
}
if(const XMLNode *mass_node = root->getNode("mass"))
mass_node->get("value", &m_mass);
if(const XMLNode *plunger_node= root->getNode("plunger"))
{
plunger_node->get("band-max-length", &m_rubber_band_max_length );
plunger_node->get("band-force", &m_rubber_band_force );
plunger_node->get("band-duration", &m_rubber_band_duration );
plunger_node->get("band-speed-increase",&m_rubber_band_speed_increase);
plunger_node->get("band-fade-out-time", &m_rubber_band_fade_out_time );
plunger_node->get("in-face-time", &m_plunger_in_face_duration);
if(m_plunger_in_face_duration.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("KartProperties",
"Invalid plunger in-face-time specification.");
}
}
if(const XMLNode *zipper_node= root->getNode("zipper"))
{
zipper_node->get("time", &m_zipper_time );
zipper_node->get("fade-out-time", &m_zipper_fade_out_time );
zipper_node->get("force", &m_zipper_force );
zipper_node->get("speed-gain", &m_zipper_speed_gain );
zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase);
}
if(const XMLNode *swatter_node= root->getNode("swatter"))
{
swatter_node->get("duration", &m_swatter_duration );
swatter_node->get("squash-duration", &m_squash_duration );
swatter_node->get("squash-slowdown", &m_squash_slowdown );
if(swatter_node->get("distance", &m_swatter_distance2) )
{
// Avoid squaring if distance is not defined, so that
// distance2 remains UNDEFINED (which is a negative value)
m_swatter_distance2 *= m_swatter_distance2;
}
}
if(const XMLNode *lean_node= root->getNode("lean"))
{
lean_node->get("max", &m_max_lean );
lean_node->get("speed", &m_lean_speed);
m_max_lean *= DEGREE_TO_RAD;
m_lean_speed *= DEGREE_TO_RAD;
}
if(const XMLNode *startup_node= root->getNode("startup"))
{
startup_node->get("time", &m_startup_times);
startup_node->get("boost", &m_startup_boost);
}
if(m_kart_model)
m_kart_model->loadInfo(*root);
} // getAllData
@ -755,6 +763,7 @@ bool KartProperties::isInGroup(const std::string &group) const
return std::find(m_groups.begin(), m_groups.end(), group) != m_groups.end();
} // isInGroups
// ----------------------------------------------------------------------------
/** Called the first time a kart accelerates after 'ready-set-go'. It searches
* through m_startup_times to find the appropriate slot, and returns the
@ -771,4 +780,16 @@ float KartProperties::getStartupBoost() const
}
return 0;
} // getStartupBoost
// ----------------------------------------------------------------------------
const float KartProperties::getAvgPower() const
{
float sum = 0.0;
for (unsigned int i = 0; i < m_gear_power_increase.size(); ++i)
{
sum += m_gear_power_increase[i]*m_max_speed[0];
}
return sum/m_gear_power_increase.size();
} // getAvgPower
/* EOF */

View File

@ -181,6 +181,9 @@ private:
*/
float m_nitro_min_consumption;
/** Type of the kart (for the properties) */
std::string m_kart_type;
/** Filename of the wheel models. */
std::string m_wheel_filename[4];
/** Radius of the graphical wheels. */
@ -543,7 +546,10 @@ public:
// ------------------------------------------------------------------------
/** Returns parameters for the speed-weighted objects */
const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const {return m_speed_weighted_object_properties;}
const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const
{
return m_speed_weighted_object_properties;
}
// ------------------------------------------------------------------------
/** Returns the wheel base (distance front to rear axis). */
@ -568,8 +574,17 @@ public:
// ------------------------------------------------------------------------
/** Returns the maximum speed dependent on the difficult level. */
float getMaxSpeed () const {return
m_max_speed[race_manager->getDifficulty()];}
float getMaxSpeed () const
{
return m_max_speed[race_manager->getDifficulty()];
}
// ------------------------------------------------------------------------
/** Return the absolute maximum speed, independent on the difficulty. */
float getAbsMaxSpeed () const
{
return m_max_speed[m_max_speed.size()-1];
}
// ------------------------------------------------------------------------
/** Returns the nitro consumption. */
@ -826,6 +841,10 @@ public:
const std::vector<float>&
getGearPowerIncrease () const {return m_gear_power_increase; }
// ------------------------------------------------------------------------
/** Returns the average power of the kart (in all gears). */
const float getAvgPower () const;
// ------------------------------------------------------------------------
/** Returns distance between kart and camera. */
float getCameraDistance () const {return m_camera_distance; }

View File

@ -589,7 +589,7 @@ void btKart::updateSuspension(btScalar deltaTime)
btScalar current_length = wheel_info.m_raycastInfo.m_suspensionLength;
btScalar length_diff = (susp_length - current_length);
if(m_kart->getKartProperties()->getExpSpringResponse())
length_diff *= length_diff/susp_length;
length_diff *= fabsf(length_diff)/susp_length;
force = wheel_info.m_suspensionStiffness * length_diff
* wheel_info.m_clippedInvContactDotSuspension;

View File

@ -232,6 +232,31 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
m_player_ident_spinner->m_w = player_name_w;
m_player_ident_spinner->m_h = player_name_h;
// ---- KartStatsWidget
m_kart_stats = NULL;
// area for the stats widget
core::recti statsArea;
if (!parent->m_multiplayer)
{
statsArea = core::recti(m_kart_stats_x,
m_kart_stats_y,
m_kart_stats_x + m_kart_stats_w,
m_kart_stats_y + m_kart_stats_h);
}
else
{
statsArea = core::recti(m_x , m_y + m_h/2,
m_x + m_w, m_y + m_h);
}
m_kart_stats = new GUIEngine::KartStatsWidget(statsArea, player_id, kart_group,
m_parent_screen->m_multiplayer);
m_kart_stats->m_properties[PROP_ID] =
StringUtils::insertValues("@p%i_stats", m_player_id);
m_children.push_back(m_kart_stats);
if (parent->m_multiplayer && associated_player)
{
if (associated_player->getDevice()->getType() == DT_KEYBOARD)
@ -272,8 +297,6 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
//m_player_ident_spinner->m_event_handler = this;
m_children.push_back(m_player_ident_spinner);
// ----- Kart model view
m_model_view = new ModelViewWidget();
@ -347,7 +370,7 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
m_model_view->setRotateContinuously( 35.0f );
// ---- Kart name label
m_kart_name = new LabelWidget();
m_kart_name = new LabelWidget(true, true);
m_kart_name->setText(props->getName(), false);
m_kart_name->m_properties[PROP_TEXT_ALIGN] = "center";
m_kart_name->m_properties[PROP_ID] =
@ -356,7 +379,6 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
m_kart_name->m_y = kart_name_y;
m_kart_name->m_w = kart_name_w;
m_kart_name->m_h = kart_name_h;
//m_kart_name->setParent(this);
m_children.push_back(m_kart_name);
} // PlayerKartWidget
// ------------------------------------------------------------------------
@ -472,7 +494,7 @@ void PlayerKartWidget::add()
m_player_ident_spinner->add();
m_player_ident_spinner->getIrrlichtElement()->setTabStop(false);
m_player_ident_spinner->setListener(this);
m_kart_stats->add();
m_model_view->add();
m_kart_name->add();
@ -660,11 +682,25 @@ void PlayerKartWidget::onUpdate(float delta)
core::recti(core::position2di(player_name_x, player_name_y),
core::dimension2di(player_name_w, player_name_h)) );
}
if (!m_parent_screen->m_multiplayer)
{
m_kart_stats->move(m_kart_stats_x,
m_kart_stats_y,
m_kart_stats_w,
m_kart_stats_h);
}
else
{
m_kart_stats->move(m_x, m_y + m_h/2,
m_w, m_h/2);
}
m_model_view->move(model_x,
model_y,
model_w,
model_h);
m_kart_name->move(kart_name_x,
kart_name_y,
kart_name_w,
@ -757,15 +793,41 @@ void PlayerKartWidget::setSize(const int x, const int y, const int w, const int
player_name_x = x + w/2 - player_name_w/2;
player_name_y = y + player_id_h;
const int modelMaxHeight = h - kart_name_h - player_name_h
- player_id_h;
const int modelMaxWidth = w;
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
const int modelY = y + player_name_h + player_id_h;
model_x = x + w/2 - (int)(bestSize/2);
model_y = modelY + modelMaxHeight/2 - bestSize/2;
model_w = (int)(bestSize);
model_h = bestSize;
if (m_parent_screen->m_multiplayer)
{
const int modelMaxHeight = (h - kart_name_h - player_name_h
- player_id_h)/2;
const int modelMaxWidth = w;
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
model_x = x + w/2 - (int)(bestSize/2);
model_y = y + player_name_h + player_id_h;
model_w = (int)(bestSize);
model_h = bestSize;
m_kart_stats_w = model_w;
m_kart_stats_h = model_h;
m_kart_stats_x = x + w/2 - (int)(bestSize/2);
m_kart_stats_y = model_y + model_h;
}
else
{
const int modelMaxHeight = h - kart_name_h - player_name_h
- player_id_h;
const int modelMaxWidth = w;
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
const int modelY = y + player_name_h + player_id_h;
model_x = x + w/4 - (int)(bestSize/2);
model_y = modelY + modelMaxHeight/2 - bestSize/2;
model_w = (int)(bestSize);
model_h = bestSize;
m_kart_stats_w = w/2;
m_kart_stats_h = h;
m_kart_stats_x = x + w/2;
m_kart_stats_y = y;
}
kart_name_x = x;
kart_name_y = y + h - kart_name_h;
@ -850,8 +912,8 @@ void KartHoverListener::onSelectionChanged(DynamicRibbonWidget* theWidget,
}
m_parent->updateKartWidgetModel(playerID, selectionID, selectionText);
m_parent->m_kart_widgets[playerID].setKartInternalName(selectionID);
m_parent->updateKartStats(playerID, selectionID);
m_parent->validateKartChoices();
} // onSelectionChanged
@ -1454,6 +1516,23 @@ void KartSelectionScreen::playerConfirm(const int playerID)
// ----------------------------------------------------------------------------
void KartSelectionScreen::updateKartStats(uint8_t widget_id,
const std::string& selection)
{
KartStatsWidget* w = m_kart_widgets[widget_id].m_kart_stats;
assert(w != NULL);
const KartProperties *kp =
kart_properties_manager->getKart(selection);
if (kp != NULL)
{
w->setValue(KartStatsWidget::SKILL_MASS, (int)(kp->getMass()/5));
w->setValue(KartStatsWidget::SKILL_SPEED, (int)((kp->getAbsMaxSpeed()-20)*9));
w->setValue(KartStatsWidget::SKILL_POWER, (int)(kp->getAvgPower()));
w->update(0);
}
}
void KartSelectionScreen::updateKartWidgetModel(uint8_t widget_id,
const std::string& selection,
const irr::core::stringw& selectionText)

View File

@ -24,7 +24,9 @@
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/model_view_widget.hpp"
#include "guiengine/widgets/spinner_widget.hpp"
#include "guiengine/widgets/progress_bar_widget.hpp"
#include "states_screens/state_manager.hpp"
#include "guiengine/widgets/kart_stats_widget.hpp"
#include <IGUIImage.h>
@ -109,6 +111,10 @@ protected:
void setKartsFromCurrentGroup();
virtual void playerConfirm(const int playerID);
void updateKartStats(uint8_t widget_id,
const std::string& selection);
/** updates model of a kart widget, to have the good selection when the user validates */
void updateKartWidgetModel(uint8_t widget_id,
const std::string& selection,
@ -236,6 +242,7 @@ class PlayerKartWidget : public GUIEngine::Widget,
int player_name_x, player_name_y, player_name_w, player_name_h;
int model_x, model_y, model_w, model_h;
int kart_name_x, kart_name_y, kart_name_w, kart_name_h;
int m_kart_stats_x, m_kart_stats_y, m_kart_stats_w, m_kart_stats_h;
/** A reserved ID for this widget if any, -1 otherwise. (If no ID is
* reserved, widget will not be in the regular tabbing order */
@ -267,6 +274,7 @@ public:
/** Sub-widgets created by this widget */
PlayerNameSpinner* m_player_ident_spinner;
GUIEngine::KartStatsWidget* m_kart_stats;
GUIEngine::ModelViewWidget* m_model_view;
GUIEngine::LabelWidget* m_kart_name;

View File

@ -146,6 +146,7 @@ void NetworkKartSelectionScreen::playerSelected(uint8_t race_id, std::string kar
assert(widget_id>=0 && widget_id < m_kart_widgets.size());
KartSelectionScreen::updateKartWidgetModel(widget_id, kart_name, irr::core::stringw(kart_name.c_str()));
KartSelectionScreen::updateKartStats(widget_id, kart_name);
m_kart_widgets[widget_id].setKartInternalName(kart_name);
m_kart_widgets[widget_id].markAsReady(); // mark player ready
}

View File

@ -97,13 +97,22 @@ const core::vector3df& TrackObjectPresentationSceneNode::getScale() const
void TrackObjectPresentationSceneNode::move(const core::vector3df& xyz, const core::vector3df& hpr,
const core::vector3df& scale)
const core::vector3df& scale)
{
if (m_node == NULL) return;
m_node->setPosition(xyz);
if (m_node->getParent() != NULL)
{
scene::ISceneNode* parent = m_node->getParent();
m_node->setPosition((xyz - parent->getAbsolutePosition()) / parent->getScale());
}
else
{
m_node->setPosition(xyz);
}
m_node->setRotation(hpr);
m_node->setScale(scale);
m_node->updateAbsolutePosition();
}
void TrackObjectPresentationSceneNode::setEnable(bool enabled)

103
tools/batch.py Normal file
View File

@ -0,0 +1,103 @@
from matplotlib import pyplot
from os import listdir
def is_numeric(x):
try:
float(x)
except ValueError:
return False
return True
avg_lap_time = {}
avg_pos = {}
avg_speed = {}
avg_top = {}
total_rescued = {}
tests = len(listdir('../../batch'))-1
for file in listdir('../../batch'):
if (file == '.DS_Store'):
continue
f = open('../../batch/'+file,'r')
'''
name_index = file.find('.')
kart_name = str(file[:name_index])
first = file.find('.',name_index+1)
track_name = file[name_index+1:first]
second = file.find('.',first+1)
run = int(file[first+1:second])
'''
track_name = "snowmountain"
kart_names = ["gnu", "sara", "tux", "elephpant"]
if track_name == "snowmountain":
contents = f.readlines()
'''
contents = contents[2:contents.index("[debug ] profile: \n")-1]
content = [s for s in contents if kart_name in s]
data = [float(x) for x in content[0].split() if is_numeric(x)]
if kart_name not in avg_lap_time:
avg_lap_time[kart_name] = []
avg_pos[kart_name] = []
avg_speed[kart_name] = []
avg_top[kart_name] = []
total_rescued[kart_name] = []
avg_lap_time[kart_name].append(data[2]/4)
avg_pos[kart_name].append(data[1])
avg_speed[kart_name].append(data[3])
avg_top[kart_name].append(data[4])
total_rescued[kart_name].append(data[7])
'''
contents = contents[2:6] #TODO check if all is in here
for kart in kart_names:
content = [s for s in contents if kart in s]
data = [float(x) for x in content[0].split() if is_numeric(x)]
if kart not in avg_lap_time:
avg_lap_time[kart] = []
avg_pos[kart] = []
avg_speed[kart] = []
avg_top[kart] = []
total_rescued[kart] = []
avg_lap_time[kart].append(data[2]/4)
avg_pos[kart].append(data[1])
avg_speed[kart].append(data[3])
avg_top[kart].append(data[4])
total_rescued[kart].append(data[7])
tests = len(avg_lap_time["gnu"])
print total_rescued
for kart in kart_names:
print "rescues for ", kart , ": ", sum(total_rescued[kart])/tests
print "avg_lap_time for " , kart , ": " , sum(avg_lap_time[kart])/tests
print "avg_pos for " , kart , ": " , sum(avg_pos[kart])/tests
print "avg_speed for " , kart , ": " , sum(avg_speed[kart])/tests
print "avg_top for " , kart , ": " , sum(avg_top[kart])/tests
pyplot.subplot(2,2,1)
pyplot.plot(list(xrange(tests)),avg_pos["gnu"], "b-")
pyplot.xlabel("tests")
pyplot.ylabel("gnu")
pyplot.subplot(2,2,2)
pyplot.plot(list(xrange(tests)),avg_pos["sara"], "r-")
pyplot.xlabel("tests")
pyplot.ylabel("sara")
pyplot.subplot(2,2,3)
pyplot.plot(list(xrange(tests)),avg_pos["elephpant"], "y-")
pyplot.xlabel("tests")
pyplot.ylabel("elephpant")
pyplot.subplot(2,2,4)
pyplot.plot(list(xrange(tests)),avg_pos["tux"], "g-")
pyplot.xlabel("tests")
pyplot.ylabel("tux")
pyplot.show()

19
tools/test.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
mkdir -p ../../batch
#tracks='snowmountain city lighthouse olivermath hacienda startrack farm zengarden'
#karts='gnu tux sara elephpant'
laps=4
#for track in $tracks; do
#for kart in $karts; do
for run in {901..1500}; do
for lap in $laps; do
./../cmake_build/bin/supertuxkart.app/Contents/MacOS/supertuxkart -R --mode=3 --numkarts=4 --track=snowmountain --with-profile --profile-laps=4 --kart=gnu --ai=sara,tux,elephpant --no-graphics > /dev/null
#./cmake_build/bin/supertuxkart.app/Contents/MacOS/supertuxkart -R --mode=3 --numkarts=4 --track=$track --with-profile --profile-laps=$lap --kart=$kart --ai=beastie,beastie,beastie --no-graphics > /dev/null
#grep "profile" ~/Library/Application\ Support/SuperTuxKart/stdout.log > ../batch/$kart.$track.$run.txt
grep "profile" ~/Library/Application\ Support/SuperTuxKart/stdout.log > ../../batch/faceoff.$run.txt
done
done
# done
#done