Add per-player difficulty

This commit is contained in:
Flakebi 2014-07-28 18:32:39 +02:00
parent bfd54cf37c
commit 71f8766cb1
32 changed files with 1137 additions and 505 deletions

View File

@ -25,13 +25,13 @@
</grand-prix>
<!-- Time in follow-the-leader after which karts are removed.
The last values applies for all remaining karts.
The last values applies for all remaining karts.
time-per-kart Additional time added to the interval
for each kart in the race. -->
<follow-the-leader intervals="30 20 10"
time-per-kart="1.5" />
<!-- Startup information.
<!-- Startup information.
Penalty: Penalty time if a kart accelerates before GO. -->
<startup penalty="1" />
@ -74,11 +74,11 @@
<!-- Skidmark data: maximum number of skid marks, and
time for skidmarks to fade out. -->
<skid-marks max-number="100" fadeout-time="60"/>
<skid-marks max-number="100" fadeout-time="60"/>
<!-- Defines when the upright constraint should be active, it's
disabled when the kart is more than this value from the track. -->
<near-ground distance="2"/>
<near-ground distance="2"/>
<!-- How long the end animation will be shown. -->
<delay-finish time="0.5"/>
@ -99,16 +99,16 @@
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
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"
<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. -->
<bomb time="30.0" time-increase="-5.0"/>
<!-- Powerup collect-mode decides what is collected if a kart has already an
<!-- Powerup collect-mode decides what is collected if a kart has already an
powerup: same: get one more item of the same type.
new: always get a new item.
only-if-same: if the random item is the same one as the
@ -121,9 +121,9 @@
nolok-bubble-gum, easter egg -->
<switch time="5" items="1 0 4 4 2 5 2 7"/>
<!-- disappear-counter: How often bubblegum gets driven over before it disappears.
shield-time: How long the bubblegum shield lasts
restrict-weapons: If true, using weapons will destroy the user's shield -->
<!-- disappear-counter: How often bubblegum gets driven over before it disappears.
shield-time: How long the bubblegum shield lasts
restrict-weapons: If true, using weapons will destroy the user's shield -->
<bubblegum disappear-counter="1" shield-time="10.0" restrict-weapons="false"/>
<!-- explosion-impulse-objects is the impulse that pushes physical objects
@ -134,10 +134,10 @@
work anymore - so for now don't enable this. -->
<networking enable="false"/>
<!-- disable-while-unskid: Disable steering when stop skidding during
<!-- disable-while-unskid: Disable steering when stop skidding during
the time it takes to adjust the physical body with the graphics.
camera-follow-skid: If true the camera will stay behind the kart,
potentially making it easier to see where the kart is going to
potentially making it easier to see where the kart is going to
after a skid. -->
<steer disable-while-unskid="false"
camera-follow-skid="true" />
@ -145,12 +145,12 @@
<!-- Default values for all karts
============================ -->
<general-kart-defaults>
<!-- Camera: Distance between kart and camera.
forward-up-angle: Angle between camera and plane of kart (pitch)
<!-- 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
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.5" forward-up-angle="15"
@ -181,16 +181,16 @@
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.
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).
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
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. -->
@ -221,12 +221,12 @@
max-item-angle: Items that would need more than this change in
direction are not considered for collection.
time-full-steer is the time for the AI to go from neutral steering to
extreme left (or right). This can be used to reduce
extreme left (or right). This can be used to reduce
'shaking' of AI karts caused by changing steering direction
too often. It also helps with making it easier to push the
AI karts (otherwise micro-corrections make this nearly
impossible). A value of 1/maxFPS / 2 will guarantee that
the wheel can go from -1 to +1 steering in one frame,
the wheel can go from -1 to +1 steering in one frame,
basically disabling this mechanism.
bad-item-closeness is the maximum distance between a good and a
bad item which can force the AI to abandon a good item in order
@ -237,7 +237,7 @@
section of the track should have in order to activate a zipper.
competitive when ahead of the player, or more competitive
when behind the player.
when behind the player.
skid-probability: Since the AI is usually very good at using
skidding, this is used to implement some rubber-banding for
@ -258,7 +258,7 @@
the speed the kart can drive at!
collect-item-probability: Probability of the AI actually
trying to collect an item (if an item is selected for
collection in the first place).
collection in the first place).
-->
<ai>
<easy time-full-steer="0.1"
@ -338,17 +338,27 @@
<!-- The per-player difficulties in multiplayer games.
These values are multiplied with the current values of a car. (except ai) -->
<difficulties>
<easiest power="4.0" max-speed="4.0" ai="-2"/>
<easier power="2.0" max-speed="2.0" ai="-1"/>
<normal power="1.0" max-speed="1.0" ai="0"/>
<harder power="0.5" max-speed="0.5" ai="+1"/>
<hardest power="0.25" max-speed="0.25" ai="+2"/>
<easiest>
<engine power="4.0" max-speed="4.0"/>
</easiest>
<easy>
<engine power="2.0" max-speed="2.0"/>
</easy>
<normal>
<engine power="1.0" max-speed="1.0"/>
</normal>
<hard>
<engine power="0.5" max-speed="0.5"/>
</hard>
<hardest>
<engine power="0.25" max-speed="0.25"/>
</hardets>
</difficulties>
<!-- Suspension related values. 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
rest: Length of suspension when at rest.
travel-cm: maximum movement of suspension - in cm!!
exp-string-response: dampen the suspension spring reaction
exponentially.
max-force: Maximum suspension force -->
<suspension stiffness="248" rest="0.2" travel-cm="19"
@ -356,9 +366,9 @@
<!-- Wheel related parameters: damping-relaxation/compression: for
bullet, damping parameters. Radius and width of wheel.
front-right, front-left, rear-right and rear-left give the
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
gravity. Default is to use the corners of the chassis to attach
the wheels to. -->
<wheels damping-relaxation="20" damping-compression="4.4" radius="0.25">
<front-right position="0.38 0 0.6" />
@ -366,20 +376,20 @@
<rear-right position="0.38 0 -0.6" />
<rear-left position="-0.38 0 -0.6"/>
</wheels>
<!-- Parameters for the speed-weighted objects:
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) -->
<speed-weighted-objects strength-factor="0.05" speed-factor="1.0" texture-speed-x="0.0" texture-speed-y="0.0"/>
<!-- friction: slip used for bullet skidding. A high value
<!-- friction: slip used for bullet skidding. A high value
(like 10000000) disables bullet skidding. -->
<friction slip="10000000"/>
<!-- Values related to stability of the chassis: damping, and reduced
impact of roll.
impact of roll.
downward-impulse-factor: A speed proportional impulse applied each
frame that pushes the vehicle onto the ground.
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
@ -397,7 +407,7 @@
'normal': impulse along the normal
'driveline': impulse towards the nearest driveline.
An impulse towards the driveline works nice when the kart is
driving more or less correctly on the track - it pushes the
driving more or less correctly on the track - it pushes the
kart in the right direction. But if the kart is significanlty
off track, it has severe problems (since an incorrect
driveline point can be selected, pusing the kart in the
@ -409,148 +419,148 @@
period, which results in less abrupt changes. If set to 0,
the impulse is only applied once.
resitution: restitution value to be used for the kart rigid bodies.
bevel-factor: for each point of the chassis collision box one
bevel-factor: for each point of the chassis collision box one
additional point is added, resulting in a bevelled box shape.
The original Z coordinate of the chassis is multiplied by
The original Z coordinate of the chassis is multiplied by
1-bevelZ (i.e. the main box part of the shape is shortened).
The bevel point has the original Z coordinate, and the X and
Y coordinates of the box are multiplied with (1-bevelX) and
The bevel point has the original Z coordinate, and the X and
Y coordinates of the box are multiplied with (1-bevelX) and
(1-bevelY). A value of 0 for all bevel coordinates disables
bevelling, and uses a simple box shape.
As an example, a value of 1 for x and z will result in a
As an example, a value of 1 for x and z will result in a
sharp 'arrow' like shape. -->
<collision impulse-type="normal"
<collision impulse-type="normal"
impulse="3000" impulse-time="0.1" terrain-impulse="8000"
restitution="1.0" bevel-factor="0.5 0.0 0.5" />
<!-- If a kart starts within the specified time after 'go',
it receives the corresponding bonus from 'boost'. Those
fields must have the same size, and must be sorted by
increasing times. -->
<startup time = "0.3 0.5"
boost = "6 3" />
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.
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"/>
<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.
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).
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.
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"/>
<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.
<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
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" />
<zipper time="3.5" force="250.0" speed-gain="4.5" max-speed-increase="15"
fade-out-time="1.0" />
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
decrease: multiplicative decrease of skidding factor in each frame.
max: maximum skidding factor = maximum increase of steering angle.
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. -->
<!-- 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"/>
visual="1.25" visual-time="0.7" revert-visual-time="0.7"
min-speed="10" time-till-bonus="1.0 3.0"
bonus-speed="4.5 6.5" bonus-time="3.0 4.0"
bonus-force="250 350"
physical-jump-time="0" graphical-jump-time="0.4"
post-skid-rotate-factor="1"
reduce-turn-min="0.2" reduce-turn-max="0.8"/>
<!-- Slipstream: length: How far behind a kart slipstream works
width: how wide slipstream works furthest away from the kart.
collect-time: How many seconds of sstream give maximum benefit
use-time: How long the benefit will last.
add-power: Additional power due to sstreaming. 1 = +100%
min-speed: Minimum speed necessary for slipstream to take effect.
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
fade-out-time: How long the slip stream speed increase will
gradually be reduced. -->
<slipstream length="10" width="2" collect-time="2" use-time="5"
add-power="3" min-speed="10"
max-speed-increase="5" duration="1" fade-out-time="2"/>
<slipstream 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"/>
<swatter duration="10" distance="3" squash-duration="5"
squash-slowdown="0.5"/>
<!-- Leaning related parameters, i.e. slightly leaning the karts when
driving a fast curve.
max: maximum leaning (i.e. when steering as much as possible at highest
speed), in degrees.
sped: Speed with which the leaning changes (in degree/second). -->
<lean max="8.6" speed="5.0" />
<!-- turn-radius defines the turn radius of the kart at
a given speed. The actual steering angle is dependent on the
wheel base of the kart: radius = wheel_base/sin(steering_angle).
@ -572,130 +582,130 @@
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)
<turn turn-radius="0:2.0 10:7.5 25:15 45:30"
time-full-steer ="0:0.15 0.5:0.15 0.5:0.25 1.0:0.25"
time-reset-steer="0.1" />
<!-- Speed and acceleration related values: power and max-speed (in m/s)
have 3 values, one for low, medium, and hard.
brake-factor: Value used when braking. max-speed-reverse-ratio is
the percentage of max speed for reverse gear. -->
<engine power="450 475 500 510" max-speed="17 21 23 25" brake-factor="11.0"
max-speed-reverse-ratio="0.3"/>
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
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"/>
<gear switch-ratio="0.25 0.7 1.0" power-increase="2.2 1.7 1.3"/>
<!-- mass -->
<mass value="225"/>
<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
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"
<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.
<!-- Kart-specific explosion parameters.
Time: how long it takes before the kart can drive again (this
determines how height the kart is being thrown).
Invulnerability-time: how long a kart will be invulnerable
after being hit by an explosion.
radius: Kart closer to this value will be affected by
an explosion as well. -->
<explosion time="2" radius="5"
invulnerability-time="6" />
<kart-type>
<light>
<startup time = "0.3 0.5"
boost = "8.5 4.5" />
<nitro engine-force="350" consumption="1" small-container="1" big-container="3"
max-speed-increase="4.5" duration="1.5" fade-out-time="2.5" max="20"/>
<slipstream length="11" width="2" collect-time="1.5" use-time="2.5"
add-power="3.2" min-speed="9"
max-speed-increase="4" duration="1.2" fade-out-time="2.3"/>
<turn turn-radius="0:3.0 10:10.0 25:20.0 45:40.0"
time-full-steer ="0:0.15 0.5:0.15 0.5:0.25 1.0:0.25"
time-reset-steer="0.1"/>
<engine power="250 300 350 400" max-speed="15.8 18.8 23.85 30.0" brake-factor="15.0"
max-speed-reverse-ratio="0.3"/>
<explosion time="2" radius="5"
invulnerability-time="6" />
<gear switch-ratio="0.20 0.55 1" power-increase="5 4 3"/>
<kart-type>
<light>
<startup time = "0.3 0.5"
boost = "8.5 4.5" />
<mass value="195"/>
<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"/>
<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"
<slipstream length="11" width="2" collect-time="1.5" use-time="2.5"
add-power="3.2" min-speed="9"
max-speed-increase="4" duration="1.2" fade-out-time="2.3"/>
<turn turn-radius="0:3.0 10:10.0 25:20.0 45:40.0"
time-full-steer ="0:0.15 0.5:0.15 0.5:0.25 1.0:0.25"
time-reset-steer="0.1"/>
<engine power="250 300 350 400" max-speed="15.8 18.8 23.85 30.0" brake-factor="15.0"
max-speed-reverse-ratio="0.3"/>
<gear switch-ratio="0.20 0.55 1" power-increase="5 4 3"/>
<mass value="195"/>
<explosion time="2.1" radius="5.5"
invulnerability-time="7" />
</light>
<medium>
<startup time = "0.3 0.5"
boost = "4.2 2.6" />
<nitro engine-force="425" consumption="1.4" small-container="1" big-container="3"
max-speed-increase="5" duration="1.2" fade-out-time="2" max="20"/>
<slipstream length="10" width="2" collect-time="2" use-time="3.3"
add-power="2.8" min-speed="10"
max-speed-increase="5" duration="0.9" fade-out-time="1.6"/>
<turn turn-radius="0:4.5 10:16.0 25:30.0 45:60.0"
time-full-steer ="0:0.17 0.5:0.17 0.5:0.28 1.0:0.28"
time-reset-steer="0.1"/>
max-speed-increase="5" duration="0.9" fade-out-time="1.6"/>
<engine power="425 500 575 600" max-speed="15 20 23.2 27" brake-factor="11.0"
max-speed-reverse-ratio="0.4"/>
<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"/>
<gear switch-ratio="0.30 0.7 1.0" power-increase="2.2 2.2 2.5"/>
<engine power="425 500 575 600" max-speed="15 20 23.2 27" brake-factor="11.0"
max-speed-reverse-ratio="0.4"/>
<mass value="250"/>
<gear switch-ratio="0.30 0.7 1.0" power-increase="2.2 2.2 2.5"/>
<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"/>
<mass value="250"/>
<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"/>
<explosion time="1.8" radius="5"
invulnerability-time="6" />
</medium>
<engine power="600 700 800 900" max-speed="15 20 23 25" brake-factor="10"
max-speed-reverse-ratio="0.65"/>
<heavy>
<startup time = "0.3 0.5"
boost = "3.8 2" />
<gear switch-ratio="0.45 0.70 1" power-increase="1.5 1.7 2.5"/>
<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"/>
<mass value="350"/>
<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"/>
<explosion time="1.5" radius="4"
invulnerability-time="6" />
</heavy>
</kart-type>
<swatter duration="10" distance="3" squash-duration="5"
squash-slowdown="0.5"/>
<turn turn-radius="0:4.0 10:18.5 25:43.0 45:72.5"
time-full-steer ="0:0.23 0.5:0.23 0.5:0.41 1.0:0.41"
time-reset-steer="0.1"/>
<engine power="600 700 800 900" max-speed="15 20 23 25" brake-factor="10"
max-speed-reverse-ratio="0.65"/>
<gear switch-ratio="0.45 0.70 1" power-increase="1.5 1.7 2.5"/>
<mass value="350"/>
<explosion time="1.5" radius="4"
invulnerability-time="6" />
</heavy>
</kart-type>
</general-kart-defaults>
</config>

View File

@ -27,6 +27,7 @@
#include "io/xml_node.hpp"
#include "items/item.hpp"
#include "karts/kart_properties.hpp"
#include "karts/player_difficulty.hpp"
#include "utils/log.hpp"
STKConfig* stk_config=0;
@ -387,16 +388,23 @@ void STKConfig::getAllData(const XMLNode * root)
throw std::runtime_error(msg.str());
}
m_default_kart_properties->getAllData(node);
const XMLNode *types = node->getNode("kart-type");
const XMLNode *child_node = node->getNode("kart-type");
for (unsigned int i = 0; i < types->getNumNodes(); ++i)
for (unsigned int i = 0; i < child_node->getNumNodes(); ++i)
{
const XMLNode* type = types->getNode(i);
const XMLNode* type = child_node->getNode(i);
m_kart_properties[type->getName()] = new KartProperties();
m_kart_properties[type->getName()]->copyFrom(m_default_kart_properties);
m_kart_properties[type->getName()]->getAllData(type);
}
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
// ----------------------------------------------------------------------------

View File

@ -26,6 +26,7 @@
* configuration file.
*/
#include "network/remote_kart_info.hpp"
#include "utils/no_copy.hpp"
#include <vector>
@ -33,6 +34,7 @@
#include <map>
class KartProperties;
class PlayerDifficulty;
class MusicInformation;
class XMLNode;
@ -47,8 +49,10 @@ class STKConfig : public NoCopy
{
protected:
/** Default kart properties. */
KartProperties *m_default_kart_properties;
KartProperties *m_default_kart_properties;
std::map<std::string, KartProperties*> m_kart_properties;
/** Per-player difficulties. */
PlayerDifficulty* m_player_difficulties[PLAYER_DIFFICULTY_COUNT];
public:
/** What to do if a kart already has a powerup when it hits a bonus box:
@ -175,6 +179,9 @@ public:
const KartProperties &
getKartProperties(std::string type) { return *m_kart_properties[type]; }
const PlayerDifficulty * getPlayerDifficulty(PerPlayerDifficulty difficulty)
{ return m_player_difficulties[difficulty]; }
}
; // STKConfig

Binary file not shown.

Binary file not shown.

View File

@ -37,26 +37,26 @@ namespace GUIEngine
* \brief A progress bar widget.
* \ingroup widgetsgroup
*/
class KartStatsWidget : public Widget
class KartStatsWidget : public Widget
{
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getWidthNeededAroundLabel() const { return 35; }
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getHeightNeededAroundLabel() const { return 4; }
/** widget coordinates */
int m_skill_bar_x, m_skill_bar_y, m_skill_bar_h, m_skill_bar_w;
int m_player_id;
std::vector<SkillLevelWidget*> m_skills;
public:
enum Stats
{
SKILL_MASS,
@ -66,7 +66,7 @@ namespace GUIEngine
};
LEAK_CHECK()
KartStatsWidget(core::recti area, const int player_id,
std::string kart_group, bool multiplayer,
bool display_text);
@ -93,7 +93,7 @@ namespace GUIEngine
/** Change the value of the widget, it must be a percent. */
void setValue(Stats type, int value);
/** Get the current values of the widget. */
int getValue(Stats type);

View File

@ -137,15 +137,15 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] =
StringUtils::toString(player_amount-1);
m_player_ident_spinner->m_properties[PROP_WRAP_AROUND] = "true";
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_EASIEST);
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_HARDEST);
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_EASIEST);
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_HARDEST);
}
else
{
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] = "0";
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_NORMAL);
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_NORMAL);
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_NORMAL);
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_NORMAL);
}
//m_player_ident_spinner->m_event_handler = this;
@ -374,7 +374,7 @@ void PlayerKartWidget::add()
m_difficulty->addLabel(_("Normal"));
m_difficulty->addLabel(_("Hard"));
m_difficulty->addLabel(_("Hardest"));
m_difficulty->setValue(RaceManager::PLAYER_DIFFICULTY_NORMAL);
m_difficulty->setValue(PLAYER_DIFFICULTY_NORMAL);
}
else
{

View File

@ -26,28 +26,28 @@ class KartSelectionScreen;
namespace GUIEngine
{
/** A small extension to the spinner widget to add features like player ID
* management or badging */
class PlayerNameSpinner : public GUIEngine::SpinnerWidget
{
int m_player_id;
bool m_incorrect;
irr::gui::IGUIImage* m_red_mark_widget;
KartSelectionScreen* m_parent;
//virtual EventPropagation focused(const int m_playerID) ;
/** A small extension to the spinner widget to add features like player ID
* management or badging */
class PlayerNameSpinner : public GUIEngine::SpinnerWidget
{
int m_player_id;
bool m_incorrect;
irr::gui::IGUIImage* m_red_mark_widget;
KartSelectionScreen* m_parent;
//virtual EventPropagation focused(const int m_playerID) ;
public:
PlayerNameSpinner(KartSelectionScreen* parent, const int playerID);
// ------------------------------------------------------------------------
void setID(const int m_playerID);
// ------------------------------------------------------------------------
/** Add a red mark on the spinner to mean "invalid choice" */
void markAsIncorrect();
public:
PlayerNameSpinner(KartSelectionScreen* parent, const int playerID);
// ------------------------------------------------------------------------
void setID(const int m_playerID);
// ------------------------------------------------------------------------
/** Add a red mark on the spinner to mean "invalid choice" */
void markAsIncorrect();
// ------------------------------------------------------------------------
/** Remove any red mark set with 'markAsIncorrect' */
void markAsCorrect();
};
// ------------------------------------------------------------------------
/** Remove any red mark set with 'markAsIncorrect' */
void markAsCorrect();
};
}
#endif

View File

@ -34,11 +34,13 @@
*/
AbstractKart::AbstractKart(const std::string& ident,
int world_kart_id, int position,
const btTransform& init_transform)
const btTransform& init_transform,
const PlayerDifficulty *difficulty)
: Moveable()
{
m_world_kart_id = world_kart_id;
m_kart_properties = kart_properties_manager->getKart(ident);
m_difficulty = difficulty;
m_kart_animation = NULL;
assert(m_kart_properties != NULL);

View File

@ -22,6 +22,7 @@
#include "items/powerup_manager.hpp"
#include "karts/moveable.hpp"
#include "karts/controller/kart_control.hpp"
#include "karts/player_difficulty.hpp"
#include "race/race_manager.hpp"
class AbstractKartAnimation;
@ -63,6 +64,9 @@ protected:
/** The kart properties. */
const KartProperties *m_kart_properties;
/** The per-player difficulty. */
const PlayerDifficulty *m_difficulty;
/** This stores a copy of the kart model. It has to be a copy
* since otherwise incosistencies can happen if the same kart
* is used more than once. */
@ -80,7 +84,8 @@ protected:
public:
AbstractKart(const std::string& ident,
int world_kart_id,
int position, const btTransform& init_transform);
int position, const btTransform& init_transform,
const PlayerDifficulty *difficulty);
virtual ~AbstractKart();
virtual core::stringw getName() const;
virtual void reset();
@ -110,6 +115,16 @@ public:
/** Sets the kart properties. */
void setKartProperties(const KartProperties *kp) { m_kart_properties=kp; }
// ========================================================================
// Access to the per-player difficulty.
// ------------------------------------------------------------------------
/** Returns the per-player difficulty of this kart. */
const PlayerDifficulty* getPlayerDifficulty() const
{ return m_difficulty; }
// ------------------------------------------------------------------------
/** Sets the per-player difficulty. */
void setPlayerDifficulty(const PlayerDifficulty *pd) { m_difficulty=pd; }
// ------------------------------------------------------------------------
/** Returns a unique identifier for this kart (name of the directory the
* kart was loaded from). */

View File

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

View File

@ -92,8 +92,10 @@
* \param init_transform The initial position and rotation for this kart.
*/
Kart::Kart (const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform)
: AbstractKart(ident, world_kart_id, position, init_transform)
int position, const btTransform& init_transform,
const PlayerDifficulty *difficulty)
: AbstractKart(ident, world_kart_id, position, init_transform,
difficulty)
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
# pragma warning(1:4355)
@ -127,7 +129,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_is_jumping = false;
m_min_nitro_time = 0.0f;
m_fire_clicked = 0;
m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false;
@ -528,7 +530,7 @@ void Kart::blockViewWithPlunger()
// Avoid that a plunger extends the plunger time
if(m_view_blocked_by_plunger<=0 && !isShielded())
m_view_blocked_by_plunger =
m_kart_properties->getPlungerInFaceTime();
m_kart_properties->getPlungerInFaceTime() * m_difficulty->getPlungerInFaceTime();
if(isShielded())
{
decreaseShieldTime();
@ -890,13 +892,16 @@ void Kart::collectedItem(Item *item, int add_info)
item->getEmitter()->getIdent() == "nolok");
// slow down
m_bubblegum_time = m_kart_properties->getBubblegumTime();
m_bubblegum_torque = (rand()%2)
m_bubblegum_time = m_kart_properties->getBubblegumTime() * m_difficulty->getBubblegumTime();
m_bubblegum_torque = ((rand()%2)
? m_kart_properties->getBubblegumTorque()
: -m_kart_properties->getBubblegumTorque();
: -m_kart_properties->getBubblegumTorque()) *
m_difficulty->getBubblegumTorque();
m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_BUBBLE,
m_kart_properties->getBubblegumSpeedFraction(),
m_kart_properties->getBubblegumFadeInTime(),
m_kart_properties->getBubblegumSpeedFraction() *
m_difficulty->getBubblegumSpeedFraction(),
m_kart_properties->getBubblegumFadeInTime() *
m_difficulty->getBubblegumFadeInTime(),
m_bubblegum_time);
m_goo_sound->position(getXYZ());
m_goo_sound->play();
@ -923,17 +928,21 @@ float Kart::getActualWheelForce()
const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio();
for(unsigned int i=0; i<gear_ratio.size(); i++)
{
if(m_speed <= m_kart_properties->getMaxSpeed()*gear_ratio[i])
if(m_speed <= m_kart_properties->getMaxSpeed() *
m_difficulty->getMaxSpeed() * gear_ratio[i])
{
assert(!isnan(m_kart_properties->getMaxPower()));
assert(!isnan(m_kart_properties->getMaxPower() *
m_difficulty->getMaxPower()));
assert(!isnan(m_kart_properties->getGearPowerIncrease()[i]));
return m_kart_properties->getMaxPower()
return m_kart_properties->getMaxPower() *
m_difficulty->getMaxPower()
*m_kart_properties->getGearPowerIncrease()[i]
+add_force;
}
}
assert(!isnan(m_kart_properties->getMaxPower()));
return m_kart_properties->getMaxPower()+add_force;
assert(!isnan(m_kart_properties->getMaxPower() * m_difficulty->getMaxPower()));
return m_kart_properties->getMaxPower() * m_difficulty->getMaxPower()
+add_force * 2;
} // getActualWheelForce
@ -1133,7 +1142,7 @@ void Kart::update(float dt)
if (m_collision_particles) m_collision_particles->update(dt);
updatePhysics(dt);
if(!m_controls.m_fire) m_fire_clicked = 0;
if(m_controls.m_fire && !m_fire_clicked && !m_kart_animation)
@ -1434,7 +1443,7 @@ void Kart::handleMaterialSFX(const Material *material)
sfx_manager->deleteSFX(m_previous_terrain_sound);
m_previous_terrain_sound = NULL;
}
bool m_schedule_pause = m_flying ||
dynamic_cast<RescueAnimation*>(getKartAnimation()) ||
dynamic_cast<ExplosionAnimation*>(getKartAnimation());
@ -1600,23 +1609,33 @@ void Kart::handleZipper(const Material *material, bool play_sound)
material->getZipperParameter(&max_speed_increase, &duration,
&speed_gain, &fade_out_time, &engine_force);
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)
duration = m_kart_properties->getZipperTime();
duration = m_kart_properties->getZipperTime() *
m_difficulty->getZipperTime();
if(speed_gain<0)
speed_gain = m_kart_properties->getZipperSpeedGain();
speed_gain = m_kart_properties->getZipperSpeedGain() *
m_difficulty->getZipperSpeedGain();
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)
engine_force = m_kart_properties->getZipperForce();
engine_force = m_kart_properties->getZipperForce() *
m_difficulty->getZipperForce();
}
else
{
max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease();
duration = m_kart_properties->getZipperTime();
speed_gain = m_kart_properties->getZipperSpeedGain();
fade_out_time = m_kart_properties->getZipperFadeOutTime();
engine_force = m_kart_properties->getZipperForce();
max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease() *
m_difficulty->getZipperMaxSpeedIncrease();
duration = m_kart_properties->getZipperTime() *
m_difficulty->getZipperTime();
speed_gain = m_kart_properties->getZipperSpeedGain() *
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
if(m_controls.m_brake || m_speed<0) return;
@ -1642,32 +1661,37 @@ void Kart::updateNitro(float dt)
if (m_min_nitro_time > 0.0f)
{
m_min_nitro_time -= dt;
// when pressing the key, don't allow the min time to go under zero.
// If it went under zero, it would be reset
if (m_controls.m_nitro && m_min_nitro_time <= 0.0f)
m_min_nitro_time = 0.1f;
}
bool increase_speed = (m_controls.m_nitro && isOnGround());
if (!increase_speed && m_min_nitro_time <= 0.0f)
{
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)
{
m_collected_energy = 0;
return;
}
if (increase_speed)
{
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
m_kart_properties->getNitroMaxSpeedIncrease(),
m_kart_properties->getNitroEngineForce(),
m_kart_properties->getNitroDuration(),
m_kart_properties->getNitroFadeOutTime() );
m_kart_properties->getNitroMaxSpeedIncrease() *
m_difficulty->getNitroMaxSpeedIncrease(),
m_kart_properties->getNitroEngineForce() *
m_difficulty->getNitroEngineForce(),
m_kart_properties->getNitroDuration() *
m_difficulty->getNitroDuration(),
m_kart_properties->getNitroFadeOutTime() *
m_difficulty->getNitroFadeOutTime());
}
} // updateNitro
@ -1960,7 +1984,8 @@ void Kart::updatePhysics(float dt)
if(!m_has_started && m_controls.m_accel)
{
m_has_started = true;
float f = m_kart_properties->getStartupBoost();
float f = m_kart_properties->getStartupBoost() *
m_difficulty->getStartupBoost();
m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER,
0.9f*f, f,
/*engine_force*/200.0f,
@ -2063,13 +2088,13 @@ void Kart::updatePhysics(float dt)
//at low velocity, forces on kart push it back and forth so we ignore this
if(fabsf(m_speed) < 0.2f) // quick'n'dirty workaround for bug 1776883
m_speed = 0;
if (dynamic_cast<RescueAnimation*>(getKartAnimation()) ||
dynamic_cast<ExplosionAnimation*>(getKartAnimation()))
{
m_speed = 0;
}
updateEngineSFX();
#ifdef XX
Log::info("Kart","forward %f %f %f %f side %f %f %f %f angVel %f %f %f heading %f"
@ -2179,7 +2204,8 @@ void Kart::updateEnginePowerAndBrakes(float dt)
applyEngineForce(0.f);
//apply the brakes
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor());
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor() *
m_difficulty->getBrakeFactor());
}
else // m_speed < 0
{
@ -2187,7 +2213,8 @@ void Kart::updateEnginePowerAndBrakes(float dt)
// going backward, apply reverse gear ratio (unless he goes
// too fast backwards)
if ( -m_speed < m_max_speed->getCurrentMaxSpeed()
*m_kart_properties->getMaxSpeedReverseRatio())
*m_kart_properties->getMaxSpeedReverseRatio() *
m_difficulty->getMaxSpeedReverseRatio())
{
// The backwards acceleration is artificially increased to
// allow players to get "unstuck" quicker if they hit e.g.
@ -2417,7 +2444,8 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
{
// fabs(speed) is important, otherwise the negative number will
// become a huge unsigned number in the particle scene node!
float f = fabsf(getSpeed())/m_kart_properties->getMaxSpeed();
float f = fabsf(getSpeed())/m_kart_properties->getMaxSpeed() *
m_difficulty->getMaxSpeed();
// The speed of the kart can be higher (due to powerups) than
// the normal maximum speed of the kart.
if(f>1.0f) f = 1.0f;
@ -2432,7 +2460,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_NITRO2, 0);
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_NITROSMOKE1, 0);
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_NITROSMOKE2, 0);
}
m_kart_gfx->resizeBox(KartGFX::KGFX_NITRO1, getSpeed(), dt);
m_kart_gfx->resizeBox(KartGFX::KGFX_NITRO2, getSpeed(), dt);
@ -2448,7 +2476,8 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
// leaning might get less if a kart gets a special that increases
// its maximum speed, but not the current speed (by much). On the
// 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->getMaxSpeed() *
m_difficulty->getMaxSpeed();
if(speed_frac>1.0f)
speed_frac = 1.0f;
else if (speed_frac < 0.0f) // no leaning when backwards driving

View File

@ -31,6 +31,7 @@
#include "items/powerup.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "karts/player_difficulty.hpp"
#include "tracks/terrain_info.hpp"
#include "utils/no_copy.hpp"
@ -134,7 +135,7 @@ private:
/** The torque to apply after hitting a bubble gum. */
float m_bubblegum_torque;
/** True if fire button was pushed and not released */
bool m_fire_clicked;
@ -154,10 +155,10 @@ private:
// -----------------
/** Time a kart is jumping. */
float m_jump_time;
/** Is time flying activated */
bool m_is_jumping;
/** The shadow of a kart. */
Shadow *m_shadow;
@ -205,7 +206,7 @@ private:
SFXBase *m_goo_sound;
SFXBase *m_boing_sound;
float m_time_last_crash;
/** To prevent using nitro in too short bursts */
float m_min_nitro_time;
@ -223,7 +224,8 @@ private:
public:
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);
virtual ~Kart();
virtual void init(RaceManager::KartType type);
virtual void updateGraphics(float dt, const Vec3& off_xyz,

View File

@ -461,149 +461,149 @@ void KartProperties::getAllData(const XMLNode * root)
} // if sounds-node exist
if(const XMLNode *nitro_node = root->getNode("nitro"))
{
nitro_node->get("consumption", &m_nitro_consumption );
nitro_node->get("small-container", &m_nitro_small_container );
nitro_node->get("big-container", &m_nitro_big_container );
nitro_node->get("max-speed-increase", &m_nitro_max_speed_increase);
nitro_node->get("engine-force", &m_nitro_engine_force );
nitro_node->get("duration", &m_nitro_duration );
nitro_node->get("fade-out-time", &m_nitro_fade_out_time );
nitro_node->get("max", &m_nitro_max );
nitro_node->get("min-consumption-time", &m_nitro_min_consumption );
}
if(const XMLNode *bubble_node = root->getNode("bubblegum"))
{
bubble_node->get("time", &m_bubblegum_time );
bubble_node->get("speed-fraction", &m_bubblegum_speed_fraction);
bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time );
bubble_node->get("torque", &m_bubblegum_torque );
}
if(const XMLNode *rescue_node = root->getNode("rescue"))
{
rescue_node->get("vert-offset", &m_rescue_vert_offset);
rescue_node->get("time", &m_rescue_time );
rescue_node->get("height", &m_rescue_height );
}
if(const XMLNode *explosion_node = root->getNode("explosion"))
{
explosion_node->get("time", &m_explosion_time );
explosion_node->get("radius", &m_explosion_radius);
explosion_node->get("invulnerability-time",
&m_explosion_invulnerability_time);
}
if(const XMLNode *skid_node = root->getNode("skid"))
{
m_skidding_properties->load(skid_node);
}
if(const XMLNode *slipstream_node = root->getNode("slipstream"))
{
slipstream_node->get("length", &m_slipstream_length );
slipstream_node->get("width", &m_slipstream_width );
slipstream_node->get("collect-time", &m_slipstream_collect_time );
slipstream_node->get("use-time", &m_slipstream_use_time );
slipstream_node->get("add-power", &m_slipstream_add_power );
slipstream_node->get("min-speed", &m_slipstream_min_speed );
slipstream_node->get("max-speed-increase",
&m_slipstream_max_speed_increase);
slipstream_node->get("duration", &m_slipstream_duration );
slipstream_node->get("fade-out-time",&m_slipstream_fade_out_time );
}
if(const XMLNode *turn_node = root->getNode("turn"))
{
turn_node->get("time-full-steer", &m_time_full_steer );
turn_node->get("time-reset-steer", &m_time_reset_steer );
turn_node->get("turn-radius", &m_turn_angle_at_speed );
// For now store the turn radius in turn angle, the correct
// value can only be determined later in ::load
}
if(const XMLNode *engine_node = root->getNode("engine"))
{
engine_node->get("brake-factor", &m_brake_factor);
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
engine_node->get("power", &m_engine_power);
if(m_engine_power.size()!=RaceManager::DIFFICULTY_COUNT)
{
nitro_node->get("consumption", &m_nitro_consumption );
nitro_node->get("small-container", &m_nitro_small_container );
nitro_node->get("big-container", &m_nitro_big_container );
nitro_node->get("max-speed-increase", &m_nitro_max_speed_increase);
nitro_node->get("engine-force", &m_nitro_engine_force );
nitro_node->get("duration", &m_nitro_duration );
nitro_node->get("fade-out-time", &m_nitro_fade_out_time );
nitro_node->get("max", &m_nitro_max );
nitro_node->get("min-consumption-time", &m_nitro_min_consumption );
Log::fatal("[KartProperties]",
"Incorrect engine-power specifications for kart '%s'",
getIdent().c_str());
}
if(const XMLNode *bubble_node = root->getNode("bubblegum"))
engine_node->get("max-speed", &m_max_speed);
if(m_max_speed.size()!=RaceManager::DIFFICULTY_COUNT)
{
bubble_node->get("time", &m_bubblegum_time );
bubble_node->get("speed-fraction", &m_bubblegum_speed_fraction);
bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time );
bubble_node->get("torque", &m_bubblegum_torque );
Log::fatal("[KartProperties]",
"Incorrect max-speed specifications for kart '%s'",
getIdent().c_str());
}
} // if getNode("engine")
if(const XMLNode *rescue_node = root->getNode("rescue"))
if(const XMLNode *gear_node = root->getNode("gear"))
{
gear_node->get("switch-ratio", &m_gear_switch_ratio );
gear_node->get("power-increase", &m_gear_power_increase);
}
if(const XMLNode *mass_node = root->getNode("mass"))
mass_node->get("value", &m_mass);
if(const XMLNode *plunger_node= root->getNode("plunger"))
{
plunger_node->get("band-max-length", &m_rubber_band_max_length );
plunger_node->get("band-force", &m_rubber_band_force );
plunger_node->get("band-duration", &m_rubber_band_duration );
plunger_node->get("band-speed-increase",&m_rubber_band_speed_increase);
plunger_node->get("band-fade-out-time", &m_rubber_band_fade_out_time );
plunger_node->get("in-face-time", &m_plunger_in_face_duration);
if(m_plunger_in_face_duration.size()!=RaceManager::DIFFICULTY_COUNT)
{
rescue_node->get("vert-offset", &m_rescue_vert_offset);
rescue_node->get("time", &m_rescue_time );
rescue_node->get("height", &m_rescue_height );
Log::fatal("KartProperties",
"Invalid plunger in-face-time specification.");
}
}
if(const XMLNode *explosion_node = root->getNode("explosion"))
if(const XMLNode *zipper_node= root->getNode("zipper"))
{
zipper_node->get("time", &m_zipper_time );
zipper_node->get("fade-out-time", &m_zipper_fade_out_time );
zipper_node->get("force", &m_zipper_force );
zipper_node->get("speed-gain", &m_zipper_speed_gain );
zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase);
}
if(const XMLNode *swatter_node= root->getNode("swatter"))
{
swatter_node->get("duration", &m_swatter_duration );
swatter_node->get("squash-duration", &m_squash_duration );
swatter_node->get("squash-slowdown", &m_squash_slowdown );
if(swatter_node->get("distance", &m_swatter_distance2) )
{
explosion_node->get("time", &m_explosion_time );
explosion_node->get("radius", &m_explosion_radius);
explosion_node->get("invulnerability-time",
&m_explosion_invulnerability_time);
// Avoid squaring if distance is not defined, so that
// distance2 remains UNDEFINED (which is a negative value)
m_swatter_distance2 *= m_swatter_distance2;
}
}
if(const XMLNode *skid_node = root->getNode("skid"))
{
m_skidding_properties->load(skid_node);
}
if(const XMLNode *lean_node= root->getNode("lean"))
{
lean_node->get("max", &m_max_lean );
lean_node->get("speed", &m_lean_speed);
m_max_lean *= DEGREE_TO_RAD;
m_lean_speed *= DEGREE_TO_RAD;
}
if(const XMLNode *slipstream_node = root->getNode("slipstream"))
{
slipstream_node->get("length", &m_slipstream_length );
slipstream_node->get("width", &m_slipstream_width );
slipstream_node->get("collect-time", &m_slipstream_collect_time );
slipstream_node->get("use-time", &m_slipstream_use_time );
slipstream_node->get("add-power", &m_slipstream_add_power );
slipstream_node->get("min-speed", &m_slipstream_min_speed );
slipstream_node->get("max-speed-increase",
&m_slipstream_max_speed_increase);
slipstream_node->get("duration", &m_slipstream_duration );
slipstream_node->get("fade-out-time",&m_slipstream_fade_out_time );
}
if(const XMLNode *turn_node = root->getNode("turn"))
{
turn_node->get("time-full-steer", &m_time_full_steer );
turn_node->get("time-reset-steer", &m_time_reset_steer );
turn_node->get("turn-radius", &m_turn_angle_at_speed );
// For now store the turn radius in turn angle, the correct
// value can only be determined later in ::load
}
if(const XMLNode *engine_node = root->getNode("engine"))
{
engine_node->get("brake-factor", &m_brake_factor);
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
engine_node->get("power", &m_engine_power);
if(m_engine_power.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("[KartProperties]",
"Incorrect engine-power specifications for kart '%s'",
getIdent().c_str());
}
engine_node->get("max-speed", &m_max_speed);
if(m_max_speed.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("[KartProperties]",
"Incorrect max-speed specifications for kart '%s'",
getIdent().c_str());
}
} // if getNode("engine")
if(const XMLNode *gear_node = root->getNode("gear"))
{
gear_node->get("switch-ratio", &m_gear_switch_ratio );
gear_node->get("power-increase", &m_gear_power_increase);
}
if(const XMLNode *mass_node = root->getNode("mass"))
mass_node->get("value", &m_mass);
if(const XMLNode *plunger_node= root->getNode("plunger"))
{
plunger_node->get("band-max-length", &m_rubber_band_max_length );
plunger_node->get("band-force", &m_rubber_band_force );
plunger_node->get("band-duration", &m_rubber_band_duration );
plunger_node->get("band-speed-increase",&m_rubber_band_speed_increase);
plunger_node->get("band-fade-out-time", &m_rubber_band_fade_out_time );
plunger_node->get("in-face-time", &m_plunger_in_face_duration);
if(m_plunger_in_face_duration.size()!=RaceManager::DIFFICULTY_COUNT)
{
Log::fatal("KartProperties",
"Invalid plunger in-face-time specification.");
}
}
if(const XMLNode *zipper_node= root->getNode("zipper"))
{
zipper_node->get("time", &m_zipper_time );
zipper_node->get("fade-out-time", &m_zipper_fade_out_time );
zipper_node->get("force", &m_zipper_force );
zipper_node->get("speed-gain", &m_zipper_speed_gain );
zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase);
}
if(const XMLNode *swatter_node= root->getNode("swatter"))
{
swatter_node->get("duration", &m_swatter_duration );
swatter_node->get("squash-duration", &m_squash_duration );
swatter_node->get("squash-slowdown", &m_squash_slowdown );
if(swatter_node->get("distance", &m_swatter_distance2) )
{
// Avoid squaring if distance is not defined, so that
// distance2 remains UNDEFINED (which is a negative value)
m_swatter_distance2 *= m_swatter_distance2;
}
}
if(const XMLNode *lean_node= root->getNode("lean"))
{
lean_node->get("max", &m_max_lean );
lean_node->get("speed", &m_lean_speed);
m_max_lean *= DEGREE_TO_RAD;
m_lean_speed *= DEGREE_TO_RAD;
}
if(const XMLNode *startup_node= root->getNode("startup"))
{
startup_node->get("time", &m_startup_times);
startup_node->get("boost", &m_startup_boost);
}
if(const XMLNode *startup_node= root->getNode("startup"))
{
startup_node->get("time", &m_startup_times);
startup_node->get("boost", &m_startup_boost);
}
if(m_kart_model)
m_kart_model->loadInfo(*root);

View File

@ -124,7 +124,7 @@ private:
/** Weight of kart. */
float m_mass;
/** Maximum force from engine for eachdifficulty. */
/** Maximum force from engine for each difficulty. */
std::vector<float> m_engine_power;
/** Braking factor * engine_power braking force. */

View File

@ -25,9 +25,10 @@
KartWithStats::KartWithStats(const std::string& ident,
unsigned int world_kart_id,
int position, const btTransform& init_transform)
int position, const btTransform& init_transform,
const PlayerDifficulty *difficulty)
: Kart(ident, world_kart_id, position,
init_transform)
init_transform, difficulty)
{
} // KartWithStats

View File

@ -74,7 +74,8 @@ public:
KartWithStats(const std::string& ident,
unsigned int world_kart_id,
int position,
const btTransform& init_transform);
const btTransform& init_transform,
const PlayerDifficulty *difficulty);
virtual void update(float dt);
virtual void reset();
virtual void collectedItem(Item *item, int add_info);

View File

@ -0,0 +1,200 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2013 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 (mostly 1).
*/
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_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_EASIEST: return "easiest"; break;
case PLAYER_DIFFICULTY_EASY: return "easy"; break;
case PLAYER_DIFFICULTY_NORMAL: return "normal"; break;
case PLAYER_DIFFICULTY_HARD: return "hard"; break;
case PLAYER_DIFFICULTY_HARDEST: return "hardest"; 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 *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("fade-in-time", &m_bubblegum_fade_in_time );
bubble_node->get("torque", &m_bubblegum_torque );
}
if(const XMLNode *rescue_node = root->getNode("rescue"))
{
rescue_node->get("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 *engine_node = root->getNode("engine"))
{
engine_node->get("brake-factor", &m_brake_factor);
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
engine_node->get("power", &m_engine_power);
engine_node->get("max-speed", &m_max_speed);
} // if getNode("engine")
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

@ -0,0 +1,342 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2013 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 the properties of a kart.
* This includes size, name, identifier, physical properties etc.
* It is atm also the base class for STKConfig, which stores the default values
* for all physics constants.
* Note that KartProperies is copied (when setting the default values from
* stk_config.
*
* \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;
/** 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; }
// ------------------------------------------------------------------------
/** 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; }
// ------------------------------------------------------------------------
/** Return the absolute maximum speed, independent on the difficulty. */
float getAbsMaxSpeed () 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

@ -105,14 +105,15 @@ void ProfileWorld::setProfileModeLaps(int laps)
*/
AbstractKart *ProfileWorld::createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id,
RaceManager::KartType type)
RaceManager::KartType type,
const PlayerDifficulty *difficulty)
{
btTransform init_pos = m_track->getStartTransform(index);
Kart *new_kart = new KartWithStats(kart_ident,
/*world kart id*/ index,
/*position*/ index+1,
init_pos);
init_pos, difficulty);
new_kart->init(RaceManager::KT_AI);
Controller *controller = loadAIController(new_kart);
new_kart->setController(controller);
@ -327,7 +328,7 @@ void ProfileWorld::enterRaceOverState()
expl_count += kart->getExplosionCount();
off_track_count += kart->getOffTrackCount();
} // for i < m_karts.size
Log::verbose("profile", std::string(max_len+85, '-').c_str());
ss.clear();
ss.str("");

View File

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

View File

@ -460,7 +460,8 @@ int SoccerWorld::getTeamLeader(unsigned int team)
//-----------------------------------------------------------------------------
AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id,
RaceManager::KartType kart_type)
RaceManager::KartType kart_type,
const PlayerDifficulty *difficulty)
{
int posIndex = index;
int position = index+1;
@ -476,7 +477,8 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
btTransform init_pos = m_track->getStartTransform(posIndex);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
difficulty);
new_kart->init(race_manager->getKartType(index));
Controller *controller = NULL;

View File

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

View File

@ -177,9 +177,12 @@ void World::init()
: race_manager->getKartIdent(i);
int local_player_id = race_manager->getKartLocalPlayerId(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,
global_player_id,
race_manager->getKartType(i));
race_manager->getKartType(i),
player_difficulty);
m_karts.push_back(newkart);
m_track->adjustForFog(newkart->getNode());
@ -284,11 +287,13 @@ void World::createRaceGUI()
*/
AbstractKart *World::createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id,
RaceManager::KartType kart_type)
RaceManager::KartType kart_type,
const PlayerDifficulty *difficulty)
{
int position = index+1;
btTransform init_pos = m_track->getStartTransform(index);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
difficulty);
new_kart->init(race_manager->getKartType(index));
Controller *controller = NULL;
switch(kart_type)
@ -455,7 +460,7 @@ void World::terminateRace()
PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_MARATHONER,
"laps", race_manager->getNumLaps());
}
Achievement *achiev = PlayerManager::getCurrentAchievementsStatus()->getAchievement(AchievementInfo::ACHIEVE_GOLD_DRIVER);
if (achiev)
{
@ -487,7 +492,7 @@ void World::terminateRace()
}
} // for i < kart_amount
} // if (achiev)
Achievement *win = PlayerManager::getCurrentAchievementsStatus()->getAchievement(AchievementInfo::ACHIEVE_UNSTOPPABLE);
//if achivement has been unlocked
if (win->getValue("wins") < 5 )
@ -805,7 +810,7 @@ void World::updateWorld(float dt)
#ifdef DEBUG
assert(m_magic_number == 0xB01D6543);
#endif
if( (!isFinishPhase()) && isRaceOver())
{
enterRaceOverState();

View File

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

View File

@ -130,6 +130,7 @@ void StartGameProtocol::update()
race_manager->setLocalKartInfo(new_player_id, profile->kart_name);
Log::info("StartGameProtocol", "Self player device added."); // self config
NetworkWorld::getInstance()->m_self_kart = profile->kart_name;
break;
}
}
for (unsigned int i = 0; i < players.size(); i++)

View File

@ -23,6 +23,7 @@
#define HEADER_REMOTE_KART_INFO_HPP
#include <string>
#include <vector>
#include <irrString.h>
enum SoccerTeam
@ -33,6 +34,17 @@ enum SoccerTeam
NB_SOCCER_TEAMS
};
/** Game difficulty per player. */
enum PerPlayerDifficulty
{
PLAYER_DIFFICULTY_EASIEST,
PLAYER_DIFFICULTY_EASY,
PLAYER_DIFFICULTY_NORMAL,
PLAYER_DIFFICULTY_HARD,
PLAYER_DIFFICULTY_HARDEST,
PLAYER_DIFFICULTY_COUNT
};
class RemoteKartInfo
{
std::string m_kart_name;
@ -42,35 +54,41 @@ class RemoteKartInfo
int m_host_id;
SoccerTeam m_soccer_team;
bool m_network_player;
PerPlayerDifficulty m_difficulty;
public:
RemoteKartInfo(int player_id, const std::string& kart_name,
const irr::core::stringw& user_name, int host_id, bool network)
: m_kart_name(kart_name), m_user_name(user_name),
m_local_player_id(player_id), m_host_id(host_id),
m_soccer_team(SOCCER_TEAM_NONE), m_network_player(network)
RemoteKartInfo(int player_id, const std::string& kart_name,
const irr::core::stringw& user_name, int host_id,
bool network)
: m_kart_name(kart_name), m_user_name(user_name),
m_local_player_id(player_id), m_host_id(host_id),
m_soccer_team(SOCCER_TEAM_NONE), m_network_player(network),
m_difficulty(PLAYER_DIFFICULTY_NORMAL)
{}
RemoteKartInfo(const std::string& kart_name) : m_kart_name(kart_name),
m_user_name(""), m_local_player_id(-1), m_host_id(-1),
m_difficulty(PLAYER_DIFFICULTY_NORMAL)
{}
RemoteKartInfo() : m_kart_name(""), m_user_name(""), m_local_player_id(-1),
m_host_id(-1), m_difficulty(PLAYER_DIFFICULTY_NORMAL)
{}
void setKartName(const std::string& n) { m_kart_name = n; }
void setPlayerName(const irr::core::stringw& u) { m_user_name = u; }
void setHostId(int id) { m_host_id = id; }
void setLocalPlayerId(int id) { m_local_player_id = id; }
void setGlobalPlayerId(int id) { m_global_player_id = id; }
void setSoccerTeam(SoccerTeam team) { m_soccer_team = team; }
void setNetworkPlayer(bool value) { m_network_player = value; }
void setDifficulty(PerPlayerDifficulty value) { m_difficulty = value; }
{};
RemoteKartInfo(const std::string& kart_name)
{m_kart_name=kart_name; m_user_name="";
m_host_id=-1; m_local_player_id=-1;}
RemoteKartInfo() {m_kart_name=""; m_user_name="";
m_host_id=-1; m_local_player_id=-1;}
void setKartName(const std::string& n) { m_kart_name = n; }
void setPlayerName(const irr::core::stringw& u) { m_user_name = u; }
void setHostId(int id) { m_host_id = id; }
void setLocalPlayerId(int id) { m_local_player_id = id; }
void setGlobalPlayerId(int id) { m_global_player_id = id; }
const void setSoccerTeam(SoccerTeam team) { m_soccer_team = team; }
void setNetworkPlayer(bool value) { m_network_player = value; }
int getHostId() const { return m_host_id; }
int getLocalPlayerId() const { return m_local_player_id; }
int getGlobalPlayerId() const { return m_global_player_id; }
bool isNetworkPlayer() const { return m_network_player; }
const std::string& getKartName() const { return m_kart_name; }
const irr::core::stringw& getPlayerName() const { return m_user_name; }
const SoccerTeam getSoccerTeam() const {return m_soccer_team; }
int getHostId() const { return m_host_id; }
int getLocalPlayerId() const { return m_local_player_id; }
int getGlobalPlayerId() const { return m_global_player_id; }
bool isNetworkPlayer() const { return m_network_player; }
const std::string& getKartName() const { return m_kart_name; }
const irr::core::stringw& getPlayerName() const { return m_user_name; }
SoccerTeam getSoccerTeam() const { return m_soccer_team; }
PerPlayerDifficulty getDifficulty() const { return m_difficulty; }
bool operator<(const RemoteKartInfo& other) const
{

View File

@ -147,9 +147,8 @@ void RaceManager::setLocalKartInfo(unsigned int player_id,
assert(kart_properties_manager->getKart(kart) != NULL);
const PlayerProfile* profile = StateManager::get()->getActivePlayerProfile(player_id);
m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart,
profile->getName(),
0, false);
m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart, profile->getName(),
0, false);
} // setLocalKartInfo
//-----------------------------------------------------------------------------
@ -312,7 +311,7 @@ void RaceManager::startNew(bool from_overworld)
for(unsigned int i=0; i<ai_kart_count; i++)
{
m_kart_status.push_back(KartStatus(m_ai_kart_list[i], i, -1, -1,
init_gp_rank, KT_AI));
init_gp_rank, KT_AI, PLAYER_DIFFICULTY_NORMAL));
init_gp_rank ++;
if(UserConfigParams::m_ftl_debug)
{
@ -329,8 +328,8 @@ void RaceManager::startNew(bool from_overworld)
m_kart_status.push_back(KartStatus(m_player_karts[i].getKartName(), i,
m_player_karts[i].getLocalPlayerId(),
m_player_karts[i].getGlobalPlayerId(),
init_gp_rank, kt
) );
init_gp_rank, kt,
m_player_karts[i].getDifficulty()));
if(UserConfigParams::m_ftl_debug)
{
Log::debug("RaceManager", "[ftl] rank %d kart %s", init_gp_rank,

View File

@ -234,13 +234,6 @@ public:
DIFFICULTY_LAST = DIFFICULTY_BEST,
DIFFICULTY_COUNT};
/** Game difficulty. */
enum PerPlayerDifficulty { PLAYER_DIFFICULTY_EASIEST,
PLAYER_DIFFICULTY_EASY,
PLAYER_DIFFICULTY_NORMAL,
PLAYER_DIFFICULTY_HARD,
PLAYER_DIFFICULTY_HARDEST };
/** Different kart types: A local player, a player connected via network,
* an AI kart, the leader kart (currently not used), a ghost kart. */
enum KartType { KT_PLAYER, KT_NETWORK_PLAYER, KT_AI, KT_LEADER,
@ -276,16 +269,19 @@ public:
/** In GPs, at the end, will hold the overall rank of this kart
* (0<=m_gp_rank < num_karts-1). */
int m_gp_rank;
/** The difficulty for this player. */
PerPlayerDifficulty m_difficulty;
KartStatus(const std::string& ident, const int& prev_finish_pos,
int local_player_id, int global_player_id,
int init_gp_rank, KartType kt) :
int init_gp_rank, KartType kt,
PerPlayerDifficulty difficulty) :
m_ident(ident), m_score(0), m_last_score(0),
m_overall_time(0.0f), m_last_time(0.0f),
m_kart_type(kt),
m_local_player_id(local_player_id),
m_global_player_id(global_player_id),
m_gp_rank(init_gp_rank)
m_gp_rank(init_gp_rank), m_difficulty(difficulty)
{}
}; // KartStatus
@ -530,21 +526,6 @@ public:
return "";
} // getDifficultyAsString
// ------------------------------------------------------------------------
/** Returns the specified difficulty as a string. */
std::string getPerPlayerDifficultyAsString(PerPlayerDifficulty diff) const
{
switch(diff)
{
case RaceManager::PLAYER_DIFFICULTY_EASIEST: return "easiest"; break;
case RaceManager::PLAYER_DIFFICULTY_EASY: return "easy"; break;
case RaceManager::PLAYER_DIFFICULTY_NORMAL: return "normal"; break;
case RaceManager::PLAYER_DIFFICULTY_HARD: return "hard"; break;
case RaceManager::PLAYER_DIFFICULTY_HARDEST: return "hardest"; break;
default: assert(false);
}
return "";
} // getPerPlayerDifficultyAsString
// ------------------------------------------------------------------------
const std::string& getTrackName() const { return m_tracks[m_track_number];}
// ------------------------------------------------------------------------
const GrandPrixData& getGrandPrix() const { return m_grand_prix; }
@ -595,6 +576,11 @@ public:
return m_kart_status[kart].m_kart_type;
}
// ------------------------------------------------------------------------
PerPlayerDifficulty getPlayerDifficulty(int kart) const
{
return m_kart_status[kart].m_difficulty;
}
// ------------------------------------------------------------------------
int getCoinTarget() const { return m_coin_target; }
// ------------------------------------------------------------------------
float getTimeTarget() const { return m_time_target; }

Binary file not shown.

View File

@ -25,7 +25,6 @@
#include "guiengine/widgets/bubble_widget.hpp"
#include "guiengine/widgets/kart_stats_widget.hpp"
#include "guiengine/widgets/model_view_widget.hpp"
#include "guiengine/widgets/player_kart_widget.hpp"
#include "guiengine/widgets/player_name_spinner.hpp"
#include "input/input_manager.hpp"
#include "input/device_manager.hpp"

View File

@ -21,13 +21,13 @@
#include "guiengine/screen.hpp"
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
#include "guiengine/widgets/player_kart_widget.hpp"
#include "states_screens/state_manager.hpp"
namespace GUIEngine
{
class Widget;
class BubbleWidget;
class PlayerKartWidget;
enum EventPropagation;
}
namespace Online