Merge remote-tracking branch 'origin/master' into battleAI

This commit is contained in:
Benau 2015-12-08 10:09:35 +08:00
commit 2644b0458b
75 changed files with 5458 additions and 2562 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@ stk-editor/
.config/ .config/
supertuxkart-64 supertuxkart-64
make*.bat make*.bat
__pycache__
data/editor data/editor
data/karts data/karts

Binary file not shown.

View File

@ -0,0 +1,404 @@
<?xml version="1.0"?>
<!-- Format
It is possible to give relative values (factors and more) for each property.
The format as a regex is: ([+-*/](%d+|x))*
An empty value means no change, a value without sign or with a '-' replaces
the previous value. If an operator prefixes the string, e.g. *1.5 (- doesn't
work because it's a sign). x will get replaced by the previous value which
means *1.5 is equal to x*1.5. It's also possible to combine operations:
+1.5*20 means "add 1.5 to the previous value and then multiply by 20".
Note that it's computed sequentially from left to right and there is no
operator precedence. Also whitespaces aren't allowed because they are used
to split arrays.
If you want to return the square of something use x*x or only *x.
ATTENTION: '-' is a special case if it is the first character of a number-
string. It means that the number is negative and NOT that the following
float will be substracted from the base value. So if x = 10 and the string
"-5" is processed, the result will be -5 and not the same as "x-5", which
would result in 10 - 5 = 5.
-->
<characteristics>
<!-- The default values that can be modified by the difficulty, karts, etc.
The values here should also be the values of the maximum difficulty. -->
<characteristic name="base">
<!-- ********** Physics ********** -->
<!-- Suspension
stiffness: kart's suspension stiffness.
rest: Length of suspension when at rest.
travel-cm: maximum movement of suspension - in cm!!
exp-string-response: dampen the suspension spring reaction
exponentially. See
http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=7369\&p=25236&hilit=vehicle#p25236
for details.
max-force: Maximum suspension force -->
<suspension stiffness="140" rest="0.3" travel="0.29"
exp-spring-response="false" max-force="12000" />
<!-- Values related to stability of the chassis: damping, and reduced
impact of roll.
downward-impulse-factor: A speed proportional impulse applied each
frame that pushes the vehicle onto the ground.
track-connection-accel: An artificial force that pulls a wheel to
the ground if its off ground. Reduces the affect if a kart loses
contact with the ground (i.e. it then can't steer or accelerate
anymore).
smooth-flying-impulse: apply a torque impulse to flying kart to keep
them parallel to the ground. -->
<stability roll-influence="0.3"
chassis-linear-damping="0.2"
chassis-angular-damping="0"
downward-impulse-factor="5"
track-connection-accel="2"
smooth-flying-impulse="250" />
<!-- Turning
radius: 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 radius="0:2.0 10:7.5 25:15 45:30"
time-full-steer="0:0.17 0.5:0.17 0.5:0.28 1.0:0.28"
time-reset-steer="0.1" />
<!-- Speed and acceleration
power: The power of the kart
max-speed: The base maximum speed of the kart in m/s
brake-factor: Value used when braking.
brake-time-increase: The brake force is multiplied by
(1 + brake_time) * brake_time_increase - i.e. the longer the
brake was pressed, the harder the kart will brake.
max-speed-reverse-ratio is the percentage of max speed for reverse
gear.
-->
<engine power="875" max-speed="25" brake-factor="15"
brake-time-increase="6" max-speed-reverse-ratio="0.65" />
<!-- 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 * 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 of a kart -->
<mass value="350" />
<!-- Wheels
damping-relaxation/compression: for bullet
damping parameters
Radius and width of wheel
front-right, front-left, rear-right and rear-left give the
position of the physics raycast wheels relative to the center of
gravity. Default is to use the corners of the chassis to attach
the wheels to. -->
<wheels damping-relaxation="35" damping-compression="5">
<front-right position="0.38 0 0.6" />
<front-left position="-0.38 0 0.6" />
<rear-right position="0.38 0 -0.6" />
<rear-left position="-0.38 0 -0.6" />
</wheels>
<!-- ********** Visuals ********** -->
<!-- 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" enabled="true" />
<!-- Camera
Distance between kart and camera.
forward-up-angle: Angle between camera and plane of kart (pitch)
when the camera is pointing forward
backward-up-angle: Angle between camera and plane of kart (pitch)
when the camera is pointing backwards. This is usually
larger than the forward-up-angle, since the kart itself
otherwise obstricts too much of the view. -->
<camera distance="1.0" forward-up-angle="15"
backward-up-angle="5" />
<!-- Jump animation
animation-time: only if the estimated time for a jump is larger
than this value will the jump animation being
shown. -->
<jump animation-time="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.
speed: Speed with which the leaning changes (in degree/second). -->
<lean max="8.6" speed="5.0" />
<!-- ********** Items ********** -->
<!-- Anvil
weight: The additional weight an anvil adds to a kart.
speed-factor: The additional slowdown caused by the anvil.
duration: The time an anvil is active. -->
<anvil duration="2.0" weight="150" speed-factor="0.2" />
<!-- Parachute
friction: The friction increase when a parachute is attached.
duration: The time an attached parachute is active
duration-other: The time a parachute attached from other kart works
lbound-fraction: The lower bound fraction of speed when lost will
detach parachute. E.g. at nearly 0 speed, only 5% of speed
need to be lost.
ubound-fraction: The upper bound fraction of speed when lost will
detach parachute. E.g. at max-speed 30% of speed must be lost.
max-speed: A factor that decides the impact of rate of speed
(distance between bounds) -->
<parachute friction="2.0" duration="4.0" duration-other="8.0"
lbound-fraction="0.95" ubound-fraction="0.7" max-speed="23" />
<!-- Bubblegum
duration: 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.
shield-duration: How long the bubblegum shield lasts -->
<bubblegum duration="1" speed-fraction="0.3" torque="500" fade-in-time="0.01"
shield-duration="10.0" />
<!-- Zipper
duration: 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 duration="3.5" force="250.0" speed-gain="4.5" max-speed-increase="15"
fade-out-time="1.0" />
<!-- Swatter
duration: How long can the swatter be active.
distance: How close a kart or an item must be before it can be hit.
This is the square of the real distance to accelerate the
compution.
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="9" squash-duration="5"
squash-slowdown="0.5" />
<!-- Plunger and rubber band handling
band-max-length: The maximum length of rubber band before it snaps.
band-force: The force a plunger/rubber band applies to the kart(s).
band-duration: 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="4.5" />
<!-- ********** Miscellaneous ********** -->
<!-- Startup
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
duration: 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" duration="1.2" height="2" />
<!-- Explosion
duration: 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 duration="2" radius="5"
invulnerability-time="6" />
<!-- 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="600" consumption="1" small-container="1" big-container="3"
max-speed-increase="5" duration="1" fade-out-time="2" max="20" />
<!-- 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" />
</characteristic>
<!-- The different difficulties (like easy, medium, hard) -->
<difficulties>
<characteristic name="easy">
<engine power="*0.66" max-speed="*0.6" />
<plunger in-face-time="3" />
</characteristic>
<characteristic name="medium">
<engine power="*0.77" max-speed="*0.8" />
<plunger in-face-time="4" />
</characteristic>
<characteristic name="hard">
<engine power="*0.89" max-speed="*0.92" />
</characteristic>
<!-- This doesn't need to be changed because the most fast/heavy/extreme
values should also be the default ones. -->
<characteristic name="best" />
</difficulties>
<!-- The different kart types, that can be specified in the kart.xml file -->
<kart-types>
<characteristic name="light">
<engine power="*0.46" max-speed="*0.92" brake-factor="*1"
max-speed-reverse-ratio="*0.77" />
<gear switch-ratio="0.20 0.55 1" power-increase="5 4 3" />
<mass value="*0.56" />
<startup time="0.3 0.5"
boost="8.5 4.5" />
<explosion time="2.1" radius="5.5"
invulnerability-time="7" />
<nitro engine-force="350" max-speed-increase="4.5" duration="1.5"
fade-out-time="2.5" />
<slipstream length="11" collect-time="1.5" use-time="2.5" add-power="3.2"
min-speed="9" max-speed-increase="4" duration="1.2"
fade-out-time="2.3" />
</characteristic>
<characteristic name="medium">
<engine power="*0.63" max-speed="*1" brake-factor="*0.73"
max-speed-reverse-ratio="*0.62" />
<gear switch-ratio="0.30 0.7 1.0" power-increase="2.2 2.2 2.5" />
<mass value="*0.71" />
<startup time="0.3 0.5"
boost="4.2 2.6" />
<explosion time="1.8" radius="5"
invulnerability-time="6" />
<nitro engine-force="425" consumption="1.4" duration="1" />
<slipstream use-time="3.3" add-power="2.8" duration="0.9"
fade-out-time="1.6" />
</characteristic>
<characteristic name="heavy">
<engine power="*1" max-speed="*1" brake-factor="*0.66"
max-speed-reverse-ratio="*1" />
<gear switch-ratio="0.45 0.70 1" power-increase="1.5 1.7 2.5" />
<mass value="*1" />
<swatter duration="10" distance="3" squash-duration="5"
squash-slowdown="0.5" />
<startup time="0.3 0.5"
boost="3.8 2" />
<explosion time="1.5" radius="4"
invulnerability-time="6" />
<nitro engine-force="600" consumption="2" max-speed-increase="8"
duration="0.7" fade-out-time="1.3" />
<slipstream length="8.5" use-time="4" add-power="2.7" min-speed="10.5"
max-speed-increase="8" duration="0.7" fade-out-time="1" />
</characteristic>
</kart-types>
<!-- Per-player settings/handicaps (or boosts) -->
<player-characteristics>
<characteristic name="normal" />
<characteristic name="handicap">
<engine brake-factor="*0.8" brake-time-increase="*0.85" max-speed-reverse-ratio="*0.8" />
<bubblegum duration="*1.5" speed-fraction="*1.5" torque="*1.5" />
<zipper duration="*0.8" force="*0.8" speed-gain="*0.8" max-speed-increase="*0.8" />
<swatter duration="*0.8" squash-duration="*1.5" squash-slowdown="*1.8" />
<plunger band-max-length="*0.8" band-speed-increase="*0.8" in-face-time="*1.3" />
<startup time="*0.8 0.8" boost="*0.8 0.8" />
<rescue duration="*1.5" />
<explosion duration="*1.3" invulnerability-time="*0.7" />
<nitro engine-force="*0.8" consumption="*1.1" max-speed-increase="*0.9" max="*0.8" />
<slipstream length="*0.8" width="*0.8" collect-time="*1.5" use-time="*0.8"
add-power="*0.8" min-speed="*0.8" max-speed-increase="*0.9" duration="*0.8" />
</characteristic>
</player-characteristics>
</characteristics>

View File

@ -85,24 +85,6 @@
<!-- How long the music credits are shown. --> <!-- How long the music credits are shown. -->
<credits music="10"/> <credits music="10"/>
<!-- weight is the additional weight an anvil adds to a kart.
speed-factor is the additional slowdown caused by the anvil.
time is the time an anvil is active. -->
<anvil time="2.0" weight="150" speed-factor="0.2"/>
<!-- friction is the friction increase when a parachute is attached.
time is the time an attached parachute is active
time-other is the time a parachute attached from other kart works
lbound-fraction is the lower bound fraction of speed when lost will
detach parachute. E.g. at nearly 0 speed, only 5% of speed
need to be lost.
ubound-fraction is the upper bound fraction of speed when lost will
detach parachute. E.g. at max-speed 30% of speed must be lost.
max-speed is a factor that decides the impact of rate of speed
(distance between bounds) -->
<parachute friction="2.0" time="4.0" time-other="8.0"
lbound-fraction="0.95" ubound-fraction="0.7" max-speed="23"/>
<!-- time is the time till a bomb explodes. time-increase is the time added <!-- time is the time till a bomb explodes. time-increase is the time added
to timer when bomb is passed on. --> to timer when bomb is passed on. -->
<bomb time="30.0" time-increase="-5.0"/> <bomb time="30.0" time-increase="-5.0"/>
@ -150,22 +132,6 @@
============================ --> ============================ -->
<general-kart-defaults> <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
backward-up-angle: Angle between camera and plane of kart (pitch)
when the camera is pointing backwards. This is usually
larger than the forward-up-angle, since the kart itself
otherwise obstricts too much of the view. -->
<camera distance="1.0" forward-up-angle="15"
backward-up-angle="5"/>
<!-- Jump animation related values:
animation-time: only if the estimated time for a jump is larger
than this value will the jump animation being
shown. -->
<jump animation-time="0.5" />
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame. <!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
decrease: multiplicative decrease of skidding factor in each frame. decrease: multiplicative decrease of skidding factor in each frame.
max: maximum skidding factor = maximum increase of steering angle. max: maximum skidding factor = maximum increase of steering angle.
@ -339,69 +305,6 @@
/> />
</ai> </ai>
<!-- The per-player difficulties in multiplayer games.
These values are multiplied with the current values of a car
so 1 means that nothing changes.
The meaning of the different values is explained below this tag. -->
<difficulties>
<normal>
<mass value="1.0"/>
<engine brake-factor="1.0" brake-time-increase="1.0" max-speed-reverse-ratio="1.0" power="1.0" max-speed="1.0"/>
<nitro consumption="1.0" max-speed-increase="1.0" duration="1.0" fade-out-time="1.0"/>
<bubblegum time="1.0" speed-fraction="1.0" torque="1.0" fade-in-time="1.0"/>
<rescue time="1.0"/>
<explosion time="1.0" radius="1.0" invulnerability-time="1.0"/>
<slipstream length="1.0" width="1.0" collect-time="1.0" use-time="1.0"
add-power="1.0" min-speed="1.0" max-speed-increase="1.0" duration="1.0"
fade-out-time="1.0"/>
<plunger band-max-length="1.0" band-force="1.0" band-duration="1.0"
band-speed-increase="1.0" band-fade-out-time="1.0" in-face-time="1.0"/>
<zipper time="1.0" force="1.0" speed-gain="1.0" max-speed-increase="1.0"
fade-out-time="1.0"/>
<swatter duration="1.0" squash-duration="1.0" squash-slowdown="1.0"/>
<startup time="1.0 1.0" boost="1.0 1.0"/>
</normal>
<handicap>
<mass value="1.0"/>
<engine brake-factor="0.8" brake-time-increase="0.85" max-speed-reverse-ratio="0.8" power="0.8" max-speed="0.8"/>
<nitro consumption="1.1" max-speed-increase="0.9" duration="1.0" fade-out-time="1.0"/>
<bubblegum time="1.5" speed-fraction="1.5" torque="1.5" fade-in-time="1.0"/>
<rescue time="1.5"/>
<explosion time="1.3" invulnerability-time="0.7"/>
<slipstream length="0.8" width="0.8" collect-time="1.5" use-time="0.8"
add-power="0.8" min-speed="0.8" max-speed-increase="0.9" duration="0.8"
fade-out-time="1.0"/>
<plunger band-max-length="0.8" band-force="1.0" band-duration="1.0"
band-speed-increase="0.8" band-fade-out-time="1.0" in-face-time="1.3"/>
<zipper time="0.8" force="0.8" speed-gain="0.8" max-speed-increase="0.8"
fade-out-time="1.0"/>
<swatter duration="0.8" squash-duration="1.5" squash-slowdown="1.8"/>
<startup time="0.8 0.8" boost="0.8 0.8"/>
</handicap>
</difficulties>
<!-- Suspension related values. stiffness: kart's suspension stiffness.
rest: Length of suspension when at rest.
travel: maximum movement of suspension!!
exp-string-response: dampen the suspension spring reaction
exponentially.
max-force: Maximum suspension force -->
<suspension stiffness="140" rest="0.3" travel="0.29"
exp-spring-response="false" max-force="12000"/>
<!-- Wheel related parameters: damping-relaxation/compression: for
bullet, damping parameters.
front-right, front-left, rear-right and rear-left give the
position of the physics raycast wheels relative to the center of
gravity. Default is to use the corners of the chassis to attach
the wheels to. -->
<wheels damping-relaxation="35" damping-compression="5">
<front-right position="0.38 0 0.6" />
<front-left position="-0.38 0 0.6" />
<rear-right position="0.38 0 -0.6" />
<rear-left position="-0.38 0 -0.6"/>
</wheels>
<!-- Parameters for the speed-weighted objects: <!-- Parameters for the speed-weighted objects:
a bigger value for strength-factor leads to the speed of the kart more quickly affecting a bigger value for strength-factor leads to the speed of the kart more quickly affecting
the strength of the animation (up to a maximum value that corresponds to the original animation) --> the strength of the animation (up to a maximum value that corresponds to the original animation) -->
@ -411,23 +314,6 @@
(like 10000000) disables bullet skidding. --> (like 10000000) disables bullet skidding. -->
<friction slip="10000000"/> <friction slip="10000000"/>
<!-- Values related to stability of the chassis: damping, and reduced
impact of roll.
downward-impulse-factor: A speed proportional impulse applied each
frame that pushes the vehicle onto the ground.
track-connection-accel: An artificial force that pulls a wheel to
the ground if its off ground. Reduces the affect if a kart loses
contact with the ground (i.e. it then can't steer or accelerate
anymore).
smooth-flying-impulse: apply a torque impulse to flying kart to keep
them parallel to the ground.-->
<stability roll-influence="0.3"
chassis-linear-damping="0.2"
chassis-angular-damping="0"
downward-impulse-factor="5"
track-connection-accel="2"
smooth-flying-impulse="250"/>
<!-- collision <!-- collision
impulse-type: STK can apply an additional impulse in case of impulse-type: STK can apply an additional impulse in case of
kart-track collision: kart-track collision:
@ -468,58 +354,6 @@
impulse="3000" impulse-time="0.1" terrain-impulse="1600" impulse="3000" impulse-time="0.1" terrain-impulse="1600"
restitution="1.0" bevel-factor="0.5 0.0 0.7" restitution="1.0" bevel-factor="0.5 0.0 0.7"
physical-wheel-position="-1" /> physical-wheel-position="-1" />
<!-- 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. <!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
decrease: multiplicative decrease of skidding factor in each frame. decrease: multiplicative decrease of skidding factor in each frame.
@ -562,34 +396,6 @@
post-skid-rotate-factor="1" post-skid-rotate-factor="1"
reduce-turn-min="0.2" reduce-turn-max="0.8"/> 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. -->
<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 <!-- Leaning related parameters, i.e. slightly leaning the karts when
driving a fast curve. driving a fast curve.
max: maximum leaning (i.e. when steering as much as possible at highest max: maximum leaning (i.e. when steering as much as possible at highest
@ -597,156 +403,10 @@
sped: Speed with which the leaning changes (in degree/second). --> sped: Speed with which the leaning changes (in degree/second). -->
<lean max="8.6" speed="5.0" /> <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 4 values, one for low, medium, hard, and supertux.
brake-factor: Value used when braking.
brake-time-increase: The brake force is multiplied by
(1+brake_time*brake_time_increase - i.e. the longer the brake was
pressed, the harder the kart will brake.
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"
brake-time-increase="6"
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> <kart-type>
<light> <light />
<startup time = "0.3 0.5" <medium />
boost = "8.5 4.5" /> <heavy />
<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="13 18 21 23.0" brake-factor="15.0"
max-speed-reverse-ratio="0.5"/>
<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="375 450 525 550" max-speed="14 19 22.0 25" 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="575 675 775 875" 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> </kart-type>
</general-kart-defaults> </general-kart-defaults>

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file. # 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_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") 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

@ -27,7 +27,6 @@
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "items/item.hpp" #include "items/item.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/player_difficulty.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
STKConfig* stk_config=0; STKConfig* stk_config=0;
@ -119,19 +118,8 @@ void STKConfig::load(const std::string &filename)
} }
CHECK_NEG(m_max_karts, "<karts max=..." ); CHECK_NEG(m_max_karts, "<karts max=..." );
CHECK_NEG(m_parachute_friction, "parachute-friction" );
CHECK_NEG(m_parachute_lbound_fraction, "parachute-lbound-fraction" );
CHECK_NEG(m_parachute_ubound_fraction, "parachute-ubound-fraction" );
CHECK_NEG(m_parachute_max_speed, "parachute-max-speed" );
CHECK_NEG(m_parachute_time, "parachute-time" );
CHECK_NEG(m_parachute_time_other, "parachute-time-other" );
CHECK_NEG(m_bomb_time, "bomb-time" );
CHECK_NEG(m_bomb_time_increase, "bomb-time-increase" );
CHECK_NEG(m_anvil_time, "anvil-time" );
CHECK_NEG(m_anvil_weight, "anvil-weight" );
CHECK_NEG(m_item_switch_time, "item-switch-time" ); CHECK_NEG(m_item_switch_time, "item-switch-time" );
CHECK_NEG(m_bubblegum_counter, "bubblegum disappear counter"); CHECK_NEG(m_bubblegum_counter, "bubblegum disappear counter");
CHECK_NEG(m_bubblegum_shield_time, "bubblegum shield-time" );
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" ); CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
CHECK_NEG(m_max_skidmarks, "max-skidmarks" ); CHECK_NEG(m_max_skidmarks, "max-skidmarks" );
CHECK_NEG(m_min_kart_version, "<kart-version min...>" ); CHECK_NEG(m_min_kart_version, "<kart-version min...>" );
@ -163,18 +151,13 @@ void STKConfig::load(const std::string &filename)
*/ */
void STKConfig::init_defaults() void STKConfig::init_defaults()
{ {
m_anvil_weight = m_parachute_friction = m_bomb_time = m_bomb_time_increase =
m_parachute_time = m_parachute_lbound_fraction = m_explosion_impulse_objects = m_music_credit_time =
m_parachute_time_other = m_anvil_speed_factor =
m_bomb_time = m_bomb_time_increase =
m_anvil_time = m_music_credit_time =
m_delay_finish_time = m_skid_fadeout_time = m_delay_finish_time = m_skid_fadeout_time =
m_near_ground = m_item_switch_time = m_near_ground = m_item_switch_time =
m_smooth_angle_limit = m_parachute_ubound_fraction = m_smooth_angle_limit = m_penalty_time =
m_penalty_time = m_explosion_impulse_objects = UNDEFINED;
m_parachute_max_speed = UNDEFINED;
m_bubblegum_counter = -100; m_bubblegum_counter = -100;
m_bubblegum_shield_time = -100;
m_shield_restrict_weapos = false; m_shield_restrict_weapos = false;
m_max_karts = -100; m_max_karts = -100;
m_max_skidmarks = -100; m_max_skidmarks = -100;
@ -310,23 +293,6 @@ void STKConfig::getAllData(const XMLNode * root)
credits_node->get("music", &m_music_credit_time); credits_node->get("music", &m_music_credit_time);
if(const XMLNode *anvil_node= root->getNode("anvil"))
{
anvil_node->get("weight", &m_anvil_weight );
anvil_node->get("speed-factor", &m_anvil_speed_factor);
anvil_node->get("time", &m_anvil_time );
}
if(const XMLNode *parachute_node= root->getNode("parachute"))
{
parachute_node->get("friction", &m_parachute_friction );
parachute_node->get("time", &m_parachute_time );
parachute_node->get("time-other", &m_parachute_time_other );
parachute_node->get("lbound-fraction", &m_parachute_lbound_fraction);
parachute_node->get("ubound-fraction", &m_parachute_ubound_fraction);
parachute_node->get("max-speed", &m_parachute_max_speed );
}
if(const XMLNode *bomb_node= root->getNode("bomb")) if(const XMLNode *bomb_node= root->getNode("bomb"))
{ {
bomb_node->get("time", &m_bomb_time); bomb_node->get("time", &m_bomb_time);
@ -359,7 +325,6 @@ void STKConfig::getAllData(const XMLNode * root)
if(const XMLNode *bubblegum_node= root->getNode("bubblegum")) if(const XMLNode *bubblegum_node= root->getNode("bubblegum"))
{ {
bubblegum_node->get("disappear-counter", &m_bubblegum_counter ); bubblegum_node->get("disappear-counter", &m_bubblegum_counter );
bubblegum_node->get("shield-time", &m_bubblegum_shield_time );
bubblegum_node->get("restrict-weapons", &m_shield_restrict_weapos); bubblegum_node->get("restrict-weapons", &m_shield_restrict_weapos);
} }
@ -415,14 +380,6 @@ void STKConfig::getAllData(const XMLNode * root)
m_kart_properties[type->getName()]->copyFrom(m_default_kart_properties); m_kart_properties[type->getName()]->copyFrom(m_default_kart_properties);
m_kart_properties[type->getName()]->getAllData(type); m_kart_properties[type->getName()]->getAllData(type);
} }
child_node = node->getNode("difficulties");
for (unsigned int i = 0; i < child_node->getNumNodes(); ++i)
{
const XMLNode* type = child_node->getNode(i);
m_player_difficulties[i] = new PlayerDifficulty();
m_player_difficulties[i]->getAllData(type);
}
} // getAllData } // getAllData
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -34,7 +34,6 @@
#include <map> #include <map>
class KartProperties; class KartProperties;
class PlayerDifficulty;
class MusicInformation; class MusicInformation;
class XMLNode; class XMLNode;
@ -51,8 +50,6 @@ protected:
/** Default kart properties. */ /** Default kart properties. */
KartProperties *m_default_kart_properties; KartProperties *m_default_kart_properties;
std::map<std::string, KartProperties*> m_kart_properties; std::map<std::string, KartProperties*> m_kart_properties;
/** Per-player difficulties. */
PlayerDifficulty* m_player_difficulties[PLAYER_DIFFICULTY_COUNT];
public: public:
/** What to do if a kart already has a powerup when it hits a bonus box: /** What to do if a kart already has a powerup when it hits a bonus box:
@ -66,26 +63,12 @@ public:
m_same_powerup_mode; m_same_powerup_mode;
static float UNDEFINED; static float UNDEFINED;
float m_anvil_weight; /**<Additional kart weight if anvil is
attached. */
float m_anvil_speed_factor; /**<Speed decrease when attached first. */
float m_parachute_friction; /**<Increased parachute air friction. */
float m_parachute_ubound_fraction; /**<Upper bound fraction of speed when
lost will detach parachute. */
float m_parachute_lbound_fraction; /**<Lower bound fraction of speed when
lost will detach parachute. */
float m_parachute_max_speed; /**<Max speed to rate current speed */
float m_parachute_time; /**<Time a parachute is active. */
float m_parachute_time_other; /**<Time a parachute attached to other
karts is active. */
float m_bomb_time; /**<Time before a bomb explodes. */ float m_bomb_time; /**<Time before a bomb explodes. */
float m_bomb_time_increase; /**<Time added to bomb timer when it's float m_bomb_time_increase; /**<Time added to bomb timer when it's
passed on. */ passed on. */
float m_anvil_time; /**<Time an anvil is active. */
float m_item_switch_time; /**< Time items will be switched. */ float m_item_switch_time; /**< Time items will be switched. */
int m_bubblegum_counter; /**< How many times bubble gums must be int m_bubblegum_counter; /**< How many times bubble gums must be
driven over before they disappear. */ driven over before they disappear. */
float m_bubblegum_shield_time; /**<How long a bubble gum shield lasts. */
bool m_shield_restrict_weapos; /**<Wether weapon usage is punished. */ bool m_shield_restrict_weapos; /**<Wether weapon usage is punished. */
float m_explosion_impulse_objects; /**<Impulse of explosion on moving float m_explosion_impulse_objects; /**<Impulse of explosion on moving
objects, e.g. road cones, ... */ objects, e.g. road cones, ... */
@ -199,10 +182,6 @@ public:
{ {
return *m_kart_properties.at(type); return *m_kart_properties.at(type);
} // getKartProperties } // getKartProperties
// ------------------------------------------------------------------------
const PlayerDifficulty * getPlayerDifficulty(PerPlayerDifficulty difficulty)
{ return m_player_difficulties[difficulty]; }
} }
; // STKConfig ; // STKConfig

View File

@ -380,7 +380,7 @@ void Camera::smoothMoveCamera(float dt)
// Smoothly interpolate towards the position and target // Smoothly interpolate towards the position and target
const KartProperties *kp = m_kart->getKartProperties(); const KartProperties *kp = m_kart->getKartProperties();
float max_increase_with_zipper = kp->getZipperMaxSpeedIncrease(); float max_increase_with_zipper = kp->getZipperMaxSpeedIncrease();
float max_speed_without_zipper = kp->getMaxSpeed(); float max_speed_without_zipper = kp->getEngineMaxSpeed();
float current_speed = m_kart->getSpeed(); float current_speed = m_kart->getSpeed();
const Skidding *ks = m_kart->getSkidding(); const Skidding *ks = m_kart->getSkidding();
@ -469,7 +469,7 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle,
else else
{ {
*above_kart = 0.75f; *above_kart = 0.75f;
*cam_angle = kp->getCameraForwardUpAngle(); *cam_angle = kp->getCameraForwardUpAngle() * DEGREE_TO_RAD;
*distance = -m_distance; *distance = -m_distance;
} }
float steering = m_kart->getSteerPercent() float steering = m_kart->getSteerPercent()
@ -484,7 +484,7 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle,
case CM_REVERSE: // Same as CM_NORMAL except it looks backwards case CM_REVERSE: // Same as CM_NORMAL except it looks backwards
{ {
*above_kart = 0.75f; *above_kart = 0.75f;
*cam_angle = kp->getCameraBackwardUpAngle(); *cam_angle = kp->getCameraBackwardUpAngle() * DEGREE_TO_RAD;
*sideway = 0; *sideway = 0;
*distance = 2.0f*m_distance; *distance = 2.0f*m_distance;
*smoothing = false; *smoothing = false;
@ -843,8 +843,7 @@ void Camera::handleEndCamera(float dt)
} }
case EndCameraInformation::EC_AHEAD_OF_KART: case EndCameraInformation::EC_AHEAD_OF_KART:
{ {
const KartProperties *kp=m_kart->getKartProperties(); float cam_angle = m_kart->getKartProperties()->getCameraBackwardUpAngle() * DEGREE_TO_RAD;
float cam_angle = kp->getCameraBackwardUpAngle();
positionCamera(dt, /*above_kart*/0.75f, positionCamera(dt, /*above_kart*/0.75f,
cam_angle, /*side_way*/0, cam_angle, /*side_way*/0,

View File

@ -57,6 +57,7 @@
#include "modes/profile_world.hpp" #include "modes/profile_world.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "physics/physics.hpp" #include "physics/physics.hpp"
#include "scriptengine/property_animator.hpp"
#include "states_screens/dialogs/confirm_resolution_dialog.hpp" #include "states_screens/dialogs/confirm_resolution_dialog.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "tracks/track_manager.hpp" #include "tracks/track_manager.hpp"
@ -2153,6 +2154,8 @@ void IrrDriver::update(float dt)
m_wind->update(); m_wind->update();
PropertyAnimator::get()->update(dt);
World *world = World::getWorld(); World *world = World::getWorld();
if (GUIEngine::getCurrentScreen() != NULL && if (GUIEngine::getCurrentScreen() != NULL &&

View File

@ -25,8 +25,8 @@
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/controller/controller.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/controller/controller.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/max_speed.hpp" #include "karts/max_speed.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
@ -67,11 +67,9 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0))); setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0)));
m_slipstream_time = 0.0f; m_slipstream_time = 0.0f;
float length = m_kart->getKartProperties()->getSlipstreamLength() * float length = m_kart->getKartProperties()->getSlipstreamLength();
m_kart->getPlayerDifficulty()->getSlipstreamLength();
float kw = m_kart->getKartWidth(); float kw = m_kart->getKartWidth();
float ew = m_kart->getKartProperties()->getSlipstreamWidth() * float ew = m_kart->getKartProperties()->getSlipstreamWidth();
m_kart->getPlayerDifficulty()->getSlipstreamWidth();
float kl = m_kart->getKartLength(); float kl = m_kart->getKartLength();
Vec3 p[4]; Vec3 p[4];
@ -314,8 +312,7 @@ void SlipStream::setIntensity(float f, const AbstractKart *kart)
bool SlipStream::isSlipstreamReady() const bool SlipStream::isSlipstreamReady() const
{ {
return m_slipstream_time> return m_slipstream_time>
m_kart->getKartProperties()->getSlipstreamCollectTime() * m_kart->getKartProperties()->getSlipstreamCollectTime();
m_kart->getPlayerDifficulty()->getSlipstreamCollectTime();
} // isSlipstreamReady } // isSlipstreamReady
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -329,16 +326,12 @@ void SlipStream::updateSlipstreamPower()
if(m_slipstream_mode==SS_USE) if(m_slipstream_mode==SS_USE)
{ {
setIntensity(2.0f, NULL); 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(),
m_kart->getPlayerDifficulty()->getSlipstreamMaxSpeedIncrease(), kp->getSlipstreamAddPower(),
kp->getSlipstreamAddPower() * kp->getSlipstreamDuration(),
m_kart->getPlayerDifficulty()->getSlipstreamAddPower(), kp->getSlipstreamFadeOutTime());
kp->getSlipstreamDuration() *
m_kart->getPlayerDifficulty()->getSlipstreamDuration(),
kp->getSlipstreamFadeOutTime() *
m_kart->getPlayerDifficulty()->getSlipstreamFadeOutTime());
} }
} // upateSlipstreamPower } // upateSlipstreamPower
@ -368,6 +361,8 @@ void SlipStream::setDebugColor(const video::SColor &color)
*/ */
void SlipStream::update(float dt) void SlipStream::update(float dt)
{ {
const KartProperties *kp = m_kart->getKartProperties();
// Low level AIs should not do any slipstreaming. // Low level AIs should not do any slipstreaming.
if(m_kart->getController()->disableSlipstreamBonus()) if(m_kart->getController()->disableSlipstreamBonus())
return; return;
@ -394,8 +389,7 @@ void SlipStream::update(float dt)
// 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()<m_kart->getKartProperties()->getSlipstreamMinSpeed() * if(m_kart->getSpeed() < kp->getSlipstreamMinSpeed())
m_kart->getPlayerDifficulty()->getSlipstreamMinSpeed())
{ {
setIntensity(0, NULL); setIntensity(0, NULL);
m_slipstream_mode = SS_NONE; m_slipstream_mode = SS_NONE;
@ -436,9 +430,7 @@ void SlipStream::update(float dt)
// entirely sure if this makes sense, but it makes it easier to // entirely sure if this makes sense, but it makes it easier to
// give karts different slipstream properties. // 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() < if (m_target_kart->getSpeed() < kp->getSlipstreamMinSpeed())
m_kart->getKartProperties()->getSlipstreamMinSpeed() *
m_kart->getPlayerDifficulty()->getSlipstreamMinSpeed())
{ {
if(UserConfigParams::m_slipstream_debug && if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isPlayerController()) m_kart->getController()->isPlayerController())
@ -452,8 +444,7 @@ void SlipStream::update(float dt)
// slipstream length+0.5*kart_length()+0.5*target_kart_length // slipstream length+0.5*kart_length()+0.5*target_kart_length
// away from the other kart // away from the other kart
Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ(); Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ();
float l = m_kart->getKartProperties()->getSlipstreamLength() * float l = kp->getSlipstreamLength()
m_kart->getPlayerDifficulty()->getSlipstreamLength()
+ 0.5f*( m_target_kart->getKartLength() + 0.5f*( m_target_kart->getKartLength()
+m_kart->getKartLength() ); +m_kart->getKartLength() );
if(delta.length2_2d() > l*l) if(delta.length2_2d() > l*l)
@ -493,9 +484,7 @@ void SlipStream::update(float dt)
{ {
m_slipstream_mode = SS_USE; m_slipstream_mode = SS_USE;
m_kart->handleZipper(); m_kart->handleZipper();
m_slipstream_time = m_slipstream_time = kp->getSlipstreamCollectTime();
m_kart->getKartProperties()->getSlipstreamCollectTime() *
m_kart->getPlayerDifficulty()->getSlipstreamCollectTime();
return; return;
} }
} }
@ -516,8 +505,7 @@ void SlipStream::update(float dt)
setIntensity(m_slipstream_time, m_target_kart); setIntensity(m_slipstream_time, m_target_kart);
m_slipstream_mode = SS_COLLECT; m_slipstream_mode = SS_COLLECT;
if(m_slipstream_time>m_kart->getKartProperties()->getSlipstreamCollectTime() * if (m_slipstream_time > kp->getSlipstreamCollectTime())
m_kart->getPlayerDifficulty()->getSlipstreamCollectTime())
{ {
setIntensity(1.0f, m_target_kart); setIntensity(1.0f, m_target_kart);
} }

View File

@ -15,21 +15,19 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config/user_config.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/widgets/kart_stats_widget.hpp" #include "guiengine/widgets/kart_stats_widget.hpp"
#include "utils/string_utils.hpp" #include "karts/abstract_characteristic.hpp"
#include <string.h>
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#include "config/user_config.hpp"
#include <IGUIEnvironment.h> #include <IGUIEnvironment.h>
#include <IGUIElement.h> #include <IGUIElement.h>
#include <IGUIButton.h> #include <IGUIButton.h>
#include <string>
using namespace GUIEngine; using namespace GUIEngine;
using namespace irr::core; using namespace irr::core;
@ -81,15 +79,21 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
m_children.push_back(skill_bar); m_children.push_back(skill_bar);
} }
m_skills[SKILL_MASS]->setValue((int)(props->getMass()/5)); // Scale the values so they look better
// The scaling factor and offset were found by trial and error.
// It should look nice and you should be able to see the difference between
// different masses or velocities.
m_skills[SKILL_MASS]->setValue((int)
((props->getCombinedCharacteristic()->getMass() - 20) / 4));
m_skills[SKILL_MASS]->setLabel(_("WEIGHT")); 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_MASS]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_mass", m_player_id);
m_skills[SKILL_SPEED]->setValue((int)((props->getAbsMaxSpeed()-20)*9)); m_skills[SKILL_SPEED]->setValue((int)
((props->getCombinedCharacteristic()->getEngineMaxSpeed() - 15) * 6));
m_skills[SKILL_SPEED]->setLabel(_("SPEED")); 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_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]->setValue((int) ((props->getAvgPower() - 30) / 20));
m_skills[SKILL_POWER]->setLabel(_("POWER")); m_skills[SKILL_POWER]->setLabel(_("POWER"));
m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id); m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id);

View File

@ -225,6 +225,7 @@ void Attachment::clear()
*/ */
void Attachment::hitBanana(Item *item, int new_attachment) void Attachment::hitBanana(Item *item, int new_attachment)
{ {
const KartProperties *kp = m_kart->getKartProperties();
const StateManager::ActivePlayer *const ap = m_kart->getController() const StateManager::ActivePlayer *const ap = m_kart->getController()
->getPlayer(); ->getPlayer();
if(ap && ap->getConstProfile()==PlayerManager::getCurrentPlayer()) if(ap && ap->getConstProfile()==PlayerManager::getCurrentPlayer())
@ -266,9 +267,7 @@ void Attachment::hitBanana(Item *item, int new_attachment)
// default time. This is necessary to avoid that a kart lands on the // default time. This is necessary to avoid that a kart lands on the
// same banana again once the explosion animation is finished, giving // same banana again once the explosion animation is finished, giving
// the kart the same penalty twice. // the kart the same penalty twice.
float f = std::max(item->getDisableTime(), float f = std::max(item->getDisableTime(), kp->getExplosionDuration() + 2.0f);
m_kart->getKartProperties()->getExplosionTime() *
m_kart->getPlayerDifficulty()->getExplosionTime() + 2.0f);
item->setDisableTime(f); item->setDisableTime(f);
break; break;
} }
@ -296,7 +295,7 @@ void Attachment::hitBanana(Item *item, int new_attachment)
switch (new_attachment) switch (new_attachment)
{ {
case 0: case 0:
set( ATTACH_PARACHUTE,stk_config->m_parachute_time+leftover_time); set(ATTACH_PARACHUTE, kp->getParachuteDuration() + leftover_time);
m_initial_speed = m_kart->getSpeed(); m_initial_speed = m_kart->getSpeed();
// if going very slowly or backwards, // if going very slowly or backwards,
@ -310,12 +309,12 @@ void Attachment::hitBanana(Item *item, int new_attachment)
// sound -> playSfx ( SOUND_SHOOMF ) ; // sound -> playSfx ( SOUND_SHOOMF ) ;
break ; break ;
case 2: case 2:
set( ATTACH_ANVIL, stk_config->m_anvil_time+leftover_time); set(ATTACH_ANVIL, kp->getAnvilDuration() + leftover_time);
// if ( m_kart == m_kart[0] ) // if ( m_kart == m_kart[0] )
// sound -> playSfx ( SOUND_SHOOMF ) ; // sound -> playSfx ( SOUND_SHOOMF ) ;
// Reduce speed once (see description above), all other changes are // Reduce speed once (see description above), all other changes are
// handled in Kart::updatePhysics // handled in Kart::updatePhysics
m_kart->adjustSpeed(stk_config->m_anvil_speed_factor); m_kart->adjustSpeed(kp->getAnvilSpeedFactor());
m_kart->updateWeight(); m_kart->updateWeight();
break ; break ;
} // switch } // switch
@ -420,12 +419,14 @@ void Attachment::update(float dt)
// This percentage is based on the ratio of // This percentage is based on the ratio of
// initial_speed / initial_max_speed // initial_speed / initial_max_speed
float f = m_initial_speed / stk_config->m_parachute_max_speed; const KartProperties *kp = m_kart->getKartProperties();
float f = m_initial_speed / kp->getParachuteMaxSpeed();
if (f > 1.0f) f = 1.0f; // cap fraction if (f > 1.0f) f = 1.0f; // cap fraction
if (m_kart->getSpeed() <= m_initial_speed * if (m_kart->getSpeed() <= m_initial_speed *
(stk_config->m_parachute_lbound_fraction + (kp->getParachuteLboundFraction() +
f * ( stk_config->m_parachute_ubound_fraction f * (kp->getParachuteUboundFraction()
- stk_config->m_parachute_lbound_fraction))) - kp->getParachuteLboundFraction())))
{ {
m_time_left = -1; m_time_left = -1;
} }
@ -507,6 +508,12 @@ void Attachment::update(float dt)
clear(); clear();
} // update } // update
// ----------------------------------------------------------------------------
float Attachment::weightAdjust() const
{
return m_type == ATTACH_ANVIL ? m_kart->getKartProperties()->getAnvilWeight() : 0.0f;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Inform any eventual plugin when an animation is done. */ /** Inform any eventual plugin when an animation is done. */
void Attachment::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node) void Attachment::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node)

View File

@ -130,8 +130,7 @@ public:
AbstractKart* getPreviousOwner() const { return m_previous_owner; } AbstractKart* getPreviousOwner() const { return m_previous_owner; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns additional weight for the kart. */ /** Returns additional weight for the kart. */
float weightAdjust() const { float weightAdjust() const;
return m_type==ATTACH_ANVIL ? stk_config->m_anvil_weight : 0.0f; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Return the currently associated scene node (used by e.g the swatter) */ /** Return the currently associated scene node (used by e.g the swatter) */
scene::IAnimatedMeshSceneNode* getNode() {return m_node;} scene::IAnimatedMeshSceneNode* getNode() {return m_node;}

View File

@ -176,8 +176,7 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
} }
else else
{ {
m_keep_alive = m_owner->getKartProperties()->getRubberBandDuration() * m_keep_alive = m_owner->getKartProperties()->getPlungerBandDuration();
m_owner->getPlayerDifficulty()->getRubberBandDuration();
// Make this object invisible by placing it faaar down. Not that if this // Make this object invisible by placing it faaar down. Not that if this
// objects is simply removed from the scene graph, it might be auto-deleted // objects is simply removed from the scene graph, it might be auto-deleted

View File

@ -171,6 +171,8 @@ void Powerup::adjustSound()
*/ */
void Powerup::use() void Powerup::use()
{ {
const KartProperties *kp = m_owner->getKartProperties();
// The player gets an achievement point for using a powerup // The player gets an achievement point for using a powerup
StateManager::ActivePlayer * player = m_owner->getController()->getPlayer(); StateManager::ActivePlayer * player = m_owner->getController()->getPlayer();
if (m_type != PowerupManager::POWERUP_NOTHING && if (m_type != PowerupManager::POWERUP_NOTHING &&
@ -221,9 +223,7 @@ void Powerup::use()
case PowerupManager::POWERUP_SWATTER: case PowerupManager::POWERUP_SWATTER:
m_owner->getAttachment() m_owner->getAttachment()
->set(Attachment::ATTACH_SWATTER, ->set(Attachment::ATTACH_SWATTER, kp->getSwatterDuration());
m_owner->getKartProperties()->getSwatterDuration() *
m_owner->getPlayerDifficulty()->getSwatterDuration());
break; break;
case PowerupManager::POWERUP_BUBBLEGUM: case PowerupManager::POWERUP_BUBBLEGUM:
@ -258,12 +258,12 @@ void Powerup::use()
if (m_owner->getIdent() == "nolok") if (m_owner->getIdent() == "nolok")
{ {
m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD,
stk_config->m_bubblegum_shield_time); kp->getBubblegumShieldDuration());
} }
else else
{ {
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD, m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
stk_config->m_bubblegum_shield_time); kp->getBubblegumShieldDuration());
} }
} }
else // using a bubble gum while still having a shield else // using a bubble gum while still having a shield
@ -271,12 +271,12 @@ void Powerup::use()
if (m_owner->getIdent() == "nolok") if (m_owner->getIdent() == "nolok")
{ {
m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD,
stk_config->m_bubblegum_shield_time + m_owner->getShieldTime()); kp->getBubblegumShieldDuration() + m_owner->getShieldTime());
} }
else else
{ {
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD, m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
stk_config->m_bubblegum_shield_time + m_owner->getShieldTime()); kp->getBubblegumShieldDuration() + m_owner->getShieldTime());
} }
} }
@ -300,9 +300,9 @@ void Powerup::use()
if(kart->getPosition() == 1) if(kart->getPosition() == 1)
{ {
kart->getAttachment()->set(Attachment::ATTACH_ANVIL, kart->getAttachment()->set(Attachment::ATTACH_ANVIL,
stk_config->m_anvil_time); kp->getAnvilDuration());
kart->updateWeight(); kart->updateWeight();
kart->adjustSpeed(stk_config->m_anvil_speed_factor*0.5f); kart->adjustSpeed(kp->getAnvilSpeedFactor() * 0.5f);
// should we position the sound at the kart that is hit, // should we position the sound at the kart that is hit,
// or the kart "throwing" the anvil? Ideally it should be both. // or the kart "throwing" the anvil? Ideally it should be both.
@ -337,9 +337,8 @@ void Powerup::use()
} }
if(m_owner->getPosition() > kart->getPosition()) if(m_owner->getPosition() > kart->getPosition())
{ {
kart->getAttachment() kart->getAttachment()->set(Attachment::ATTACH_PARACHUTE,
->set(Attachment::ATTACH_PARACHUTE, kp->getParachuteDurationOther());
stk_config->m_parachute_time_other);
if(kart->getController()->isPlayerController()) if(kart->getController()->isPlayerController())
player_kart = kart; player_kart = kart;

View File

@ -134,6 +134,8 @@ void RubberBand::updatePosition()
*/ */
void RubberBand::update(float dt) void RubberBand::update(float dt)
{ {
const KartProperties *kp = m_owner->getKartProperties();
if(m_owner->isEliminated()) if(m_owner->isEliminated())
{ {
// Rubber band snaps // Rubber band snaps
@ -149,8 +151,7 @@ void RubberBand::update(float dt)
// Check for rubber band snapping // Check for rubber band snapping
// ------------------------------ // ------------------------------
float l = (m_end_position-k).length2(); float l = (m_end_position-k).length2();
float max_len = m_owner->getKartProperties()->getRubberBandMaxLength() * float max_len = kp->getPlungerBandMaxLength();
m_owner->getPlayerDifficulty()->getRubberBandMaxLength();
if(l>max_len*max_len) if(l>max_len*max_len)
{ {
// Rubber band snaps // Rubber band snaps
@ -163,8 +164,7 @@ void RubberBand::update(float dt)
// ---------------------------- // ----------------------------
if(m_attached_state!=RB_TO_PLUNGER) if(m_attached_state!=RB_TO_PLUNGER)
{ {
float force = m_owner->getKartProperties()->getRubberBandForce() * float force = kp->getPlungerBandForce();
m_owner->getPlayerDifficulty()->getRubberBandForce();
Vec3 diff = m_end_position-k; Vec3 diff = m_end_position-k;
// detach rubber band if kart gets very close to hit point // detach rubber band if kart gets very close to hit point
@ -180,12 +180,10 @@ void RubberBand::update(float dt)
diff.normalize(); // diff can't be zero here diff.normalize(); // diff can't be zero here
m_owner->getBody()->applyCentralForce(diff*force); m_owner->getBody()->applyCentralForce(diff*force);
m_owner->increaseMaxSpeed(MaxSpeed::MS_INCREASE_RUBBER, m_owner->increaseMaxSpeed(MaxSpeed::MS_INCREASE_RUBBER,
m_owner->getKartProperties()->getRubberBandSpeedIncrease() * kp->getPlungerBandSpeedIncrease(),
m_owner->getPlayerDifficulty()->getRubberBandSpeedIncrease(),
/*engine_force*/ 0.0f, /*engine_force*/ 0.0f,
/*duration*/0.1f, /*duration*/0.1f,
m_owner->getKartProperties()->getRubberBandFadeOutTime() * kp->getPlungerBandFadeOutTime());
m_owner->getPlayerDifficulty()->getRubberBandFadeOutTime());
if(m_attached_state==RB_TO_KART) if(m_attached_state==RB_TO_KART)
m_hit_kart->getBody()->applyCentralForce(diff*(-force)); m_hit_kart->getBody()->applyCentralForce(diff*(-force));
} }

View File

@ -157,7 +157,7 @@ bool Swatter::updateAndTestFinished(float dt)
(m_target->getXYZ()- Vec3(m_scene_node->getAbsolutePosition())) (m_target->getXYZ()- Vec3(m_scene_node->getAbsolutePosition()))
.length2(); .length2();
float min_dist2 float min_dist2
= m_kart->getKartProperties()->getSwatterDistance2(); = m_kart->getKartProperties()->getSwatterDistance();
if(dist_to_target2 < min_dist2) if(dist_to_target2 < min_dist2)
{ {
// Start squashing // Start squashing
@ -271,10 +271,10 @@ void Swatter::pointToTarget()
*/ */
bool Swatter::squashThingsAround() bool Swatter::squashThingsAround()
{ {
const KartProperties* kp = m_kart->getKartProperties(); const KartProperties *kp = m_kart->getKartProperties();
// Square of the minimum distance // Square of the minimum distance
float min_dist2 = kp->getSwatterDistance2(); float min_dist2 = kp->getSwatterDistance();
const World* world = World::getWorld(); const World* world = World::getWorld();
// Get the node corresponding to the joint at the center of the swatter // Get the node corresponding to the joint at the center of the swatter
// (by swatter, I mean the thing hold in the hand, not the whole thing) // (by swatter, I mean the thing hold in the hand, not the whole thing)
@ -287,7 +287,7 @@ bool Swatter::squashThingsAround()
bool target_is_hit = false; bool target_is_hit = false;
// Squash karts around // Squash karts around
for(unsigned int i=0; i<world->getNumKarts(); i++) for(unsigned int i = 0; i < world->getNumKarts(); i++)
{ {
AbstractKart *kart = world->getKart(i); AbstractKart *kart = world->getKart(i);
// TODO: isSwatterReady() // TODO: isSwatterReady()
@ -301,8 +301,7 @@ bool Swatter::squashThingsAround()
if(dist2 >= min_dist2) continue; // too far away, ignore this kart if(dist2 >= min_dist2) continue; // too far away, ignore this kart
kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(), kart->setSquash(kp->getSwatterSquashDuration(), kp->getSwatterSquashSlowdown());
kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown());
target_is_hit = true; target_is_hit = true;
//Handle achievement if the swatter is used by the current player //Handle achievement if the swatter is used by the current player

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,383 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// 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_ABSTRACT_CHARACTERISTICS_HPP
#define HEADER_ABSTRACT_CHARACTERISTICS_HPP
#include <string>
#include <vector>
class InterpolationArray;
/**
* Characteristics are the properties of a kart that influence
* gameplay mechanics.
* The biggest parts are:
* - Physics
* - Visuals
* - Items
* - and miscellaneous properties like nitro and startup boost.
*
* The documentation of these properties can be found in
* the kart_characteristics.xml file.
* Large parts of this file are generated by tools/create_kart_properties.py.
* Please don't change the generated code here, instead change the script,
* regenerate the code and overwrite the whole generated part with the result.
*/
class AbstractCharacteristic
{
public:
union Value
{
float *f;
bool *b;
std::vector<float> *fv;
InterpolationArray *ia;
Value(float *f) : f(f) {}
Value(bool *b) : b(b) {}
Value(std::vector<float> *fv) : fv(fv) {}
Value(InterpolationArray *ia) : ia(ia) {}
};
enum ValueType
{
TYPE_FLOAT,
TYPE_BOOL,
TYPE_FLOAT_VECTOR,
TYPE_INTERPOLATION_ARRAY
};
enum CharacteristicType
{
// Script-generated content generated by tools/create_kart_properties.py enum
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start enum> */
// Suspension
SUSPENSION_STIFFNESS,
SUSPENSION_REST,
SUSPENSION_TRAVEL,
SUSPENSION_EXP_SPRING_RESPONSE,
SUSPENSION_MAX_FORCE,
// Stability
STABILITY_ROLL_INFLUENCE,
STABILITY_CHASSIS_LINEAR_DAMPING,
STABILITY_CHASSIS_ANGULAR_DAMPING,
STABILITY_DOWNWARD_IMPULSE_FACTOR,
STABILITY_TRACK_CONNECTION_ACCEL,
STABILITY_SMOOTH_FLYING_IMPULSE,
// Turn
TURN_RADIUS,
TURN_TIME_RESET_STEER,
TURN_TIME_FULL_STEER,
// Engine
ENGINE_POWER,
ENGINE_MAX_SPEED,
ENGINE_BRAKE_FACTOR,
ENGINE_BRAKE_TIME_INCREASE,
ENGINE_MAX_SPEED_REVERSE_RATIO,
// Gear
GEAR_SWITCH_RATIO,
GEAR_POWER_INCREASE,
// Mass
MASS,
// Wheels
WHEELS_DAMPING_RELAXATION,
WHEELS_DAMPING_COMPRESSION,
// Camera
CAMERA_DISTANCE,
CAMERA_FORWARD_UP_ANGLE,
CAMERA_BACKWARD_UP_ANGLE,
// Jump
JUMP_ANIMATION_TIME,
// Lean
LEAN_MAX,
LEAN_SPEED,
// Anvil
ANVIL_DURATION,
ANVIL_WEIGHT,
ANVIL_SPEED_FACTOR,
// Parachute
PARACHUTE_FRICTION,
PARACHUTE_DURATION,
PARACHUTE_DURATION_OTHER,
PARACHUTE_LBOUND_FRACTION,
PARACHUTE_UBOUND_FRACTION,
PARACHUTE_MAX_SPEED,
// Bubblegum
BUBBLEGUM_DURATION,
BUBBLEGUM_SPEED_FRACTION,
BUBBLEGUM_TORQUE,
BUBBLEGUM_FADE_IN_TIME,
BUBBLEGUM_SHIELD_DURATION,
// Zipper
ZIPPER_DURATION,
ZIPPER_FORCE,
ZIPPER_SPEED_GAIN,
ZIPPER_MAX_SPEED_INCREASE,
ZIPPER_FADE_OUT_TIME,
// Swatter
SWATTER_DURATION,
SWATTER_DISTANCE,
SWATTER_SQUASH_DURATION,
SWATTER_SQUASH_SLOWDOWN,
// Plunger
PLUNGER_BAND_MAX_LENGTH,
PLUNGER_BAND_FORCE,
PLUNGER_BAND_DURATION,
PLUNGER_BAND_SPEED_INCREASE,
PLUNGER_BAND_FADE_OUT_TIME,
PLUNGER_IN_FACE_TIME,
// Startup
STARTUP_TIME,
STARTUP_BOOST,
// Rescue
RESCUE_DURATION,
RESCUE_VERT_OFFSET,
RESCUE_HEIGHT,
// Explosion
EXPLOSION_DURATION,
EXPLOSION_RADIUS,
EXPLOSION_INVULNERABILITY_TIME,
// Nitro
NITRO_DURATION,
NITRO_ENGINE_FORCE,
NITRO_CONSUMPTION,
NITRO_SMALL_CONTAINER,
NITRO_BIG_CONTAINER,
NITRO_MAX_SPEED_INCREASE,
NITRO_FADE_OUT_TIME,
NITRO_MAX,
// Slipstream
SLIPSTREAM_DURATION,
SLIPSTREAM_LENGTH,
SLIPSTREAM_WIDTH,
SLIPSTREAM_COLLECT_TIME,
SLIPSTREAM_USE_TIME,
SLIPSTREAM_ADD_POWER,
SLIPSTREAM_MIN_SPEED,
SLIPSTREAM_MAX_SPEED_INCREASE,
SLIPSTREAM_FADE_OUT_TIME,
// Skid
SKID_INCREASE,
SKID_DECREASE,
SKID_MAX,
SKID_TIME_TILL_MAX,
SKID_VISUAL,
SKID_VISUAL_TIME,
SKID_REVERT_VISUAL_TIME,
SKID_MIN_SPEED,
SKID_TIME_TILL_BONUS,
SKID_BONUS_SPEED,
SKID_BONUS_TIME,
SKID_BONUS_FORCE,
SKID_PHYSICAL_JUMP_TIME,
SKID_GRAPHICAL_JUMP_TIME,
SKID_POST_SKID_ROTATE_FACTOR,
SKID_REDUCE_TURN_MIN,
SKID_REDUCE_TURN_MAX,
SKID_ENABLED,
/* <characteristics-end enum> */
// Count
CHARACTERISTIC_COUNT
};
public:
AbstractCharacteristic();
virtual ~AbstractCharacteristic() {}
/**
* The process function is the core of this characteristics system.
* Any computation of the properties should happen here and modify the
* values of the value-pointer (be sure to use the right type!) and the
* is_set parameter when the value was set by the call (and wasn't set
* before).
*
* \param type The characteristic that should be modified.
* \param value The current value and result at the same time.
* \param is_set If the current value was already set (so it can be used
* for computations).
*/
virtual void process(CharacteristicType type, Value value, bool *is_set) const;
static ValueType getType(CharacteristicType type);
static std::string getName(CharacteristicType type);
// Script-generated content generated by tools/create_kart_properties.py defs
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start acdefs> */
float getSuspensionStiffness() const;
float getSuspensionRest() const;
float getSuspensionTravel() const;
bool getSuspensionExpSpringResponse() const;
float getSuspensionMaxForce() const;
float getStabilityRollInfluence() const;
float getStabilityChassisLinearDamping() const;
float getStabilityChassisAngularDamping() const;
float getStabilityDownwardImpulseFactor() const;
float getStabilityTrackConnectionAccel() const;
float getStabilitySmoothFlyingImpulse() const;
InterpolationArray getTurnRadius() const;
float getTurnTimeResetSteer() const;
InterpolationArray getTurnTimeFullSteer() const;
float getEnginePower() const;
float getEngineMaxSpeed() const;
float getEngineBrakeFactor() const;
float getEngineBrakeTimeIncrease() const;
float getEngineMaxSpeedReverseRatio() const;
std::vector<float> getGearSwitchRatio() const;
std::vector<float> getGearPowerIncrease() const;
float getMass() const;
float getWheelsDampingRelaxation() const;
float getWheelsDampingCompression() const;
float getCameraDistance() const;
float getCameraForwardUpAngle() const;
float getCameraBackwardUpAngle() const;
float getJumpAnimationTime() const;
float getLeanMax() const;
float getLeanSpeed() const;
float getAnvilDuration() const;
float getAnvilWeight() const;
float getAnvilSpeedFactor() const;
float getParachuteFriction() const;
float getParachuteDuration() const;
float getParachuteDurationOther() const;
float getParachuteLboundFraction() const;
float getParachuteUboundFraction() const;
float getParachuteMaxSpeed() const;
float getBubblegumDuration() const;
float getBubblegumSpeedFraction() const;
float getBubblegumTorque() const;
float getBubblegumFadeInTime() const;
float getBubblegumShieldDuration() const;
float getZipperDuration() const;
float getZipperForce() const;
float getZipperSpeedGain() const;
float getZipperMaxSpeedIncrease() const;
float getZipperFadeOutTime() const;
float getSwatterDuration() const;
float getSwatterDistance() const;
float getSwatterSquashDuration() const;
float getSwatterSquashSlowdown() const;
float getPlungerBandMaxLength() const;
float getPlungerBandForce() const;
float getPlungerBandDuration() const;
float getPlungerBandSpeedIncrease() const;
float getPlungerBandFadeOutTime() const;
float getPlungerInFaceTime() const;
std::vector<float> getStartupTime() const;
std::vector<float> getStartupBoost() const;
float getRescueDuration() const;
float getRescueVertOffset() const;
float getRescueHeight() const;
float getExplosionDuration() const;
float getExplosionRadius() const;
float getExplosionInvulnerabilityTime() const;
float getNitroDuration() const;
float getNitroEngineForce() const;
float getNitroConsumption() const;
float getNitroSmallContainer() const;
float getNitroBigContainer() const;
float getNitroMaxSpeedIncrease() const;
float getNitroFadeOutTime() const;
float getNitroMax() const;
float getSlipstreamDuration() const;
float getSlipstreamLength() const;
float getSlipstreamWidth() const;
float getSlipstreamCollectTime() const;
float getSlipstreamUseTime() const;
float getSlipstreamAddPower() const;
float getSlipstreamMinSpeed() const;
float getSlipstreamMaxSpeedIncrease() const;
float getSlipstreamFadeOutTime() const;
float getSkidIncrease() const;
float getSkidDecrease() const;
float getSkidMax() const;
float getSkidTimeTillMax() const;
float getSkidVisual() const;
float getSkidVisualTime() const;
float getSkidRevertVisualTime() const;
float getSkidMinSpeed() const;
std::vector<float> getSkidTimeTillBonus() const;
std::vector<float> getSkidBonusSpeed() const;
std::vector<float> getSkidBonusTime() const;
std::vector<float> getSkidBonusForce() const;
float getSkidPhysicalJumpTime() const;
float getSkidGraphicalJumpTime() const;
float getSkidPostSkidRotateFactor() const;
float getSkidReduceTurnMin() const;
float getSkidReduceTurnMax() const;
bool getSkidEnabled() const;
/* <characteristics-end acdefs> */
};
#endif

View File

@ -35,14 +35,15 @@
AbstractKart::AbstractKart(const std::string& ident, AbstractKart::AbstractKart(const std::string& ident,
int world_kart_id, int position, int world_kart_id, int position,
const btTransform& init_transform, const btTransform& init_transform,
const PlayerDifficulty *difficulty) PerPlayerDifficulty difficulty)
: Moveable() : Moveable()
{ {
m_world_kart_id = world_kart_id; m_world_kart_id = world_kart_id;
m_kart_properties = kart_properties_manager->getKart(ident); m_kart_properties.reset(new KartProperties());
m_kart_properties->copyForPlayer(kart_properties_manager->getKart(ident));
m_difficulty = difficulty; m_difficulty = difficulty;
m_kart_animation = NULL; m_kart_animation = NULL;
assert(m_kart_properties != NULL); assert(m_kart_properties);
// We have to take a copy of the kart model, since otherwise // We have to take a copy of the kart model, since otherwise
// the animations will be mixed up (i.e. different instances of // the animations will be mixed up (i.e. different instances of

View File

@ -19,10 +19,11 @@
#ifndef HEADER_ABSTRACT_KART_HPP #ifndef HEADER_ABSTRACT_KART_HPP
#define HEADER_ABSTRACT_KART_HPP #define HEADER_ABSTRACT_KART_HPP
#include <memory>
#include "items/powerup_manager.hpp" #include "items/powerup_manager.hpp"
#include "karts/moveable.hpp" #include "karts/moveable.hpp"
#include "karts/controller/kart_control.hpp" #include "karts/controller/kart_control.hpp"
#include "karts/player_difficulty.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
namespace irr namespace irr
@ -70,10 +71,10 @@ private:
protected: protected:
/** The kart properties. */ /** The kart properties. */
const KartProperties *m_kart_properties; std::unique_ptr<KartProperties> m_kart_properties;
/** The per-player difficulty. */ /** The per-player difficulty. */
const PlayerDifficulty *m_difficulty; PerPlayerDifficulty m_difficulty;
/** This stores a copy of the kart model. It has to be a copy /** This stores a copy of the kart model. It has to be a copy
* since otherwise incosistencies can happen if the same kart * since otherwise incosistencies can happen if the same kart
@ -95,7 +96,7 @@ public:
AbstractKart(const std::string& ident, AbstractKart(const std::string& ident,
int world_kart_id, int world_kart_id,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
const PlayerDifficulty *difficulty); PerPlayerDifficulty difficulty);
virtual ~AbstractKart(); virtual ~AbstractKart();
virtual core::stringw getName() const; virtual core::stringw getName() const;
virtual void reset(); virtual void reset();
@ -120,20 +121,17 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the kart properties of this kart. */ /** Returns the kart properties of this kart. */
const KartProperties* getKartProperties() const const KartProperties* getKartProperties() const
{ return m_kart_properties; } { return m_kart_properties.get(); }
// ------------------------------------------------------------------------
/** Sets the kart properties. */
void setKartProperties(const KartProperties *kp) { m_kart_properties=kp; }
// ======================================================================== // ========================================================================
// Access to the per-player difficulty. // Access to the per-player difficulty.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the per-player difficulty of this kart. */ /** Returns the per-player difficulty of this kart. */
const PlayerDifficulty* getPlayerDifficulty() const const PerPlayerDifficulty getPerPlayerDifficulty() const
{ return m_difficulty; } { return m_difficulty; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Sets the per-player difficulty. */ /** Sets the per-player difficulty. */
void setPlayerDifficulty(const PlayerDifficulty *pd) { m_difficulty=pd; } void setPerPlayerDifficulty(const PerPlayerDifficulty d) { m_difficulty=d; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a unique identifier for this kart (name of the directory the /** Returns a unique identifier for this kart (name of the directory the
@ -144,6 +142,10 @@ public:
* speed. */ * speed. */
virtual float getMaxSteerAngle () const = 0; virtual float getMaxSteerAngle () const = 0;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the (maximum) speed for a given turn radius.
* \param radius The radius for which the speed needs to be computed. */
virtual float getSpeedForTurnRadius(float radius) const = 0;
// ------------------------------------------------------------------------
/** Returns the time till full steering is reached for this kart. /** Returns the time till full steering is reached for this kart.
* This can depend on the current steering value, which must be >= 0. * This can depend on the current steering value, which must be >= 0.
*/ */

View File

@ -0,0 +1,203 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "karts/cached_characteristic.hpp"
#include "utils/interpolation_array.hpp"
CachedCharacteristic::CachedCharacteristic(const AbstractCharacteristic *origin) :
m_values(CHARACTERISTIC_COUNT),
m_origin(origin)
{
updateSource();
}
// ----------------------------------------------------------------------------
/** Deletes all allocated values. */
CachedCharacteristic::~CachedCharacteristic()
{
// Delete all not-null values
for (int i = 0; i < CHARACTERISTIC_COUNT; i++)
{
SaveValue &v = m_values[i];
if (v.content)
{
switch (getType(static_cast<CharacteristicType>(i)))
{
case TYPE_FLOAT:
delete static_cast<float*>(v.content);
break;
case TYPE_FLOAT_VECTOR:
delete static_cast<std::vector<float>*>(v.content);
break;
case TYPE_INTERPOLATION_ARRAY:
delete static_cast<InterpolationArray*>(v.content);
break;
case TYPE_BOOL:
delete static_cast<bool*>(v.content);
break;
}
v.content = nullptr;
}
}
} // ~CachedCharacteristic
// ----------------------------------------------------------------------------
/** Recompute the values of all characteristics based on the list of
* source-characteristics.
*/
void CachedCharacteristic::updateSource()
{
for (int i = 0; i < CHARACTERISTIC_COUNT; i++)
{
SaveValue &v = m_values[i];
bool is_set = false;
switch (getType(static_cast<CharacteristicType>(i)))
{
case TYPE_FLOAT:
{
float value;
float *ptr = static_cast<float*>(v.content);
m_origin->process(static_cast<CharacteristicType>(i), &value, &is_set);
if (is_set)
{
if (!ptr)
{
float *newPtr = new float();
v.content = newPtr;
ptr = newPtr;
}
*ptr = value;
}
else
{
if (ptr)
{
delete ptr;
v.content = nullptr;
}
}
break;
}
case TYPE_FLOAT_VECTOR:
{
std::vector<float> value;
std::vector<float> *ptr = static_cast<std::vector<float>*>(v.content);
m_origin->process(static_cast<CharacteristicType>(i), &value, &is_set);
if (is_set)
{
if (!ptr)
{
std::vector<float> *newPtr = new std::vector<float>();
v.content = newPtr;
ptr = newPtr;
}
*ptr = value;
}
else
{
if (ptr)
{
delete ptr;
v.content = nullptr;
}
}
break;
}
case TYPE_INTERPOLATION_ARRAY:
{
InterpolationArray value;
InterpolationArray *ptr = static_cast<InterpolationArray*>(v.content);
m_origin->process(static_cast<CharacteristicType>(i), &value, &is_set);
if (is_set)
{
if (!ptr)
{
InterpolationArray *newPtr = new InterpolationArray();
v.content = newPtr;
ptr = newPtr;
}
*ptr = value;
}
else
{
if (ptr)
{
delete ptr;
v.content = nullptr;
}
}
break;
}
case TYPE_BOOL:
{
bool value;
bool *ptr = static_cast<bool*>(v.content);
m_origin->process(static_cast<CharacteristicType>(i), &value, &is_set);
if (is_set)
{
if (!ptr)
{
bool *newPtr = new bool();
v.content = newPtr;
ptr = newPtr;
}
*ptr = value;
}
else
{
if (ptr)
{
delete ptr;
v.content = nullptr;
}
}
break;
}
} // switch (type)
} // foreach characteristic
} // updateSource
// ----------------------------------------------------------------------------
/** Returns the stored value. */
void CachedCharacteristic::process(CharacteristicType type, Value value,
bool *is_set) const
{
void *v = m_values[type].content;
if (v)
{
switch (getType(type))
{
case TYPE_FLOAT:
*value.f = *static_cast<float*>(v);
break;
case TYPE_FLOAT_VECTOR:
*value.fv = *static_cast<std::vector<float>*>(v);
break;
case TYPE_INTERPOLATION_ARRAY:
*value.ia = *static_cast<InterpolationArray*>(v);
break;
case TYPE_BOOL:
*value.b = *static_cast<bool*>(v);
break;
}
*is_set = true;
}
} // process

View File

@ -0,0 +1,54 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// 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_CACHED_CHARACTERISTICS_HPP
#define HEADER_CACHED_CHARACTERISTICS_HPP
#include "karts/abstract_characteristic.hpp"
class CachedCharacteristic : public AbstractCharacteristic
{
private:
/** Used to store a value. */
struct SaveValue
{
void *content;
SaveValue() : content(nullptr) {}
SaveValue(void *content) : content(content) {}
};
/** All values for a characteristic. A nullptr means it is not set. */
std::vector<SaveValue> m_values;
/** The characteristics that hold the original values. */
const AbstractCharacteristic *m_origin;
public:
CachedCharacteristic(const AbstractCharacteristic *origin);
CachedCharacteristic(const CachedCharacteristic &characteristics) = delete;
virtual ~CachedCharacteristic();
/** Fetches all cached values from the original source. */
void updateSource();
virtual void process(CharacteristicType type, Value value, bool *is_set) const;
};
#endif

View File

@ -69,7 +69,7 @@ CannonAnimation::~CannonAnimation()
m_kart->getHeading() )); m_kart->getHeading() ));
m_kart->getBody()->setCenterOfMassTransform(pos); m_kart->getBody()->setCenterOfMassTransform(pos);
Vec3 v(0, 0, m_kart->getKartProperties()->getMaxSpeed()); Vec3 v(0, 0, m_kart->getKartProperties()->getEngineMaxSpeed());
m_kart->setVelocity(pos.getBasis()*v); m_kart->setVelocity(pos.getBasis()*v);
} // ~CannonAnimation } // ~CannonAnimation

View File

@ -0,0 +1,35 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "karts/combined_characteristic.hpp"
void CombinedCharacteristic::addCharacteristic(
const AbstractCharacteristic *characteristic)
{
m_childs.push_back(characteristic);
} // addCharacteristic
// ----------------------------------------------------------------------------
/** Combines all contained source characteristics. */
void CombinedCharacteristic::process(CharacteristicType type, Value value,
bool *is_set) const
{
for (const AbstractCharacteristic *characteristic : m_childs)
characteristic->process(type, value, is_set);
} // process

View File

@ -0,0 +1,36 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// 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_COMBINDED_CHARACTERISTICS_HPP
#define HEADER_COMBINDED_CHARACTERISTICS_HPP
#include "karts/abstract_characteristic.hpp"
class CombinedCharacteristic : public AbstractCharacteristic
{
private:
std::vector<const AbstractCharacteristic*> m_childs;
public:
void addCharacteristic(const AbstractCharacteristic *characteristic);
virtual void process(CharacteristicType type, Value value, bool *is_set) const;
};
#endif

View File

@ -22,7 +22,6 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/skidding_properties.hpp"
#include "karts/controller/ai_properties.hpp" #include "karts/controller/ai_properties.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
@ -241,8 +240,7 @@ bool AIBaseController::doSkid(float steer_fraction)
// FIXME: Disable skidding for now if the new skidding // FIXME: Disable skidding for now if the new skidding
// code is activated, since the AI can not handle this // code is activated, since the AI can not handle this
// properly. // properly.
if(m_kart->getKartProperties()->getSkiddingProperties() if(m_kart->getKartProperties()->getSkidVisualTime() > 0)
->getSkidVisualTime()>0)
return false; return false;
// Otherwise return if we need a sharp turn (which is // Otherwise return if we need a sharp turn (which is

View File

@ -197,7 +197,7 @@ void NetworkPlayerController::steer(float dt, int steer_val)
// change speed is used. // change speed is used.
const float STEER_CHANGE = ( (steer_val<=0 && m_controls->m_steer<0) || const float STEER_CHANGE = ( (steer_val<=0 && m_controls->m_steer<0) ||
(steer_val>=0 && m_controls->m_steer>0) ) (steer_val>=0 && m_controls->m_steer>0) )
? dt/m_kart->getKartProperties()->getTimeResetSteer() ? dt/m_kart->getKartProperties()->getTurnTimeResetSteer()
: dt/m_kart->getTimeFullSteer(fabsf(m_controls->m_steer)); : dt/m_kart->getTimeFullSteer(fabsf(m_controls->m_steer));
if (steer_val < 0) if (steer_val < 0)
{ {

View File

@ -256,7 +256,7 @@ void PlayerController::steer(float dt, int steer_val)
// change speed is used. // change speed is used.
const float STEER_CHANGE = ( (steer_val<=0 && m_controls->m_steer<0) || const float STEER_CHANGE = ( (steer_val<=0 && m_controls->m_steer<0) ||
(steer_val>=0 && m_controls->m_steer>0) ) (steer_val>=0 && m_controls->m_steer>0) )
? dt/m_kart->getKartProperties()->getTimeResetSteer() ? dt/m_kart->getKartProperties()->getTurnTimeResetSteer()
: dt/m_kart->getTimeFullSteer(fabsf(m_controls->m_steer)); : dt/m_kart->getTimeFullSteer(fabsf(m_controls->m_steer));
if (steer_val < 0) if (steer_val < 0)
{ {

View File

@ -38,7 +38,6 @@
#include "karts/max_speed.hpp" #include "karts/max_speed.hpp"
#include "karts/rescue_animation.hpp" #include "karts/rescue_animation.hpp"
#include "karts/skidding.hpp" #include "karts/skidding.hpp"
#include "karts/skidding_properties.hpp"
#include "modes/linear_world.hpp" #include "modes/linear_world.hpp"
#include "modes/profile_world.hpp" #include "modes/profile_world.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
@ -430,8 +429,7 @@ void SkiddingAI::handleBraking()
m_current_track_direction==GraphNode::DIR_RIGHT ) m_current_track_direction==GraphNode::DIR_RIGHT )
{ {
float max_turn_speed = float max_turn_speed =
m_kart->getKartProperties() m_kart->getSpeedForTurnRadius(m_current_curve_radius);
->getSpeedForTurnRadius(m_current_curve_radius);
if(m_kart->getSpeed() > 1.5f*max_turn_speed && if(m_kart->getSpeed() > 1.5f*max_turn_speed &&
m_kart->getSpeed()>MIN_SPEED && m_kart->getSpeed()>MIN_SPEED &&
@ -1032,6 +1030,8 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle,
std::vector<const Item *> *items_to_avoid, std::vector<const Item *> *items_to_avoid,
std::vector<const Item *> *items_to_collect) std::vector<const Item *> *items_to_collect)
{ {
const KartProperties *kp = m_kart->getKartProperties();
// Ignore items that are currently disabled // Ignore items that are currently disabled
if(item->getDisableTime()>0) return; if(item->getDisableTime()>0) return;
@ -1052,18 +1052,16 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle,
// Positive items: try to collect // Positive items: try to collect
case Item::ITEM_NITRO_BIG: case Item::ITEM_NITRO_BIG:
// Only collect nitro, if it can actually be stored. // Only collect nitro, if it can actually be stored.
if(m_kart->getEnergy() + if (m_kart->getEnergy() + kp->getNitroBigContainer()
m_kart->getKartProperties()->getNitroBigContainer() > kp->getNitroMax())
> m_kart->getKartProperties()->getNitroMax())
return; return;
// fall through: if we have enough space to store a big // fall through: if we have enough space to store a big
// container, we can also store a small container, and // container, we can also store a small container, and
// finally fall through to the bonus box code. // finally fall through to the bonus box code.
case Item::ITEM_NITRO_SMALL: avoid = false; case Item::ITEM_NITRO_SMALL: avoid = false;
// Only collect nitro, if it can actually be stored. // Only collect nitro, if it can actually be stored.
if (m_kart->getEnergy() + if (m_kart->getEnergy() + kp->getNitroSmallContainer()
m_kart->getKartProperties()->getNitroSmallContainer() > kp->getNitroMax())
> m_kart->getKartProperties()->getNitroMax())
return; return;
case Item::ITEM_BONUS_BOX: case Item::ITEM_BONUS_BOX:
break; break;
@ -1093,7 +1091,7 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle,
// be if the kart would need to turn sharper, therefore stops // be if the kart would need to turn sharper, therefore stops
// skidding, and will get the bonus speed. // skidding, and will get the bonus speed.
bool high_speed = (m_kart->getCurrentMaxSpeed() > bool high_speed = (m_kart->getCurrentMaxSpeed() >
m_kart->getKartProperties()->getMaxSpeed() ) || kp->getEngineMaxSpeed() ) ||
m_kart->getSkidding()->getSkidBonusReady(); m_kart->getSkidding()->getSkidBonusReady();
float max_angle = high_speed float max_angle = high_speed
? m_ai_properties->m_max_item_angle_high_speed ? m_ai_properties->m_max_item_angle_high_speed
@ -1355,13 +1353,13 @@ void SkiddingAI::handleItems(const float dt)
case PowerupManager::POWERUP_PARACHUTE: case PowerupManager::POWERUP_PARACHUTE:
// Wait one second more than a previous parachute // Wait one second more than a previous parachute
if(m_time_since_last_shot > stk_config->m_parachute_time_other+1.0f) if(m_time_since_last_shot > m_kart->getKartProperties()->getParachuteDurationOther() + 1.0f)
m_controls->m_fire = true; m_controls->m_fire = true;
break; // POWERUP_PARACHUTE break; // POWERUP_PARACHUTE
case PowerupManager::POWERUP_ANVIL: case PowerupManager::POWERUP_ANVIL:
// Wait one second more than a previous anvil // Wait one second more than a previous anvil
if(m_time_since_last_shot < stk_config->m_anvil_time+1.0f) break; if(m_time_since_last_shot < m_kart->getKartProperties()->getAnvilDuration() + 1.0f) break;
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER) if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER)
{ {
@ -1378,7 +1376,7 @@ void SkiddingAI::handleItems(const float dt)
case PowerupManager::POWERUP_SWATTER: case PowerupManager::POWERUP_SWATTER:
{ {
// Squared distance for which the swatter works // Squared distance for which the swatter works
float d2 = m_kart->getKartProperties()->getSwatterDistance2(); float d2 = m_kart->getKartProperties()->getSwatterDistance();
// if the kart has a shield, do not break it by using a swatter. // if the kart has a shield, do not break it by using a swatter.
if(m_kart->getShieldTime() > min_bubble_time) if(m_kart->getShieldTime() > min_bubble_time)
break; break;
@ -2260,7 +2258,6 @@ bool SkiddingAI::doSkid(float steer_fraction)
// the actual path is adjusted during the turn. So apply an // the actual path is adjusted during the turn. So apply an
// experimentally found factor in to get better estimates. // experimentally found factor in to get better estimates.
duration *= 1.5f; duration *= 1.5f;
const Skidding *skidding = m_kart->getSkidding();
// If the remaining estimated time for skidding is too short, stop // If the remaining estimated time for skidding is too short, stop
// it. This code will mostly trigger the bonus at the end of a skid. // it. This code will mostly trigger the bonus at the end of a skid.
@ -2289,8 +2286,8 @@ bool SkiddingAI::doSkid(float steer_fraction)
return false; return false;
} }
// If there is a skidding bonus, try to get it. // If there is a skidding bonus, try to get it.
else if(skidding->getNumberOfBonusTimes()>0 && else if (m_kart->getKartProperties()->getSkidBonusSpeed().size() > 0 &&
skidding->getTimeTillBonus(0) < duration) m_kart->getKartProperties()->getSkidTimeTillBonus()[0] < duration)
{ {
#ifdef DEBUG #ifdef DEBUG
if(!m_controls->m_skid && m_ai_debug) if(!m_controls->m_skid && m_ai_debug)

View File

@ -78,8 +78,7 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
m_xyz = m_kart->getXYZ(); m_xyz = m_kart->getXYZ();
m_orig_y = m_xyz.getY(); m_orig_y = m_xyz.getY();
m_kart->playCustomSFX(SFXManager::CUSTOM_EXPLODE); m_kart->playCustomSFX(SFXManager::CUSTOM_EXPLODE);
m_timer = m_kart->getKartProperties()->getExplosionTime() * m_timer = m_kart->getKartProperties()->getExplosionDuration();
m_kart->getPlayerDifficulty()->getExplosionTime();
// Non-direct hits will be only affected half as much. // Non-direct hits will be only affected half as much.
if(!direct_hit) m_timer*=0.5f; if(!direct_hit) m_timer*=0.5f;
@ -106,8 +105,7 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f ); m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f );
// Set invulnerable time, and graphical effects // Set invulnerable time, and graphical effects
float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime() * float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime();
m_kart->getPlayerDifficulty()->getExplosionInvulnerabilityTime();
m_kart->setInvulnerableTime(t); m_kart->setInvulnerableTime(t);
m_kart->showStarEffect(t); m_kart->showStarEffect(t);

View File

@ -24,8 +24,7 @@
GhostKart::GhostKart(const std::string& ident) GhostKart::GhostKart(const std::string& ident)
: Kart(ident, /*world kart id*/99999, : Kart(ident, /*world kart id*/99999,
/*position*/-1, btTransform(), stk_config->getPlayerDifficulty( /*position*/-1, btTransform(), PLAYER_DIFFICULTY_NORMAL)
PLAYER_DIFFICULTY_NORMAL))
{ {
m_current_transform = 0; m_current_transform = 0;
m_next_event = 0; m_next_event = 0;

View File

@ -38,6 +38,8 @@
#include "graphics/stk_text_billboard.hpp" #include "graphics/stk_text_billboard.hpp"
#include "graphics/stars.hpp" #include "graphics/stars.hpp"
#include "guiengine/scalable_font.hpp" #include "guiengine/scalable_font.hpp"
#include "karts/abstract_characteristic.hpp"
#include "karts/cached_characteristic.hpp"
#include "karts/explosion_animation.hpp" #include "karts/explosion_animation.hpp"
#include "karts/kart_gfx.hpp" #include "karts/kart_gfx.hpp"
#include "karts/rescue_animation.hpp" #include "karts/rescue_animation.hpp"
@ -95,7 +97,7 @@
*/ */
Kart::Kart (const std::string& ident, unsigned int world_kart_id, Kart::Kart (const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
const PlayerDifficulty *difficulty) PerPlayerDifficulty difficulty)
: AbstractKart(ident, world_kart_id, position, init_transform, : AbstractKart(ident, world_kart_id, position, init_transform,
difficulty) difficulty)
@ -223,8 +225,7 @@ void Kart::init(RaceManager::KartType type)
loadData(type, animations); loadData(type, animations);
m_kart_gfx = new KartGFX(this); m_kart_gfx = new KartGFX(this);
m_skidding = new Skidding(this, m_skidding = new Skidding(this);
m_kart_properties->getSkiddingProperties());
// Create the stars effect // Create the stars effect
m_stars_effect = m_stars_effect =
new Stars(getNode(), new Stars(getNode(),
@ -363,8 +364,8 @@ void Kart::reset()
// 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)
m_body->setDamping(m_kart_properties->getChassisLinearDamping(), m_body->setDamping(m_kart_properties->getStabilityChassisLinearDamping(),
m_kart_properties->getChassisAngularDamping() ); m_kart_properties->getStabilityChassisAngularDamping());
if(m_terrain_sound) if(m_terrain_sound)
{ {
@ -521,8 +522,7 @@ void Kart::blockViewWithPlunger()
{ {
// Avoid that a plunger extends the plunger time // Avoid that a plunger extends the plunger time
if(m_view_blocked_by_plunger<=0 && !isShielded()) if(m_view_blocked_by_plunger<=0 && !isShielded())
m_view_blocked_by_plunger = m_view_blocked_by_plunger = m_kart_properties->getPlungerInFaceTime();
m_kart_properties->getPlungerInFaceTime() * m_difficulty->getPlungerInFaceTime();
if(isShielded()) if(isShielded())
{ {
decreaseShieldTime(); decreaseShieldTime();
@ -553,6 +553,12 @@ btTransform Kart::getAlignedTransform(const float custom_pitch)
return trans; return trans;
} // getAlignedTransform } // getAlignedTransform
// ----------------------------------------------------------------------------
float Kart::getTimeFullSteer(float steer) const
{
return m_kart_properties->getTurnTimeFullSteer().get(steer);
} // getTimeFullSteer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Creates the physical representation of this kart. Atm it uses the actual /** Creates the physical representation of this kart. Atm it uses the actual
* extention of the kart model to determine the size of the collision body. * extention of the kart model to determine the size of the collision body.
@ -595,7 +601,7 @@ void Kart::createPhysics()
if (y == -1) if (y == -1)
{ {
int index = (x + 1) / 2 + 1 - z; // get index of wheel int index = (x + 1) / 2 + 1 - z; // get index of wheel
float f = getKartProperties()->getPhysicalWheelPosition(); float f = m_kart_properties->getPhysicalWheelPosition();
// f < 0 indicates to use the old physics position, i.e. // f < 0 indicates to use the old physics position, i.e.
// to place the wheels outside of the chassis // to place the wheels outside of the chassis
if(f<0) if(f<0)
@ -642,8 +648,8 @@ void Kart::createPhysics()
createBody(mass, trans, &m_kart_chassis, createBody(mass, trans, &m_kart_chassis,
m_kart_properties->getRestitution()); m_kart_properties->getRestitution());
m_user_pointer.set(this); m_user_pointer.set(this);
m_body->setDamping(m_kart_properties->getChassisLinearDamping(), m_body->setDamping(m_kart_properties->getStabilityChassisLinearDamping(),
m_kart_properties->getChassisAngularDamping() ); m_kart_properties->getStabilityChassisAngularDamping() );
// Reset velocities // Reset velocities
// ---------------- // ----------------
@ -672,9 +678,9 @@ void Kart::createPhysics()
tuning.m_maxSuspensionTravel = tuning.m_maxSuspensionTravel =
m_kart_properties->getSuspensionTravel(); m_kart_properties->getSuspensionTravel();
tuning.m_maxSuspensionForce = tuning.m_maxSuspensionForce =
m_kart_properties->getMaxSuspensionForce(); m_kart_properties->getSuspensionMaxForce();
const Vec3 &cs = getKartProperties()->getGravityCenterShift(); const Vec3 &cs = m_kart_properties->getGravityCenterShift();
for(unsigned int i=0; i<4; i++) for(unsigned int i=0; i<4; i++)
{ {
bool is_front_wheel = i<2; bool is_front_wheel = i<2;
@ -684,10 +690,10 @@ void Kart::createPhysics()
m_kart_model->getWheelGraphicsRadius(i), m_kart_model->getWheelGraphicsRadius(i),
tuning, is_front_wheel); tuning, is_front_wheel);
wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness(); wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness();
wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelDampingRelaxation(); wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelsDampingRelaxation();
wheel.m_wheelsDampingCompression = m_kart_properties->getWheelDampingCompression(); wheel.m_wheelsDampingCompression = m_kart_properties->getWheelsDampingCompression();
wheel.m_frictionSlip = m_kart_properties->getFrictionSlip(); wheel.m_frictionSlip = m_kart_properties->getFrictionSlip();
wheel.m_rollInfluence = m_kart_properties->getRollInfluence(); wheel.m_rollInfluence = m_kart_properties->getStabilityRollInfluence();
} }
// Obviously these allocs have to be properly managed/freed // Obviously these allocs have to be properly managed/freed
btTransform t; btTransform t;
@ -780,6 +786,34 @@ void Kart::updateWeight()
m_body->setMassProps(mass, inertia); m_body->setMassProps(mass, inertia);
} // updateWeight } // updateWeight
// ------------------------------------------------------------------------
/** Returns the (maximum) speed for a given turn radius.
* \param radius The radius for which the speed needs to be computed. */
float Kart::getSpeedForTurnRadius(float radius) const
{
InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius();
// Convert the turn radius into turn angle
for(std::size_t i = 0; i < turn_angle_at_speed.size(); i++)
turn_angle_at_speed.setY(i, sin(m_kart_properties->getWheelBase() /
turn_angle_at_speed.getY(i)));
float angle = sin(m_kart_properties->getWheelBase() / radius);
return turn_angle_at_speed.getReverse(angle);
} // getSpeedForTurnRadius
// ------------------------------------------------------------------------
/** Returns the maximum steering angle (depending on speed). */
float Kart::getMaxSteerAngle(float speed) const
{
InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius();
// Convert the turn radius into turn angle
for(std::size_t i = 0; i < turn_angle_at_speed.size(); i++)
turn_angle_at_speed.setY(i, sin(m_kart_properties->getWheelBase() /
turn_angle_at_speed.getY(i)));
return turn_angle_at_speed.get(speed);
} // getMaxSteerAngle
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Sets that this kart has finished the race and finishing time. It also /** Sets that this kart has finished the race and finishing time. It also
* notifies the race_manager about the race completion for this kart. * notifies the race_manager about the race completion for this kart.
@ -902,16 +936,13 @@ void Kart::collectedItem(Item *item, int add_info)
item->getEmitter()->getIdent() == "nolok"); item->getEmitter()->getIdent() == "nolok");
// slow down // slow down
m_bubblegum_time = m_kart_properties->getBubblegumTime() * m_difficulty->getBubblegumTime(); m_bubblegum_time = m_kart_properties->getBubblegumDuration();
m_bubblegum_torque = ((rand()%2) m_bubblegum_torque = ((rand()%2)
? m_kart_properties->getBubblegumTorque() ? m_kart_properties->getBubblegumTorque()
: -m_kart_properties->getBubblegumTorque()) * : -m_kart_properties->getBubblegumTorque());
m_difficulty->getBubblegumTorque();
m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_BUBBLE, m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_BUBBLE,
m_kart_properties->getBubblegumSpeedFraction() * m_kart_properties->getBubblegumSpeedFraction() ,
m_difficulty->getBubblegumSpeedFraction(), m_kart_properties->getBubblegumFadeInTime(),
m_kart_properties->getBubblegumFadeInTime() *
m_difficulty->getBubblegumFadeInTime(),
m_bubblegum_time); m_bubblegum_time);
m_goo_sound->setPosition(getXYZ()); m_goo_sound->setPosition(getXYZ());
m_goo_sound->play(); m_goo_sound->play();
@ -927,6 +958,25 @@ void Kart::collectedItem(Item *item, int add_info)
} // collectedItem } // collectedItem
//-----------------------------------------------------------------------------
/** Called the first time a kart accelerates after 'ready-set-go'. It searches
* through the startup times to find the appropriate slot, and returns the
* speed-boost from the corresponding entry.
* If the kart started too slow (i.e. slower than the longest time in the
* startup times list), it returns 0.
*/
float Kart::getStartupBoost() const
{
float t = World::getWorld()->getTime();
std::vector<float> startup_times = m_kart_properties->getStartupTime();
for (unsigned int i = 0; i < startup_times.size(); i++)
{
if (t <= startup_times[i])
return m_kart_properties->getStartupBoost()[i];
}
return 0;
} // getStartupBoost
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Simulates gears by adjusting the force of the engine. It also takes the /** Simulates gears by adjusting the force of the engine. It also takes the
* effect of the zipper into account. * effect of the zipper into account.
@ -938,21 +988,17 @@ float Kart::getActualWheelForce()
const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio(); const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio();
for(unsigned int i=0; i<gear_ratio.size(); i++) for(unsigned int i=0; i<gear_ratio.size(); i++)
{ {
if(m_speed <= m_kart_properties->getMaxSpeed() * if(m_speed <= m_kart_properties->getEngineMaxSpeed() * gear_ratio[i])
m_difficulty->getMaxSpeed() * gear_ratio[i])
{ {
assert(!isnan(m_kart_properties->getMaxPower() * assert(!isnan(m_kart_properties->getEnginePower()));
m_difficulty->getMaxPower()));
assert(!isnan(m_kart_properties->getGearPowerIncrease()[i])); assert(!isnan(m_kart_properties->getGearPowerIncrease()[i]));
return m_kart_properties->getMaxPower() * return m_kart_properties->getEnginePower()
m_difficulty->getMaxPower() * m_kart_properties->getGearPowerIncrease()[i]
*m_kart_properties->getGearPowerIncrease()[i] + add_force;
+add_force;
} }
} }
assert(!isnan(m_kart_properties->getMaxPower() * m_difficulty->getMaxPower())); assert(!isnan(m_kart_properties->getEnginePower()));
return m_kart_properties->getMaxPower() * m_difficulty->getMaxPower() return m_kart_properties->getEnginePower() + add_force * 2;
+add_force * 2;
} // getActualWheelForce } // getActualWheelForce
@ -1149,12 +1195,12 @@ void Kart::update(float dt)
// When the kart is jumping, linear damping reduces the falling speed // When the kart is jumping, linear damping reduces the falling speed
// of a kart so much that it can appear to be in slow motion. So // of a kart so much that it can appear to be in slow motion. So
// disable linear damping if a kart is in the air // disable linear damping if a kart is in the air
m_body->setDamping(0, m_kart_properties->getChassisAngularDamping()); m_body->setDamping(0, m_kart_properties->getStabilityChassisAngularDamping());
} }
else else
{ {
m_body->setDamping(m_kart_properties->getChassisLinearDamping(), m_body->setDamping(m_kart_properties->getStabilityChassisLinearDamping(),
m_kart_properties->getChassisAngularDamping()); m_kart_properties->getStabilityChassisAngularDamping());
} }
if(m_kart_animation) if(m_kart_animation)
@ -1322,7 +1368,7 @@ void Kart::update(float dt)
static video::SColor green(255, 61, 87, 23); static video::SColor green(255, 61, 87, 23);
// draw skidmarks if relevant (we force pink skidmarks on when hitting a bubblegum) // draw skidmarks if relevant (we force pink skidmarks on when hitting a bubblegum)
if(m_kart_properties->getSkiddingProperties()->hasSkidmarks()) if(m_kart_properties->getSkidEnabled())
{ {
m_skidmarks->update(dt, m_skidmarks->update(dt,
m_bubblegum_time > 0, m_bubblegum_time > 0,
@ -1365,7 +1411,7 @@ void Kart::update(float dt)
// Jump if either the jump is estimated to be long enough, or // Jump if either the jump is estimated to be long enough, or
// the texture has the jump property set. // the texture has the jump property set.
if (t > getKartProperties()->getJumpAnimationTime() || if (t > m_kart_properties->getJumpAnimationTime() ||
last_m->isJumpTexture()) last_m->isJumpTexture())
{ {
m_kart_model->setAnimation(KartModel::AF_JUMP_START); m_kart_model->setAnimation(KartModel::AF_JUMP_START);
@ -1660,33 +1706,23 @@ void Kart::handleZipper(const Material *material, bool play_sound)
material->getZipperParameter(&max_speed_increase, &duration, material->getZipperParameter(&max_speed_increase, &duration,
&speed_gain, &fade_out_time, &engine_force); &speed_gain, &fade_out_time, &engine_force);
if(max_speed_increase<0) if(max_speed_increase<0)
max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease() * max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease();
m_difficulty->getZipperMaxSpeedIncrease();
if(duration<0) if(duration<0)
duration = m_kart_properties->getZipperTime() * duration = m_kart_properties->getZipperDuration();
m_difficulty->getZipperTime();
if(speed_gain<0) if(speed_gain<0)
speed_gain = m_kart_properties->getZipperSpeedGain() * speed_gain = m_kart_properties->getZipperSpeedGain();
m_difficulty->getZipperSpeedGain();
if(fade_out_time<0) if(fade_out_time<0)
fade_out_time = m_kart_properties->getZipperFadeOutTime() * fade_out_time = m_kart_properties->getZipperFadeOutTime();
m_difficulty->getZipperFadeOutTime();
if(engine_force<0) if(engine_force<0)
engine_force = m_kart_properties->getZipperForce() * engine_force = m_kart_properties->getZipperForce();
m_difficulty->getZipperForce();
} }
else else
{ {
max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease() * max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease();
m_difficulty->getZipperMaxSpeedIncrease(); duration = m_kart_properties->getZipperDuration();
duration = m_kart_properties->getZipperTime() * speed_gain = m_kart_properties->getZipperSpeedGain();
m_difficulty->getZipperTime(); fade_out_time = m_kart_properties->getZipperFadeOutTime();
speed_gain = m_kart_properties->getZipperSpeedGain() * engine_force = m_kart_properties->getZipperForce();
m_difficulty->getZipperSpeedGain();
fade_out_time = m_kart_properties->getZipperFadeOutTime() *
m_difficulty->getZipperFadeOutTime();
engine_force = m_kart_properties->getZipperForce() *
m_difficulty->getZipperForce();
} }
// Ignore a zipper that's activated while braking // Ignore a zipper that's activated while braking
if(m_controls.m_brake || m_speed<0) return; if(m_controls.m_brake || m_speed<0) return;
@ -1727,8 +1763,7 @@ void Kart::updateNitro(float dt)
return; return;
} }
m_collected_energy -= dt * m_kart_properties->getNitroConsumption() * m_collected_energy -= dt * m_kart_properties->getNitroConsumption();
m_difficulty->getNitroConsumption();
if (m_collected_energy < 0) if (m_collected_energy < 0)
{ {
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING) if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
@ -1742,14 +1777,10 @@ void Kart::updateNitro(float dt)
if(m_nitro_sound->getStatus() != SFXBase::SFX_PLAYING) if(m_nitro_sound->getStatus() != SFXBase::SFX_PLAYING)
m_nitro_sound->play(); m_nitro_sound->play();
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO, m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
m_kart_properties->getNitroMaxSpeedIncrease() * m_kart_properties->getNitroMaxSpeedIncrease(),
m_difficulty->getNitroMaxSpeedIncrease(), m_kart_properties->getNitroEngineForce(),
m_kart_properties->getNitroEngineForce() * m_kart_properties->getNitroDuration(),
m_difficulty->getNitroEngineForce(), m_kart_properties->getNitroFadeOutTime());
m_kart_properties->getNitroDuration() *
m_difficulty->getNitroDuration(),
m_kart_properties->getNitroFadeOutTime() *
m_difficulty->getNitroFadeOutTime());
} }
else else
{ {
@ -1808,7 +1839,7 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
#endif #endif
const LinearWorld *lw = dynamic_cast<LinearWorld*>(World::getWorld()); const LinearWorld *lw = dynamic_cast<LinearWorld*>(World::getWorld());
if(getKartProperties()->getTerrainImpulseType() if(m_kart_properties->getTerrainImpulseType()
==KartProperties::IMPULSE_NORMAL && ==KartProperties::IMPULSE_NORMAL &&
m_vehicle->getCentralImpulseTime()<=0 ) m_vehicle->getCentralImpulseTime()<=0 )
{ {
@ -1835,7 +1866,7 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
// graph node center (we have to use the previous point since the // graph node center (we have to use the previous point since the
// kart might have only now reached the new quad, meaning the kart // kart might have only now reached the new quad, meaning the kart
// would be pushed forward). // would be pushed forward).
else if(getKartProperties()->getTerrainImpulseType() else if(m_kart_properties->getTerrainImpulseType()
==KartProperties::IMPULSE_TO_DRIVELINE && ==KartProperties::IMPULSE_TO_DRIVELINE &&
lw && m_vehicle->getCentralImpulseTime()<=0 && lw && m_vehicle->getCentralImpulseTime()<=0 &&
World::getWorld()->getTrack()->isPushBackEnabled()) World::getWorld()->getTrack()->isPushBackEnabled())
@ -2038,8 +2069,7 @@ void Kart::updatePhysics(float dt)
if(!m_has_started && m_controls.m_accel) if(!m_has_started && m_controls.m_accel)
{ {
m_has_started = true; m_has_started = true;
float f = m_kart_properties->getStartupBoost() * float f = getStartupBoost();
m_difficulty->getStartupBoost();
m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER, m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER,
0.9f*f, f, 0.9f*f, f,
/*engine_force*/200.0f, /*engine_force*/200.0f,
@ -2107,11 +2137,11 @@ void Kart::updatePhysics(float dt)
// Only apply if near ground instead of purely based on speed avoiding // Only apply if near ground instead of purely based on speed avoiding
// the "parachute on top" look. // the "parachute on top" look.
const Vec3 &v = m_body->getLinearVelocity(); const Vec3 &v = m_body->getLinearVelocity();
if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravel()*60) if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravel() * 60)
{ {
Vec3 v_clamped = v; Vec3 v_clamped = v;
// clamp the speed to 99% of the maxium falling speed. // clamp the speed to 99% of the maxium falling speed.
v_clamped.setY(-m_kart_properties->getSuspensionTravel()*60 * 0.99f); v_clamped.setY(-m_kart_properties->getSuspensionTravel() * 60 * 0.99f);
//m_body->setLinearVelocity(v_clamped); //m_body->setLinearVelocity(v_clamped);
} }
@ -2213,8 +2243,8 @@ void Kart::updateEnginePowerAndBrakes(float dt)
engine_power *= 5.0f; engine_power *= 5.0f;
// Lose some traction when skidding, to balance the advantage // Lose some traction when skidding, to balance the advantage
if(m_controls.m_skid && if (m_controls.m_skid &&
m_kart_properties->getSkiddingProperties()->getSkidVisualTime()==0) m_kart_properties->getSkidVisualTime() == 0)
engine_power *= 0.5f; engine_power *= 0.5f;
applyEngineForce(engine_power*m_controls.m_accel); applyEngineForce(engine_power*m_controls.m_accel);
@ -2237,10 +2267,8 @@ void Kart::updateEnginePowerAndBrakes(float dt)
m_brake_time += dt; m_brake_time += dt;
// Apply the brakes - include the time dependent brake increase // Apply the brakes - include the time dependent brake increase
float f = 1 + m_brake_time float f = 1 + m_brake_time
* m_kart_properties->getBrakeTimeIncrease() * * m_kart_properties->getEngineBrakeTimeIncrease();
m_difficulty->getBrakeTimeIncrease(); m_vehicle->setAllBrakes(m_kart_properties->getEngineBrakeFactor() * f);
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor() *
m_difficulty->getBrakeFactor() * f);
} }
else // m_speed < 0 else // m_speed < 0
{ {
@ -2248,8 +2276,7 @@ void Kart::updateEnginePowerAndBrakes(float dt)
// going backward, apply reverse gear ratio (unless he goes // going backward, apply reverse gear ratio (unless he goes
// too fast backwards) // too fast backwards)
if ( -m_speed < m_max_speed->getCurrentMaxSpeed() if ( -m_speed < m_max_speed->getCurrentMaxSpeed()
*m_kart_properties->getMaxSpeedReverseRatio() * *m_kart_properties->getEngineMaxSpeedReverseRatio())
m_difficulty->getMaxSpeedReverseRatio())
{ {
// The backwards acceleration is artificially increased to // The backwards acceleration is artificially increased to
// allow players to get "unstuck" quicker if they hit e.g. // allow players to get "unstuck" quicker if they hit e.g.
@ -2418,7 +2445,7 @@ void Kart::loadData(RaceManager::KartType type, bool is_animated_model)
m_slipstream = new SlipStream(this); m_slipstream = new SlipStream(this);
if(m_kart_properties->getSkiddingProperties()->hasSkidmarks()) if (m_kart_properties->getSkidEnabled())
{ {
m_skidmarks = new SkidMarks(*this); m_skidmarks = new SkidMarks(*this);
m_skidmarks->adjustFog( m_skidmarks->adjustFog(
@ -2428,7 +2455,7 @@ void Kart::loadData(RaceManager::KartType type, bool is_animated_model)
if (!CVS->supportsShadows()) if (!CVS->supportsShadows())
{ {
m_shadow = new Shadow(m_kart_properties, m_node, m_shadow = new Shadow(m_kart_properties.get(), m_node,
-m_kart_model->getLowestPoint()); -m_kart_model->getLowestPoint());
} }
World::getWorld()->kartAdded(this, m_node); World::getWorld()->kartAdded(this, m_node);
@ -2602,8 +2629,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
{ {
// 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!
nitro_frac = fabsf(getSpeed())/(m_kart_properties->getMaxSpeed() * nitro_frac = fabsf(getSpeed()) / (m_kart_properties->getEngineMaxSpeed());
m_difficulty->getMaxSpeed() );
// The speed of the kart can be higher (due to powerups) than // The speed of the kart can be higher (due to powerups) than
// the normal maximum speed of the kart. // the normal maximum speed of the kart.
if(nitro_frac>1.0f) nitro_frac = 1.0f; if(nitro_frac>1.0f) nitro_frac = 1.0f;
@ -2617,8 +2643,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
// leaning might get less if a kart gets a special that increases // leaning might get less if a kart gets a special that increases
// its maximum speed, but not the current speed (by much). On the // its maximum speed, but not the current speed (by much). On the
// other hand, that ratio can often be greater than 1. // other hand, that ratio can often be greater than 1.
float speed_frac = m_speed / m_kart_properties->getMaxSpeed() * float speed_frac = m_speed / m_kart_properties->getEngineMaxSpeed();
m_difficulty->getMaxSpeed();
if(speed_frac>1.0f) if(speed_frac>1.0f)
speed_frac = 1.0f; speed_frac = 1.0f;
else if (speed_frac < 0.0f) // no leaning when backwards driving else if (speed_frac < 0.0f) // no leaning when backwards driving
@ -2626,14 +2651,14 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
const float steer_frac = m_skidding->getSteeringFraction(); const float steer_frac = m_skidding->getSteeringFraction();
const float roll_speed = m_kart_properties->getLeanSpeed(); const float roll_speed = m_kart_properties->getLeanSpeed() * DEGREE_TO_RAD;
if(speed_frac > 0.8f && fabsf(steer_frac)>0.5f) if(speed_frac > 0.8f && fabsf(steer_frac)>0.5f)
{ {
// Use steering ^ 7, which means less effect at lower // Use steering ^ 7, which means less effect at lower
// steering // steering
const float f = m_skidding->getSteeringFraction(); const float f = m_skidding->getSteeringFraction();
const float f2 = f*f; const float f2 = f*f;
const float max_lean = -m_kart_properties->getMaxLean() const float max_lean = -m_kart_properties->getLeanMax() * DEGREE_TO_RAD
* f2*f2*f2*f * f2*f2*f2*f
* speed_frac; * speed_frac;
if(max_lean>0) if(max_lean>0)

View File

@ -31,7 +31,6 @@
#include "items/powerup.hpp" #include "items/powerup.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/player_difficulty.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
class btKart; class btKart;
@ -228,7 +227,7 @@ private:
public: public:
Kart(const std::string& ident, unsigned int world_kart_id, Kart(const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
const PlayerDifficulty *difficulty); PerPlayerDifficulty difficulty);
virtual ~Kart(); virtual ~Kart();
virtual void init(RaceManager::KartType type); virtual void init(RaceManager::KartType type);
virtual void kartIsInRestNow(); virtual void kartIsInRestNow();
@ -236,6 +235,8 @@ public:
const btQuaternion& off_rotation); const btQuaternion& off_rotation);
virtual void createPhysics (); virtual void createPhysics ();
virtual void updateWeight (); virtual void updateWeight ();
virtual float getSpeedForTurnRadius(float radius) const;
virtual float getMaxSteerAngle(float speed) const;
virtual bool isInRest () const; virtual bool isInRest () const;
virtual void applyEngineForce (float force); virtual void applyEngineForce (float force);
@ -251,6 +252,8 @@ public:
float fade_in_time); float fade_in_time);
virtual float getSpeedIncreaseTimeLeft(unsigned int category) const; virtual float getSpeedIncreaseTimeLeft(unsigned int category) const;
virtual void collectedItem(Item *item, int random_attachment); virtual void collectedItem(Item *item, int random_attachment);
virtual float getStartupBoost() const;
virtual const Material *getMaterial() const; virtual const Material *getMaterial() const;
virtual const Material *getLastMaterial() const; virtual const Material *getLastMaterial() const;
/** Returns the pitch of the terrain depending on the heading. */ /** Returns the pitch of the terrain depending on the heading. */
@ -331,15 +334,12 @@ public:
/** Returns the time till full steering is reached for this kart. /** Returns the time till full steering is reached for this kart.
* \param steer Current steer value (must be >=0), on which the time till * \param steer Current steer value (must be >=0), on which the time till
* full steer depends. */ * full steer depends. */
virtual float getTimeFullSteer(float steer) const virtual float getTimeFullSteer(float steer) const;
{
return m_kart_properties->getTimeFullSteer(steer);
} // getTimeFullSteer
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the maximum steering angle for this kart, which depends on the /** Returns the maximum steering angle for this kart, which depends on the
* speed. */ * speed. */
virtual float getMaxSteerAngle () const virtual float getMaxSteerAngle () const
{ return m_kart_properties->getMaxSteerAngle(getSpeed()); } { return getMaxSteerAngle(getSpeed()); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the skidding object for this kart (which can be used to query /** Returns the skidding object for this kart (which can be used to query
* skidding related values). */ * skidding related values). */

View File

@ -326,8 +326,7 @@ void KartGFX::updateTerrain(const ParticleKind *pk)
if (skidding > 1.0f && on_ground) if (skidding > 1.0f && on_ground)
rate = fabsf(m_kart->getControls().m_steer) > 0.8 ? skidding - 1 : 0; rate = fabsf(m_kart->getControls().m_steer) > 0.8 ? skidding - 1 : 0;
else if (speed >= 0.5f && on_ground) else if (speed >= 0.5f && on_ground)
rate = speed/m_kart->getKartProperties()->getMaxSpeed() * rate = speed/m_kart->getKartProperties()->getEngineMaxSpeed();
m_kart->getPlayerDifficulty()->getMaxSpeed();
else else
{ {
pe->setCreationRateAbsolute(0); pe->setCreationRateAbsolute(0);

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
#ifndef HEADER_KART_PROPERTIES_HPP #ifndef HEADER_KART_PROPERTIES_HPP
#define HEADER_KART_PROPERTIES_HPP #define HEADER_KART_PROPERTIES_HPP
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -37,9 +38,11 @@ using namespace irr;
#include "utils/interpolation_array.hpp" #include "utils/interpolation_array.hpp"
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
class AbstractCharacteristic;
class AIProperties; class AIProperties;
class CachedCharacteristic;
class CombinedCharacteristic;
class Material; class Material;
class SkiddingProperties;
class XMLNode; class XMLNode;
/** /**
@ -47,7 +50,7 @@ class XMLNode;
* This includes size, name, identifier, physical properties etc. * This includes size, name, identifier, physical properties etc.
* It is atm also the base class for STKConfig, which stores the default values * It is atm also the base class for STKConfig, which stores the default values
* for all physics constants. * for all physics constants.
* Note that KartProperies is copied (when setting the default values from * Note that KartProperties is copied (when setting the default values from
* stk_config. * stk_config.
* *
* \ingroup karts * \ingroup karts
@ -58,16 +61,11 @@ private:
/** Base directory for this kart. */ /** Base directory for this kart. */
std::string m_root; std::string m_root;
/** The skididing properties for this kart, as a separate object in order
* to reduce dependencies (and therefore compile time) when changing
* any skidding property. */
SkiddingProperties *m_skidding_properties;
/** AI Properties for this kart, as a separate object in order to /** AI Properties for this kart, as a separate object in order to
* reduce dependencies (and therefore compile time) when changing * reduce dependencies (and therefore compile time) when changing
* any AI property. There is one separate object for each * any AI property. There is one separate object for each
* difficulty. */ * difficulty. */
AIProperties *m_ai_properties[RaceManager::DIFFICULTY_COUNT]; std::shared_ptr<AIProperties> m_ai_properties[RaceManager::DIFFICULTY_COUNT];
/** The absolute path of the icon texture to use. */ /** The absolute path of the icon texture to use. */
Material *m_icon_material; Material *m_icon_material;
@ -82,7 +80,7 @@ private:
/** The kart model and wheels. It is mutable since the wheels of the /** The kart model and wheels. It is mutable since the wheels of the
* KartModel can rotate and turn, and animations are played, but otherwise * KartModel can rotate and turn, and animations are played, but otherwise
* the kart_properties object is const. */ * the kart_properties object is const. */
mutable KartModel *m_kart_model; mutable std::shared_ptr<KartModel> m_kart_model;
/** List of all groups the kart belongs to. */ /** List of all groups the kart belongs to. */
std::vector<std::string> m_groups; std::vector<std::string> m_groups;
@ -119,33 +117,18 @@ private:
* status bar and on the track-view. */ * status bar and on the track-view. */
int m_shape; /**< Number of vertices in polygon when int m_shape; /**< Number of vertices in polygon when
* drawing the dot on the mini map. */ * drawing the dot on the mini map. */
/** The physical, item, etc. characteristics of this kart that are loaded
* from the xml file.
*/
std::shared_ptr<AbstractCharacteristic> m_characteristic;
/** The base characteristics combined with the characteristics of this kart. */
std::shared_ptr<CombinedCharacteristic> m_combined_characteristic;
/** The cached combined characteristics. */
std::shared_ptr<CachedCharacteristic> m_cached_characteristic;
// Physic properties // Physic properties
// ----------------- // -----------------
/** Weight of kart. */
float m_mass;
/** Maximum force from engine for each difficulty. */
std::vector<float> m_engine_power;
/** Braking factor * engine_power braking force. */
float m_brake_factor;
/** Brake_time * m_brake_time_increase will increase the break time
* over time. */
float m_brake_time_increase;
/** Time for player karts to reach full steer angle. */
InterpolationArray m_time_full_steer;
/** Time for steering to go back to zero from full steer. */
float m_time_reset_steer;
/** A torque impulse applied to keep the kart parallel to the ground. */
float m_smooth_flying_impulse;;
/** The turn angle depending on speed. */
InterpolationArray m_turn_angle_at_speed;
/** If != 0 a bevelled box shape is used by using a point cloud as a /** If != 0 a bevelled box shape is used by using a point cloud as a
* collision shape. */ * collision shape. */
Vec3 m_bevel_factor; Vec3 m_bevel_factor;
@ -159,39 +142,6 @@ private:
*/ */
float m_physical_wheel_position; float m_physical_wheel_position;
/** Time a kart is moved upwards after when it is rescued. */
float m_rescue_time;
/** Distance the kart is raised before dropped. */
float m_rescue_height;
/** Time an animated explosion is shown. Longer = more delay for kart. */
float m_explosion_time;
/** How far away from an explosion karts will still be affected. */
float m_explosion_radius;
/** How long a kart is invulnerable after it is hit by an explosion. */
float m_explosion_invulnerability_time;
/** Duration a zipper is active. */
float m_zipper_time;
/** Fade out time for a zipper. */
float m_zipper_fade_out_time;
/** Additional force added to the acceleration. */
float m_zipper_force;
/** Initial one time speed gain. */
float m_zipper_speed_gain;
/** Absolute increase of the kart's maximum speed (in m/s). */
float m_zipper_max_speed_increase;
/** Vertical offset after rescue. */
float m_rescue_vert_offset;
/** Minimum time during which nitro is consumed when pressing /** Minimum time during which nitro is consumed when pressing
* the nitro key (to prevent using in very small bursts) * the nitro key (to prevent using in very small bursts)
*/ */
@ -202,64 +152,12 @@ private:
/** Filename of the wheel models. */ /** Filename of the wheel models. */
std::string m_wheel_filename[4]; std::string m_wheel_filename[4];
/** Radius of the graphical wheels. */
float m_wheel_graphics_radius[4];
/** An additional Y offset added to the y position of the graphical /** An additional Y offset added to the y position of the graphical
* chassis. Useful for karts that don't have enough space for suspension * chassis. Useful for karts that don't have enough space for suspension
* compression. */ * compression. */
float m_graphical_y_offset; float m_graphical_y_offset;
/** Max. length of plunger rubber band. */
float m_rubber_band_max_length;
/** Force of an attached rubber band. */
/** Duration a rubber band works. */
float m_rubber_band_force;
/** How long the rubber band will fly. */
float m_rubber_band_duration;
/** Increase of maximum speed of the kart when the rubber band pulls. */
float m_rubber_band_speed_increase;
/** Fade out time when the rubber band is removed. */
float m_rubber_band_fade_out_time;
/**Duration of plunger in face depending on difficulty. */
std::vector<float> m_plunger_in_face_duration;
/** Wheel base of the kart. */ /** Wheel base of the kart. */
float m_wheel_base; float m_wheel_base;
/** Nitro consumption. */
float m_nitro_consumption;
/** Nitro amount for small bottle. */
float m_nitro_small_container;
/** Nitro amount for big bittle. */
float m_nitro_big_container;
/** How much the speed of a kart might exceed its maximum speed (in m/s). */
float m_nitro_max_speed_increase;
/** Additional engine force to affect the kart. */
float m_nitro_engine_force;
/** How long the increased nitro max speed will be valid after
* the kart stops using nitro (and the fade-out-time starts). */
float m_nitro_duration;
/** Duration during which the increased maximum speed
* due to nitro fades out. */
float m_nitro_fade_out_time;
/** Maximum nitro a kart can collect. */
float m_nitro_max;
/** Bubble gum diration. */
float m_bubblegum_time;
/** Torque to add when a bubble gum was hit in order to make the kart go
* sideways a bit. */
float m_bubblegum_torque;
/** Fraction of top speed that can be reached maximum after hitting a
* bubble gum. */
float m_bubblegum_speed_fraction;
/** How long to fade in the slowdown for a bubble gum. */
float m_bubblegum_fade_in_time;
/** Square of the maximum distance a swatter can operate. */
float m_swatter_distance2;
/** How long the swatter lasts. */
float m_swatter_duration;
/** How long a kart will remain squashed. */
float m_squash_duration;
/** The slowdown to apply while a kart is squashed. The new maxspeed
* is max_speed*m_squash_slowdown. */
float m_squash_slowdown;
/** The maximum roll a kart graphics should show when driving in a fast /** The maximum roll a kart graphics should show when driving in a fast
* curve. This is read in as degrees, but stored in radians. */ * curve. This is read in as degrees, but stored in radians. */
@ -269,57 +167,19 @@ private:
* (in radians/second). */ * (in radians/second). */
float m_lean_speed; float m_lean_speed;
/** How long a jump must be in order to trigger the jump animation. */
float m_jump_animation_time;
/** Engine sound effect. */ /** Engine sound effect. */
std::string m_engine_sfx_type; std::string m_engine_sfx_type;
// bullet physics data // bullet physics data
// ------------------- // -------------------
float m_suspension_stiffness;
float m_wheel_damping_relaxation;
float m_wheel_damping_compression;
float m_max_suspension_force;
float m_friction_slip; float m_friction_slip;
float m_roll_influence;
/** Parameters for the speed-weighted objects */ /** Parameters for the speed-weighted objects */
SpeedWeightedObject::Properties m_speed_weighted_object_properties; SpeedWeightedObject::Properties m_speed_weighted_object_properties;
/** An impulse pushing the kart down which is proportional to speed. So
* the actual impulse is speed * m_downward_impulse_factor. Set it to
* 0 to disable completely. Based on
* http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=6059\
* &p=21240&hilit=vehicle#p21240 */
float m_downward_impulse_factor;
/** Artifical acceleration that pulls a kart down onto the track if one
* axis loses contact with the track. */
float m_track_connection_accel;
/** Linear damping of the chassis to prevent it from toppling over. */
float m_chassis_linear_damping;
/** Angular damping to prevent it from turning too easily. */
float m_chassis_angular_damping;
/** The maximum speed at each difficulty. */
std::vector<float> m_max_speed;
float m_max_speed_reverse_ratio;
/** Shift of center of gravity. */ /** Shift of center of gravity. */
Vec3 m_gravity_center_shift; Vec3 m_gravity_center_shift;
/** The suspension reaction is dampened to reach an exponential behaviour.
* See http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=7369\
* &p=25236&hilit=vehicle#p25236 for details. */
bool m_exp_spring_response;
float m_suspension_rest;
float m_suspension_travel;
public: public:
/** STK can add an impulse to push karts away from the track in case /** STK can add an impulse to push karts away from the track in case
* of a kart-track collision. This can be done in two ways: either * of a kart-track collision. This can be done in two ways: either
@ -345,80 +205,33 @@ private:
/** The restitution factor to be used in collsions for this kart. */ /** The restitution factor to be used in collsions for this kart. */
float m_restitution; float m_restitution;
/** How far behind a kart slipstreaming is effective. */
float m_slipstream_length;
/** How wide the slipstream area is at the end. */
float m_slipstream_width;
/** Time after which sstream gives a bonus. */
float m_slipstream_collect_time;
/** Time slip-stream bonus is effective. */
float m_slipstream_use_time;
/** Additional power due to sstreaming. */
float m_slipstream_add_power;
/** Minimum speed for slipstream to take effect. */
float m_slipstream_min_speed;
/** How much the speed of the kart might exceed its
* normal maximum speed. */
float m_slipstream_max_speed_increase;
/** How long the higher speed lasts after slipstream stopped working. */
float m_slipstream_duration;
/** How long the slip stream speed increase will gradually be reduced. */
float m_slipstream_fade_out_time;
/** Distance of normal camera from kart. */
float m_camera_distance;
/** Up angle of the camera in relation to the pitch of the kart when
* driving forwards. */
float m_camera_forward_up_angle;
/** Up angle of the camera in relation to the pitch of the kart when
* driving backwards. */
float m_camera_backward_up_angle;
/** The following two vectors define at what ratio of the maximum speed what
* gear is selected. E.g. 0.25 means: if speed <=0.25*maxSpeed --> gear 1,
* 0.5 means: if speed <=0.5 *maxSpeed --> gear 2 */
std::vector<float> m_gear_switch_ratio;
/** This vector contains the increase in max power (to simulate different
* gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1. See
m_gear_switch_ratio). */
std::vector<float> m_gear_power_increase;
/** If the kart starts within the specified time at index I after 'go',
* it receives the speed boost from m_startup_boost[I]. */
std::vector<float> m_startup_times;
/** The startup boost is the kart starts fast enough. */
std::vector<float> m_startup_boost;
void load (const std::string &filename, void load (const std::string &filename,
const std::string &node); const std::string &node);
void combineCharacteristics();
public: public:
/** Returns the string representation of a per-player difficulty. */
static std::string getPerPlayerDifficultyAsString(PerPlayerDifficulty d);
KartProperties (const std::string &filename=""); KartProperties (const std::string &filename="");
~KartProperties (); ~KartProperties ();
void copyForPlayer (const KartProperties *source);
void copyFrom (const KartProperties *source); void copyFrom (const KartProperties *source);
void getAllData (const XMLNode * root); void getAllData (const XMLNode * root);
void checkAllSet (const std::string &filename); void checkAllSet (const std::string &filename);
float getStartupBoost () const;
bool isInGroup (const std::string &group) const; bool isInGroup (const std::string &group) const;
bool operator<(const KartProperties &other) const; bool operator<(const KartProperties &other) const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the (maximum) speed for a given turn radius. /** Returns the characteristics for this kart. */
* \param radius The radius for which the speed needs to be computed. */ const AbstractCharacteristic* getCharacteristic() const;
float getSpeedForTurnRadius(float radius) const {
float angle = sin(m_wheel_base / radius);
return m_turn_angle_at_speed.getReverse(angle);
} // getSpeedForTurnRadius
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the maximum steering angle (depending on speed). */ /** Returns the characteristics for this kart combined with the base
float getMaxSteerAngle(float speed) const { * characteristic. This value isn't used for the race, because the
return m_turn_angle_at_speed.get(speed); * difficulty is missing, but it can be used e.g. for the kart stats widget.
} // getMaxSteerAngle */
const AbstractCharacteristic* getCombinedCharacteristic() const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the material for the kart icons. */ /** Returns the material for the kart icons. */
@ -462,6 +275,10 @@ public:
/** Returns the internal identifier of this kart. */ /** Returns the internal identifier of this kart. */
const std::string& getIdent () const {return m_ident; } const std::string& getIdent () const {return m_ident; }
// ------------------------------------------------------------------------
/** Returns the type of this kart. */
const std::string& getKartType () const { return m_kart_type; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the shadow texture to use. */ /** Returns the shadow texture to use. */
video::ITexture *getShadowTexture() const {return m_shadow_texture; } video::ITexture *getShadowTexture() const {return m_shadow_texture; }
@ -492,47 +309,6 @@ public:
/** Returns the list of groups this kart belongs to. */ /** Returns the list of groups this kart belongs to. */
const std::vector<std::string>& const std::vector<std::string>&
getGroups () const {return m_groups; } getGroups () const {return m_groups; }
// ------------------------------------------------------------------------
/** Returns the mass of this kart. */
float getMass () const {return m_mass; }
// ------------------------------------------------------------------------
/** Returns the maximum engine power depending on difficulty. */
float getMaxPower () const
{return m_engine_power[race_manager->getDifficulty()];}
// ------------------------------------------------------------------------
/** Returns the time the kart needs to fully steer in one direction from
* steering straight depending on the current steering value.
* \param steer Current steering value, must be >=0. */
float getTimeFullSteer(float steer) const
{
assert(steer>=0);
return m_time_full_steer.get(steer);
} // getTimeFullSteer
// ------------------------------------------------------------------------
/** Returns the time the kart needs to go back to steering straight from
* full steer. */
float getTimeResetSteer () const { return m_time_reset_steer; }
// ------------------------------------------------------------------------
/** Get braking information. */
float getBrakeFactor () const {return m_brake_factor; }
// ------------------------------------------------------------------------
/** Returns the additional brake factor which depends on time. */
float getBrakeTimeIncrease() const { return m_brake_time_increase; }
// ------------------------------------------------------------------------
/** Returns the torque scaling factor used to keep the karts parallel to
* the ground when flying. */
float getSmoothFlyingImpulse() const
{
return m_smooth_flying_impulse;
} // getSmoothFlyingImpulse
// ------------------------------------------------------------------------
/** Get maximum reverse speed ratio. */
float getMaxSpeedReverseRatio() const {return m_max_speed_reverse_ratio; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the engine type (used to change sfx depending on kart size). */ /** Returns the engine type (used to change sfx depending on kart size). */
@ -540,31 +316,9 @@ public:
// Bullet physics get functions // Bullet physics get functions
//----------------------------- //-----------------------------
/** Returns the suspension stiffness. */
float getSuspensionStiffness () const {return m_suspension_stiffness; }
// ------------------------------------------------------------------------
/** Returns damping relaxation. */
float getWheelDampingRelaxation () const
{return m_wheel_damping_relaxation; }
// ------------------------------------------------------------------------
/** Returns the wheel damping compression. */
float getWheelDampingCompression() const
{return m_wheel_damping_compression;}
// ------------------------------------------------------------------------
/** Returns maximum suspension force. */
float getMaxSuspensionForce() const {return m_max_suspension_force; }
// ------------------------------------------------------------------------
/** Returns friction slip. */ /** Returns friction slip. */
float getFrictionSlip () const {return m_friction_slip; } float getFrictionSlip () const {return m_friction_slip; }
// ------------------------------------------------------------------------
/** Returns roll influence. */
float getRollInfluence () const {return m_roll_influence; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns parameters for the speed-weighted objects */ /** Returns parameters for the speed-weighted objects */
const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const
@ -576,99 +330,11 @@ public:
/** Returns the wheel base (distance front to rear axis). */ /** Returns the wheel base (distance front to rear axis). */
float getWheelBase () const {return m_wheel_base; } float getWheelBase () const {return m_wheel_base; }
// ------------------------------------------------------------------------
/** Returns linear damping of chassis. */
float getChassisLinearDamping () const {return m_chassis_linear_damping;}
// ------------------------------------------------------------------------
/** Returns angular damping of chassis. */
float getChassisAngularDamping () const
{return m_chassis_angular_damping; }
// ------------------------------------------------------------------------
/** Artifical downward impulse every frame. */
float getDownwardImpulseFactor() const { return m_downward_impulse_factor;}
// ------------------------------------------------------------------------
/** Returns artificial acceleration to keep wheels on track. */
float getTrackConnectionAccel () const {return m_track_connection_accel;}
// ------------------------------------------------------------------------
/** Returns the maximum speed dependent on the difficult level. */
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. */
float getNitroConsumption () const {return m_nitro_consumption; }
// ------------------------------------------------------------------------
/** Returns the amount of nitro for a small container. */
float getNitroSmallContainer () const {return m_nitro_small_container; }
// ------------------------------------------------------------------------
/** Returns the amount of nitro for a big container. */
float getNitroBigContainer () const {return m_nitro_big_container; }
// ------------------------------------------------------------------------
/** Returns the increase of maximum speed due to nitro. */
float getNitroMaxSpeedIncrease () const
{return m_nitro_max_speed_increase; }
// ------------------------------------------------------------------------
float getNitroEngineForce () const {return m_nitro_engine_force; }
// ------------------------------------------------------------------------
/** Returns how long the increased nitro max speed will be valid after
* the kart stops using nitro (and the fade-out-time starts). */
float getNitroDuration () const {return m_nitro_duration; }
// ------------------------------------------------------------------------
/** Returns the duration during which the increased maximum speed
* due to nitro fades out. */
float getNitroFadeOutTime () const {return m_nitro_fade_out_time; }
// ------------------------------------------------------------------------
/** Returns the maximum amount of nitro a kart can store. */
float getNitroMax () const {return m_nitro_max; }
// ------------------------------------------------------------------------
/** Returns how long a bubble gum is active. */
float getBubblegumTime() const { return m_bubblegum_time; }
// ------------------------------------------------------------------------
/** Returns the torque to add when a bubble gum was hit . */
float getBubblegumTorque() const { return m_bubblegum_torque; }
// ------------------------------------------------------------------------
/** Returns the fraction of top speed that can be reached maximum after
* hitting a bubble gum. */
float getBubblegumSpeedFraction() const {return m_bubblegum_speed_fraction;}
// ------------------------------------------------------------------------
/** Returns how long to fade in the slowdown for a bubble gum. */
float getBubblegumFadeInTime() const { return m_bubblegum_fade_in_time; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a shift of the center of mass (lowering the center of mass /** Returns a shift of the center of mass (lowering the center of mass
* makes the karts more stable. */ * makes the karts more stable. */
const Vec3&getGravityCenterShift() const {return m_gravity_center_shift; } const Vec3&getGravityCenterShift() const {return m_gravity_center_shift; }
// ------------------------------------------------------------------------
/** Retusn suspension rest length. */
float getSuspensionRest () const {return m_suspension_rest; }
// ------------------------------------------------------------------------
/** Returns the amount the suspension can extend. */
float getSuspensionTravel () const {return m_suspension_travel; }
// ------------------------------------------------------------------------
/** Returns if the spring should be exponentially dampened. */
bool getExpSpringResponse() const {return m_exp_spring_response; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns an artificial impulse to push karts away from the terrain /** Returns an artificial impulse to push karts away from the terrain
* it hits. */ * it hits. */
@ -693,128 +359,6 @@ public:
/** Returns the restitution factor for this kart. */ /** Returns the restitution factor for this kart. */
float getRestitution () const { return m_restitution; } float getRestitution () const { return m_restitution; }
// ------------------------------------------------------------------------
/** Returns the vertical offset when rescuing karts to avoid karts being
* rescued in (or under) the track. */
float getVertRescueOffset () const {return m_rescue_vert_offset; }
// ------------------------------------------------------------------------
/** Returns the time a kart is rised during a rescue. */
float getRescueTime () const {return m_rescue_time; }
// ------------------------------------------------------------------------
/** Returns the height a kart is moved to during a rescue. */
float getRescueHeight () const {return m_rescue_height; }
// ------------------------------------------------------------------------
/** Returns the time an explosion animation is shown. */
float getExplosionTime () const {return m_explosion_time; }
// ------------------------------------------------------------------------
/** Returns the height of the explosion animation. */
float getExplosionRadius () const {return m_explosion_radius; }
// ------------------------------------------------------------------------
/** Returns how long a kart is invulnerable after being hit by an
explosion. */
float getExplosionInvulnerabilityTime() const
{ return m_explosion_invulnerability_time; }
// ------------------------------------------------------------------------
/** Returns the maximum length of a rubber band before it breaks. */
float getRubberBandMaxLength () const {return m_rubber_band_max_length;}
// ------------------------------------------------------------------------
/** Returns force a rubber band has when attached to a kart. */
float getRubberBandForce () const {return m_rubber_band_force; }
// ------------------------------------------------------------------------
/** Returns the duration a rubber band is active for. */
float getRubberBandDuration () const {return m_rubber_band_duration; }
// ------------------------------------------------------------------------
/** Returns the increase of maximum speed while a rubber band is
* pulling. */
float getRubberBandSpeedIncrease() const
{
return m_rubber_band_speed_increase;
}
// ------------------------------------------------------------------------
/** Return the fade out time once a rubber band is removed. */
float getRubberBandFadeOutTime() const
{
return m_rubber_band_fade_out_time;
}
// ------------------------------------------------------------------------
/** Returns duration of a plunger in your face. */
float getPlungerInFaceTime () const
{return m_plunger_in_face_duration[race_manager->getDifficulty()];}
// ------------------------------------------------------------------------
/** Returns the time a zipper is active. */
float getZipperTime () const {return m_zipper_time; }
// ------------------------------------------------------------------------
/** Returns the time a zipper is active. */
float getZipperFadeOutTime () const {return m_zipper_fade_out_time; }
// ------------------------------------------------------------------------
/** Returns the additional force added applied to the kart. */
float getZipperForce () const { return m_zipper_force; }
// ------------------------------------------------------------------------
/** Returns the initial zipper speed gain. */
float getZipperSpeedGain () const { return m_zipper_speed_gain; }
// ------------------------------------------------------------------------
/** Returns the increase of the maximum speed of the kart
* if a zipper is active. */
float getZipperMaxSpeedIncrease () const
{ return m_zipper_max_speed_increase;}
// ------------------------------------------------------------------------
/** Returns how far behind a kart slipstreaming works. */
float getSlipstreamLength () const {return m_slipstream_length; }
// ------------------------------------------------------------------------
/** Returns how wide the slipstream area is at the end. */
float getSlipstreamWidth () const {return m_slipstream_width; }
// ------------------------------------------------------------------------
/** Returns time after which slipstream has maximum effect. */
float getSlipstreamCollectTime () const
{return m_slipstream_collect_time; }
// ------------------------------------------------------------------------
/** Returns time after which slipstream has maximum effect. */
float getSlipstreamUseTime () const {return m_slipstream_use_time; }
// ------------------------------------------------------------------------
/** Returns additional power due to slipstreaming. */
float getSlipstreamAddPower () const {return m_slipstream_add_power; }
// ------------------------------------------------------------------------
/** Returns the minimum slipstream speed. */
float getSlipstreamMinSpeed () const {return m_slipstream_min_speed; }
// ------------------------------------------------------------------------
/** Returns the increase of the maximum speed of a kart
* due to slipstream. */
float getSlipstreamMaxSpeedIncrease() const
{ return m_slipstream_max_speed_increase; }
// ------------------------------------------------------------------------
/** Returns how long the higher speed lasts after slipstream
* stopped working. */
float getSlipstreamDuration () const { return m_slipstream_duration; }
// ------------------------------------------------------------------------
/** Returns how long the slip stream speed increase will gradually
* be reduced. */
float getSlipstreamFadeOutTime () const
{ return m_slipstream_fade_out_time; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the scale factor by which the shadow plane /** Returns the scale factor by which the shadow plane
* had to be set. */ * had to be set. */
@ -830,79 +374,18 @@ public:
* had to be set. */ * had to be set. */
float getShadowZOffset () const {return m_shadow_z_offset; } float getShadowZOffset () const {return m_shadow_z_offset; }
// ------------------------------------------------------------------------
/** Returns a pointer to the skidding properties. */
const SkiddingProperties *getSkiddingProperties() const
{ return m_skidding_properties; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a pointer to the AI properties. */ /** Returns a pointer to the AI properties. */
const AIProperties *getAIPropertiesForDifficulty() const const AIProperties *getAIPropertiesForDifficulty() const
{ {
return m_ai_properties[race_manager->getDifficulty()]; return m_ai_properties[race_manager->getDifficulty()].get();
} // getAIProperties } // getAIProperties
// ------------------------------------------------------------------------
/** Returns ratio of current speed to max speed at which the gear will
* change (for our simualated gears = simple change of engine power). */
const std::vector<float>&
getGearSwitchRatio () const {return m_gear_switch_ratio; }
// ------------------------------------------------------------------------
/** Returns the power increase depending on gear. */
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; }
// ------------------------------------------------------------------------
/** Returns the angle the camera has relative to the pitch of the kart. */
float getCameraForwardUpAngle () const
{return m_camera_forward_up_angle; }
// ------------------------------------------------------------------------
/** Returns the angle the camera has relative to the pitch of the kart. */
float getCameraBackwardUpAngle () const
{return m_camera_backward_up_angle; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the full path where the files for this kart are stored. */ /** Returns the full path where the files for this kart are stored. */
const std::string& getKartDir () const {return m_root; } const std::string& getKartDir () const {return m_root; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the square of the maximum distance at which a swatter
* can hit karts. */
float getSwatterDistance2() const { return m_swatter_distance2; }
// ------------------------------------------------------------------------
/** Returns how long a swatter will stay attached/ready to be used. */
float getSwatterDuration() const { return m_swatter_duration; }
// ------------------------------------------------------------------------
/** Returns how long a kart remains squashed. */
float getSquashDuration() const {return m_squash_duration; }
// ------------------------------------------------------------------------
/** Returns the slowdown of a kart that is squashed. */
float getSquashSlowdown() const {return m_squash_slowdown; }
// ------------------------------------------------------------------------
/** The maximum leaning a kart should show (In radians). */
float getMaxLean() const { return m_max_lean; }
// ------------------------------------------------------------------------
/** The speed with which a kart should lean (in radians/s). */
float getLeanSpeed() const { return m_lean_speed; }
// ------------------------------------------------------------------------
/** Return show long a jump must last in order to play the jump
* animation. */
float getJumpAnimationTime() const { return m_jump_animation_time; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns minimum time during which nitro is consumed when pressing nitro /** Returns minimum time during which nitro is consumed when pressing nitro
* key, to prevent using nitro in very short bursts * key, to prevent using nitro in very short bursts
@ -921,8 +404,142 @@ public:
{ {
return m_physical_wheel_position; return m_physical_wheel_position;
} // getPhysicalWheelPosition } // getPhysicalWheelPosition
// ------------------------------------------------------------------------
float getAvgPower() const;
// Script-generated content generated by tools/create_kart_properties.py defs
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start kpdefs> */
float getSuspensionStiffness() const;
float getSuspensionRest() const;
float getSuspensionTravel() const;
bool getSuspensionExpSpringResponse() const;
float getSuspensionMaxForce() const;
float getStabilityRollInfluence() const;
float getStabilityChassisLinearDamping() const;
float getStabilityChassisAngularDamping() const;
float getStabilityDownwardImpulseFactor() const;
float getStabilityTrackConnectionAccel() const;
float getStabilitySmoothFlyingImpulse() const;
InterpolationArray getTurnRadius() const;
float getTurnTimeResetSteer() const;
InterpolationArray getTurnTimeFullSteer() const;
float getEnginePower() const;
float getEngineMaxSpeed() const;
float getEngineBrakeFactor() const;
float getEngineBrakeTimeIncrease() const;
float getEngineMaxSpeedReverseRatio() const;
std::vector<float> getGearSwitchRatio() const;
std::vector<float> getGearPowerIncrease() const;
float getMass() const;
float getWheelsDampingRelaxation() const;
float getWheelsDampingCompression() const;
float getCameraDistance() const;
float getCameraForwardUpAngle() const;
float getCameraBackwardUpAngle() const;
float getJumpAnimationTime() const;
float getLeanMax() const;
float getLeanSpeed() const;
float getAnvilDuration() const;
float getAnvilWeight() const;
float getAnvilSpeedFactor() const;
float getParachuteFriction() const;
float getParachuteDuration() const;
float getParachuteDurationOther() const;
float getParachuteLboundFraction() const;
float getParachuteUboundFraction() const;
float getParachuteMaxSpeed() const;
float getBubblegumDuration() const;
float getBubblegumSpeedFraction() const;
float getBubblegumTorque() const;
float getBubblegumFadeInTime() const;
float getBubblegumShieldDuration() const;
float getZipperDuration() const;
float getZipperForce() const;
float getZipperSpeedGain() const;
float getZipperMaxSpeedIncrease() const;
float getZipperFadeOutTime() const;
float getSwatterDuration() const;
float getSwatterDistance() const;
float getSwatterSquashDuration() const;
float getSwatterSquashSlowdown() const;
float getPlungerBandMaxLength() const;
float getPlungerBandForce() const;
float getPlungerBandDuration() const;
float getPlungerBandSpeedIncrease() const;
float getPlungerBandFadeOutTime() const;
float getPlungerInFaceTime() const;
std::vector<float> getStartupTime() const;
std::vector<float> getStartupBoost() const;
float getRescueDuration() const;
float getRescueVertOffset() const;
float getRescueHeight() const;
float getExplosionDuration() const;
float getExplosionRadius() const;
float getExplosionInvulnerabilityTime() const;
float getNitroDuration() const;
float getNitroEngineForce() const;
float getNitroConsumption() const;
float getNitroSmallContainer() const;
float getNitroBigContainer() const;
float getNitroMaxSpeedIncrease() const;
float getNitroFadeOutTime() const;
float getNitroMax() const;
float getSlipstreamDuration() const;
float getSlipstreamLength() const;
float getSlipstreamWidth() const;
float getSlipstreamCollectTime() const;
float getSlipstreamUseTime() const;
float getSlipstreamAddPower() const;
float getSlipstreamMinSpeed() const;
float getSlipstreamMaxSpeedIncrease() const;
float getSlipstreamFadeOutTime() const;
float getSkidIncrease() const;
float getSkidDecrease() const;
float getSkidMax() const;
float getSkidTimeTillMax() const;
float getSkidVisual() const;
float getSkidVisualTime() const;
float getSkidRevertVisualTime() const;
float getSkidMinSpeed() const;
std::vector<float> getSkidTimeTillBonus() const;
std::vector<float> getSkidBonusSpeed() const;
std::vector<float> getSkidBonusTime() const;
std::vector<float> getSkidBonusForce() const;
float getSkidPhysicalJumpTime() const;
float getSkidGraphicalJumpTime() const;
float getSkidPostSkidRotateFactor() const;
float getSkidReduceTurnMin() const;
float getSkidReduceTurnMax() const;
bool getSkidEnabled() const;
/* <characteristics-end kpdefs> */
}; // KartProperties }; // KartProperties
#endif #endif
/* EOF */

View File

@ -28,6 +28,7 @@
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/xml_characteristic.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
@ -175,12 +176,68 @@ void KartPropertiesManager::loadAllKarts(bool loading_icon)
} // loadAllKarts } // loadAllKarts
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Loads a single kart and (if not disabled) the oorresponding 3d model. /** Loads the characteristics from the characteristics config file.
* \param root The xml node where the characteristics are stored.
*/
void KartPropertiesManager::loadCharacteristics(const XMLNode *root)
{
// Load base characteristics
std::vector<XMLNode*> nodes;
root->getNodes("characteristic", nodes);
bool found = false;
std::string name;
for (const XMLNode *baseNode : nodes)
{
baseNode->get("name", &name);
if (name == "base")
{
found = true;
m_base_characteristic.reset(new XmlCharacteristic(baseNode));
break;
}
}
if (!found)
Log::fatal("KartPropertiesManager", "Base characteristics not found");
// Load difficulties
nodes.clear();
root->getNode("difficulties")->getNodes("characteristic", nodes);
for (const XMLNode *type : nodes)
{
type->get("name", &name);
m_difficulty_characteristics.insert(std::pair<const std::string,
std::unique_ptr<AbstractCharacteristic> >(name,
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(type))));
}
// Load kart type characteristics
nodes.clear();
root->getNode("kart-types")->getNodes("characteristic", nodes);
for (const XMLNode *type : nodes)
{
type->get("name", &name);
m_kart_type_characteristics.insert(std::pair<const std::string,
std::unique_ptr<AbstractCharacteristic> >(name,
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(type))));
}
// Load player difficulties
nodes.clear();
root->getNode("player-characteristics")->getNodes("characteristic", nodes);
for (const XMLNode *type : nodes)
{
type->get("name", &name);
m_player_characteristics.insert(std::pair<const std::string,
std::unique_ptr<AbstractCharacteristic> >(name,
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(type))));
}
}
//-----------------------------------------------------------------------------
/** Loads a single kart and (if not disabled) the corresponding 3d model.
* \param filename Full path to the kart config file. * \param filename Full path to the kart config file.
*/ */
bool KartPropertiesManager::loadKart(const std::string &dir) bool KartPropertiesManager::loadKart(const std::string &dir)
{ {
std::string config_filename=dir+"/kart.xml"; std::string config_filename = dir + "/kart.xml";
if(!file_manager->fileExists(config_filename)) if(!file_manager->fileExists(config_filename))
return false; return false;
@ -191,7 +248,7 @@ bool KartPropertiesManager::loadKart(const std::string &dir)
} }
catch (std::runtime_error& err) catch (std::runtime_error& err)
{ {
Log::error("[Kart_Properties_Manager]","Giving up loading '%s': %s", Log::error("[KartPropertiesManager]", "Giving up loading '%s': %s",
config_filename.c_str(), err.what()); config_filename.c_str(), err.what());
return false; return false;
} }
@ -201,7 +258,7 @@ bool KartPropertiesManager::loadKart(const std::string &dir)
if (kart_properties->getVersion() < stk_config->m_min_kart_version || if (kart_properties->getVersion() < stk_config->m_min_kart_version ||
kart_properties->getVersion() > stk_config->m_max_kart_version) kart_properties->getVersion() > stk_config->m_max_kart_version)
{ {
Log::warn("[Kart_Properties_Manager]", "Warning: kart '%s' is not " Log::warn("[KartPropertiesManager]", "Warning: kart '%s' is not "
"supported by this binary, ignored.", "supported by this binary, ignored.",
kart_properties->getIdent().c_str()); kart_properties->getIdent().c_str());
delete kart_properties; delete kart_properties;
@ -221,7 +278,7 @@ bool KartPropertiesManager::loadKart(const std::string &dir)
} }
m_all_kart_dirs.push_back(dir); m_all_kart_dirs.push_back(dir);
return true; return true;
} // loadKartData } // loadKart
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Sets the name of a mesh to use as a hat for all karts. /** Sets the name of a mesh to use as a hat for all karts.
@ -235,6 +292,36 @@ void KartPropertiesManager::setHatMeshName(const std::string &hat_name)
} }
} // setHatMeshName } // setHatMeshName
//-----------------------------------------------------------------------------
const AbstractCharacteristic* KartPropertiesManager::getDifficultyCharacteristic(const std::string &type) const
{
std::map<std::string, std::unique_ptr<AbstractCharacteristic> >::const_iterator
it = m_difficulty_characteristics.find(type);
if (it == m_difficulty_characteristics.cend())
return nullptr;
return it->second.get();
} // getDifficultyCharacteristic
//-----------------------------------------------------------------------------
const AbstractCharacteristic* KartPropertiesManager::getKartTypeCharacteristic(const std::string &type) const
{
std::map<std::string, std::unique_ptr<AbstractCharacteristic> >::const_iterator
it = m_kart_type_characteristics.find(type);
if (it == m_kart_type_characteristics.cend())
return nullptr;
return it->second.get();
} // getKartTypeCharacteristic
//-----------------------------------------------------------------------------
const AbstractCharacteristic* KartPropertiesManager::getPlayerCharacteristic(const std::string &type) const
{
std::map<std::string, std::unique_ptr<AbstractCharacteristic> >::const_iterator
it = m_player_characteristics.find(type);
if (it == m_player_characteristics.cend())
return nullptr;
return it->second.get();
} // getPlayerCharacteristic
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Returns index of the kart properties with the given ident. /** Returns index of the kart properties with the given ident.
* \return Index of kart (between 0 and number of karts - 1). * \return Index of kart (between 0 and number of karts - 1).

View File

@ -22,13 +22,16 @@
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
#include <map> #include <map>
#include <memory>
#include "network/remote_kart_info.hpp" #include "network/remote_kart_info.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#define ALL_KART_GROUPS_ID "all" #define ALL_KART_GROUPS_ID "all"
class AbstractCharacteristic;
class KartProperties; class KartProperties;
class XMLNode;
/** /**
* \ingroup karts * \ingroup karts
@ -58,6 +61,11 @@ private:
* all clients or not. */ * all clients or not. */
std::vector<bool> m_kart_available; std::vector<bool> m_kart_available;
std::unique_ptr<AbstractCharacteristic> m_base_characteristic;
std::map<std::string, std::unique_ptr<AbstractCharacteristic> > m_difficulty_characteristics;
std::map<std::string, std::unique_ptr<AbstractCharacteristic> > m_kart_type_characteristics;
std::map<std::string, std::unique_ptr<AbstractCharacteristic> > m_player_characteristics;
protected: protected:
typedef PtrVector<KartProperties> KartPropertiesVector; typedef PtrVector<KartProperties> KartPropertiesVector;
@ -74,6 +82,7 @@ public:
int getKartByGroup(const std::string& group, int getKartByGroup(const std::string& group,
int i) const; int i) const;
void loadCharacteristics (const XMLNode *root);
bool loadKart (const std::string &dir); bool loadKart (const std::string &dir);
void loadAllKarts (bool loading_icon = true); void loadAllKarts (bool loading_icon = true);
void unloadAllKarts (); void unloadAllKarts ();
@ -89,6 +98,18 @@ public:
std::vector<std::string> *ai_list); std::vector<std::string> *ai_list);
void setHatMeshName(const std::string &hat_name); void setHatMeshName(const std::string &hat_name);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Get the characteristic that holds the base values. */
const AbstractCharacteristic* getBaseCharacteristic() const { return m_base_characteristic.get(); }
// ------------------------------------------------------------------------
/** Get a characteristic that holds the values for a certain difficulty. */
const AbstractCharacteristic* getDifficultyCharacteristic(const std::string &type) const;
// ------------------------------------------------------------------------
/** Get a characteristic that holds the values for a kart type. */
const AbstractCharacteristic* getKartTypeCharacteristic(const std::string &type) const;
// ------------------------------------------------------------------------
/** Get a characteristic that holds the values for a player difficulty. */
const AbstractCharacteristic* getPlayerCharacteristic(const std::string &type) const;
// ------------------------------------------------------------------------
/** Returns a list of all groups. */ /** Returns a list of all groups. */
const std::vector<std::string>& getAllGroups() const {return m_all_groups;} const std::vector<std::string>& getAllGroups() const {return m_all_groups;}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -26,7 +26,7 @@
KartWithStats::KartWithStats(const std::string& ident, KartWithStats::KartWithStats(const std::string& ident,
unsigned int world_kart_id, unsigned int world_kart_id,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
const PlayerDifficulty *difficulty) PerPlayerDifficulty difficulty)
: Kart(ident, world_kart_id, position, : Kart(ident, world_kart_id, position,
init_transform, difficulty) init_transform, difficulty)
{ {

View File

@ -75,7 +75,7 @@ public:
unsigned int world_kart_id, unsigned int world_kart_id,
int position, int position,
const btTransform& init_transform, const btTransform& init_transform,
const PlayerDifficulty *difficulty); PerPlayerDifficulty difficulty);
virtual void update(float dt); virtual void update(float dt);
virtual void reset(); virtual void reset();
virtual void collectedItem(Item *item, int add_info); virtual void collectedItem(Item *item, int add_info);

View File

@ -62,8 +62,7 @@ MaxSpeed::MaxSpeed(AbstractKart *kart)
*/ */
void MaxSpeed::reset() void MaxSpeed::reset()
{ {
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed() * m_current_max_speed = m_kart->getKartProperties()->getEngineMaxSpeed();
m_kart->getPlayerDifficulty()->getMaxSpeed();
m_min_speed = -1.0f; m_min_speed = -1.0f;
for(unsigned int i=MS_DECREASE_MIN; i<MS_DECREASE_MAX; i++) for(unsigned int i=MS_DECREASE_MIN; i<MS_DECREASE_MAX; i++)
@ -243,8 +242,7 @@ void MaxSpeed::update(float dt)
} }
m_add_engine_force = 0; m_add_engine_force = 0;
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed() * m_current_max_speed = m_kart->getKartProperties()->getEngineMaxSpeed();
m_kart->getPlayerDifficulty()->getMaxSpeed();
// Then add the speed increase from each category // Then add the speed increase from each category
// ---------------------------------------------- // ----------------------------------------------

View File

@ -1,199 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "karts/player_difficulty.hpp"
#include "config/stk_config.hpp"
#include "io/xml_node.hpp"
#include "karts/skidding_properties.hpp"
#include "race/race_manager.hpp"
#include "modes/world.hpp"
#include "utils/log.hpp"
/**
* The constructor initialises all values with default values.
*/
PlayerDifficulty::PlayerDifficulty(const std::string &filename)
{
// Set all other values to undefined, so that it can later be tested
// if everything is defined properly.
m_mass = m_brake_factor = m_brake_time_increase = m_rescue_time =
m_explosion_time = m_explosion_invulnerability_time = m_zipper_time =
m_zipper_fade_out_time = m_zipper_force = m_zipper_speed_gain =
m_zipper_max_speed_increase = m_rubber_band_max_length =
m_rubber_band_force = m_rubber_band_duration =
m_rubber_band_speed_increase = m_rubber_band_fade_out_time =
m_nitro_consumption = m_nitro_max_speed_increase =
m_nitro_engine_force = m_nitro_duration = m_nitro_fade_out_time =
m_bubblegum_time = m_bubblegum_torque = m_bubblegum_speed_fraction =
m_bubblegum_fade_in_time = m_swatter_duration = m_squash_duration =
m_squash_slowdown = m_max_speed_reverse_ratio = m_slipstream_length =
m_slipstream_width = m_slipstream_collect_time =
m_slipstream_use_time = m_slipstream_add_power =
m_slipstream_min_speed = m_slipstream_max_speed_increase =
m_slipstream_duration = m_slipstream_fade_out_time = 1;
m_startup_times.resize(RaceManager::DIFFICULTY_COUNT, 1);
m_startup_boost.resize(RaceManager::DIFFICULTY_COUNT, 1);
// The default constructor for stk_config uses filename=""
if (filename != "")
load(filename, "normal");
} // PlayerDifficulty
//-----------------------------------------------------------------------------
/** Destructor, dereferences the kart model. */
PlayerDifficulty::~PlayerDifficulty()
{
} // ~PlayerDifficulty
//-----------------------------------------------------------------------------
/** */
std::string PlayerDifficulty::getIdent() const
{
switch(m_difficulty)
{
case PLAYER_DIFFICULTY_NORMAL: return "normal"; break;
case PLAYER_DIFFICULTY_HANDICAP: return "handicap"; break;
default: assert(false);
}
return "";
}
//-----------------------------------------------------------------------------
/** Loads the difficulty properties from a file.
* \param filename Filename to load.
* \param node Name of the xml node to load the data from
*/
void PlayerDifficulty::load(const std::string &filename, const std::string &node)
{
const XMLNode* root = new XMLNode(filename);
getAllData(root->getNode(node));
if(root)
delete root;
} // load
//-----------------------------------------------------------------------------
/** Actually reads in the data from the xml file.
* \param root Root of the xml tree.
*/
void PlayerDifficulty::getAllData(const XMLNode * root)
{
if(const XMLNode *mass_node = root->getNode("mass"))
mass_node->get("value", &m_mass);
if(const XMLNode *engine_node = root->getNode("engine"))
{
engine_node->get("brake-factor", &m_brake_factor);
engine_node->get("brake-time-increase", &m_brake_time_increase);
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
engine_node->get("power", &m_engine_power);
engine_node->get("max-speed", &m_max_speed);
}
if(const XMLNode *nitro_node = root->getNode("nitro"))
{
nitro_node->get("consumption", &m_nitro_consumption );
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 );
}
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("torque", &m_bubblegum_torque );
bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time );
}
if(const XMLNode *rescue_node = root->getNode("rescue"))
rescue_node->get("time", &m_rescue_time);
if(const XMLNode *explosion_node = root->getNode("explosion"))
{
explosion_node->get("time", &m_explosion_time);
explosion_node->get("invulnerability-time",
&m_explosion_invulnerability_time);
}
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 *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(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(const XMLNode *startup_node= root->getNode("startup"))
{
startup_node->get("time", &m_startup_times);
startup_node->get("boost", &m_startup_boost);
}
} // getAllData
// ----------------------------------------------------------------------------
/** 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
* speed-boost from the corresponding entry in m_startup_boost.
* If the kart started too slow (i.e. slower than the longest time in
* m_startup_times, it returns 0.
*/
float PlayerDifficulty::getStartupBoost() const
{
float t = World::getWorld()->getTime();
for(unsigned int i=0; i<m_startup_times.size(); i++)
{
if(t<=m_startup_times[i]) return m_startup_boost[i];
}
return 0;
} // getStartupBoost

View File

@ -1,345 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// 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_PLAYER_DIFFICULTY_HPP
#define HEADER_PLAYER_DIFFICULTY_HPP
#include "network/remote_kart_info.hpp"
#include <string>
#include <vector>
class XMLNode;
/**
* \brief This class stores values that modify the properties of a kart.
* This includes physical properties like speed and the effect of items.
* The values stored in this class get multiplied with the current
* properties of the kart. If all values here are set to 1, nothing changes.
*
* \ingroup karts
*/
class PlayerDifficulty
{
private:
/** Actual difficulty */
PerPlayerDifficulty m_difficulty;
// -----------------
/** Weight of kart. */
float m_mass;
/** Maximum force from engine for each difficulty. */
float m_engine_power;
/** Braking factor * engine_power braking force. */
float m_brake_factor;
/** Brake_time * m_brake_time_increase will increase the break time
* over time. */
float m_brake_time_increase;
/** Time a kart is moved upwards after when it is rescued. */
float m_rescue_time;
/** Time an animated explosion is shown. Longer = more delay for kart. */
float m_explosion_time;
/** How long a kart is invulnerable after it is hit by an explosion. */
float m_explosion_invulnerability_time;
/** Duration a zipper is active. */
float m_zipper_time;
/** Fade out time for a zipper. */
float m_zipper_fade_out_time;
/** Additional force added to the acceleration. */
float m_zipper_force;
/** Initial one time speed gain. */
float m_zipper_speed_gain;
/** Absolute increase of the kart's maximum speed (in m/s). */
float m_zipper_max_speed_increase;
/** Max. length of plunger rubber band. */
float m_rubber_band_max_length;
/** Force of an attached rubber band. */
/** Duration a rubber band works. */
float m_rubber_band_force;
/** How long the rubber band will fly. */
float m_rubber_band_duration;
/** Increase of maximum speed of the kart when the rubber band pulls. */
float m_rubber_band_speed_increase;
/** Fade out time when the rubber band is removed. */
float m_rubber_band_fade_out_time;
/**Duration of plunger in face depending on difficulty. */
float m_plunger_in_face_duration;
/** Nitro consumption. */
float m_nitro_consumption;
/* How much the speed of a kart might exceed its maximum speed (in m/s). */
float m_nitro_max_speed_increase;
/** Additional engine force to affect the kart. */
float m_nitro_engine_force;
/** How long the increased nitro max speed will be valid after
* the kart stops using nitro (and the fade-out-time starts). */
float m_nitro_duration;
/** Duration during which the increased maximum speed
* due to nitro fades out. */
float m_nitro_fade_out_time;
/** Bubble gum diration. */
float m_bubblegum_time;
/** Torque to add when a bubble gum was hit in order to make the kart go
* sideways a bit. */
float m_bubblegum_torque;
/** Fraction of top speed that can be reached maximum after hitting a
* bubble gum. */
float m_bubblegum_speed_fraction;
/** How long to fade in the slowdown for a bubble gum. */
float m_bubblegum_fade_in_time;
/** How long the swatter lasts. */
float m_swatter_duration;
/** How long a kart will remain squashed. */
float m_squash_duration;
/** The slowdown to apply while a kart is squashed. The new maxspeed
* is max_speed*m_squash_slowdown. */
float m_squash_slowdown;
/** The maximum speed at each difficulty. */
float m_max_speed;
float m_max_speed_reverse_ratio;
/** How far behind a kart slipstreaming is effective. */
float m_slipstream_length;
/** How wide the slipstream area is at the end. */
float m_slipstream_width;
/** Time after which sstream gives a bonus. */
float m_slipstream_collect_time;
/** Time slip-stream bonus is effective. */
float m_slipstream_use_time;
/** Additional power due to sstreaming. */
float m_slipstream_add_power;
/** Minimum speed for slipstream to take effect. */
float m_slipstream_min_speed;
/** How much the speed of the kart might exceed its
* normal maximum speed. */
float m_slipstream_max_speed_increase;
/** How long the higher speed lasts after slipstream stopped working. */
float m_slipstream_duration;
/** How long the slip stream speed increase will gradually be reduced. */
float m_slipstream_fade_out_time;
/** If the kart starts within the specified time at index I after 'go',
* it receives the speed boost from m_startup_boost[I]. */
std::vector<float> m_startup_times;
/** The startup boost is the kart starts fast enough. */
std::vector<float> m_startup_boost;
void load (const std::string &filename,
const std::string &node);
public:
PlayerDifficulty (const std::string &filename="");
~PlayerDifficulty ();
void getAllData (const XMLNode * root);
std::string getIdent() const;
float getStartupBoost () const;
// ------------------------------------------------------------------------
/** Returns the maximum engine power depending on difficulty. */
float getMaxPower () const {return m_engine_power; }
// ------------------------------------------------------------------------
/** Get braking information. */
float getBrakeFactor () const {return m_brake_factor; }
// ------------------------------------------------------------------------
/** Returns the additional brake factor which depends on time. */
float getBrakeTimeIncrease() const { return m_brake_time_increase; }
// ------------------------------------------------------------------------
/** Get maximum reverse speed ratio. */
float getMaxSpeedReverseRatio () const
{return m_max_speed_reverse_ratio; }
// ------------------------------------------------------------------------
/** Returns the maximum speed dependent on the difficult level. */
float getMaxSpeed () const { return m_max_speed; }
// ------------------------------------------------------------------------
/** Returns the nitro consumption. */
float getNitroConsumption () const {return m_nitro_consumption; }
// ------------------------------------------------------------------------
/** Returns the increase of maximum speed due to nitro. */
float getNitroMaxSpeedIncrease () const
{return m_nitro_max_speed_increase; }
// ------------------------------------------------------------------------
float getNitroEngineForce () const {return m_nitro_engine_force; }
// ------------------------------------------------------------------------
/** Returns how long the increased nitro max speed will be valid after
* the kart stops using nitro (and the fade-out-time starts). */
float getNitroDuration () const {return m_nitro_duration; }
// ------------------------------------------------------------------------
/** Returns the duration during which the increased maximum speed
* due to nitro fades out. */
float getNitroFadeOutTime () const {return m_nitro_fade_out_time; }
// ------------------------------------------------------------------------
/** Returns how long a bubble gum is active. */
float getBubblegumTime() const { return m_bubblegum_time; }
// ------------------------------------------------------------------------
/** Returns the torque to add when a bubble gum was hit . */
float getBubblegumTorque() const { return m_bubblegum_torque; }
// ------------------------------------------------------------------------
/** Returns the fraction of top speed that can be reached maximum after
* hitting a bubble gum. */
float getBubblegumSpeedFraction() const {return m_bubblegum_speed_fraction;}
// ------------------------------------------------------------------------
/** Returns how long to fade in the slowdown for a bubble gum. */
float getBubblegumFadeInTime() const { return m_bubblegum_fade_in_time; }
// ------------------------------------------------------------------------
/** Returns the time a kart is rised during a rescue. */
float getRescueTime () const {return m_rescue_time; }
// ------------------------------------------------------------------------
/** Returns the time an explosion animation is shown. */
float getExplosionTime () const {return m_explosion_time; }
// ------------------------------------------------------------------------
/** Returns how long a kart is invulnerable after being hit by an
explosion. */
float getExplosionInvulnerabilityTime() const
{ return m_explosion_invulnerability_time; }
// ------------------------------------------------------------------------
/** Returns the maximum length of a rubber band before it breaks. */
float getRubberBandMaxLength () const {return m_rubber_band_max_length;}
// ------------------------------------------------------------------------
/** Returns force a rubber band has when attached to a kart. */
float getRubberBandForce () const {return m_rubber_band_force; }
// ------------------------------------------------------------------------
/** Returns the duration a rubber band is active for. */
float getRubberBandDuration () const {return m_rubber_band_duration; }
// ------------------------------------------------------------------------
/** Returns the increase of maximum speed while a rubber band is
* pulling. */
float getRubberBandSpeedIncrease() const
{
return m_rubber_band_speed_increase;
}
// ------------------------------------------------------------------------
/** Return the fade out time once a rubber band is removed. */
float getRubberBandFadeOutTime() const
{
return m_rubber_band_fade_out_time;
}
// ------------------------------------------------------------------------
/** Returns duration of a plunger in your face. */
float getPlungerInFaceTime () const {return m_plunger_in_face_duration;}
// ------------------------------------------------------------------------
/** Returns the time a zipper is active. */
float getZipperTime () const {return m_zipper_time; }
// ------------------------------------------------------------------------
/** Returns the time a zipper is active. */
float getZipperFadeOutTime () const {return m_zipper_fade_out_time; }
// ------------------------------------------------------------------------
/** Returns the additional force added applied to the kart. */
float getZipperForce () const { return m_zipper_force; }
// ------------------------------------------------------------------------
/** Returns the initial zipper speed gain. */
float getZipperSpeedGain () const { return m_zipper_speed_gain; }
// ------------------------------------------------------------------------
/** Returns the increase of the maximum speed of the kart
* if a zipper is active. */
float getZipperMaxSpeedIncrease () const
{ return m_zipper_max_speed_increase;}
// ------------------------------------------------------------------------
/** Returns how far behind a kart slipstreaming works. */
float getSlipstreamLength () const {return m_slipstream_length; }
// ------------------------------------------------------------------------
/** Returns how wide the slipstream area is at the end. */
float getSlipstreamWidth () const {return m_slipstream_width; }
// ------------------------------------------------------------------------
/** Returns time after which slipstream has maximum effect. */
float getSlipstreamCollectTime () const
{return m_slipstream_collect_time; }
// ------------------------------------------------------------------------
/** Returns time after which slipstream has maximum effect. */
float getSlipstreamUseTime () const {return m_slipstream_use_time; }
// ------------------------------------------------------------------------
/** Returns additional power due to slipstreaming. */
float getSlipstreamAddPower () const {return m_slipstream_add_power; }
// ------------------------------------------------------------------------
/** Returns the minimum slipstream speed. */
float getSlipstreamMinSpeed () const {return m_slipstream_min_speed; }
// ------------------------------------------------------------------------
/** Returns the increase of the maximum speed of a kart
* due to slipstream. */
float getSlipstreamMaxSpeedIncrease() const
{ return m_slipstream_max_speed_increase; }
// ------------------------------------------------------------------------
/** Returns how long the higher speed lasts after slipstream
* stopped working. */
float getSlipstreamDuration () const { return m_slipstream_duration; }
// ------------------------------------------------------------------------
/** Returns how long the slip stream speed increase will gradually
* be reduced. */
float getSlipstreamFadeOutTime () const
{ return m_slipstream_fade_out_time; }
// ------------------------------------------------------------------------
/** Returns how long a swatter will stay attached/ready to be used. */
float getSwatterDuration() const { return m_swatter_duration; }
// ------------------------------------------------------------------------
/** Returns how long a kart remains squashed. */
float getSquashDuration() const {return m_squash_duration; }
// ------------------------------------------------------------------------
/** Returns the slowdown of a kart that is squashed. */
float getSquashSlowdown() const {return m_squash_slowdown; }
}; // KartProperties
#endif

View File

@ -39,8 +39,7 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
{ {
m_referee = new Referee(*m_kart); m_referee = new Referee(*m_kart);
m_kart->getNode()->addChild(m_referee->getSceneNode()); m_kart->getNode()->addChild(m_referee->getSceneNode());
m_timer = m_kart->getKartProperties()->getRescueTime() * m_timer = m_kart->getKartProperties()->getRescueDuration();
m_kart->getPlayerDifficulty()->getRescueTime();
m_velocity = m_kart->getKartProperties()->getRescueHeight() / m_timer; m_velocity = m_kart->getKartProperties()->getRescueHeight() / m_timer;
m_xyz = m_kart->getXYZ(); m_xyz = m_kart->getXYZ();

View File

@ -36,7 +36,7 @@
/** Constructor of the skidding object. /** Constructor of the skidding object.
*/ */
Skidding::Skidding(Kart *kart, const SkiddingProperties *sp) Skidding::Skidding(Kart *kart)
{ {
#ifdef SKID_DEBUG #ifdef SKID_DEBUG
m_predicted_curve = new ShowCurve(0.05f, 0.05f, m_predicted_curve = new ShowCurve(0.05f, 0.05f,
@ -47,8 +47,8 @@ Skidding::Skidding(Kart *kart, const SkiddingProperties *sp)
m_actual_curve->setVisible(false); m_actual_curve->setVisible(false);
#endif #endif
m_kart = kart; m_kart = kart;
copyFrom(sp); m_skid_reduce_turn_delta = m_kart->getKartProperties()->getSkidReduceTurnMax()
m_skid_reduce_turn_delta = m_skid_reduce_turn_max - m_skid_reduce_turn_min; - m_kart->getKartProperties()->getSkidReduceTurnMin();
reset(); reset();
} // Skidding } // Skidding
@ -95,13 +95,15 @@ void Skidding::reset()
*/ */
void Skidding::updateSteering(float steer, float dt) void Skidding::updateSteering(float steer, float dt)
{ {
const KartProperties *kp = m_kart->getKartProperties();
switch(m_skid_state) switch(m_skid_state)
{ {
case SKID_SHOW_GFX_LEFT: case SKID_SHOW_GFX_LEFT:
case SKID_SHOW_GFX_RIGHT: case SKID_SHOW_GFX_RIGHT:
case SKID_NONE: case SKID_NONE:
m_real_steering = steer; m_real_steering = steer;
if(m_skid_time<m_skid_visual_time && m_skid_time>0) if (m_skid_time < kp->getSkidVisualTime() && m_skid_time > 0)
{ {
float f = m_visual_rotation - m_visual_rotation*dt/m_skid_time; float f = m_visual_rotation - m_visual_rotation*dt/m_skid_time;
// Floating point errors when m_skid_time is very close to 0 // Floating point errors when m_skid_time is very close to 0
@ -125,25 +127,27 @@ void Skidding::updateSteering(float steer, float dt)
case SKID_ACCUMULATE_RIGHT: case SKID_ACCUMULATE_RIGHT:
{ {
float f = (1.0f+steer)*0.5f; // map [-1,1] --> [0, 1] float f = (1.0f+steer)*0.5f; // map [-1,1] --> [0, 1]
m_real_steering = m_skid_reduce_turn_min+ m_real_steering = kp->getSkidReduceTurnMin()
m_skid_reduce_turn_delta*f; + m_skid_reduce_turn_delta * f;
if(m_skid_time < m_skid_visual_time) if(m_skid_time < kp->getSkidVisualTime())
m_visual_rotation = m_skid_visual*m_real_steering*m_skid_time m_visual_rotation = kp->getSkidVisual()
/ m_skid_visual_time; * m_real_steering * m_skid_time
/ kp->getSkidVisualTime();
else else
m_visual_rotation = m_skid_visual * m_real_steering; m_visual_rotation = kp->getSkidVisual() * m_real_steering;
break; break;
} }
case SKID_ACCUMULATE_LEFT: case SKID_ACCUMULATE_LEFT:
{ {
float f = (-1.0f+steer)*0.5f; // map [-1,1] --> [-1, 0] float f = (-1.0f+steer)*0.5f; // map [-1,1] --> [-1, 0]
m_real_steering = -m_skid_reduce_turn_min+ m_real_steering = -kp->getSkidReduceTurnMin()
m_skid_reduce_turn_delta*f; + m_skid_reduce_turn_delta * f;
if(m_skid_time < m_skid_visual_time) if(m_skid_time < kp->getSkidVisualTime())
m_visual_rotation = m_skid_visual*m_real_steering*m_skid_time m_visual_rotation = kp->getSkidVisual()
/ m_skid_visual_time; * m_real_steering * m_skid_time
/ kp->getSkidVisualTime();
else else
m_visual_rotation = m_skid_visual * m_real_steering; m_visual_rotation = kp->getSkidVisual() * m_real_steering;
break; break;
} }
@ -173,13 +177,13 @@ float Skidding::getSteeringWhenSkidding(float steering) const
break; break;
case SKID_ACCUMULATE_RIGHT: case SKID_ACCUMULATE_RIGHT:
{ {
float f = (steering - m_skid_reduce_turn_min) float f = (steering - m_kart->getKartProperties()->getSkidReduceTurnMin())
/ m_skid_reduce_turn_delta; / m_skid_reduce_turn_delta;
return f *2.0f-1.0f; return f *2.0f-1.0f;
} }
case SKID_ACCUMULATE_LEFT: case SKID_ACCUMULATE_LEFT:
{ {
float f = (steering + m_skid_reduce_turn_min) float f = (steering + m_kart->getKartProperties()->getSkidReduceTurnMin())
/ m_skid_reduce_turn_delta; / m_skid_reduce_turn_delta;
return 2.0f * f +1.0f; return 2.0f * f +1.0f;
} }
@ -198,6 +202,8 @@ float Skidding::getSteeringWhenSkidding(float steering) const
void Skidding::update(float dt, bool is_on_ground, void Skidding::update(float dt, bool is_on_ground,
float steering, KartControl::SkidControl skidding) float steering, KartControl::SkidControl skidding)
{ {
const KartProperties *kp = m_kart->getKartProperties();
// If a kart animation is shown, stop all skidding bonuses. // If a kart animation is shown, stop all skidding bonuses.
if(m_kart->getKartAnimation()) if(m_kart->getKartAnimation())
{ {
@ -212,7 +218,7 @@ void Skidding::update(float dt, bool is_on_ground,
#endif #endif
// No skidding backwards or while stopped // No skidding backwards or while stopped
if(m_kart->getSpeed() < m_min_skid_speed && if(m_kart->getSpeed() < kp->getSkidMinSpeed() &&
m_skid_state != SKID_NONE && m_skid_state != SKID_BREAK) m_skid_state != SKID_NONE && m_skid_state != SKID_BREAK)
{ {
m_skid_state = SKID_BREAK; m_skid_state = SKID_BREAK;
@ -223,15 +229,16 @@ void Skidding::update(float dt, bool is_on_ground,
m_skid_bonus_ready = false; m_skid_bonus_ready = false;
if (is_on_ground) if (is_on_ground)
{ {
if((fabs(steering) > 0.001f) && if ((fabs(steering) > 0.001f) &&
m_kart->getSpeed()>m_min_skid_speed && m_kart->getSpeed() > kp->getSkidMinSpeed() &&
(skidding==KartControl::SC_LEFT||skidding==KartControl::SC_RIGHT)) (skidding == KartControl::SC_LEFT || skidding == KartControl::SC_RIGHT))
{ {
m_skid_factor += m_skid_increase *dt/m_time_till_max_skid; m_skid_factor += kp->getSkidIncrease()
* dt / kp->getSkidTimeTillMax();
} }
else if(m_skid_factor>1.0f) else if (m_skid_factor > 1.0f)
{ {
m_skid_factor *= m_skid_decrease; m_skid_factor *= kp->getSkidDecrease();
} }
} }
else else
@ -239,10 +246,10 @@ void Skidding::update(float dt, bool is_on_ground,
m_skid_factor = 1.0f; // Lose any skid factor as soon as we fly m_skid_factor = 1.0f; // Lose any skid factor as soon as we fly
} }
if(m_skid_factor>m_skid_max) if (m_skid_factor > kp->getSkidMax())
m_skid_factor = m_skid_max; m_skid_factor = kp->getSkidMax();
else else
if(m_skid_factor<1.0f) m_skid_factor = 1.0f; if (m_skid_factor < 1.0f) m_skid_factor = 1.0f;
// If skidding was started and a graphical jump should still // If skidding was started and a graphical jump should still
// be displayed, update the data // be displayed, update the data
@ -288,8 +295,9 @@ void Skidding::update(float dt, bool is_on_ground,
break; break;
// Don't allow skidding while the kart is (apparently) // Don't allow skidding while the kart is (apparently)
// still in the air, or when the kart is too slow // still in the air, or when the kart is too slow
if(m_remaining_jump_time>0 || if (m_remaining_jump_time > 0 ||
m_kart->getSpeed() <m_min_skid_speed) break; m_kart->getSpeed() < kp->getSkidMinSpeed())
break;
m_skid_state = skidding==KartControl::SC_RIGHT m_skid_state = skidding==KartControl::SC_RIGHT
? SKID_ACCUMULATE_RIGHT ? SKID_ACCUMULATE_RIGHT
@ -300,14 +308,14 @@ void Skidding::update(float dt, bool is_on_ground,
// Then use this speed to determine the impulse necessary to // Then use this speed to determine the impulse necessary to
// reach this speed. // reach this speed.
float v = World::getWorld()->getTrack()->getGravity() float v = World::getWorld()->getTrack()->getGravity()
* 0.5f*m_physical_jump_time; * 0.5f * kp->getSkidPhysicalJumpTime();
btVector3 imp(0, v / m_kart->getBody()->getInvMass(),0); btVector3 imp(0, v / m_kart->getBody()->getInvMass(),0);
m_kart->getVehicle()->getRigidBody()->applyCentralImpulse(imp); m_kart->getVehicle()->getRigidBody()->applyCentralImpulse(imp);
// Some karts might use a graphical-only jump. Set it up: // Some karts might use a graphical-only jump. Set it up:
m_jump_speed = World::getWorld()->getTrack()->getGravity() m_jump_speed = World::getWorld()->getTrack()->getGravity()
* 0.5f*m_graphical_jump_time; * 0.5f * kp->getSkidGraphicalJumpTime();
m_remaining_jump_time = m_graphical_jump_time; m_remaining_jump_time = kp->getSkidGraphicalJumpTime();
#ifdef SKID_DEBUG #ifdef SKID_DEBUG
#define SPEED 20.0f #define SPEED 20.0f
@ -318,13 +326,13 @@ void Skidding::update(float dt, bool is_on_ground,
m_predicted_curve->setVisible(true); m_predicted_curve->setVisible(true);
m_predicted_curve->setPosition(m_kart->getXYZ()); m_predicted_curve->setPosition(m_kart->getXYZ());
m_predicted_curve->setHeading(m_kart->getHeading()); m_predicted_curve->setHeading(m_kart->getHeading());
float angle = m_kart->getKartProperties() float angle = kp
->getMaxSteerAngle(m_kart->getSpeed()) ->getMaxSteerAngle(m_kart->getSpeed())
* fabsf(getSteeringFraction()); * fabsf(getSteeringFraction());
angle = m_kart->getKartProperties() angle = kp
->getMaxSteerAngle(SPEED) ->getMaxSteerAngle(SPEED)
* fabsf(getSteeringFraction()); * fabsf(getSteeringFraction());
float r = m_kart->getKartProperties()->getWheelBase() float r = kp->getWheelBase()
/ asin(angle)*1.0f; / asin(angle)*1.0f;
const int num_steps = 50; const int num_steps = 50;
@ -335,7 +343,7 @@ void Skidding::update(float dt, bool is_on_ground,
{ {
float real_x = m_skid_state==SKID_ACCUMULATE_LEFT ? -x : x; float real_x = m_skid_state==SKID_ACCUMULATE_LEFT ? -x : x;
Vec3 xyz(real_x, 0.2f, sqrt(r*r-(r-x)*(r-x))*(1.0f+SPEED/150.0f) Vec3 xyz(real_x, 0.2f, sqrt(r*r-(r-x)*(r-x))*(1.0f+SPEED/150.0f)
*(1+(angle/m_kart->getKartProperties()->getMaxSteerAngle(SPEED)-0.6f)*0.1f)); *(1+(angle/kp->getMaxSteerAngle(SPEED)-0.6f)*0.1f));
Vec3 xyz1=m_kart->getTrans()(xyz); Vec3 xyz1=m_kart->getTrans()(xyz);
Log::debug("Skidding", "predict %f %f %f speed %f angle %f", Log::debug("Skidding", "predict %f %f %f speed %f angle %f",
xyz1.getX(), xyz1.getY(), xyz1.getZ(), xyz1.getX(), xyz1.getY(), xyz1.getZ(),
@ -368,7 +376,7 @@ void Skidding::update(float dt, bool is_on_ground,
Log::debug("Skidding", "actual %f %f %f turn %f speed %f angle %f", Log::debug("Skidding", "actual %f %f %f turn %f speed %f angle %f",
m_kart->getXYZ().getX(),m_kart->getXYZ().getY(),m_kart->getXYZ().getZ(), m_kart->getXYZ().getX(),m_kart->getXYZ().getY(),m_kart->getXYZ().getZ(),
m_real_steering, m_kart->getSpeed(), m_real_steering, m_kart->getSpeed(),
m_kart->getKartProperties()->getMaxSteerAngle(m_kart->getSpeed())); kp->getMaxSteerAngle(m_kart->getSpeed()));
#endif #endif
m_skid_time += dt; m_skid_time += dt;
float bonus_time, bonus_speed, bonus_force; float bonus_time, bonus_speed, bonus_force;
@ -388,11 +396,11 @@ void Skidding::update(float dt, bool is_on_ground,
m_skid_state = m_skid_state == SKID_ACCUMULATE_LEFT m_skid_state = m_skid_state == SKID_ACCUMULATE_LEFT
? SKID_SHOW_GFX_LEFT ? SKID_SHOW_GFX_LEFT
: SKID_SHOW_GFX_RIGHT; : SKID_SHOW_GFX_RIGHT;
float t = std::min(m_skid_time, m_skid_visual_time); float t = std::min(m_skid_time, kp->getSkidVisualTime());
t = std::min(t, m_skid_revert_visual_time); t = std::min(t, kp->getSkidRevertVisualTime());
float vso = getVisualSkidRotation(); float vso = getVisualSkidRotation();
btVector3 rot(0, vso*m_post_skid_rotate_factor, 0); btVector3 rot(0, vso * kp->getSkidPostSkidRotateFactor(), 0);
m_kart->getVehicle()->setTimedRotation(t, rot); m_kart->getVehicle()->setTimedRotation(t, rot);
// skid_time is used to count backwards for the GFX // skid_time is used to count backwards for the GFX
m_skid_time = t; m_skid_time = t;
@ -452,16 +460,19 @@ unsigned int Skidding::getSkidBonus(float *bonus_time,
float *bonus_speed, float *bonus_speed,
float *bonus_force) const float *bonus_force) const
{ {
const KartProperties *kp = m_kart->getKartProperties();
*bonus_time = 0; *bonus_time = 0;
*bonus_speed = 0; *bonus_speed = 0;
*bonus_force = 0; *bonus_force = 0;
for(unsigned int i=0; i<m_skid_bonus_speed.size(); i++) for (unsigned int i = 0; i < kp->getSkidBonusSpeed().size(); i++)
{ {
if(m_skid_time<=m_skid_time_till_bonus[i]) return i; if (m_skid_time <= kp->getSkidTimeTillBonus()[i])
*bonus_speed = m_skid_bonus_speed[i]; return i;
*bonus_time = m_skid_bonus_time[i]; *bonus_speed = kp->getSkidBonusSpeed()[i];
*bonus_force = m_skid_bonus_force[i]; *bonus_time = kp->getSkidBonusTime()[i];
*bonus_force = kp->getSkidBonusForce()[i];
} }
return (unsigned int) m_skid_bonus_speed.size(); return (unsigned int) kp->getSkidBonusSpeed().size();
} // getSkidBonusForce } // getSkidBonusForce

View File

@ -19,7 +19,6 @@
#ifndef HEADER_SKIDDING_HPP #ifndef HEADER_SKIDDING_HPP
#define HEADER_SKIDDING_HPP #define HEADER_SKIDDING_HPP
#include "karts/skidding_properties.hpp"
#include "karts/controller/kart_control.hpp" #include "karts/controller/kart_control.hpp"
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
@ -35,7 +34,7 @@ class ShowCurve;
#undef SKID_DEBUG #undef SKID_DEBUG
class Skidding : public SkiddingProperties class Skidding
{ {
public: public:
LEAK_CHECK(); LEAK_CHECK();
@ -101,7 +100,7 @@ private:
float *bonus_force) const; float *bonus_force) const;
void updateSteering(float steer, float dt); void updateSteering(float steer, float dt);
public: public:
Skidding(Kart *kart, const SkiddingProperties *sp); Skidding(Kart *kart);
~Skidding(); ~Skidding();
void reset(); void reset();
void update(float dt, bool is_on_ground, float steer, void update(float dt, bool is_on_ground, float steer,

View File

@ -1,134 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2012-2015 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "karts/skidding_properties.hpp"
#include "io/xml_node.hpp"
#include "utils/log.hpp"
#include <string.h>
float SkiddingProperties::UNDEFINED = -99.9f;
SkiddingProperties::SkiddingProperties()
{
m_skid_increase = UNDEFINED;
m_skid_decrease = UNDEFINED;
m_skid_max = UNDEFINED;
m_time_till_max_skid = UNDEFINED;
m_skid_visual = UNDEFINED;
m_skid_visual_time = UNDEFINED;
m_skid_revert_visual_time = UNDEFINED;
m_post_skid_rotate_factor = UNDEFINED;
m_skid_reduce_turn_min = UNDEFINED;
m_skid_reduce_turn_max = UNDEFINED;
m_physical_jump_time = UNDEFINED;
m_graphical_jump_time = UNDEFINED;
m_min_skid_speed = UNDEFINED;
m_has_skidmarks = true;
m_skid_bonus_time.clear();
m_skid_bonus_speed.clear();
m_skid_time_till_bonus.clear();
m_skid_bonus_force.clear();
} // SkiddingProperties
// ----------------------------------------------------------------------------
void SkiddingProperties::load(const XMLNode *skid_node)
{
skid_node->get("increase", &m_skid_increase );
skid_node->get("decrease", &m_skid_decrease );
skid_node->get("max", &m_skid_max );
skid_node->get("time-till-max", &m_time_till_max_skid );
skid_node->get("visual", &m_skid_visual );
skid_node->get("visual-time", &m_skid_visual_time );
skid_node->get("revert-visual-time", &m_skid_revert_visual_time);
skid_node->get("post-skid-rotate-factor",&m_post_skid_rotate_factor);
skid_node->get("reduce-turn-min", &m_skid_reduce_turn_min );
skid_node->get("reduce-turn-max", &m_skid_reduce_turn_max );
skid_node->get("enable", &m_has_skidmarks );
skid_node->get("bonus-time", &m_skid_bonus_time );
skid_node->get("bonus-speed", &m_skid_bonus_speed );
skid_node->get("time-till-bonus", &m_skid_time_till_bonus );
skid_node->get("bonus-force", &m_skid_bonus_force );
skid_node->get("physical-jump-time", &m_physical_jump_time );
skid_node->get("graphical-jump-time", &m_graphical_jump_time );
skid_node->get("min-speed", &m_min_skid_speed );
} // load
// ----------------------------------------------------------------------------
void SkiddingProperties::checkAllSet(const std::string &filename) const
{
#define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \
Log::fatal("Skidding_Properties", "Missing default value for '%s'"\
"in '%s'.", \
strA,filename.c_str()); \
}
CHECK_NEG(m_skid_increase, "skid increase" );
CHECK_NEG(m_skid_decrease, "skid decrease" );
CHECK_NEG(m_skid_max, "skid max" );
CHECK_NEG(m_time_till_max_skid, "skid time-till-max" );
CHECK_NEG(m_skid_visual, "skid visual" );
CHECK_NEG(m_skid_visual_time, "skid visual-time" );
CHECK_NEG(m_skid_revert_visual_time, "skid revert-visual-time" );
CHECK_NEG(m_post_skid_rotate_factor, "skid post-skid-rotate-factor" );
CHECK_NEG(m_skid_reduce_turn_min, "skid reduce-turn-min" );
CHECK_NEG(m_skid_reduce_turn_max, "skid reduce-turn-max" );
CHECK_NEG(m_physical_jump_time, "skid physical-jump-time" );
CHECK_NEG(m_graphical_jump_time, "skid graphical-jump-time" );
CHECK_NEG(m_min_skid_speed, "skid min-speed" );
if(m_skid_time_till_bonus.size()==0)
Log::error("Skidding_Properties", "Warning: no skid time declared,"
"can be ignored.");
if(m_skid_time_till_bonus.size()!=m_skid_bonus_speed.size())
{
Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus"
"and bonus-speed\n must have same number of elements.");
}
if(m_skid_time_till_bonus.size()!=m_skid_bonus_time.size())
{
Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus"
"and bonus-time must\n have same number of elements.");
}
if(m_skid_time_till_bonus.size()!=m_skid_bonus_force.size())
{
Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus"
"and bonus-force must\n have same number of elements.");
}
for(unsigned int i=0; i<m_skid_time_till_bonus.size()-1; i++)
{
if(m_skid_time_till_bonus[i]>=m_skid_time_till_bonus[i+1])
{
Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus"
"not sorted.");
}
} // for i
} // check
// ----------------------------------------------------------------------------
void SkiddingProperties::copyFrom(const SkiddingProperties *destination)
{
*this = *destination;
} // copyFrom
// ----------------------------------------------------------------------------
/* EOF */

View File

@ -1,171 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2012-2015 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_SKIDDING_PROPERTIES_HPP
#define HEADER_SKIDDING_PROPERTIES_HPP
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
class Kart;
class XMLNode;
#include <string>
#include <vector>
/** A simple class that stores all skidding related properties. It acts as
* interface between kart_properties and Skidding (to avoid either passing
* very many individual variables, or making KartProperties a dependency
* of Skidding).
* \ingroup karts
*/
class SkiddingProperties
{
public:
//LEAK_CHECK();
protected:
/** Skidding is multiplied by this when skidding
* to increase to m_skid_increase. */
float m_skid_increase;
/** Skidding is multiplied by this when not skidding to decrease to 1.0. */
float m_skid_decrease;
/** How long it takes for visual skid to reach maximum. */
float m_skid_visual_time;
/** How long it takes for the physical and graphical bodies to be
* in sync again after a skid. */
float m_skid_revert_visual_time;
/** Time till maximum skidding is reached. */
float m_time_till_max_skid;
/** Maximal increase of steering when skidding. */
float m_skid_max;
/** Additional rotation of 3d model when skidding. */
float m_skid_visual;
/** Time for a small physical when skidding starts. */
float m_physical_jump_time;
/** Time for a small graphics-only jump when skidding starts. */
float m_graphical_jump_time;
/** This factor is 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). */
float m_post_skid_rotate_factor;
/*** Minimum speed a kart must have before it can skid. */
float m_min_skid_speed;
/** Time of skidding before you get a bonus boost. It's possible to
* define more than one time, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_time_till_bonus;
/** How much additional speed a kart gets when skidding. It's possible to
* define more than one speed, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_bonus_speed;
/** How long the bonus will last. It's possible to define more than one
* time, i.e. longer skidding gives more bonus. */
std::vector<float> m_skid_bonus_time;
/** Additional force accelerating the kart (in addition to the immediate
* speed bonus). Without this force turning to correct the direction
* after skidding will use up nearly all of the additional speed (turning
* reduces the forward engine impulse) */
std::vector<float> m_skid_bonus_force;
/** A factor is used to reduce the amount of steering while skidding. This
* is the minimum factor used (i.e. resulting in the largest turn
* radius). */
float m_skid_reduce_turn_min;
/** A factor is used to reduce the amount of steering while skidding. This
* is the maximum factor used (i.e. resulting in the smallest turn
* radius). */
float m_skid_reduce_turn_max;
/** Kart leaves skid marks. */
bool m_has_skidmarks;
/** Used to check that all values are defined in the xml file. */
static float UNDEFINED;
public:
SkiddingProperties();
void load(const XMLNode *skid_node);
void copyFrom(const SkiddingProperties *destination);
void checkAllSet(const std::string &filename) const;
// ------------------------------------------------------------------------
/** Returns if the kart leaves skidmarks or not. */
bool hasSkidmarks() const { return m_has_skidmarks; }
// ------------------------------------------------------------------------
/** Returns the maximum factor by which the steering angle
* can be increased. */
float getMaxSkid() const {return m_skid_max; }
// ------------------------------------------------------------------------
/** Returns additional rotation of 3d model when skidding. */
float getSkidVisual () const {return m_skid_visual; }
// ------------------------------------------------------------------------
/** Returns the time for the visual skid to reach maximum. */
float getSkidVisualTime () const {return m_skid_visual_time; }
// ------------------------------------------------------------------------
/** Returns 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). */
float getPostSkidRotateFactor () const {return m_post_skid_rotate_factor;}
// ------------------------------------------------------------------------
/** Returns the factor by which to recude the amount of steering while
skidding. */
float getSkidReduceTurnMin () const { return m_skid_reduce_turn_min; }
// ------------------------------------------------------------------------
float getSkidReduceTurnMax () const { return m_skid_reduce_turn_max; }
// ------------------------------------------------------------------------
/** Returns how many boni are defined for this kart. */
int getNumberOfBonusTimes() const { return (int) m_skid_bonus_time.size(); }
// ------------------------------------------------------------------------
/** Returns how long a kart must skid in order to reach the specified
* bonus level.
* param n Bonus level (0<=n<m_skid_bonus_time.size())
*/
float getTimeTillBonus(unsigned int n) const
{ return m_skid_time_till_bonus[n]; }
// ------------------------------------------------------------------------
}; // SkiddingProperties
#endif
/* EOF */

View File

@ -0,0 +1,603 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "karts/xml_characteristic.hpp"
#include "utils/interpolation_array.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include "io/xml_node.hpp"
XmlCharacteristic::XmlCharacteristic(const XMLNode *node) :
m_values(CHARACTERISTIC_COUNT)
{
if (node)
load(node);
} // XmlCharacteristic constructor
// ----------------------------------------------------------------------------
/** process will execute the operation that is specified in the saved string.
* The format of the operations is specified in kart_characteristics.xml.
*/
void XmlCharacteristic::process(CharacteristicType type, Value value,
bool *is_set) const
{
if (m_values[type].empty())
// That value was not changed in this configuration
return;
switch (getType(type))
{
case TYPE_FLOAT:
processFloat(m_values[type], value.f, is_set);
break;
case TYPE_BOOL:
processBool(m_values[type], value.b, is_set);
break;
case TYPE_FLOAT_VECTOR:
{
const std::vector<std::string> processors =
StringUtils::split(m_values[type], ' ');
// If the array should be completely replaced
// That has to happen when the size is not the same or it is not yet set
bool shouldReplace = false;
if (*is_set)
{
if (processors.size() != value.fv->size())
shouldReplace = true;
else
{
std::vector<float>::iterator fit = value.fv->begin();
for (const std::string &processor : processors)
{
processFloat(processor, &*fit, is_set);
if (!*is_set)
{
Log::error("XmlCharacteristic::process", "Can't process %s",
processor.c_str());
value.fv->clear();
break;
}
fit++;
}
}
}
else
shouldReplace = true;
if (shouldReplace)
{
value.fv->resize(processors.size());
std::vector<float>::iterator fit = value.fv->begin();
for (const std::string &processor : processors)
{
*is_set = false;
processFloat(processor, &*fit, is_set);
if (!*is_set)
{
Log::error("XmlCharacteristic::process", "Can't process %s",
getName(type).c_str());
value.fv->clear();
break;
}
fit++;
}
}
break;
}
case TYPE_INTERPOLATION_ARRAY:
{
const std::vector<std::string> processors =
StringUtils::split(m_values[type], ' ');
// If the interpolation array should be completely replaced
// That has to happen when the format is not the same
bool shouldReplace = false;
if (*is_set)
{
if (processors.size() != value.fv->size())
shouldReplace = true;
else
{
for (const std::string &processor : processors)
{
std::vector<std::string> pair = StringUtils::split(processor, ':');
if (pair.size() != 2)
Log::error("XmlCharacteristic::process",
"Can't process %s: Wrong format", getName(type).c_str());
else
{
float x;
if (!StringUtils::fromString(pair[0], x))
Log::error("XmlCharacteristic::process",
"Can't process %s: Not a float", getName(type).c_str());
else
{
// Search the index of this x value
bool found = false;
for (unsigned int i = 0; i < value.ia->size(); i++)
{
if (value.ia->getX(i) == x)
{
float val;
processFloat(pair[1], &val, is_set);
value.ia->setY(i, val);
found = true;
break;
}
}
if (!found)
{
// The searched value was not found so we have
// a different format
shouldReplace = true;
break;
}
}
}
}
}
}
else
// It's not yet set, so we will the current content
shouldReplace = true;
if (shouldReplace)
{
value.ia->clear();
// Replace all values
for (const std::string &processor : processors)
{
std::vector<std::string> pair = StringUtils::split(processor,':');
if (pair.size() != 2)
Log::error("XmlCharacteristic::process",
"Can't process %s: Wrong format", getName(type).c_str());
else
{
float x;
if (!StringUtils::fromString(pair[0], x))
Log::error("XmlCharacteristic::process",
"Can't process %s: Not a float", getName(type).c_str());
else
{
float val;
*is_set = false;
processFloat(pair[1], &val, is_set);
if (!*is_set)
{
Log::error("XmlCharacteristic::process", "Can't process %s",
getName(type).c_str());
value.ia->clear();
break;
}
value.ia->push_back(x, val);
}
}
}
}
break;
}
default:
Log::fatal("XmlCharacteristic::process", "Unknown type for %s",
getName(type).c_str());
}
} // process
// ----------------------------------------------------------------------------
/** Executes an operation on a float value. */
void XmlCharacteristic::processFloat(const std::string &processor, float *value,
bool *is_set)
{
// Split the string by operators
static const std::string operators = "*/+-";
std::vector<std::string> parts;
std::vector<std::string> operations;
std::size_t pos = 0;
std::size_t pos2;
while ((pos2 = processor.find_first_of(operators, pos)) != std::string::npos)
{
parts.push_back(processor.substr(pos, pos2));
operations.push_back(processor.substr(pos2, pos2 + 1));
pos = pos2 + 1;
}
parts.push_back(processor.substr(pos));
// Compute the result
float x = *value;
std::size_t index = 0;
// If nothing preceeds the first operator, insert x
if (parts[index].empty())
{
if (!*is_set)
{
Log::error("XmlCharacteristic::processFloat", "x is unknown");
return;
}
// - is a special case: We don't take e.g. "-5" as relative, it
// describes a negative number
else if (operations[index] == "-")
*value = 0;
else
*value = x;
}
else
{
float val;
if (!StringUtils::fromString(parts[index], val))
{
Log::fatal("XmlCharacteristic::processFloat",
"Can't parse %s: Not a float", parts[index].c_str());
return;
}
*value = val;
}
index++;
for (; index < parts.size(); index++)
{
float val;
if (parts[index] == "x" || parts[index] == "X")
val = x;
else if (!StringUtils::fromString(parts[index], val))
{
Log::fatal("XmlCharacteristic::processFloat",
"Can't parse %s: Not a float", parts[index].c_str());
return;
}
if (operations[index - 1] == "*")
*value *= val;
else if (operations[index - 1] == "/")
*value /= val;
else if (operations[index - 1] == "+")
*value += val;
else if (operations[index - 1] == "-")
*value -= val;
else
Log::fatal("XmlCharacteristic::processFloat",
"Unknown operator (%s)", operations[index - 1].c_str());
}
*is_set = true;
} // processFloat
// ----------------------------------------------------------------------------
/** Executes an operation on a bool value. */
void XmlCharacteristic::processBool(const std::string &processor, bool *value,
bool *is_set)
{
if (processor == "true")
{
*value = true;
*is_set = true;
}
else if (processor == "false")
{
*value = false;
*is_set = true;
}
else
Log::error("XmlCharacteristic::processBool", "Can't parse %s: Not a bool",
processor.c_str());
} // processBool
// ----------------------------------------------------------------------------
/** Loads all commands from a given xml file.
* Non-existing tags will be omitted.
*/
void XmlCharacteristic::load(const XMLNode *node)
{
// Script-generated content generated by tools/create_kart_properties.py getXml
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start getXml> */
if (const XMLNode *sub_node = node->getNode("suspension"))
{
sub_node->get("stiffness",
&m_values[SUSPENSION_STIFFNESS]);
sub_node->get("rest",
&m_values[SUSPENSION_REST]);
sub_node->get("travel",
&m_values[SUSPENSION_TRAVEL]);
sub_node->get("exp-spring-response",
&m_values[SUSPENSION_EXP_SPRING_RESPONSE]);
sub_node->get("max-force",
&m_values[SUSPENSION_MAX_FORCE]);
}
if (const XMLNode *sub_node = node->getNode("stability"))
{
sub_node->get("roll-influence",
&m_values[STABILITY_ROLL_INFLUENCE]);
sub_node->get("chassis-linear-damping",
&m_values[STABILITY_CHASSIS_LINEAR_DAMPING]);
sub_node->get("chassis-angular-damping",
&m_values[STABILITY_CHASSIS_ANGULAR_DAMPING]);
sub_node->get("downward-impulse-factor",
&m_values[STABILITY_DOWNWARD_IMPULSE_FACTOR]);
sub_node->get("track-connection-accel",
&m_values[STABILITY_TRACK_CONNECTION_ACCEL]);
sub_node->get("smooth-flying-impulse",
&m_values[STABILITY_SMOOTH_FLYING_IMPULSE]);
}
if (const XMLNode *sub_node = node->getNode("turn"))
{
sub_node->get("radius",
&m_values[TURN_RADIUS]);
sub_node->get("time-reset-steer",
&m_values[TURN_TIME_RESET_STEER]);
sub_node->get("time-full-steer",
&m_values[TURN_TIME_FULL_STEER]);
}
if (const XMLNode *sub_node = node->getNode("engine"))
{
sub_node->get("power",
&m_values[ENGINE_POWER]);
sub_node->get("max-speed",
&m_values[ENGINE_MAX_SPEED]);
sub_node->get("brake-factor",
&m_values[ENGINE_BRAKE_FACTOR]);
sub_node->get("brake-time-increase",
&m_values[ENGINE_BRAKE_TIME_INCREASE]);
sub_node->get("max-speed-reverse-ratio",
&m_values[ENGINE_MAX_SPEED_REVERSE_RATIO]);
}
if (const XMLNode *sub_node = node->getNode("gear"))
{
sub_node->get("switch-ratio",
&m_values[GEAR_SWITCH_RATIO]);
sub_node->get("power-increase",
&m_values[GEAR_POWER_INCREASE]);
}
if (const XMLNode *sub_node = node->getNode("mass"))
{
sub_node->get("value",
&m_values[MASS]);
}
if (const XMLNode *sub_node = node->getNode("wheels"))
{
sub_node->get("damping-relaxation",
&m_values[WHEELS_DAMPING_RELAXATION]);
sub_node->get("damping-compression",
&m_values[WHEELS_DAMPING_COMPRESSION]);
}
if (const XMLNode *sub_node = node->getNode("camera"))
{
sub_node->get("distance",
&m_values[CAMERA_DISTANCE]);
sub_node->get("forward-up-angle",
&m_values[CAMERA_FORWARD_UP_ANGLE]);
sub_node->get("backward-up-angle",
&m_values[CAMERA_BACKWARD_UP_ANGLE]);
}
if (const XMLNode *sub_node = node->getNode("jump"))
{
sub_node->get("animation-time",
&m_values[JUMP_ANIMATION_TIME]);
}
if (const XMLNode *sub_node = node->getNode("lean"))
{
sub_node->get("max",
&m_values[LEAN_MAX]);
sub_node->get("speed",
&m_values[LEAN_SPEED]);
}
if (const XMLNode *sub_node = node->getNode("anvil"))
{
sub_node->get("duration",
&m_values[ANVIL_DURATION]);
sub_node->get("weight",
&m_values[ANVIL_WEIGHT]);
sub_node->get("speed-factor",
&m_values[ANVIL_SPEED_FACTOR]);
}
if (const XMLNode *sub_node = node->getNode("parachute"))
{
sub_node->get("friction",
&m_values[PARACHUTE_FRICTION]);
sub_node->get("duration",
&m_values[PARACHUTE_DURATION]);
sub_node->get("duration-other",
&m_values[PARACHUTE_DURATION_OTHER]);
sub_node->get("lbound-fraction",
&m_values[PARACHUTE_LBOUND_FRACTION]);
sub_node->get("ubound-fraction",
&m_values[PARACHUTE_UBOUND_FRACTION]);
sub_node->get("max-speed",
&m_values[PARACHUTE_MAX_SPEED]);
}
if (const XMLNode *sub_node = node->getNode("bubblegum"))
{
sub_node->get("duration",
&m_values[BUBBLEGUM_DURATION]);
sub_node->get("speed-fraction",
&m_values[BUBBLEGUM_SPEED_FRACTION]);
sub_node->get("torque",
&m_values[BUBBLEGUM_TORQUE]);
sub_node->get("fade-in-time",
&m_values[BUBBLEGUM_FADE_IN_TIME]);
sub_node->get("shield-duration",
&m_values[BUBBLEGUM_SHIELD_DURATION]);
}
if (const XMLNode *sub_node = node->getNode("zipper"))
{
sub_node->get("duration",
&m_values[ZIPPER_DURATION]);
sub_node->get("force",
&m_values[ZIPPER_FORCE]);
sub_node->get("speed-gain",
&m_values[ZIPPER_SPEED_GAIN]);
sub_node->get("max-speed-increase",
&m_values[ZIPPER_MAX_SPEED_INCREASE]);
sub_node->get("fade-out-time",
&m_values[ZIPPER_FADE_OUT_TIME]);
}
if (const XMLNode *sub_node = node->getNode("swatter"))
{
sub_node->get("duration",
&m_values[SWATTER_DURATION]);
sub_node->get("distance",
&m_values[SWATTER_DISTANCE]);
sub_node->get("squash-duration",
&m_values[SWATTER_SQUASH_DURATION]);
sub_node->get("squash-slowdown",
&m_values[SWATTER_SQUASH_SLOWDOWN]);
}
if (const XMLNode *sub_node = node->getNode("plunger"))
{
sub_node->get("band-max-length",
&m_values[PLUNGER_BAND_MAX_LENGTH]);
sub_node->get("band-force",
&m_values[PLUNGER_BAND_FORCE]);
sub_node->get("band-duration",
&m_values[PLUNGER_BAND_DURATION]);
sub_node->get("band-speed-increase",
&m_values[PLUNGER_BAND_SPEED_INCREASE]);
sub_node->get("band-fade-out-time",
&m_values[PLUNGER_BAND_FADE_OUT_TIME]);
sub_node->get("in-face-time",
&m_values[PLUNGER_IN_FACE_TIME]);
}
if (const XMLNode *sub_node = node->getNode("startup"))
{
sub_node->get("time",
&m_values[STARTUP_TIME]);
sub_node->get("boost",
&m_values[STARTUP_BOOST]);
}
if (const XMLNode *sub_node = node->getNode("rescue"))
{
sub_node->get("duration",
&m_values[RESCUE_DURATION]);
sub_node->get("vert-offset",
&m_values[RESCUE_VERT_OFFSET]);
sub_node->get("height",
&m_values[RESCUE_HEIGHT]);
}
if (const XMLNode *sub_node = node->getNode("explosion"))
{
sub_node->get("duration",
&m_values[EXPLOSION_DURATION]);
sub_node->get("radius",
&m_values[EXPLOSION_RADIUS]);
sub_node->get("invulnerability-time",
&m_values[EXPLOSION_INVULNERABILITY_TIME]);
}
if (const XMLNode *sub_node = node->getNode("nitro"))
{
sub_node->get("duration",
&m_values[NITRO_DURATION]);
sub_node->get("engine-force",
&m_values[NITRO_ENGINE_FORCE]);
sub_node->get("consumption",
&m_values[NITRO_CONSUMPTION]);
sub_node->get("small-container",
&m_values[NITRO_SMALL_CONTAINER]);
sub_node->get("big-container",
&m_values[NITRO_BIG_CONTAINER]);
sub_node->get("max-speed-increase",
&m_values[NITRO_MAX_SPEED_INCREASE]);
sub_node->get("fade-out-time",
&m_values[NITRO_FADE_OUT_TIME]);
sub_node->get("max",
&m_values[NITRO_MAX]);
}
if (const XMLNode *sub_node = node->getNode("slipstream"))
{
sub_node->get("duration",
&m_values[SLIPSTREAM_DURATION]);
sub_node->get("length",
&m_values[SLIPSTREAM_LENGTH]);
sub_node->get("width",
&m_values[SLIPSTREAM_WIDTH]);
sub_node->get("collect-time",
&m_values[SLIPSTREAM_COLLECT_TIME]);
sub_node->get("use-time",
&m_values[SLIPSTREAM_USE_TIME]);
sub_node->get("add-power",
&m_values[SLIPSTREAM_ADD_POWER]);
sub_node->get("min-speed",
&m_values[SLIPSTREAM_MIN_SPEED]);
sub_node->get("max-speed-increase",
&m_values[SLIPSTREAM_MAX_SPEED_INCREASE]);
sub_node->get("fade-out-time",
&m_values[SLIPSTREAM_FADE_OUT_TIME]);
}
if (const XMLNode *sub_node = node->getNode("skid"))
{
sub_node->get("increase",
&m_values[SKID_INCREASE]);
sub_node->get("decrease",
&m_values[SKID_DECREASE]);
sub_node->get("max",
&m_values[SKID_MAX]);
sub_node->get("time-till-max",
&m_values[SKID_TIME_TILL_MAX]);
sub_node->get("visual",
&m_values[SKID_VISUAL]);
sub_node->get("visual-time",
&m_values[SKID_VISUAL_TIME]);
sub_node->get("revert-visual-time",
&m_values[SKID_REVERT_VISUAL_TIME]);
sub_node->get("min-speed",
&m_values[SKID_MIN_SPEED]);
sub_node->get("time-till-bonus",
&m_values[SKID_TIME_TILL_BONUS]);
sub_node->get("bonus-speed",
&m_values[SKID_BONUS_SPEED]);
sub_node->get("bonus-time",
&m_values[SKID_BONUS_TIME]);
sub_node->get("bonus-force",
&m_values[SKID_BONUS_FORCE]);
sub_node->get("physical-jump-time",
&m_values[SKID_PHYSICAL_JUMP_TIME]);
sub_node->get("graphical-jump-time",
&m_values[SKID_GRAPHICAL_JUMP_TIME]);
sub_node->get("post-skid-rotate-factor",
&m_values[SKID_POST_SKID_ROTATE_FACTOR]);
sub_node->get("reduce-turn-min",
&m_values[SKID_REDUCE_TURN_MIN]);
sub_node->get("reduce-turn-max",
&m_values[SKID_REDUCE_TURN_MAX]);
sub_node->get("enabled",
&m_values[SKID_ENABLED]);
}
/* <characteristics-end getXml> */
} // load

View File

@ -0,0 +1,47 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team
//
// 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_XML_CHARACTERISTICS_HPP
#define HEADER_XML_CHARACTERISTICS_HPP
#include "karts/abstract_characteristic.hpp"
#include <string>
class XMLNode;
class XmlCharacteristic : public AbstractCharacteristic
{
private:
/** The computation that was read from an xml file */
std::vector<std::string> m_values;
public:
XmlCharacteristic(const XMLNode *node = nullptr);
virtual void process(CharacteristicType type, Value value, bool *is_set) const;
void load(const XMLNode *node);
private:
static void processFloat(const std::string &processor, float *value, bool *is_set);
static void processBool(const std::string &processor, bool *value, bool *is_set);
};
#endif

View File

@ -1159,6 +1159,11 @@ void initRest()
track_manager->addTrackSearchDir( track_manager->addTrackSearchDir(
file_manager->getAddonsFile("tracks/")); file_manager->getAddonsFile("tracks/"));
{
XMLNode characteristicsNode(file_manager->getAsset("kart_characteristics.xml"));
kart_properties_manager->loadCharacteristics(&characteristicsNode);
}
track_manager->loadTrackList(); track_manager->loadTrackList();
music_manager->addMusicToTracks(); music_manager->addMusicToTracks();

View File

@ -106,7 +106,7 @@ void ProfileWorld::setProfileModeLaps(int laps)
AbstractKart *ProfileWorld::createKart(const std::string &kart_ident, int index, AbstractKart *ProfileWorld::createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id, int local_player_id, int global_player_id,
RaceManager::KartType type, RaceManager::KartType type,
const PlayerDifficulty *difficulty) PerPlayerDifficulty difficulty)
{ {
btTransform init_pos = getStartTransform(index); btTransform init_pos = getStartTransform(index);

View File

@ -75,7 +75,7 @@ protected:
virtual AbstractKart *createKart(const std::string &kart_ident, int index, virtual AbstractKart *createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id, int local_player_id, int global_player_id,
RaceManager::KartType type, RaceManager::KartType type,
const PlayerDifficulty *difficulty); PerPlayerDifficulty difficulty);
public: public:
ProfileWorld(); ProfileWorld();

View File

@ -385,7 +385,7 @@ int SoccerWorld::getTeamLeader(unsigned int team)
AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index, AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id, int local_player_id, int global_player_id,
RaceManager::KartType kart_type, RaceManager::KartType kart_type,
const PlayerDifficulty *difficulty) PerPlayerDifficulty difficulty)
{ {
int posIndex = index; int posIndex = index;
int position = index+1; int position = index+1;

View File

@ -106,7 +106,7 @@ protected:
virtual AbstractKart *createKart(const std::string &kart_ident, int index, virtual AbstractKart *createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id, int local_player_id, int global_player_id,
RaceManager::KartType type, RaceManager::KartType type,
const PlayerDifficulty *difficulty); PerPlayerDifficulty difficulty);
}; // SoccerWorld }; // SoccerWorld

View File

@ -185,12 +185,10 @@ void World::init()
: race_manager->getKartIdent(i); : race_manager->getKartIdent(i);
int local_player_id = race_manager->getKartLocalPlayerId(i); int local_player_id = race_manager->getKartLocalPlayerId(i);
int global_player_id = race_manager->getKartGlobalPlayerId(i); int global_player_id = race_manager->getKartGlobalPlayerId(i);
const PlayerDifficulty *player_difficulty =
stk_config->getPlayerDifficulty(race_manager->getPlayerDifficulty(i));
AbstractKart* newkart = createKart(kart_ident, i, local_player_id, AbstractKart* newkart = createKart(kart_ident, i, local_player_id,
global_player_id, global_player_id,
race_manager->getKartType(i), race_manager->getKartType(i),
player_difficulty); race_manager->getPlayerDifficulty(i));
m_karts.push_back(newkart); m_karts.push_back(newkart);
m_track->adjustForFog(newkart->getNode()); m_track->adjustForFog(newkart->getNode());
@ -301,7 +299,7 @@ void World::createRaceGUI()
AbstractKart *World::createKart(const std::string &kart_ident, int index, AbstractKart *World::createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id, int local_player_id, int global_player_id,
RaceManager::KartType kart_type, RaceManager::KartType kart_type,
const PlayerDifficulty *difficulty) PerPlayerDifficulty difficulty)
{ {
int position = index+1; int position = index+1;
btTransform init_pos = getStartTransform(index); btTransform init_pos = getStartTransform(index);

View File

@ -126,7 +126,7 @@ protected:
virtual AbstractKart *createKart(const std::string &kart_ident, int index, virtual AbstractKart *createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id, int local_player_id, int global_player_id,
RaceManager::KartType type, RaceManager::KartType type,
const PlayerDifficulty *difficulty); PerPlayerDifficulty difficulty);
/** Pointer to the track. The track is managed by world. */ /** Pointer to the track. The track is managed by world. */
Track* m_track; Track* m_track;

View File

@ -461,7 +461,7 @@ void btKart::updateVehicle( btScalar step )
av.setZ(0); av.setZ(0);
m_chassisBody->setAngularVelocity(av); m_chassisBody->setAngularVelocity(av);
// Give a nicely balanced feeling for rebalancing the kart // Give a nicely balanced feeling for rebalancing the kart
m_chassisBody->applyTorqueImpulse(axis * m_kart->getKartProperties()->getSmoothFlyingImpulse()); m_chassisBody->applyTorqueImpulse(axis * m_kart->getKartProperties()->getStabilitySmoothFlyingImpulse());
} }
// Work around: make sure that either both wheels on one axis // Work around: make sure that either both wheels on one axis
@ -543,7 +543,7 @@ void btKart::updateVehicle( btScalar step )
// If configured, add a force to keep karts on the track // If configured, add a force to keep karts on the track
// ----------------------------------------------------- // -----------------------------------------------------
float dif = m_kart->getKartProperties()->getDownwardImpulseFactor(); float dif = m_kart->getKartProperties()->getStabilityDownwardImpulseFactor();
if(dif!=0 && m_num_wheels_on_ground==4) if(dif!=0 && m_num_wheels_on_ground==4)
{ {
float f = -fabsf(m_kart->getSpeed()) * dif; float f = -fabsf(m_kart->getSpeed()) * dif;
@ -655,7 +655,7 @@ void btKart::updateSuspension(btScalar deltaTime)
// is already guaranteed that either both or no wheels on one axis // is already guaranteed that either both or no wheels on one axis
// are on the ground, so we have to test only one of the wheels // are on the ground, so we have to test only one of the wheels
wheel_info.m_wheelsSuspensionForce = wheel_info.m_wheelsSuspensionForce =
-m_kart->getKartProperties()->getTrackConnectionAccel() -m_kart->getKartProperties()->getStabilityTrackConnectionAccel()
* chassisMass; * chassisMass;
continue; continue;
} }
@ -666,7 +666,7 @@ void btKart::updateSuspension(btScalar deltaTime)
btScalar susp_length = wheel_info.getSuspensionRestLength(); btScalar susp_length = wheel_info.getSuspensionRestLength();
btScalar current_length = wheel_info.m_raycastInfo.m_suspensionLength; btScalar current_length = wheel_info.m_raycastInfo.m_suspensionLength;
btScalar length_diff = (susp_length - current_length); btScalar length_diff = (susp_length - current_length);
if(m_kart->getKartProperties()->getExpSpringResponse()) if(m_kart->getKartProperties()->getSuspensionExpSpringResponse())
length_diff *= fabsf(length_diff)/susp_length; length_diff *= fabsf(length_diff)/susp_length;
float f = (1.0f + fabsf(length_diff) / susp_length); float f = (1.0f + fabsf(length_diff) / susp_length);
// Scale the length diff. This results that in uphill sections, when // Scale the length diff. This results that in uphill sections, when

View File

@ -218,9 +218,9 @@ void Physics::update(float dt)
} }
else if (obj->isFlattenKartObject()) else if (obj->isFlattenKartObject())
{ {
const KartProperties* kp = kart->getKartProperties(); const KartProperties *kp = kart->getKartProperties();
kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(), kart->setSquash(kp->getSwatterSquashDuration(),
kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown()); kp->getSwatterSquashSlowdown());
} }
else if(obj->isSoccerBall() && else if(obj->isSoccerBall() &&
race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
@ -248,9 +248,9 @@ void Physics::update(float dt)
else if (anim->isFlattenKartObject()) else if (anim->isFlattenKartObject())
{ {
AbstractKart *kart = p->getUserPointer(1)->getPointerKart(); AbstractKart *kart = p->getUserPointer(1)->getPointerKart();
const KartProperties* kp = kart->getKartProperties(); const KartProperties *kp = kart->getKartProperties();
kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(), kart->setSquash(kp->getSwatterSquashDuration(),
kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown()); kp->getSwatterSquashSlowdown());
} }
continue; continue;

View File

@ -46,6 +46,7 @@
#include "network/protocol_manager.hpp" #include "network/protocol_manager.hpp"
#include "network/network_world.hpp" #include "network/network_world.hpp"
#include "network/protocols/start_game_protocol.hpp" #include "network/protocols/start_game_protocol.hpp"
#include "scriptengine/property_animator.hpp"
#include "states_screens/grand_prix_cutscene.hpp" #include "states_screens/grand_prix_cutscene.hpp"
#include "states_screens/grand_prix_lose.hpp" #include "states_screens/grand_prix_lose.hpp"
#include "states_screens/grand_prix_win.hpp" #include "states_screens/grand_prix_win.hpp"
@ -520,6 +521,7 @@ void RaceManager::startNextRace()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void RaceManager::next() void RaceManager::next()
{ {
PropertyAnimator::get()->clear();
World::deleteWorld(); World::deleteWorld();
m_num_finished_karts = 0; m_num_finished_karts = 0;
m_num_finished_players = 0; m_num_finished_players = 0;
@ -720,7 +722,11 @@ void RaceManager::exitRace(bool delete_world)
} }
} }
if (delete_world) World::deleteWorld(); if (delete_world)
{
PropertyAnimator::get()->clear();
World::deleteWorld();
}
delete_world = false; delete_world = false;
StateManager::get()->enterGameState(); StateManager::get()->enterGameState();
@ -757,7 +763,11 @@ void RaceManager::exitRace(bool delete_world)
} }
} }
if (delete_world) World::deleteWorld(); if (delete_world)
{
PropertyAnimator::get()->clear();
World::deleteWorld();
}
m_saved_gp = NULL; m_saved_gp = NULL;
m_track_number = 0; m_track_number = 0;

View File

@ -0,0 +1,132 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart Team
//
// 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 "scriptengine/property_animator.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object_presentation.hpp"
#include "utils/log.hpp"
AnimatedProperty::AnimatedProperty(AnimatablePropery property,
int values_count, double* values_from, double* values_to,
double duration, void* data)
{
m_property = property;
m_remaining_time = m_total_time = duration;
m_data = data;
m_values_count = values_count;
m_values_from = values_from;
m_values_to = values_to;
m_new_values = new double[values_count];
}
// ----------------------------------------------------------------------------
bool AnimatedProperty::update(double dt)
{
bool done = false;
m_remaining_time -= dt;
if (m_remaining_time < 0)
{
m_remaining_time = 0;
done = true;
}
double ratio = 1.0 - m_remaining_time / m_total_time;
for (int i = 0; i < m_values_count; i++)
{
m_new_values[i] = m_values_from[i] + (m_values_to[i] - m_values_from[i]) * ratio;
}
switch (m_property)
{
case AnimatablePropery::AP_LIGHT_ENERGY:
{
TrackObjectPresentationLight* light = (TrackObjectPresentationLight*)m_data;
light->setEnergy((float)m_new_values[0]);
break;
}
case AnimatablePropery::FOG_RANGE:
{
Track* track = (Track*)m_data;
track->setFogStart((float)m_new_values[0]);
track->setFogEnd((float)m_new_values[1]);
break;
}
case AnimatablePropery::FOG_MAX:
{
Track* track = (Track*)m_data;
track->setFogMax((float)m_new_values[0]);
break;
}
case AnimatablePropery::FOG_COLOR:
{
Track* track = (Track*)m_data;
video::SColor color(255, (int)m_new_values[0], (int)m_new_values[1], (int)m_new_values[2]);
track->setFogColor(color);
break;
}
default:
Log::error("PropertyAnimator", "Unknown properry %i", (int)m_property);
break;
}
return done;
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
PropertyAnimator* PropertyAnimator::s_instance = NULL;
PropertyAnimator* PropertyAnimator::get()
{
if (s_instance == NULL)
s_instance = new PropertyAnimator();
return s_instance;
}
// ----------------------------------------------------------------------------
void PropertyAnimator::add(AnimatedProperty* prop)
{
m_properties.push_back(prop);
}
// ----------------------------------------------------------------------------
void PropertyAnimator::update(double dt)
{
for (int i = m_properties.size() - 1; i >= 0; i--)
{
bool done = m_properties[i].update(dt);
if (done)
m_properties.erase(i);
}
}
// ----------------------------------------------------------------------------
void PropertyAnimator::clear()
{
m_properties.clearAndDeleteAll();
}

View File

@ -0,0 +1,73 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart Team
//
// 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_PROPERTY_ANIMATOR_HPP
#define HEADER_PROPERTY_ANIMATOR_HPP
#include "utils/no_copy.hpp"
#include "utils/ptr_vector.hpp"
enum AnimatablePropery
{
AP_LIGHT_ENERGY,
FOG_RANGE,
FOG_MAX,
FOG_COLOR
};
class AnimatedProperty : NoCopy
{
AnimatablePropery m_property;
int m_values_count;
double* m_values_from;
double* m_values_to;
double* m_new_values;
double m_total_time;
double m_remaining_time;
void* m_data;
public:
AnimatedProperty(AnimatablePropery property, int values_count,
double* values_from, double* values_to,
double duration, void* data);
~AnimatedProperty()
{
delete[] m_values_from;
delete[] m_values_to;
delete[] m_new_values;
}
bool update(double dt);
};
class PropertyAnimator
{
PtrVector<AnimatedProperty> m_properties;
static PropertyAnimator* s_instance;
public:
static PropertyAnimator* get();
void add(AnimatedProperty* prop);
void update(double dt);
void clear();
};
#endif

View File

@ -16,13 +16,14 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <assert.h> #include "script_kart.hpp"
#include <angelscript.h>
#include "karts/kart.hpp" #include "karts/kart.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "script_kart.hpp"
#include "scriptvec3.hpp" #include "scriptvec3.hpp"
#include <assert.h>
#include <angelscript.h>
//debug //debug
#include <iostream> #include <iostream>
@ -121,8 +122,7 @@ namespace Scripting
float getMaxSpeed(int idKart) float getMaxSpeed(int idKart)
{ {
AbstractKart* kart = World::getWorld()->getKart(idKart); AbstractKart* kart = World::getWorld()->getKart(idKart);
return kart->getKartProperties()->getMaxSpeed() * return kart->getKartProperties()->getEngineMaxSpeed();
kart->getPlayerDifficulty()->getMaxSpeed();
} }
/** @}*/ /** @}*/

View File

@ -26,6 +26,7 @@
#include "input/input_device.hpp" #include "input/input_device.hpp"
#include "input/input_manager.hpp" #include "input/input_manager.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "scriptengine/property_animator.hpp"
#include "states_screens/dialogs/tutorial_message_dialog.hpp" #include "states_screens/dialogs/tutorial_message_dialog.hpp"
#include "states_screens/dialogs/race_paused_dialog.hpp" #include "states_screens/dialogs/race_paused_dialog.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
@ -133,6 +134,38 @@ namespace Scripting
{ {
new RacePausedDialog(0.8f, 0.6f); new RacePausedDialog(0.8f, 0.6f);
} }
void setFog(float maxDensity, float start, float end, int r, int g, int b, float duration)
{
PropertyAnimator* animator = PropertyAnimator::get();
::Track* track = World::getWorld()->getTrack();
animator->add(
new AnimatedProperty(FOG_MAX, 1,
new double[1] { track->getFogMax() },
new double[1] { maxDensity }, duration, track)
);
animator->add(
new AnimatedProperty(FOG_RANGE, 2,
new double[2] { track->getFogStart(), track->getFogEnd() },
new double[2] { start, end }, duration, track)
);
video::SColor color = track->getFogColor();
animator->add(
new AnimatedProperty(FOG_COLOR, 3,
new double[3] {
(double)color.getRed(),
(double)color.getGreen(),
(double)color.getBlue()
},
new double[3] {
(double)r,
(double)g,
(double)b
},
duration, track)
);
}
} }
/** \cond DOXYGEN_IGNORE */ /** \cond DOXYGEN_IGNORE */
@ -230,7 +263,12 @@ namespace Scripting
void animateEnergy(float energy, float duration, /** \cond DOXYGEN_IGNORE */void *memory /** \endcond */) void animateEnergy(float energy, float duration, /** \cond DOXYGEN_IGNORE */void *memory /** \endcond */)
{ {
((TrackObjectPresentationLight*)memory)->setEnergy(energy, duration); TrackObjectPresentationLight* light = ((TrackObjectPresentationLight*)memory);
PropertyAnimator::get()->add(
new AnimatedProperty(AP_LIGHT_ENERGY, 1,
new double[1] { light->getEnergy() },
new double[1] { energy }, duration, light)
);
} }
/** @} */ /** @} */
@ -326,6 +364,7 @@ namespace Scripting
r = engine->RegisterGlobalFunction("TrackObject@ getTrackObject(const string &in, const string &in)", asFUNCTION(getTrackObject), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("TrackObject@ getTrackObject(const string &in, const string &in)", asFUNCTION(getTrackObject), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void exitRace()", asFUNCTION(exitRace), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void exitRace()", asFUNCTION(exitRace), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void pauseRace()", asFUNCTION(pauseRace), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void pauseRace()", asFUNCTION(pauseRace), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void setFog(float maxDensity, float start, float end, int r, int g, int b, float duration)", asFUNCTION(setFog), asCALL_CDECL); assert(r >= 0);
// TrackObject // TrackObject
r = engine->RegisterObjectMethod("TrackObject", "void setEnabled(bool status)", asMETHOD(::TrackObject, setEnabled), asCALL_THISCALL); assert(r >= 0); r = engine->RegisterObjectMethod("TrackObject", "void setEnabled(bool status)", asMETHOD(::TrackObject, setEnabled), asCALL_THISCALL); assert(r >= 0);

View File

@ -31,6 +31,7 @@
#include "input/input_manager.hpp" #include "input/input_manager.hpp"
#include "input/device_manager.hpp" #include "input/device_manager.hpp"
#include "items/item_manager.hpp" #include "items/item_manager.hpp"
#include "karts/abstract_characteristic.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "modes/overworld.hpp" #include "modes/overworld.hpp"
@ -810,9 +811,13 @@ void KartSelectionScreen::updateKartStats(uint8_t widget_id,
kart_properties_manager->getKart(selection); kart_properties_manager->getKart(selection);
if (kp != NULL) if (kp != NULL)
{ {
w->setValue(KartStatsWidget::SKILL_MASS, (int)(kp->getMass()/5)); // Scale the values so they look better
w->setValue(KartStatsWidget::SKILL_SPEED, (int)((kp->getAbsMaxSpeed()-20)*9)); w->setValue(KartStatsWidget::SKILL_MASS, (int)
w->setValue(KartStatsWidget::SKILL_POWER, (int)(kp->getAvgPower())); ((kp->getCombinedCharacteristic()->getMass() - 20) / 4));
w->setValue(KartStatsWidget::SKILL_SPEED, (int)
((kp->getCombinedCharacteristic()->getEngineMaxSpeed() - 15) * 6));
w->setValue(KartStatsWidget::SKILL_POWER, (int)
((kp->getAvgPower() - 30) / 20));
w->update(0); w->update(0);
} }
} }

View File

@ -43,6 +43,7 @@
#include "modes/soccer_world.hpp" #include "modes/soccer_world.hpp"
#include "modes/world_with_rank.hpp" #include "modes/world_with_rank.hpp"
#include "race/highscores.hpp" #include "race/highscores.hpp"
#include "scriptengine/property_animator.hpp"
#include "states_screens/feature_unlocked.hpp" #include "states_screens/feature_unlocked.hpp"
#include "states_screens/main_menu_screen.hpp" #include "states_screens/main_menu_screen.hpp"
#include "states_screens/networking_lobby.hpp" #include "states_screens/networking_lobby.hpp"
@ -270,6 +271,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
// kart will no longer be available during cutscene, drop reference // kart will no longer be available during cutscene, drop reference
StateManager::get()->getActivePlayer(playerID)->setKart(NULL); StateManager::get()->getActivePlayer(playerID)->setKart(NULL);
PropertyAnimator::get()->clear();
World::deleteWorld(); World::deleteWorld();
CutsceneWorld::setUseDuration(true); CutsceneWorld::setUseDuration(true);
@ -287,6 +289,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
else else
{ {
StateManager::get()->popMenu(); StateManager::get()->popMenu();
PropertyAnimator::get()->clear();
World::deleteWorld(); World::deleteWorld();
CutsceneWorld::setUseDuration(false); CutsceneWorld::setUseDuration(false);

View File

@ -1358,6 +1358,7 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml)
// to lower case, for case-insensitive comparison // to lower case, for case-insensitive comparison
name = StringUtils::toLowerCase(name); name = StringUtils::toLowerCase(name);
int moving_textures_found = 0;
for(unsigned int i=0; i<node->getMaterialCount(); i++) for(unsigned int i=0; i<node->getMaterialCount(); i++)
{ {
video::SMaterial &irrMaterial=node->getMaterial(i); video::SMaterial &irrMaterial=node->getMaterial(i);
@ -1374,8 +1375,12 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml)
if (texture_name != name) continue; if (texture_name != name) continue;
core::matrix4 *m = &irrMaterial.getTextureMatrix(j); core::matrix4 *m = &irrMaterial.getTextureMatrix(j);
m_animated_textures.push_back(new MovingTexture(m, *texture_node)); m_animated_textures.push_back(new MovingTexture(m, *texture_node));
moving_textures_found++;
} // for j<MATERIAL_MAX_TEXTURES } // for j<MATERIAL_MAX_TEXTURES
} // for i<getMaterialCount } // for i<getMaterialCount
if (moving_textures_found == 0)
Log::warn("AnimTexture", "Did not find animate texture '%s'", name.c_str());
} // for node_number < xml->getNumNodes } // for node_number < xml->getNumNodes
} // handleAnimatedTextures } // handleAnimatedTextures
@ -2377,4 +2382,3 @@ bool Track::findGround(AbstractKart *kart)
return true; return true;
} // findGround } // findGround

View File

@ -556,16 +556,24 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
float getFogStart() const { return m_fog_start; } float getFogStart() const { return m_fog_start; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setFogStart(float start) { m_fog_start = start; }
// ------------------------------------------------------------------------
float getFogEnd() const { return m_fog_end; } float getFogEnd() const { return m_fog_end; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setFogEnd(float end) { m_fog_end = end; }
// ------------------------------------------------------------------------
float getFogStartHeight() const { return m_fog_height_start; } float getFogStartHeight() const { return m_fog_height_start; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
float getFogEndHeight() const { return m_fog_height_end; } float getFogEndHeight() const { return m_fog_height_end; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
float getFogMax() const { return m_fog_max; } float getFogMax() const { return m_fog_max; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setFogMax(float max) { m_fog_max = max; }
// ------------------------------------------------------------------------
video::SColor getFogColor() const { return m_fog_color; } video::SColor getFogColor() const { return m_fog_color; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setFogColor(video::SColor& color) { m_fog_color = color; }
// ------------------------------------------------------------------------
video::SColor getSunColor() const { return m_sun_diffuse_color; } video::SColor getSunColor() const { return m_sun_diffuse_color; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Whether this is an "internal" track. If so it won't be offered /** Whether this is an "internal" track. If so it won't be offered

View File

@ -967,11 +967,6 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(
{ {
m_node = NULL; // lights require shaders to work m_node = NULL; // lights require shaders to work
} }
m_energy_animation_from = 0.0f;
m_energy_animation_to = 0.0f;
m_energy_animation_total_duration = 0.0f;
m_energy_animation_remaining_duration = 0.0f;
} // TrackObjectPresentationLight } // TrackObjectPresentationLight
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -989,29 +984,6 @@ void TrackObjectPresentationLight::setEnergy(float energy)
} }
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void TrackObjectPresentationLight::setEnergy(float energy, float duration)
{
m_energy_animation_from = m_energy;
m_energy_animation_to = energy;
m_energy_animation_total_duration = duration;
m_energy_animation_remaining_duration = duration;
}
// ----------------------------------------------------------------------------
void TrackObjectPresentationLight::update(float dt)
{
if (m_energy_animation_remaining_duration > 0.0f)
{
m_energy_animation_remaining_duration -= dt;
if (m_energy_animation_remaining_duration < 0.0f)
m_energy_animation_remaining_duration = 0.0f;
float ratio = m_energy_animation_remaining_duration / m_energy_animation_total_duration;
setEnergy(m_energy_animation_from +
(m_energy_animation_to - m_energy_animation_from)*(1.0f - ratio));
}
}
// ----------------------------------------------------------------------------
TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(
const XMLNode& xml_node) const XMLNode& xml_node)
: TrackObjectPresentation(xml_node) : TrackObjectPresentation(xml_node)

View File

@ -354,19 +354,12 @@ private:
video::SColor m_color; video::SColor m_color;
float m_distance; float m_distance;
float m_energy; float m_energy;
float m_energy_animation_from;
float m_energy_animation_to;
float m_energy_animation_total_duration;
float m_energy_animation_remaining_duration;
public: public:
TrackObjectPresentationLight(const XMLNode& xml_node, TrackObjectPresentationLight(const XMLNode& xml_node,
scene::ISceneNode* parent); scene::ISceneNode* parent);
virtual ~TrackObjectPresentationLight(); virtual ~TrackObjectPresentationLight();
float getEnergy() const { return m_energy; }
void setEnergy(float energy); void setEnergy(float energy);
void setEnergy(float energy, float duration);
virtual void update(float dt) OVERRIDE;
}; // TrackObjectPresentationLight }; // TrackObjectPresentationLight
// ============================================================================ // ============================================================================

View File

@ -26,6 +26,7 @@
#include "items/powerup_manager.hpp" #include "items/powerup_manager.hpp"
#include "items/attachment.hpp" #include "items/attachment.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "karts/controller/controller.hpp" #include "karts/controller/controller.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "physics/irr_debug_drawer.hpp" #include "physics/irr_debug_drawer.hpp"
@ -140,14 +141,14 @@ void addAttachment(Attachment::AttachmentType type)
if (type == Attachment::ATTACH_ANVIL) if (type == Attachment::ATTACH_ANVIL)
{ {
kart->getAttachment() kart->getAttachment()
->set(type, stk_config->m_anvil_time); ->set(type, kart->getKartProperties()->getAnvilDuration());
kart->adjustSpeed(stk_config->m_anvil_speed_factor); kart->adjustSpeed(kart->getKartProperties()->getAnvilSpeedFactor());
kart->updateWeight(); kart->updateWeight();
} }
else if (type == Attachment::ATTACH_PARACHUTE) else if (type == Attachment::ATTACH_PARACHUTE)
{ {
kart->getAttachment() kart->getAttachment()
->set(type, stk_config->m_parachute_time); ->set(type, kart->getKartProperties()->getParachuteDuration());
} }
else if (type == Attachment::ATTACH_BOMB) else if (type == Attachment::ATTACH_BOMB)
{ {

View File

@ -43,6 +43,14 @@ private:
public: public:
InterpolationArray() {}; InterpolationArray() {};
/** Removes all saved values from this object. */
void clear()
{
m_x.clear();
m_y.clear();
m_delta.clear();
}
/** Adds the value pair x/y to the list of all points. It is tested /** Adds the value pair x/y to the list of all points. It is tested
* that the x values are added in order. * that the x values are added in order.
* \param x, y The pair to add. * \param x, y The pair to add.

285
tools/create_kart_properties.py Executable file
View File

@ -0,0 +1,285 @@
#!/usr/bin/env python3
#
# SuperTuxKart - a fun racing game with go-kart
# Copyright (C) 2006-2015 SuperTuxKart-Team
#
# 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.
# This script creates code for the characteristics.
# It takes an argument that specifies what the output of the script should be.
# The output options can be seen by running this script without arguments.
# A more convenient version to update the code is to run update_characteristics.py
import sys
# Input data
# Each line contains a topic and the attributes of that topic.
# This model is used for the xml file and to access the kart properties in the code.
characteristics = """Suspension: stiffness, rest, travel, expSpringResponse(bool), maxForce
Stability: rollInfluence, chassisLinearDamping, chassisAngularDamping, downwardImpulseFactor, trackConnectionAccel, smoothFlyingImpulse
Turn: radius(InterpolationArray), timeResetSteer, timeFullSteer(InterpolationArray)
Engine: power, maxSpeed, brakeFactor, brakeTimeIncrease, maxSpeedReverseRatio
Gear: switchRatio(std::vector<float>/floatVector), powerIncrease(std::vector<float>/floatVector)
Mass
Wheels: dampingRelaxation, dampingCompression
Camera: distance, forwardUpAngle, backwardUpAngle
Jump: animationTime
Lean: max, speed
Anvil: duration, weight, speedFactor
Parachute: friction, duration, durationOther, lboundFraction, uboundFraction, maxSpeed
Bubblegum: duration, speedFraction, torque, fadeInTime, shieldDuration
Zipper: duration, force, speedGain, maxSpeedIncrease, fadeOutTime
Swatter: duration, distance, squashDuration, squashSlowdown
Plunger: bandMaxLength, bandForce, bandDuration, bandSpeedIncrease, bandFadeOutTime, inFaceTime
Startup: time(std::vector<float>/floatVector), boost(std::vector<float>/floatVector)
Rescue: duration, vertOffset, height
Explosion: duration, radius, invulnerabilityTime
Nitro: duration, engineForce, consumption, smallContainer, bigContainer, maxSpeedIncrease, fadeOutTime, max
Slipstream: duration, length, width, collectTime, useTime, addPower, minSpeed, maxSpeedIncrease, fadeOutTime
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.
In the xml files, a value will be assigned to it.
If the name of the attribute is 'value', the getter method will only
contain the group name and 'value' will be omitted (e.g. used for mass). """
class GroupMember:
def __init__(self, name, typeC, typeStr):
self.name = name
if name == "value":
self.getName = ""
else:
self.getName = name
self.typeC = typeC
self.typeStr = typeStr
""" E.g. power(std::vector<float>/floatVector)
or speed(InterpolationArray)
The default type is float
The name 'value' is special: Only the group name will be used to access
the member but in the xml file it will be still value (because we
need a name). """
def parse(content):
typeC = "float"
typeStr = typeC
name = content.strip()
pos = content.find("(")
end = content.find(")", pos)
if pos != -1 and end != -1:
name = content[:pos].strip()
pos2 = content.find("/", pos, end)
if pos2 != -1:
typeC = content[pos + 1:pos2].strip()
typeStr = content[pos2 + 1:end].strip()
else:
typeC = content[pos + 1:end].strip()
typeStr = typeC
return GroupMember(name, typeC, typeStr)
""" A Group has a base name and can contain GroupMembers.
In the xml files, a group is a tag. """
class Group:
def __init__(self, baseName):
self.baseName = baseName
self.members = []
""" Parses and adds a member to this group """
def addMember(self, content):
self.members.append(GroupMember.parse(content))
def getBaseName(self):
return self.baseName
""" E.g. engine: power, gears(std::vector<Gear>/Gears)
or mass(float) or only mass """
def parse(content):
pos = content.find(":")
if pos == -1:
group = Group(content)
group.addMember("value")
return group
else:
group = Group(content[:pos].strip())
for m in content[pos + 1:].split(","):
group.addMember(m)
return group
""" Creates a list of words from a titlecase string """
def toList(name):
result = []
cur = ""
for c in name:
if c.isupper() and len(cur) != 0:
result.append(cur)
cur = ""
cur += c.lower()
if len(cur) != 0:
result.append(cur)
return result
""" titleCase: true = result is titlecase
false = result has underscores """
def joinSubName(group, member, titleCase):
words = toList(group.baseName) + toList(member.getName)
first = True
if titleCase:
words = [w.title() for w in words]
return "".join(words)
else:
return "_".join(words)
# Functions to generate code
def createEnum(groups):
for g in groups:
print()
print(" // {0}".format(g.getBaseName().title()))
for m in g.members:
print(" {0},".format(joinSubName(g, m, False).upper()))
def createAcDefs(groups):
for g in groups:
print()
for m in g.members:
nameTitle = joinSubName(g, m, True)
nameUnderscore = joinSubName(g, m, False)
typeC = m.typeC
print(" {0} get{1}() const;".
format(typeC, nameTitle, nameUnderscore))
def createAcGetter(groups):
for g in groups:
for m in g.members:
nameTitle = joinSubName(g, m, True)
nameUnderscore = joinSubName(g, m, False)
typeC = m.typeC
result = "result"
print("""// ----------------------------------------------------------------------------
{3} AbstractCharacteristic::get{1}() const
{{
{0} result;
bool is_set = false;
process({2}, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName({2}).c_str());
return {4};
}} // get{1}
""".format(m.typeC, nameTitle, nameUnderscore.upper(), typeC, result))
def createKpDefs(groups):
for g in groups:
print()
for m in g.members:
nameTitle = joinSubName(g, m, True)
nameUnderscore = joinSubName(g, m, False)
typeC = m.typeC
print(" {0} get{1}() const;".
format(typeC, nameTitle, nameUnderscore))
def createKpGetter(groups):
for g in groups:
for m in g.members:
nameTitle = joinSubName(g, m, True)
nameUnderscore = joinSubName(g, m, False)
typeC = m.typeC
result = "result"
print("""// ----------------------------------------------------------------------------
{1} KartProperties::get{0}() const
{{
return m_cached_characteristic->get{0}();
}} // get{0}
""".format(nameTitle, typeC))
def createGetType(groups):
for g in groups:
for m in g.members:
nameTitle = joinSubName(g, m, True)
nameUnderscore = joinSubName(g, m, False)
print(" case {0}:\n return TYPE_{1};".
format(nameUnderscore.upper(), "_".join(toList(m.typeStr)).upper()))
def createGetName(groups):
for g in groups:
for m in g.members:
nameTitle = joinSubName(g, m, True)
nameUnderscore = joinSubName(g, m, False).upper()
print(" case {0}:\n return \"{0}\";".
format(nameUnderscore))
def createLoadXml(groups):
for g in groups:
print(" if (const XMLNode *sub_node = node->getNode(\"{0}\"))\n {{".
format(g.baseName.lower()))
for m in g.members:
nameUnderscore = joinSubName(g, m, False)
nameMinus = "-".join(toList(m.name))
print(""" sub_node->get(\"{0}\",
&m_values[{1}]);""".
format(nameMinus, nameUnderscore.upper()))
print(" }\n")
# Dicionary that maps an argument string to a tupel of
# a generator function, a help string and a filename
functions = {
"enum": (createEnum, "List the enum values for all characteristics", "karts/abstract_characteristic.hpp"),
"acdefs": (createAcDefs, "Create the header function definitions", "karts/abstract_characteristic.hpp"),
"acgetter": (createAcGetter, "Implement the getters", "karts/abstract_characteristic.cpp"),
"getType": (createGetType, "Implement the getType function", "karts/abstract_characteristic.cpp"),
"getName": (createGetName, "Implement the getName function", "karts/abstract_characteristic.cpp"),
"kpdefs": (createKpDefs, "Create the header function definitions for the getters", "karts/kart_properties.hpp"),
"kpgetter": (createKpGetter, "Implement the getters", "karts/kart_properties.cpp"),
"loadXml": (createLoadXml, "Code to load the characteristics from an xml file", "karts/xml_characteristic.hpp"),
}
def main():
# Find out what to do
if len(sys.argv) != 2:
print("""Usage: ./create_kart_properties.py <operation>
Operations:""")
maxOperationLength = 0
maxDescriptionLength = 0
for o, f in functions.items():
l = len(o)
if l > maxOperationLength:
maxOperationLength = l
l = len(f[1])
if l > maxDescriptionLength:
maxDescriptionLength = l
formatString = " {{0:{0}}} {{1:{1}}} in {{2}}".format(maxOperationLength, maxDescriptionLength)
for o, f in functions.items():
print(formatString.format(o, f[1], f[2]))
return
task = sys.argv[1]
if task not in functions:
print("The wanted operation was not found. Please call this script without arguments to list available arguments.")
return
# Parse properties
groups = [Group.parse(line) for line in characteristics.split("\n")]
# Create the wanted code
functions[task][0](groups)
if __name__ == '__main__':
main()

50
tools/update_characteristics.py Executable file
View File

@ -0,0 +1,50 @@
#!/usr/bin/env python3
#
# SuperTuxKart - a fun racing game with go-kart
# Copyright (C) 2006-2015 SuperTuxKart-Team
#
# 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.
# This script uses create_kart_properties.py to create code and then replaces
# the code in the source files. The parts in the source are marked with tags, that
# contain the argument that has to be passed to create_kart_properties.py.
# The script has to be run from the root directory of this project.
import os
import re
import subprocess
from create_kart_properties import functions
def main():
# Check, if it runs in the root directory
if not os.path.isfile("tools/update_characteristics.py"):
print("Please run this script in the root directory of the project.")
exit(1)
for operation, function in functions.items():
result = subprocess.Popen("tools/create_kart_properties.py " +
operation, shell = True,
stdout = subprocess.PIPE).stdout.read().decode('UTF-8')
with open("src/" + function[2], "r") as f:
text = f.read()
# Replace the text by using look behinds and look forwards
text = re.sub("(?<=/\* \<characteristics-start " + operation +
"\> \*/\\n)(.|\n)*(?=\\n\s*/\* <characteristics-end " + operation + "> \*/)", result, text)
with open("src/" + function[2], "w") as f:
f.write(text)
if __name__ == '__main__':
main()