Merge branch 'Flakebi-perPlayerDifficulties'
1
.gitignore
vendored
@@ -39,6 +39,7 @@ src/html
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*~
|
||||
*.swp
|
||||
|
||||
packets_log.txt
|
||||
history.dat
|
||||
|
||||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
@@ -20,13 +20,13 @@
|
||||
I18N="Menu item" text="Move up" />
|
||||
<icon-button id="down" width="128" height="128" icon="gui/down.png"
|
||||
I18N="Menu item" text="Move down" />
|
||||
<icon-button id="add" width="128" height="128" icon="gui/gp_add_track.png"
|
||||
<icon-button id="add" width="128" height="128" icon="gui/blue_plus.png"
|
||||
I18N="Menu item" text="Add" />
|
||||
<icon-button id="edit" width="128" height="128" icon="gui/gp_edit_track.png"
|
||||
<icon-button id="edit" width="128" height="128" icon="gui/edit.png"
|
||||
I18N="Menu item" text="Edit" />
|
||||
<icon-button id="remove" width="128" height="128" icon="gui/gp_remove_track.png"
|
||||
<icon-button id="remove" width="128" height="128" icon="gui/remove.png"
|
||||
I18N="Menu item" text="Remove" />
|
||||
<icon-button id="save" width="128" height="128" icon="gui/gp_save.png"
|
||||
<icon-button id="save" width="128" height="128" icon="gui/save.png"
|
||||
I18N="Menu item" text="Save" />
|
||||
</buttonbar>
|
||||
</div>
|
||||
|
||||
@@ -35,11 +35,11 @@
|
||||
I18N="Menu item" text="New" />
|
||||
<icon-button id="copy" width="128" height="128" icon="gui/gp_copy.png"
|
||||
I18N="Menu item" text="Copy" />
|
||||
<icon-button id="edit" width="128" height="128" icon="gui/gp_edit.png"
|
||||
<icon-button id="edit" width="128" height="128" icon="gui/edit.png"
|
||||
I18N="Menu item" text="Edit" />
|
||||
<icon-button id="remove" width="128" height="128" icon="gui/gp_remove.png"
|
||||
I18N="Menu item" text="Remove" />
|
||||
<icon-button id="rename" width="128" height="128" icon="gui/gp_rename.png"
|
||||
<icon-button id="rename" width="128" height="128" icon="gui/rename.png"
|
||||
I18N="Menu item" text="Rename" />
|
||||
</buttonbar>
|
||||
|
||||
|
||||
@@ -16,40 +16,68 @@
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
|
||||
<spacer height="5" width="10"/>
|
||||
<spacer height="5" width="10" />
|
||||
|
||||
<!-- ************ SKIN CHOICE ************ -->
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<label I18N="In the graphics settings" text="Skin" align="center"/>
|
||||
<label I18N="In the ui settings" text="Skin" align="center"/>
|
||||
<spacer width="20" height="20"/>
|
||||
<spinner id="skinchoice" width="30%"/>
|
||||
</div>
|
||||
|
||||
<spacer width="20" height="18" />
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="showfps"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Display FPS"/>
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row">
|
||||
<checkbox id="showfps"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Display FPS"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="perPlayerDifficulty"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Enable handicaped users"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="show-login"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Always show login screen"/>
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="show-login"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Always show login screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="aiHandicap"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Handicap AI karts"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-internet"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Allow STK to connect to the Internet"/>
|
||||
</div>
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-hw-report"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label id="label-hw-report" height="100%" I18N="In the ui settings"
|
||||
text="Allow STK to send anonymous HW statistics"/>
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-internet"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Connect to the Internet"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="enable-hw-report"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" id="label-hw-report" I18N="In the ui settings"
|
||||
text="Send anonymous HW statistics"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="18" width="4"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
@@ -15,7 +15,7 @@
|
||||
<spacer height="15" width="10"/>
|
||||
<div width="90%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="online" I18N="In the login screen" text_align="left"/>
|
||||
<checkbox width="fit" id="online" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the login screen" text="Online"/>
|
||||
</div>
|
||||
@@ -28,13 +28,13 @@
|
||||
<!-- Disable guest accounts for now
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label width="40%" id="label_guest" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the login screen" text_align="left"/>
|
||||
I18N="In the user screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the user screen" text_align="left"/>
|
||||
</div>
|
||||
-->
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label width="40%" id="label_username" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Username"/>
|
||||
I18N="In the user screen" text="Username"/>
|
||||
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
<spacer height="20" width="20"/>
|
||||
@@ -52,9 +52,9 @@
|
||||
<buttonbar id="options" width="90%" height="13%" align="bottom">
|
||||
<icon-button id="ok" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Login dialog" text="OK" label_location="bottom"/>
|
||||
<icon-button id="new_user" width="64" height="64" icon="gui/gp_add_track.png"
|
||||
<icon-button id="new_user" width="64" height="64" icon="gui/blue_plus.png"
|
||||
I18N="Login dialog" text="Add user" label_location="bottom"/>
|
||||
<icon-button id="delete" width="64" height="64" icon="gui/gp_remove_track.png"
|
||||
<icon-button id="delete" width="64" height="64" icon="gui/remove.png"
|
||||
I18N="Login dialog" text="Delete" label_location="bottom"/>
|
||||
<icon-button id="rename" width="64" height="64" icon="gui/gp_rename.png"
|
||||
I18N="Login dialog" text="Rename" label_location="bottom"/>
|
||||
|
||||
@@ -32,18 +32,18 @@
|
||||
<checkbox width="fit" id="remember-user" I18N="In the login screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label id="label_remember" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Remember password"/>
|
||||
I18N="In the user screen" text="Remember password"/>
|
||||
</div>
|
||||
<!-- Disable guest accounts for now
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_guest" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the login screen" text_align="left"/>
|
||||
I18N="In the user screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the user screen" text_align="left"/>
|
||||
</div>
|
||||
-->
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_username" width="40%" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Username"/>
|
||||
I18N="In the user screen" text="Username"/>
|
||||
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
<spacer height="20" width="20"/>
|
||||
@@ -61,11 +61,11 @@
|
||||
<buttonbar id="options" width="90%" height="13%" align="center">
|
||||
<icon-button id="ok" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Login dialog" text="OK" label_location="bottom"/>
|
||||
<icon-button id="new_user" width="64" height="64" icon="gui/gp_add_track.png"
|
||||
<icon-button id="new_user" width="64" height="64" icon="gui/blue_plus.png"
|
||||
I18N="Login dialog" text="Add user" label_location="bottom"/>
|
||||
<icon-button id="delete" width="64" height="64" icon="gui/gp_remove_track.png"
|
||||
<icon-button id="delete" width="64" height="64" icon="gui/remove.png"
|
||||
I18N="Login dialog" text="Delete" label_location="bottom"/>
|
||||
<icon-button id="rename" width="64" height="64" icon="gui/gp_rename.png"
|
||||
<icon-button id="rename" width="64" height="64" icon="gui/rename.png"
|
||||
I18N="Login dialog" text="Rename" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Login dialog" text="Cancel" label_location="bottom"/>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
<!-- Defines when the upright constraint should be acctive, it's
|
||||
<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-angke: Angle between camera and plane of kart (pitch)
|
||||
when the camera is pointing backwards. This is usually
|
||||
backward-up-angle: Angle between camera and plane of kart (pitch)
|
||||
when the camera is pointing backwards. This is usually
|
||||
larger than the forward-up-angle, since the kart itself
|
||||
otherwise obstricts too much of the view. -->
|
||||
<camera distance="1.0" forward-up-angle="15"
|
||||
@@ -158,10 +158,11 @@
|
||||
<!-- Additional offset to move graphical chassis with regards to the physics. -->
|
||||
<graphics y-offset="0.0"/>
|
||||
|
||||
<!-- Jump animation related values:
|
||||
animation-time: only if the estimated time for a jump is larger
|
||||
than this value will the jump animation being shown. -->
|
||||
<jump animation-time="0.5" />
|
||||
<!-- Jump animation related values:
|
||||
animation-time: only if the estimated time for a jump is larger
|
||||
than this value will the jump animation being
|
||||
shown. -->
|
||||
<jump animation-time="0.5" />
|
||||
|
||||
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
|
||||
decrease: multiplicative decrease of skidding factor in each frame.
|
||||
@@ -182,16 +183,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. -->
|
||||
@@ -222,12 +223,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
|
||||
@@ -238,7 +239,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
|
||||
@@ -259,7 +260,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"
|
||||
@@ -335,11 +336,52 @@
|
||||
skidding-threshold="2.0"
|
||||
/>
|
||||
</ai>
|
||||
|
||||
|
||||
<!-- The per-player difficulties in multiplayer games.
|
||||
These values are multiplied with the current values of a car
|
||||
so 1 means that nothing changes.
|
||||
The meaning of the different values is explained below this tag. -->
|
||||
<difficulties>
|
||||
<normal>
|
||||
<mass value="1.0"/>
|
||||
<engine brake-factor="1.0" brake-time-increase="1.0" max-speed-reverse-ratio="1.0" power="1.0" max-speed="1.0"/>
|
||||
<nitro consumption="1.0" max-speed-increase="1.0" duration="1.0" fade-out-time="1.0"/>
|
||||
<bubblegum time="1.0" speed-fraction="1.0" torque="1.0" fade-in-time="1.0"/>
|
||||
<rescue time="1.0"/>
|
||||
<explosion time="1.0" radius="1.0" invulnerability-time="1.0"/>
|
||||
<slipstream length="1.0" width="1.0" collect-time="1.0" use-time="1.0"
|
||||
add-power="1.0" min-speed="1.0" max-speed-increase="1.0" duration="1.0"
|
||||
fade-out-time="1.0"/>
|
||||
<plunger band-max-length="1.0" band-force="1.0" band-duration="1.0"
|
||||
band-speed-increase="1.0" band-fade-out-time="1.0" in-face-time="1.0"/>
|
||||
<zipper time="1.0" force="1.0" speed-gain="1.0" max-speed-increase="1.0"
|
||||
fade-out-time="1.0"/>
|
||||
<swatter duration="1.0" squash-duration="1.0" squash-slowdown="1.0"/>
|
||||
<startup time="1.0 1.0" boost="1.0 1.0"/>
|
||||
</normal>
|
||||
<handicap>
|
||||
<mass value="1.0"/>
|
||||
<engine brake-factor="0.8" brake-time-increase="0.85" max-speed-reverse-ratio="0.8" power="0.8" max-speed="0.8"/>
|
||||
<nitro consumption="1.1" max-speed-increase="0.9" duration="1.0" fade-out-time="1.0"/>
|
||||
<bubblegum time="1.5" speed-fraction="1.5" torque="1.5" fade-in-time="1.0"/>
|
||||
<rescue time="1.5"/>
|
||||
<explosion time="1.3" invulnerability-time="0.7"/>
|
||||
<slipstream length="0.8" width="0.8" collect-time="1.5" use-time="0.8"
|
||||
add-power="0.8" min-speed="0.8" max-speed-increase="0.9" duration="0.8"
|
||||
fade-out-time="1.0"/>
|
||||
<plunger band-max-length="0.8" band-force="1.0" band-duration="1.0"
|
||||
band-speed-increase="0.8" band-fade-out-time="1.0" in-face-time="1.3"/>
|
||||
<zipper time="0.8" force="0.8" speed-gain="0.8" max-speed-increase="0.8"
|
||||
fade-out-time="1.0"/>
|
||||
<swatter duration="0.8" squash-duration="1.5" squash-slowdown="1.8"/>
|
||||
<startup time="0.8 0.8" boost="0.8 0.8"/>
|
||||
</handicap>
|
||||
</difficulties>
|
||||
|
||||
<!-- Suspension related values. stiffness: kart's suspension stiffness.
|
||||
rest: Length of suspension when at rest.
|
||||
travel-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="140" rest="0.3" travel-cm="29"
|
||||
@@ -347,9 +389,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="35" damping-compression="5" radius="0.25">
|
||||
<front-right position="0.38 0 0.6" />
|
||||
@@ -357,20 +399,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
|
||||
@@ -391,7 +433,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
|
||||
@@ -403,15 +445,15 @@
|
||||
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.
|
||||
physical-wheel-position: Defines where the 'physical' (raycast)
|
||||
wheel will be located. It's a weight factor with 0 = being
|
||||
@@ -420,7 +462,7 @@
|
||||
physics settings are used which places the raycast wheels
|
||||
outside of the chassis and results in more stable physical
|
||||
behaviour of the karts. -->
|
||||
<collision impulse-type="normal"
|
||||
<collision impulse-type="normal"
|
||||
impulse="3000" impulse-time="0.1" terrain-impulse="1600"
|
||||
restitution="1.0" bevel-factor="0.5 0.0 0.7"
|
||||
physical-wheel-position="-1" />
|
||||
@@ -428,131 +470,131 @@
|
||||
<!-- 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).
|
||||
@@ -574,14 +616,14 @@
|
||||
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.
|
||||
brake-time-increase: The brake force is multiplied by
|
||||
brake-time-increase: The brake force is multiplied by
|
||||
(1+brake_time*brake_time_increase - i.e. the longer the brake was
|
||||
pressed, the harder the kart will brake.
|
||||
max-speed-reverse-ratio is the percentage of max speed for reverse gear.
|
||||
@@ -592,117 +634,117 @@
|
||||
|
||||
<!-- 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>
|
||||
|
||||
@@ -198,7 +198,7 @@ void PlayerProfile::save(UTFWriter &out)
|
||||
<< L"\" guest=\"" << m_is_guest_account
|
||||
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
|
||||
|
||||
out << L" icon-filename=\"" << m_icon_filename <<L"\"\n";
|
||||
out << L" icon-filename=\"" << m_icon_filename << L"\"\n";
|
||||
|
||||
out << L" unique-id=\"" << m_unique_id
|
||||
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define HEADER_PLAYER_PROFILE_HPP
|
||||
|
||||
#include "challenges/story_mode_status.hpp"
|
||||
#include "network/remote_kart_info.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/types.hpp"
|
||||
@@ -66,6 +67,10 @@ public:
|
||||
private:
|
||||
LEAK_CHECK()
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int m_magic_number;
|
||||
#endif
|
||||
|
||||
/** The name of the player (wide string, so it can be in native
|
||||
* language). */
|
||||
core::stringw m_local_name;
|
||||
@@ -73,10 +78,6 @@ private:
|
||||
/** True if this account is a guest account. */
|
||||
bool m_is_guest_account;
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int m_magic_number;
|
||||
#endif
|
||||
|
||||
/** Counts how often this player was used (always -1 for guests). */
|
||||
int m_use_frequency;
|
||||
|
||||
@@ -111,8 +112,8 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
PlayerProfile(const core::stringw &name, bool is_guest = false);
|
||||
PlayerProfile(const XMLNode *node);
|
||||
PlayerProfile(const core::stringw &name, bool is_guest = false);
|
||||
PlayerProfile(const XMLNode *node);
|
||||
virtual ~PlayerProfile();
|
||||
void save(UTFWriter &out);
|
||||
void loadRemainingData(const XMLNode *node);
|
||||
|
||||
@@ -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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -672,6 +672,20 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( StringUserConfigParam("Peach.stkskin", "skin_file",
|
||||
"Name of the skin to use") );
|
||||
|
||||
PARAM_PREFIX GroupUserConfigParam m_handicap
|
||||
PARAM_DEFAULT( GroupUserConfigParam("Handicap",
|
||||
"Everything related to handicaps.") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_per_player_difficulty
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "per_player_difficulty",
|
||||
&m_handicap,
|
||||
"If handicapped users can be selected") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_ai_handicap
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "ai_handicap",
|
||||
&m_handicap,
|
||||
"If AIs are handicapped") );
|
||||
|
||||
// ---- Internet related
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_internet_status
|
||||
|
||||
@@ -351,7 +351,7 @@ void IrrDriver::initDevice()
|
||||
UserConfigParams::m_height = (int)ssize.Height;
|
||||
}
|
||||
|
||||
core::dimension2d<u32> res = core::dimension2du(UserConfigParams::m_width,
|
||||
core::dimension2d<u32> res = core::dimension2du(UserConfigParams::m_width,
|
||||
UserConfigParams::m_height);
|
||||
|
||||
if (UserConfigParams::m_fullscreen)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <IMeshSceneNode.h>
|
||||
#include <ISceneNode.h>
|
||||
|
||||
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node,
|
||||
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node,
|
||||
float scale = 1.0, float x_offset = 0.0, float y_offset = 0.0,
|
||||
float z_offset = 0.0)
|
||||
{
|
||||
|
||||
@@ -69,9 +69,11 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
||||
setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0)));
|
||||
m_slipstream_time = 0.0f;
|
||||
|
||||
float length = m_kart->getKartProperties()->getSlipstreamLength();
|
||||
float length = m_kart->getKartProperties()->getSlipstreamLength() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamLength();
|
||||
float kw = m_kart->getKartWidth();
|
||||
float ew = m_kart->getKartProperties()->getSlipstreamWidth();
|
||||
float ew = m_kart->getKartProperties()->getSlipstreamWidth() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamWidth();
|
||||
float kl = m_kart->getKartLength();
|
||||
|
||||
Vec3 p[4];
|
||||
@@ -299,7 +301,8 @@ void SlipStream::setIntensity(float f, const AbstractKart *kart)
|
||||
bool SlipStream::isSlipstreamReady() const
|
||||
{
|
||||
return m_slipstream_time>
|
||||
m_kart->getKartProperties()->getSlipstreamCollectTime();
|
||||
m_kart->getKartProperties()->getSlipstreamCollectTime() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamCollectTime();
|
||||
} // isSlipstreamReady
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -315,10 +318,14 @@ void SlipStream::updateSlipstreamPower()
|
||||
setIntensity(2.0f, NULL);
|
||||
const KartProperties *kp=m_kart->getKartProperties();
|
||||
m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM,
|
||||
kp->getSlipstreamMaxSpeedIncrease(),
|
||||
kp->getSlipstreamAddPower(),
|
||||
kp->getSlipstreamDuration(),
|
||||
kp->getSlipstreamFadeOutTime() );
|
||||
kp->getSlipstreamMaxSpeedIncrease() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamMaxSpeedIncrease(),
|
||||
kp->getSlipstreamAddPower() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamAddPower(),
|
||||
kp->getSlipstreamDuration() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamDuration(),
|
||||
kp->getSlipstreamFadeOutTime() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamFadeOutTime());
|
||||
}
|
||||
} // upateSlipstreamPower
|
||||
|
||||
@@ -372,7 +379,8 @@ void SlipStream::update(float dt)
|
||||
// not moving. This is useful for debugging the graphics of SS-ing.
|
||||
#undef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
||||
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
||||
if(m_kart->getSpeed()<m_kart->getKartProperties()->getSlipstreamMinSpeed())
|
||||
if(m_kart->getSpeed()<m_kart->getKartProperties()->getSlipstreamMinSpeed() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamMinSpeed())
|
||||
{
|
||||
setIntensity(0, NULL);
|
||||
m_slipstream_mode = SS_NONE;
|
||||
@@ -414,7 +422,8 @@ void SlipStream::update(float dt)
|
||||
// give karts different slipstream properties.
|
||||
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
|
||||
if(m_target_kart->getSpeed() <
|
||||
m_kart->getKartProperties()->getSlipstreamMinSpeed())
|
||||
m_kart->getKartProperties()->getSlipstreamMinSpeed() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamMinSpeed())
|
||||
{
|
||||
if(UserConfigParams::m_slipstream_debug &&
|
||||
m_kart->getController()->isPlayerController())
|
||||
@@ -428,7 +437,8 @@ void SlipStream::update(float dt)
|
||||
// slipstream length+0.5*kart_length()+0.5*target_kart_length
|
||||
// away from the other kart
|
||||
Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ();
|
||||
float l = m_target_kart->getKartProperties()->getSlipstreamLength()
|
||||
float l = m_kart->getKartProperties()->getSlipstreamLength() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamLength()
|
||||
+ 0.5f*( m_target_kart->getKartLength()
|
||||
+m_kart->getKartLength() );
|
||||
if(delta.length2_2d() > l*l)
|
||||
@@ -469,7 +479,8 @@ void SlipStream::update(float dt)
|
||||
m_slipstream_mode = SS_USE;
|
||||
m_kart->handleZipper();
|
||||
m_slipstream_time =
|
||||
m_kart->getKartProperties()->getSlipstreamCollectTime();
|
||||
m_kart->getKartProperties()->getSlipstreamCollectTime() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamCollectTime();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -490,7 +501,8 @@ void SlipStream::update(float dt)
|
||||
setIntensity(m_slipstream_time, m_target_kart);
|
||||
|
||||
m_slipstream_mode = SS_COLLECT;
|
||||
if(m_slipstream_time>m_kart->getKartProperties()->getSlipstreamCollectTime())
|
||||
if(m_slipstream_time>m_kart->getKartProperties()->getSlipstreamCollectTime() *
|
||||
m_kart->getPlayerDifficulty()->getSlipstreamCollectTime())
|
||||
{
|
||||
setIntensity(1.0f, m_target_kart);
|
||||
}
|
||||
|
||||
@@ -171,4 +171,4 @@ void STKTextBillboard::collectChar(video::ITexture* texture,
|
||||
const video::SColor* const colors)
|
||||
{
|
||||
m_chars.push_back(STKTextBillboardChar(texture, destRect, sourceRect, colors));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,10 +286,7 @@ SetTexture(GLMesh &mesh, unsigned i, bool isSrgb, const std::string &matname)
|
||||
{
|
||||
if (!mesh.textures[i])
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::fatal("STKMesh", "Missing texture %d for material %s, mesh <%s>",
|
||||
i, matname.c_str(), mesh.debug_name.c_str());
|
||||
#endif
|
||||
Log::fatal("STKMesh", "Missing texture %d for material %s", i, matname.c_str());
|
||||
return;
|
||||
}
|
||||
compressTexture(mesh.textures[i], isSrgb);
|
||||
|
||||
@@ -67,4 +67,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,7 @@ Weather::Weather(bool lightning, std::string sound)
|
||||
|
||||
if (m_lightning)
|
||||
{
|
||||
m_thunder_sound = SFXManager::get()->createSoundSource("thunder");
|
||||
m_thunder_sound = SFXManager::get()->createSoundSource("thunder");
|
||||
}
|
||||
|
||||
if (sound != "")
|
||||
@@ -50,10 +50,10 @@ Weather::Weather(bool lightning, std::string sound)
|
||||
|
||||
Weather::~Weather()
|
||||
{
|
||||
if (m_thunder_sound != NULL)
|
||||
if (m_thunder_sound != NULL)
|
||||
m_thunder_sound->deleteSFX();
|
||||
|
||||
if (m_weather_sound != NULL)
|
||||
if (m_weather_sound != NULL)
|
||||
m_weather_sound->deleteSFX();
|
||||
} // ~Weather
|
||||
|
||||
@@ -73,7 +73,7 @@ void Weather::update(float dt)
|
||||
{
|
||||
gui_base->doLightning();
|
||||
|
||||
if (m_thunder_sound)
|
||||
if (m_thunder_sound)
|
||||
{
|
||||
m_thunder_sound->play();
|
||||
}
|
||||
@@ -89,9 +89,9 @@ void Weather::update(float dt)
|
||||
|
||||
void Weather::playSound()
|
||||
{
|
||||
if (m_weather_sound)
|
||||
if (m_weather_sound)
|
||||
{
|
||||
m_weather_sound->setLoop(true);
|
||||
m_weather_sound->play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2082,6 +2082,20 @@ void Skin::drawBadgeOn(const Widget* widget, const core::recti& rect)
|
||||
"hourglass.png");
|
||||
doDrawBadge(texture, rect, max_icon_size, true);
|
||||
}
|
||||
if (widget->m_badges & ZIPPER_BADGE)
|
||||
{
|
||||
float max_icon_size = 0.43f;
|
||||
video::ITexture* texture = irr_driver->getTexture(FileManager::MODEL,
|
||||
"zipper_collect.png");
|
||||
doDrawBadge(texture, rect, max_icon_size, false);
|
||||
}
|
||||
if (widget->m_badges & ANCHOR_BADGE)
|
||||
{
|
||||
float max_icon_size = 0.43f;
|
||||
video::ITexture* texture = irr_driver->getTexture(FileManager::MODEL,
|
||||
"anchor-icon.png");
|
||||
doDrawBadge(texture, rect, max_icon_size, false);
|
||||
}
|
||||
} // drawBadgeOn
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -60,19 +60,23 @@ namespace GUIEngine
|
||||
enum BadgeType
|
||||
{
|
||||
/** display a lock on the widget, to mean a certain game feature is locked */
|
||||
LOCKED_BADGE = 1,
|
||||
LOCKED_BADGE = 1,
|
||||
/** display a green check on a widget, useful e.g. to display confirmation */
|
||||
OK_BADGE = 2,
|
||||
OK_BADGE = 2,
|
||||
/** display a red mark badge on the widget, useful e.g. to warn of an invalid choice */
|
||||
BAD_BADGE = 4,
|
||||
BAD_BADGE = 4,
|
||||
/** display a trophy badge on the widget, useful e.g. for challenges */
|
||||
TROPHY_BADGE = 8,
|
||||
TROPHY_BADGE = 8,
|
||||
/** A gamepad icon */
|
||||
GAMEPAD_BADGE = 16,
|
||||
GAMEPAD_BADGE = 16,
|
||||
/** A keyboard icon */
|
||||
KEYBOARD_BADGE = 32,
|
||||
/** An hourglass badge to indicate loading */
|
||||
LOADING_BADGE = 64
|
||||
LOADING_BADGE = 64,
|
||||
/** A zipper badge to indicate that this player receives a boost */
|
||||
ZIPPER_BADGE = 128,
|
||||
/** A anchor badge to indicate that this player receives a handicap */
|
||||
ANCHOR_BADGE = 256
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -38,14 +38,11 @@ using namespace irr;
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
bool multiplayer) : Widget(WTYPE_DIV)
|
||||
std::string kart_group, bool multiplayer,
|
||||
bool display_text) : Widget(WTYPE_DIV)
|
||||
{
|
||||
m_player_id = player_id;
|
||||
|
||||
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
|
||||
area.getWidth(), area.getHeight() );
|
||||
|
||||
const std::string default_kart = UserConfigParams::m_default_kart;
|
||||
const KartProperties* props =
|
||||
kart_properties_manager->getKart(default_kart);
|
||||
@@ -72,19 +69,16 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
|
||||
}
|
||||
|
||||
|
||||
const int offset = (m_h - (SKILL_COUNT*m_skill_bar_h)) / 2;
|
||||
for (int i = 0; i < SKILL_COUNT; ++i)
|
||||
{
|
||||
irr::core::recti skillArea(m_skill_bar_x, m_skill_bar_y + offset*i,
|
||||
m_skill_bar_x + m_skill_bar_w,
|
||||
m_skill_bar_y + m_skill_bar_h + offset*i);
|
||||
irr::core::recti skillArea(0, 0, 1, 1);
|
||||
|
||||
SkillLevelWidget* skill_bar = NULL;
|
||||
|
||||
skill_bar = new SkillLevelWidget(skillArea, m_player_id, multiplayer);
|
||||
skill_bar = new SkillLevelWidget(skillArea, m_player_id, multiplayer, display_text);
|
||||
|
||||
m_skills.push_back(skill_bar);
|
||||
m_children.push_back(skill_bar);
|
||||
m_skills.push_back(skill_bar);
|
||||
m_children.push_back(skill_bar);
|
||||
}
|
||||
|
||||
m_skills[SKILL_MASS]->setValue((int)(props->getMass()/5));
|
||||
@@ -99,6 +93,8 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
|
||||
m_skills[SKILL_POWER]->setLabel("POWER");
|
||||
m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id);
|
||||
|
||||
move(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
|
||||
area.getWidth(), area.getHeight());
|
||||
} // KartStatsWidget
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -114,11 +110,14 @@ void KartStatsWidget::move(int x, int y, int w, int h)
|
||||
{
|
||||
Widget::move(x,y,w,h);
|
||||
setSize(m_x, m_y, m_w, m_h);
|
||||
int offset = (m_h - (SKILL_COUNT*m_skill_bar_h)) / 2;
|
||||
int margin = m_h / SKILL_COUNT - m_skill_bar_h / 2;
|
||||
if (margin > m_skill_bar_h)
|
||||
margin = m_skill_bar_h;
|
||||
int offset = (m_h - (SKILL_COUNT * margin)) / 2;
|
||||
for (int i = 0; i < SKILL_COUNT; ++i)
|
||||
{
|
||||
m_skills[i]->move(m_skill_bar_x,
|
||||
m_y + offset + m_skill_bar_h*i,
|
||||
m_y + offset + margin * i,
|
||||
m_skill_bar_w,
|
||||
m_skill_bar_h);
|
||||
}
|
||||
@@ -163,4 +162,13 @@ void KartStatsWidget::setSize(const int x, const int y, const int w, const int h
|
||||
m_skill_bar_y = y + h/2 - m_skill_bar_h/2;
|
||||
} // setSize
|
||||
|
||||
void KartStatsWidget::setDisplayText(bool display_text)
|
||||
{
|
||||
for (int i = 0; i < SKILL_COUNT; ++i)
|
||||
{
|
||||
m_skills[i]->setDisplayText(display_text);
|
||||
}
|
||||
} // setDisplayText
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -37,28 +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,
|
||||
@@ -68,10 +66,10 @@ class KartStatsWidget : public Widget
|
||||
};
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
|
||||
KartStatsWidget(core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
bool multiplayer);
|
||||
std::string kart_group, bool multiplayer,
|
||||
bool display_text);
|
||||
virtual ~KartStatsWidget() {};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -95,9 +93,12 @@ class KartStatsWidget : public Widget
|
||||
|
||||
/** 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);
|
||||
|
||||
/** If the labels should be displayed. */
|
||||
void setDisplayText(bool display_text);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
711
src/guiengine/widgets/player_kart_widget.cpp
Normal file
@@ -0,0 +1,711 @@
|
||||
// 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 "config/player_manager.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_device.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "online/online_profile.hpp"
|
||||
#include "states_screens/kart_selection.hpp"
|
||||
#include <IGUIEnvironment.h>
|
||||
|
||||
static const char RANDOM_KART_ID[] = "randomkart";
|
||||
|
||||
using namespace GUIEngine;
|
||||
|
||||
PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
|
||||
StateManager::ActivePlayer* associated_player,
|
||||
Online::OnlineProfile* associated_user,
|
||||
core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
const int irrlicht_widget_id) : Widget(WTYPE_DIV)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (associated_player)
|
||||
assert(associated_player->ok());
|
||||
m_magic_number = 0x33445566;
|
||||
#endif
|
||||
m_ready_text = NULL;
|
||||
m_parent_screen = parent;
|
||||
|
||||
m_associated_user = associated_user;
|
||||
m_associated_player = associated_player;
|
||||
x_speed = 1.0f;
|
||||
y_speed = 1.0f;
|
||||
w_speed = 1.0f;
|
||||
h_speed = 1.0f;
|
||||
m_ready = false;
|
||||
m_handicapped = false;
|
||||
m_not_updated_yet = true;
|
||||
|
||||
m_irrlicht_widget_id = irrlicht_widget_id;
|
||||
|
||||
m_player_id = player_id;
|
||||
m_properties[PROP_ID] = StringUtils::insertValues("@p%i", m_player_id);
|
||||
|
||||
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
|
||||
area.getWidth(), area.getHeight() );
|
||||
target_x = m_x;
|
||||
target_y = m_y;
|
||||
target_w = m_w;
|
||||
target_h = m_h;
|
||||
|
||||
// ---- Player identity spinner
|
||||
m_player_ident_spinner = NULL;
|
||||
|
||||
m_player_ident_spinner = new PlayerNameSpinner(parent, m_player_id);
|
||||
m_player_ident_spinner->m_x = player_name_x;
|
||||
m_player_ident_spinner->m_y = player_name_y;
|
||||
m_player_ident_spinner->m_w = player_name_w;
|
||||
m_player_ident_spinner->m_h = player_name_h;
|
||||
|
||||
// ---- KartStatsWidget
|
||||
m_kart_stats = NULL;
|
||||
|
||||
// area for the stats widget
|
||||
core::recti statsArea;
|
||||
if (!parent->m_multiplayer)
|
||||
{
|
||||
statsArea = core::recti(m_kart_stats_x,
|
||||
m_kart_stats_y,
|
||||
m_kart_stats_x + m_kart_stats_w,
|
||||
m_kart_stats_y + m_kart_stats_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
statsArea = core::recti(m_x , m_y + m_h/2,
|
||||
m_x + m_w, m_y + m_h);
|
||||
}
|
||||
|
||||
|
||||
m_kart_stats = new GUIEngine::KartStatsWidget(statsArea, player_id, kart_group,
|
||||
m_parent_screen->m_multiplayer,
|
||||
!m_parent_screen->m_multiplayer || parent->m_kart_widgets.size() == 0);
|
||||
m_kart_stats->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_stats", m_player_id);
|
||||
m_children.push_back(m_kart_stats);
|
||||
|
||||
if (parent->m_multiplayer && associated_player)
|
||||
{
|
||||
if (associated_player->getDevice()->getType() == DT_KEYBOARD)
|
||||
{
|
||||
m_player_ident_spinner->setBadge(KEYBOARD_BADGE);
|
||||
}
|
||||
else if (associated_player->getDevice()->getType() == DT_GAMEPAD)
|
||||
{
|
||||
m_player_ident_spinner->setBadge(GAMEPAD_BADGE);
|
||||
}
|
||||
}
|
||||
else if (m_associated_user) // online user, FIXME is that useful ?
|
||||
{
|
||||
m_player_ident_spinner->setBadge(OK_BADGE);
|
||||
}
|
||||
|
||||
if (irrlicht_widget_id == -1)
|
||||
{
|
||||
m_player_ident_spinner->m_tab_down_root = g_root_id;
|
||||
}
|
||||
|
||||
spinnerID = StringUtils::insertValues("@p%i_spinner", m_player_id);
|
||||
|
||||
m_player_ident_spinner->m_properties[PROP_ID] = spinnerID;
|
||||
if (parent->m_multiplayer)
|
||||
{
|
||||
const int player_amount = PlayerManager::get()->getNumPlayers();
|
||||
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
|
||||
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] =
|
||||
StringUtils::toString(player_amount-1);
|
||||
m_player_ident_spinner->m_properties[PROP_WRAP_AROUND] = "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
|
||||
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] = "0";
|
||||
}
|
||||
|
||||
//m_player_ident_spinner->m_event_handler = this;
|
||||
m_children.push_back(m_player_ident_spinner);
|
||||
|
||||
// ----- Kart model view
|
||||
m_model_view = new ModelViewWidget();
|
||||
|
||||
m_model_view->m_x = model_x;
|
||||
m_model_view->m_y = model_y;
|
||||
m_model_view->m_w = model_w;
|
||||
m_model_view->m_h = model_h;
|
||||
m_model_view->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_model", m_player_id);
|
||||
//m_model_view->setParent(this);
|
||||
m_children.push_back(m_model_view);
|
||||
|
||||
// Init kart model
|
||||
const std::string default_kart = UserConfigParams::m_default_kart;
|
||||
const KartProperties* props =
|
||||
kart_properties_manager->getKart(default_kart);
|
||||
|
||||
if(!props)
|
||||
{
|
||||
// If the default kart can't be found (e.g. previously a addon
|
||||
// kart was used, but the addon package was removed), use the
|
||||
// first kart as a default. This way we don't have to hardcode
|
||||
// any kart names.
|
||||
int id = kart_properties_manager->getKartByGroup(kart_group, 0);
|
||||
if (id == -1)
|
||||
{
|
||||
props = kart_properties_manager->getKartById(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
props = kart_properties_manager->getKartById(id);
|
||||
}
|
||||
|
||||
if(!props)
|
||||
Log::fatal("KartSelectionScreen", "Can't find default "
|
||||
"kart '%s' nor any other kart.",
|
||||
default_kart.c_str());
|
||||
}
|
||||
m_kartInternalName = props->getIdent();
|
||||
|
||||
const KartModel &kart_model = props->getMasterKartModel();
|
||||
|
||||
float scale = 35.0f;
|
||||
if (kart_model.getLength() > 1.45f)
|
||||
{
|
||||
// if kart is too long, size it down a bit so that it fits
|
||||
scale = 30.0f;
|
||||
}
|
||||
|
||||
m_model_view->addModel( kart_model.getModel(), Vec3(0,0,0),
|
||||
Vec3(scale, scale, scale),
|
||||
kart_model.getBaseFrame() );
|
||||
m_model_view->addModel( kart_model.getWheelModel(0),
|
||||
kart_model.getWheelGraphicsPosition(0) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(1),
|
||||
kart_model.getWheelGraphicsPosition(1) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(2),
|
||||
kart_model.getWheelGraphicsPosition(2) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(3),
|
||||
kart_model.getWheelGraphicsPosition(3) );
|
||||
for(size_t i=0 ; i < kart_model.getSpeedWeightedObjectsCount() ; i++)
|
||||
{
|
||||
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject((int)i);
|
||||
m_model_view->addModel(obj.m_model, obj.m_position);
|
||||
}
|
||||
m_model_view->setRotateContinuously( 35.0f );
|
||||
|
||||
// ---- Kart name label
|
||||
m_kart_name = new LabelWidget(true, true);
|
||||
m_kart_name->setText(props->getName(), false);
|
||||
m_kart_name->m_properties[PROP_TEXT_ALIGN] = "center";
|
||||
m_kart_name->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_kartname", m_player_id);
|
||||
m_kart_name->m_x = kart_name_x;
|
||||
m_kart_name->m_y = kart_name_y;
|
||||
m_kart_name->m_w = kart_name_w;
|
||||
m_kart_name->m_h = kart_name_h;
|
||||
m_children.push_back(m_kart_name);
|
||||
} // PlayerKartWidget
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
PlayerKartWidget::~PlayerKartWidget()
|
||||
{
|
||||
if (GUIEngine::getFocusForPlayer(m_player_id) == this)
|
||||
{
|
||||
GUIEngine::focusNothingForPlayer(m_player_id);
|
||||
}
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->setListener(NULL);
|
||||
|
||||
if (m_player_ident_spinner->getIrrlichtElement() != NULL)
|
||||
{
|
||||
m_player_ident_spinner->getIrrlichtElement()->remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_model_view->getIrrlichtElement() != NULL)
|
||||
m_model_view->getIrrlichtElement()->remove();
|
||||
|
||||
if (m_kart_name->getIrrlichtElement() != NULL)
|
||||
m_kart_name->getIrrlichtElement()->remove();
|
||||
getCurrentScreen()->manualRemoveWidget(this);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xDEADBEEF;
|
||||
#endif
|
||||
} // ~PlayerKartWidget
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void PlayerKartWidget::setPlayerID(const int newPlayerID)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
|
||||
if (StateManager::get()->getActivePlayer(newPlayerID)
|
||||
!= m_associated_player)
|
||||
{
|
||||
Log::error("KartSelectionScreen", "Internal "
|
||||
"inconsistency, PlayerKartWidget has IDs and "
|
||||
"pointers that do not correspond to one player");
|
||||
Log::fatal("KartSelectionScreen", " Player: %p - Index: %d - m_associated_player: %p",
|
||||
StateManager::get()->getActivePlayer(newPlayerID),
|
||||
newPlayerID, m_associated_player);
|
||||
}
|
||||
|
||||
// Remove current focus, but remember it
|
||||
Widget* focus = GUIEngine::getFocusForPlayer(m_player_id);
|
||||
GUIEngine::focusNothingForPlayer(m_player_id);
|
||||
|
||||
// Change the player ID
|
||||
m_player_id = newPlayerID;
|
||||
if (!m_ready)
|
||||
m_player_ident_spinner->setID(m_player_id);
|
||||
m_kart_stats->setDisplayText(m_player_id == 0);
|
||||
// restore previous focus, but with new player ID
|
||||
if (focus != NULL) focus->setFocusForPlayer(m_player_id);
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->setID(m_player_id);
|
||||
}
|
||||
} // setPlayerID
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int PlayerKartWidget::getPlayerID() const
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_player_id;
|
||||
} // getPlayerID
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add the widgets to the current screen */
|
||||
void PlayerKartWidget::add()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
|
||||
assert(KartSelectionScreen::getRunningInstance()
|
||||
->m_kart_widgets.contains(this));
|
||||
if (m_associated_player) // if player is local
|
||||
{
|
||||
bool mineInList = false;
|
||||
for (unsigned int p=0; p<StateManager::get()->activePlayerCount(); p++)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(StateManager::get()->getActivePlayer(p)->ok());
|
||||
#endif
|
||||
if (StateManager::get()->getActivePlayer(p) == m_associated_player)
|
||||
{
|
||||
mineInList = true;
|
||||
}
|
||||
}
|
||||
assert(mineInList);
|
||||
}
|
||||
|
||||
// the first player will have an ID of its own to allow for keyboard
|
||||
// navigation despite this widget being added last
|
||||
if (m_irrlicht_widget_id != -1)
|
||||
m_player_ident_spinner->m_reserved_id = m_irrlicht_widget_id;
|
||||
else
|
||||
m_player_ident_spinner->m_reserved_id = Widget::getNewNoFocusID();
|
||||
|
||||
m_player_ident_spinner->add();
|
||||
m_player_ident_spinner->getIrrlichtElement()->setTabStop(false);
|
||||
m_player_ident_spinner->setListener(this);
|
||||
m_kart_stats->add();
|
||||
m_model_view->add();
|
||||
m_kart_name->add();
|
||||
|
||||
m_model_view->update(0);
|
||||
|
||||
m_player_ident_spinner->clearLabels();
|
||||
|
||||
irr::core::stringw name; // name of the player
|
||||
if (m_associated_player)
|
||||
name = m_associated_player->getProfile()->getName();
|
||||
if (m_associated_user)
|
||||
name = m_associated_user->getUserName();
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
const int player_amount = PlayerManager::get()->getNumPlayers();
|
||||
for (int n=0; n<player_amount; n++)
|
||||
{
|
||||
core::stringw name = PlayerManager::get()->getPlayer(n)->getName();
|
||||
m_player_ident_spinner->addLabel(translations->fribidize(name));
|
||||
if (UserConfigParams::m_per_player_difficulty)
|
||||
// The second player is the same, but with handicap
|
||||
m_player_ident_spinner->addLabel(translations->fribidize(name));
|
||||
}
|
||||
|
||||
// select the right player profile in the spinner
|
||||
m_player_ident_spinner->setValue(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player_ident_spinner->addLabel(name);
|
||||
m_player_ident_spinner->setVisible(false);
|
||||
}
|
||||
|
||||
// Add anchor badge if the player is handicapped
|
||||
int spinner_value = m_player_ident_spinner->getValue();
|
||||
|
||||
assert(m_player_ident_spinner->getStringValue() == name);
|
||||
} // add
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the associated ActivePlayer object*/
|
||||
StateManager::ActivePlayer* PlayerKartWidget::getAssociatedPlayer()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_associated_player;
|
||||
} // getAssociatedPlayer
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Starts a 'move/resize' animation, by simply passing destination coords.
|
||||
* The animation will then occur on each call to 'onUpdate'. */
|
||||
void PlayerKartWidget::move(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
target_x = x;
|
||||
target_y = y;
|
||||
target_w = w;
|
||||
target_h = h;
|
||||
|
||||
x_speed = abs( m_x - x ) / 300.0f;
|
||||
y_speed = abs( m_y - y ) / 300.0f;
|
||||
w_speed = abs( m_w - w ) / 300.0f;
|
||||
h_speed = abs( m_h - h ) / 300.0f;
|
||||
} // move
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Call when player confirmed his identity and kart */
|
||||
void PlayerKartWidget::markAsReady()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
if (m_ready) return; // already ready
|
||||
|
||||
m_ready = true;
|
||||
|
||||
stringw playerNameString = m_player_ident_spinner->getStringValue();
|
||||
core::rect<s32> rect(core::position2di(m_player_ident_spinner->m_x,
|
||||
m_player_ident_spinner->m_y),
|
||||
core::dimension2di(m_player_ident_spinner->m_w,
|
||||
m_player_ident_spinner->m_h));
|
||||
// 'playerNameString' is already fribidize, so we need to use
|
||||
// 'insertValues' and not _("...", a) so it's not flipped again
|
||||
m_ready_text =
|
||||
GUIEngine::getGUIEnv()->addStaticText(
|
||||
StringUtils::insertValues(_("%s is ready"),
|
||||
playerNameString).c_str(),
|
||||
rect );
|
||||
m_ready_text->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER );
|
||||
|
||||
m_children.remove(m_player_ident_spinner);
|
||||
m_player_ident_spinner->setListener(NULL);
|
||||
m_player_ident_spinner->getIrrlichtElement()->remove();
|
||||
m_player_ident_spinner->elementRemoved();
|
||||
delete m_player_ident_spinner;
|
||||
m_player_ident_spinner = NULL;
|
||||
|
||||
SFXManager::get()->quickSound( "wee" );
|
||||
|
||||
m_model_view->setRotateTo(30.0f, 1.0f);
|
||||
|
||||
player_name_w = 0;
|
||||
|
||||
m_model_view->setBadge(OK_BADGE);
|
||||
} // markAsReady
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player confirmed his kart and indent selection */
|
||||
bool PlayerKartWidget::isReady()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_ready;
|
||||
} // isReady
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player is handicapped or not */
|
||||
bool PlayerKartWidget::isHandicapped()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_handicapped;
|
||||
} // isHandicapped
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Updates the animation (moving/shrinking/etc.) */
|
||||
void PlayerKartWidget::onUpdate(float delta)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
if (target_x == m_x && target_y == m_y &&
|
||||
target_w == m_w && target_h == m_h) return;
|
||||
|
||||
int move_step = (int)(delta*1000.0f);
|
||||
|
||||
// move x towards target
|
||||
if (m_x < target_x)
|
||||
{
|
||||
m_x += (int)(move_step*x_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_x > target_x) m_x = target_x;
|
||||
}
|
||||
else if (m_x > target_x)
|
||||
{
|
||||
m_x -= (int)(move_step*x_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_x < target_x) m_x = target_x;
|
||||
}
|
||||
|
||||
// move y towards target
|
||||
if (m_y < target_y)
|
||||
{
|
||||
m_y += (int)(move_step*y_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_y > target_y) m_y = target_y;
|
||||
}
|
||||
else if (m_y > target_y)
|
||||
{
|
||||
m_y -= (int)(move_step*y_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_y < target_y) m_y = target_y;
|
||||
}
|
||||
|
||||
// move w towards target
|
||||
if (m_w < target_w)
|
||||
{
|
||||
m_w += (int)(move_step*w_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_w > target_w) m_w = target_w;
|
||||
}
|
||||
else if (m_w > target_w)
|
||||
{
|
||||
m_w -= (int)(move_step*w_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_w < target_w) m_w = target_w;
|
||||
}
|
||||
// move h towards target
|
||||
if (m_h < target_h)
|
||||
{
|
||||
m_h += (int)(move_step*h_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_h > target_h) m_h = target_h;
|
||||
}
|
||||
else if (m_h > target_h)
|
||||
{
|
||||
m_h -= (int)(move_step*h_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_h < target_h) m_h = target_h;
|
||||
}
|
||||
|
||||
setSize(m_x, m_y, m_w, m_h);
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->move(player_name_x,
|
||||
player_name_y,
|
||||
player_name_w,
|
||||
player_name_h );
|
||||
}
|
||||
if (m_ready_text != NULL)
|
||||
{
|
||||
m_ready_text->setRelativePosition(
|
||||
core::recti(core::position2di(player_name_x, player_name_y),
|
||||
core::dimension2di(player_name_w, player_name_h)) );
|
||||
}
|
||||
if (!m_parent_screen->m_multiplayer)
|
||||
{
|
||||
m_kart_stats->move(m_kart_stats_x,
|
||||
m_kart_stats_y,
|
||||
m_kart_stats_w,
|
||||
m_kart_stats_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_kart_stats->move(m_x, m_y + m_h/2,
|
||||
m_w, m_h/2);
|
||||
}
|
||||
|
||||
|
||||
m_model_view->move(model_x,
|
||||
model_y,
|
||||
model_w,
|
||||
model_h);
|
||||
|
||||
m_kart_name->move(kart_name_x,
|
||||
kart_name_y,
|
||||
kart_name_w,
|
||||
kart_name_h);
|
||||
|
||||
// When coming from the overworld, we must rebuild the preview scene at
|
||||
// least once, since the scene is being cleared by leaving the overworld
|
||||
if (m_not_updated_yet)
|
||||
{
|
||||
m_model_view->clearRttProvider();
|
||||
m_not_updated_yet = false;
|
||||
}
|
||||
} // onUpdate
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
GUIEngine::EventPropagation PlayerKartWidget::transmitEvent(Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id )
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
// if it's declared ready, there is really nothing to process
|
||||
if (m_ready) return EVENT_LET;
|
||||
|
||||
//std::cout << "= kart selection :: transmitEvent "
|
||||
// << originator << " =\n";
|
||||
|
||||
std::string name = w->m_properties[PROP_ID];
|
||||
|
||||
//std::cout << " (checking if that's me: I am "
|
||||
// << spinnerID << ")\n";
|
||||
|
||||
// update player profile when spinner changed
|
||||
if (originator == spinnerID)
|
||||
{
|
||||
if(UserConfigParams::logGUI())
|
||||
{
|
||||
Log::info("[KartSelectionScreen]", "Identity changed "
|
||||
"for player %s : %s",m_player_id,
|
||||
irr::core::stringc(
|
||||
m_player_ident_spinner->getStringValue()
|
||||
.c_str()).c_str());
|
||||
}
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
int spinner_value = m_player_ident_spinner->getValue();
|
||||
PlayerProfile* profile = PlayerManager::get()->getPlayer(
|
||||
UserConfigParams::m_per_player_difficulty ? spinner_value / 2 : spinner_value);
|
||||
m_associated_player->setPlayerProfile(profile);
|
||||
if(UserConfigParams::m_per_player_difficulty && spinner_value % 2 != 0)
|
||||
{
|
||||
m_handicapped = true;
|
||||
m_model_view->setBadge(ANCHOR_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_handicapped = false;
|
||||
m_model_view->unsetBadge(ANCHOR_BADGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EVENT_LET; // continue propagating the event
|
||||
} // transmitEvent
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Sets the size of the widget as a whole, and placed children widgets
|
||||
* inside itself */
|
||||
void PlayerKartWidget::setSize(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_w = w;
|
||||
m_h = h;
|
||||
|
||||
// -- sizes
|
||||
player_name_h = 40;
|
||||
player_name_w = std::min(400, w);
|
||||
|
||||
kart_name_w = w;
|
||||
kart_name_h = 25;
|
||||
|
||||
// for shrinking effect
|
||||
if (h < 175)
|
||||
{
|
||||
const float factor = h / 175.0f;
|
||||
kart_name_h = (int)(kart_name_h*factor);
|
||||
player_name_h = (int)(player_name_h*factor);
|
||||
}
|
||||
|
||||
// --- layout
|
||||
player_name_x = x + w/2 - player_name_w/2;
|
||||
player_name_y = y;
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
const int modelMaxHeight = (h - kart_name_h - player_name_h)/2;
|
||||
const int modelMaxWidth = w;
|
||||
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
|
||||
model_x = x + w/2 - (int)(bestSize/2);
|
||||
model_y = y + player_name_h;
|
||||
model_w = bestSize;
|
||||
model_h = bestSize;
|
||||
|
||||
m_kart_stats_w = model_w;
|
||||
m_kart_stats_h = model_h;
|
||||
m_kart_stats_x = x + w/2 - (int)(bestSize/2);
|
||||
m_kart_stats_y = model_y + model_h;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int modelMaxHeight = h - kart_name_h - player_name_h;
|
||||
const int modelMaxWidth = w;
|
||||
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
|
||||
const int modelY = y + player_name_h;
|
||||
model_x = x + w/4 - (int)(bestSize/2);
|
||||
model_y = modelY + modelMaxHeight/2 - bestSize/2;
|
||||
model_w = bestSize;
|
||||
model_h = bestSize;
|
||||
|
||||
m_kart_stats_w = w/2;
|
||||
m_kart_stats_h = h;
|
||||
m_kart_stats_x = x + w/2;
|
||||
m_kart_stats_y = y;
|
||||
}
|
||||
|
||||
kart_name_x = x;
|
||||
kart_name_y = y + h - kart_name_h;
|
||||
} // setSize
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Sets which kart was selected for this player */
|
||||
void PlayerKartWidget::setKartInternalName(const std::string& whichKart)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
m_kartInternalName = whichKart;
|
||||
} // setKartInternalName
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const std::string& PlayerKartWidget::getKartInternalName() const
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_kartInternalName;
|
||||
} // getKartInternalName
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** \brief Event callback from ISpinnerConfirmListener */
|
||||
EventPropagation PlayerKartWidget::onSpinnerConfirmed()
|
||||
{
|
||||
KartSelectionScreen::getRunningInstance()->playerConfirm(m_player_id);
|
||||
return EVENT_BLOCK;
|
||||
} // onSpinnerConfirmed
|
||||
|
||||
177
src/guiengine/widgets/player_kart_widget.hpp
Normal file
@@ -0,0 +1,177 @@
|
||||
// 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 PLAYER_KART_WIDGET_HPP
|
||||
#define PLAYER_KART_WIDGET_HPP
|
||||
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include <IGUIStaticText.h>
|
||||
#include <IGUIImage.h>
|
||||
#include <string>
|
||||
|
||||
namespace Online
|
||||
{
|
||||
class OnlineProfile;
|
||||
}
|
||||
|
||||
class KartSelectionScreen;
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
class PlayerNameSpinner;
|
||||
class KartStatsWidget;
|
||||
class ModelViewWidget;
|
||||
class LabelWidget;
|
||||
|
||||
/** A widget representing the kart selection for a player (i.e. the player's
|
||||
* number, name, the kart view, the kart's name) */
|
||||
class PlayerKartWidget : public GUIEngine::Widget,
|
||||
public GUIEngine::SpinnerWidget::ISpinnerConfirmListener
|
||||
{
|
||||
/** Whether this player confirmed their selection */
|
||||
bool m_ready;
|
||||
/** If the player is handicapped. */
|
||||
bool m_handicapped;
|
||||
|
||||
/** widget coordinates */
|
||||
int player_name_x, player_name_y, player_name_w, player_name_h;
|
||||
int model_x, model_y, model_w, model_h;
|
||||
int kart_name_x, kart_name_y, kart_name_w, kart_name_h;
|
||||
int m_kart_stats_x, m_kart_stats_y, m_kart_stats_w, m_kart_stats_h;
|
||||
|
||||
/** A reserved ID for this widget if any, -1 otherwise. (If no ID is
|
||||
* reserved, widget will not be in the regular tabbing order */
|
||||
int m_irrlicht_widget_id;
|
||||
|
||||
/** For animation purposes (see method 'move') */
|
||||
int target_x, target_y, target_w, target_h;
|
||||
float x_speed, y_speed, w_speed, h_speed;
|
||||
|
||||
/** Object representing this player */
|
||||
/** Local info about the player. */
|
||||
StateManager::ActivePlayer* m_associated_player;
|
||||
int m_player_id;
|
||||
|
||||
/** Network info about the user. */
|
||||
Online::OnlineProfile* m_associated_user;
|
||||
|
||||
/** Internal name of the spinner; useful to interpret spinner events,
|
||||
* which contain the name of the activated object */
|
||||
std::string spinnerID;
|
||||
|
||||
#ifdef DEBUG
|
||||
long m_magic_number;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
/** Sub-widgets created by this widget */
|
||||
PlayerNameSpinner* m_player_ident_spinner;
|
||||
KartStatsWidget* m_kart_stats;
|
||||
ModelViewWidget* m_model_view;
|
||||
LabelWidget* m_kart_name;
|
||||
|
||||
KartSelectionScreen* m_parent_screen;
|
||||
|
||||
irr::gui::IGUIStaticText* m_ready_text;
|
||||
|
||||
core::stringw deviceName;
|
||||
std::string m_kartInternalName;
|
||||
|
||||
bool m_not_updated_yet;
|
||||
|
||||
PlayerKartWidget(KartSelectionScreen* parent,
|
||||
StateManager::ActivePlayer* associated_player,
|
||||
Online::OnlineProfile* associated_user,
|
||||
core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
const int irrlicht_idget_id=-1);
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
~PlayerKartWidget();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void setPlayerID(const int newPlayerID);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int getPlayerID() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add the widgets to the current screen */
|
||||
virtual void add();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the associated ActivePlayer object*/
|
||||
StateManager::ActivePlayer* getAssociatedPlayer();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Starts a 'move/resize' animation, by simply passing destination coords.
|
||||
* The animation will then occur on each call to 'onUpdate'. */
|
||||
void move(const int x, const int y, const int w, const int h);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Call when player confirmed his identity and kart */
|
||||
void markAsReady();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player confirmed his kart and indent selection */
|
||||
bool isReady();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player is handicapped or not */
|
||||
bool isHandicapped();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Updates the animation (moving/shrinking/etc.) */
|
||||
void onUpdate(float delta);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
virtual GUIEngine::EventPropagation transmitEvent(
|
||||
GUIEngine::Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Sets the size of the widget as a whole, and placed children widgets
|
||||
* inside itself */
|
||||
void setSize(const int x, const int y, const int w, const int h);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Sets which kart was selected for this player */
|
||||
void setKartInternalName(const std::string& whichKart);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const std::string& getKartInternalName() const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** \brief Event callback from ISpinnerConfirmListener */
|
||||
virtual GUIEngine::EventPropagation onSpinnerConfirmed();
|
||||
}; // PlayerKartWidget
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
77
src/guiengine/widgets/player_name_spinner.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
// 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 "guiengine/widgets/player_name_spinner.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include <IGUIEnvironment.h>
|
||||
|
||||
using namespace GUIEngine;
|
||||
|
||||
PlayerNameSpinner::PlayerNameSpinner(KartSelectionScreen* parent,
|
||||
const int player_id)
|
||||
{
|
||||
m_player_id = player_id;
|
||||
m_incorrect = false;
|
||||
m_red_mark_widget = NULL;
|
||||
m_parent = parent;
|
||||
setUseBackgroundColor();//except for multiplayer kart selection, this is false
|
||||
setSpinnerWidgetPlayerID(m_player_id);
|
||||
} // PlayerNameSpinner
|
||||
// ------------------------------------------------------------------------
|
||||
void PlayerNameSpinner::setID(const int m_player_id)
|
||||
{
|
||||
PlayerNameSpinner::m_player_id = m_player_id;
|
||||
setSpinnerWidgetPlayerID(m_player_id);
|
||||
} // setID
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add a red mark on the spinner to mean "invalid choice" */
|
||||
void PlayerNameSpinner::markAsIncorrect()
|
||||
{
|
||||
if (m_incorrect) return; // already flagged as incorrect
|
||||
|
||||
m_incorrect = true;
|
||||
|
||||
irr::video::ITexture* texture = irr_driver->getTexture(FileManager::GUI,
|
||||
"red_mark.png" );
|
||||
const int mark_size = m_h;
|
||||
const int mark_x = m_w - mark_size*2;
|
||||
const int mark_y = 0;
|
||||
core::recti red_mark_area(mark_x, mark_y, mark_x + mark_size,
|
||||
mark_y + mark_size);
|
||||
m_red_mark_widget = GUIEngine::getGUIEnv()->addImage( red_mark_area,
|
||||
/* parent */ m_element );
|
||||
m_red_mark_widget->setImage(texture);
|
||||
m_red_mark_widget->setScaleImage(true);
|
||||
m_red_mark_widget->setTabStop(false);
|
||||
m_red_mark_widget->setUseAlphaChannel(true);
|
||||
} // markAsIncorrect
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Remove any red mark set with 'markAsIncorrect' */
|
||||
void PlayerNameSpinner::markAsCorrect()
|
||||
{
|
||||
if (m_incorrect)
|
||||
{
|
||||
m_red_mark_widget->remove();
|
||||
m_red_mark_widget = NULL;
|
||||
m_incorrect = false;
|
||||
}
|
||||
} // markAsCorrect
|
||||
|
||||
54
src/guiengine/widgets/player_name_spinner.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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 PLAYER_NAME_SPINNER_HPP
|
||||
#define PLAYER_NAME_SPINNER_HPP
|
||||
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include <IGUIImage.h>
|
||||
|
||||
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) ;
|
||||
|
||||
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();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,10 +33,17 @@ using namespace irr;
|
||||
ProgressBarWidget::ProgressBarWidget(bool show_label) : Widget(WTYPE_PROGRESS)
|
||||
{
|
||||
m_value = 0;
|
||||
m_target_value = 0;
|
||||
m_previous_value = 0;
|
||||
m_show_label = show_label;
|
||||
setFocusable(false);
|
||||
}
|
||||
|
||||
ProgressBarWidget::~ProgressBarWidget()
|
||||
{
|
||||
GUIEngine::needsUpdate.remove(this);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ProgressBarWidget::add()
|
||||
@@ -48,17 +55,52 @@ void ProgressBarWidget::add()
|
||||
m_id = m_element->getID();
|
||||
m_element->setTabStop(false);
|
||||
m_element->setTabGroup(false);
|
||||
|
||||
/* Copied from model_view_widget.cpp
|
||||
FIXME: remove this unclean thing, I think irrlicht provides this feature:
|
||||
virtual void IGUIElement::OnPostRender (u32 timeMs)
|
||||
\brief animate the element and its children.
|
||||
*/
|
||||
GUIEngine::needsUpdate.push_back(this);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ProgressBarWidget::setValue(int value)
|
||||
{
|
||||
m_value = value;
|
||||
m_target_value = value;
|
||||
m_previous_value = value;
|
||||
if (m_show_label)
|
||||
{
|
||||
setLabel(std::string(StringUtils::toString(value) + "%").c_str());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ProgressBarWidget::moveValue(int value)
|
||||
{
|
||||
m_previous_value = m_value;
|
||||
m_target_value = value;
|
||||
if (m_show_label)
|
||||
setLabel(std::string(StringUtils::toString(value) + "%").c_str());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ProgressBarWidget::update(float delta)
|
||||
{
|
||||
if (m_target_value != m_value)
|
||||
{
|
||||
// Compute current progress in the animation
|
||||
float cur = (static_cast<float>(m_value) - m_previous_value) / (m_target_value - m_previous_value);
|
||||
// Animation time: 1.0 seconds
|
||||
cur += delta * 10;
|
||||
if (cur > 1)
|
||||
cur = 1;
|
||||
m_value = m_previous_value + cur * (m_target_value - m_previous_value);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ProgressBarWidget::setLabel(irr::core::stringw label)
|
||||
|
||||
@@ -37,31 +37,39 @@ namespace GUIEngine
|
||||
/** 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; }
|
||||
|
||||
|
||||
/** Change the label on the widget */
|
||||
void setLabel(const irr::core::stringw label);
|
||||
int m_value;
|
||||
bool m_show_label;
|
||||
|
||||
|
||||
/** Values for animation */
|
||||
int m_target_value;
|
||||
int m_previous_value;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
LEAK_CHECK()
|
||||
ProgressBarWidget(bool show_label = true);
|
||||
virtual ~ProgressBarWidget() {}
|
||||
|
||||
virtual ~ProgressBarWidget();
|
||||
|
||||
/** Change the value of the widget, it must be a percent. */
|
||||
void setValue(int value);
|
||||
|
||||
|
||||
|
||||
/** Change the value of the widget smooth, it must be a percent. */
|
||||
void moveValue(int value);
|
||||
|
||||
virtual void update(float delta);
|
||||
|
||||
void add();
|
||||
|
||||
|
||||
/** Get the current value of the widget. */
|
||||
int getValue() {return m_value; };
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,12 @@ using namespace irr;
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
SkillLevelWidget::SkillLevelWidget(core::recti area, const int player_id,
|
||||
bool multiplayer, const int value,
|
||||
const stringw& label) : Widget(WTYPE_DIV)
|
||||
bool multiplayer, bool display_text,
|
||||
const int value, const stringw& label)
|
||||
: Widget(WTYPE_DIV)
|
||||
{
|
||||
m_player_id = player_id;
|
||||
m_display_text = display_text;
|
||||
|
||||
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
|
||||
area.getWidth(), area.getHeight() );
|
||||
@@ -79,6 +81,7 @@ void SkillLevelWidget::add()
|
||||
{
|
||||
m_bar->add();
|
||||
m_label->add();
|
||||
m_label->setVisible(m_display_text);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -115,7 +118,10 @@ void SkillLevelWidget::setSize(const int x, const int y, const int w, const int
|
||||
m_h = h;
|
||||
|
||||
// -- sizes
|
||||
m_bar_w = 3*(w/2)/4;
|
||||
if (m_display_text)
|
||||
m_bar_w = (w / 2) * 3 / 4;
|
||||
else
|
||||
m_bar_w = w * 2 / 3;
|
||||
m_bar_h = h;
|
||||
m_label_w = w/2;
|
||||
m_label_h = h;
|
||||
@@ -128,7 +134,10 @@ void SkillLevelWidget::setSize(const int x, const int y, const int w, const int
|
||||
m_label_h = (int)(m_label_h*factor);
|
||||
}
|
||||
|
||||
m_bar_x = x + w/2;
|
||||
if (m_display_text)
|
||||
m_bar_x = x + w / 2;
|
||||
else
|
||||
m_bar_x = x + w / 6;
|
||||
m_bar_y = y + m_h/2 - m_bar_h/2;
|
||||
|
||||
m_label_x = x;
|
||||
@@ -139,8 +148,7 @@ void SkillLevelWidget::setSize(const int x, const int y, const int w, const int
|
||||
|
||||
void SkillLevelWidget::setValue(const int value)
|
||||
{
|
||||
m_bar->setValue(value);
|
||||
|
||||
m_bar->moveValue(value);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -150,3 +158,13 @@ void SkillLevelWidget::setLabel(const irr::core::stringw& label)
|
||||
m_label->setText(label, false);
|
||||
}
|
||||
|
||||
void SkillLevelWidget::setDisplayText(bool display_text)
|
||||
{
|
||||
if(m_display_text != display_text)
|
||||
{
|
||||
m_display_text = display_text;
|
||||
m_label->setVisible(display_text);
|
||||
setSize(m_x, m_y, m_w, m_h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@ namespace GUIEngine
|
||||
* \brief A skill level widget.
|
||||
* \ingroup widgetsgroup
|
||||
*/
|
||||
|
||||
class SkillLevelWidget : public Widget
|
||||
class SkillLevelWidget : public Widget
|
||||
{
|
||||
/** When inferring widget size from its label length, this method will be called to
|
||||
* if/how much space must be added to the raw label's size for the widget to be large enough */
|
||||
@@ -54,6 +53,7 @@ class SkillLevelWidget : public Widget
|
||||
std::string m_label_name;
|
||||
|
||||
int m_player_id;
|
||||
bool m_display_text;
|
||||
|
||||
public:
|
||||
|
||||
@@ -62,7 +62,7 @@ class SkillLevelWidget : public Widget
|
||||
LabelWidget* m_label;
|
||||
ProgressBarWidget* m_bar;
|
||||
|
||||
SkillLevelWidget(core::recti area, const int player_id, bool multiplayer,
|
||||
SkillLevelWidget(core::recti area, const int player_id, bool multiplayer, bool display_text,
|
||||
const int value = 0, const irr::core::stringw& label = "default");
|
||||
|
||||
virtual ~SkillLevelWidget() {};
|
||||
@@ -91,11 +91,13 @@ class SkillLevelWidget : public Widget
|
||||
void setLabel(const irr::core::stringw& label);
|
||||
|
||||
/** Get the current label of the widget. */
|
||||
const irr::core::stringw& getLabel()
|
||||
const irr::core::stringw getLabel()
|
||||
{
|
||||
return m_label->getText();
|
||||
}
|
||||
|
||||
/** If the label should be displayed. */
|
||||
void setDisplayText(bool display_text);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace GUIEngine
|
||||
* value is set to the new maximum. */
|
||||
void setMax(int n)
|
||||
{
|
||||
m_max = n;
|
||||
m_max = n;
|
||||
if(getValue()>m_max) setValue(m_max);
|
||||
} // setMax
|
||||
// --------------------------------------------------------------------
|
||||
@@ -179,7 +179,7 @@ namespace GUIEngine
|
||||
* value is set to the new minimum. */
|
||||
void setMin(int n)
|
||||
{
|
||||
m_min = n;
|
||||
m_min = n;
|
||||
if(getValue()<m_min) setValue(m_min);
|
||||
} // setMin
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ Attachment::~Attachment()
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (m_bubble_explode_sound)
|
||||
{
|
||||
m_bubble_explode_sound->deleteSFX();
|
||||
@@ -125,7 +125,7 @@ void Attachment::set(AttachmentType type, float time,
|
||||
|
||||
clear();
|
||||
m_node_scale = 0.3f;
|
||||
|
||||
|
||||
// If necessary create the appropriate plugin which encapsulates
|
||||
// the associated behavior
|
||||
switch(type)
|
||||
@@ -266,7 +266,8 @@ void Attachment::hitBanana(Item *item, int new_attachment)
|
||||
// same banana again once the explosion animation is finished, giving
|
||||
// the kart the same penalty twice.
|
||||
float f = std::max(item->getDisableTime(),
|
||||
m_kart->getKartProperties()->getExplosionTime()+2.0f);
|
||||
m_kart->getKartProperties()->getExplosionTime() *
|
||||
m_kart->getPlayerDifficulty()->getExplosionTime() + 2.0f);
|
||||
item->setDisableTime(f);
|
||||
break;
|
||||
}
|
||||
@@ -329,7 +330,7 @@ void Attachment::hitBanana(Item *item, int new_attachment)
|
||||
void Attachment::handleCollisionWithKart(AbstractKart *other)
|
||||
{
|
||||
Attachment *attachment_other=other->getAttachment();
|
||||
|
||||
|
||||
if(getType()==Attachment::ATTACH_BOMB)
|
||||
{
|
||||
// Don't attach a bomb when the kart is shielded
|
||||
@@ -386,11 +387,11 @@ void Attachment::update(float dt)
|
||||
{
|
||||
if(m_type==ATTACH_NOTHING) return;
|
||||
m_time_left -=dt;
|
||||
|
||||
|
||||
|
||||
|
||||
bool is_shield = (m_type == ATTACH_BUBBLEGUM_SHIELD|| m_type == ATTACH_NOLOK_BUBBLEGUM_SHIELD);
|
||||
float m_wanted_node_scale = is_shield ? std::max(1.0f, m_kart->getHighestPoint()*1.1f) : 1.0f;
|
||||
|
||||
|
||||
if (m_node_scale < m_wanted_node_scale)
|
||||
{
|
||||
m_node_scale += dt*1.5f;
|
||||
@@ -476,7 +477,7 @@ void Attachment::update(float dt)
|
||||
m_bubble_explode_sound = SFXManager::get()->createSoundSource("bubblegum_explode");
|
||||
m_bubble_explode_sound->setPosition(m_kart->getXYZ());
|
||||
m_bubble_explode_sound->play();
|
||||
|
||||
|
||||
// drop a small bubble gum
|
||||
Vec3 hit_point;
|
||||
Vec3 normal;
|
||||
@@ -493,7 +494,7 @@ void Attachment::update(float dt)
|
||||
normal.normalize();
|
||||
|
||||
pos.setY(hit_point.getY()-0.05f);
|
||||
|
||||
|
||||
ItemManager::get()->newItem(Item::ITEM_BUBBLEGUM, pos, normal, m_kart);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ bool Plunger::updateAndDelete(float dt)
|
||||
bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
||||
{
|
||||
if(isOwnerImmunity(kart)) return false;
|
||||
|
||||
|
||||
// pulling back makes no sense in battle mode, since this mode is not a race.
|
||||
// so in battle mode, always hide view
|
||||
if( m_reverse_mode || race_manager->isBattleMode() )
|
||||
@@ -178,7 +178,8 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keep_alive = m_owner->getKartProperties()->getRubberBandDuration();
|
||||
m_keep_alive = m_owner->getKartProperties()->getRubberBandDuration() *
|
||||
m_owner->getPlayerDifficulty()->getRubberBandDuration();
|
||||
|
||||
// Make this object invisible by placing it faaar down. Not that if this
|
||||
// objects is simply removed from the scene graph, it might be auto-deleted
|
||||
|
||||
@@ -222,7 +222,8 @@ void Powerup::use()
|
||||
case PowerupManager::POWERUP_SWATTER:
|
||||
m_owner->getAttachment()
|
||||
->set(Attachment::ATTACH_SWATTER,
|
||||
m_owner->getKartProperties()->getSwatterDuration());
|
||||
m_owner->getKartProperties()->getSwatterDuration() *
|
||||
m_owner->getPlayerDifficulty()->getSwatterDuration());
|
||||
break;
|
||||
|
||||
case PowerupManager::POWERUP_BUBBLEGUM:
|
||||
|
||||
@@ -151,7 +151,8 @@ void RubberBand::update(float dt)
|
||||
// Check for rubber band snapping
|
||||
// ------------------------------
|
||||
float l = (m_end_position-k).length2();
|
||||
float max_len = m_owner->getKartProperties()->getRubberBandMaxLength();
|
||||
float max_len = m_owner->getKartProperties()->getRubberBandMaxLength() *
|
||||
m_owner->getPlayerDifficulty()->getRubberBandMaxLength();
|
||||
if(l>max_len*max_len)
|
||||
{
|
||||
// Rubber band snaps
|
||||
@@ -164,7 +165,8 @@ void RubberBand::update(float dt)
|
||||
// ----------------------------
|
||||
if(m_attached_state!=RB_TO_PLUNGER)
|
||||
{
|
||||
float force = m_owner->getKartProperties()->getRubberBandForce();
|
||||
float force = m_owner->getKartProperties()->getRubberBandForce() *
|
||||
m_owner->getPlayerDifficulty()->getRubberBandForce();
|
||||
Vec3 diff = m_end_position-k;
|
||||
|
||||
// detach rubber band if kart gets very close to hit point
|
||||
@@ -180,10 +182,12 @@ void RubberBand::update(float dt)
|
||||
diff.normalize(); // diff can't be zero here
|
||||
m_owner->getBody()->applyCentralForce(diff*force);
|
||||
m_owner->increaseMaxSpeed(MaxSpeed::MS_INCREASE_RUBBER,
|
||||
m_owner->getKartProperties()->getRubberBandSpeedIncrease(),
|
||||
m_owner->getKartProperties()->getRubberBandSpeedIncrease() *
|
||||
m_owner->getPlayerDifficulty()->getRubberBandSpeedIncrease(),
|
||||
/*engine_force*/ 0.0f,
|
||||
/*duration*/0.1f,
|
||||
m_owner->getKartProperties()->getRubberBandFadeOutTime());
|
||||
m_owner->getKartProperties()->getRubberBandFadeOutTime() *
|
||||
m_owner->getPlayerDifficulty()->getRubberBandFadeOutTime());
|
||||
if(m_attached_state==RB_TO_KART)
|
||||
m_hit_kart->getBody()->applyCentralForce(diff*(-force));
|
||||
}
|
||||
|
||||
@@ -293,7 +293,8 @@ void Swatter::squashThingsAround()
|
||||
|
||||
if(dist2 >= min_dist2) continue; // too far away, ignore this kart
|
||||
|
||||
kart->setSquash(kp->getSquashDuration(), kp->getSquashSlowdown());
|
||||
kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(),
|
||||
kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown());
|
||||
|
||||
if (kart->getAttachment()->getType()==Attachment::ATTACH_BOMB)
|
||||
{ // make bomb explode
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -131,4 +133,4 @@ void AbstractKart::kartIsInRestNow()
|
||||
// Update the kart transforms with the newly computed position
|
||||
// after all karts are reset
|
||||
setTrans(getBody()->getWorldTransform());
|
||||
} // kartIsInRest
|
||||
} // kartIsInRest
|
||||
|
||||
@@ -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). */
|
||||
@@ -155,7 +170,7 @@ public:
|
||||
float getHighestPoint() const { return m_kart_highest_point; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called after the kart comes to rest. It can be used to e.g. compute
|
||||
* differences between graphical and physical chassis. Note that
|
||||
* differences between graphical and physical chassis. Note that
|
||||
* overwriting this function is possible, but this implementation must
|
||||
* be called. */
|
||||
virtual void kartIsInRestNow();
|
||||
|
||||
@@ -39,7 +39,7 @@ ExplosionAnimation *ExplosionAnimation::create(AbstractKart *kart,
|
||||
bool direct_hit)
|
||||
{
|
||||
if(kart->isInvulnerable()) return NULL;
|
||||
|
||||
|
||||
float r = kart->getKartProperties()->getExplosionRadius();
|
||||
|
||||
// Ignore explosion that are too far away.
|
||||
@@ -78,7 +78,8 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
|
||||
m_xyz = m_kart->getXYZ();
|
||||
m_orig_y = m_xyz.getY();
|
||||
m_kart->playCustomSFX(SFXManager::CUSTOM_EXPLODE);
|
||||
m_timer = m_kart->getKartProperties()->getExplosionTime();
|
||||
m_timer = m_kart->getKartProperties()->getExplosionTime() *
|
||||
m_kart->getPlayerDifficulty()->getExplosionTime();
|
||||
|
||||
// Non-direct hits will be only affected half as much.
|
||||
if(!direct_hit) m_timer*=0.5f;
|
||||
@@ -105,7 +106,8 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
|
||||
m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f );
|
||||
|
||||
// Set invulnerable time, and graphical effects
|
||||
float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime();
|
||||
float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime() *
|
||||
m_kart->getPlayerDifficulty()->getExplosionInvulnerabilityTime();
|
||||
m_kart->setInvulnerableTime(t);
|
||||
if ( UserConfigParams::m_graphical_effects )
|
||||
{
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
m_current_transform = 0;
|
||||
m_next_event = 0;
|
||||
|
||||
@@ -94,8 +94,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)
|
||||
@@ -130,7 +132,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
|
||||
m_min_nitro_time = 0.0f;
|
||||
m_fire_clicked = 0;
|
||||
m_wrongway_counter = 0;
|
||||
|
||||
|
||||
m_view_blocked_by_plunger = 0;
|
||||
m_has_caught_nolok_bubblegum = false;
|
||||
|
||||
@@ -533,7 +535,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();
|
||||
@@ -608,7 +610,7 @@ void Kart::createPhysics()
|
||||
{
|
||||
int index = (x + 1) / 2 + 1 - z; // get index of wheel
|
||||
float f = getKartProperties()->getPhysicalWheelPosition();
|
||||
// f < 0 indicates to use the old physics position, i.e.
|
||||
// f < 0 indicates to use the old physics position, i.e.
|
||||
// to place the wheels outside of the chassis
|
||||
if(f<0)
|
||||
{
|
||||
@@ -920,13 +922,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->setPosition(getXYZ());
|
||||
m_goo_sound->play();
|
||||
@@ -953,17 +958,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
|
||||
|
||||
@@ -1125,7 +1134,7 @@ void Kart::update(float dt)
|
||||
|
||||
// TODO: hiker said this probably will be moved to btKart or so when updating bullet engine.
|
||||
// Neutralize any yaw change if the kart leaves the ground, so the kart falls more or less
|
||||
// straight after jumping, but still allowing some "boat shake" (roIll and pitch).
|
||||
// straight after jumping, but still allowing some "boat shake" (roll and pitch).
|
||||
// Otherwise many non perfect jumps end in a total roll over or a serious change of
|
||||
// direction, sometimes 90 or even full U turn (real but less fun for a karting game).
|
||||
// As side effect steering becames a bit less responsive (any wheel on air), but not too bad.
|
||||
@@ -1161,7 +1170,7 @@ void Kart::update(float dt)
|
||||
|
||||
m_kart_gfx->update(dt);
|
||||
if (m_collision_particles) m_collision_particles->update(dt);
|
||||
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Kart::updatePhysics", 0x60, 0x34, 0x7F);
|
||||
updatePhysics(dt);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
@@ -1462,7 +1471,7 @@ void Kart::handleMaterialSFX(const Material *material)
|
||||
m_previous_terrain_sound->deleteSFX();
|
||||
m_previous_terrain_sound = NULL;
|
||||
}
|
||||
|
||||
|
||||
bool m_schedule_pause = m_flying ||
|
||||
dynamic_cast<RescueAnimation*>(getKartAnimation()) ||
|
||||
dynamic_cast<ExplosionAnimation*>(getKartAnimation());
|
||||
@@ -1628,23 +1637,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;
|
||||
@@ -1670,32 +1689,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
|
||||
|
||||
@@ -1992,7 +2016,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,
|
||||
@@ -2071,13 +2096,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"
|
||||
@@ -2189,8 +2214,10 @@ void Kart::updateEnginePowerAndBrakes(float dt)
|
||||
m_brake_time += dt;
|
||||
// Apply the brakes - include the time dependent brake increase
|
||||
float f = 1 + m_brake_time
|
||||
* getKartProperties()->getBrakeTimeIncrease();
|
||||
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor()*f);
|
||||
* m_kart_properties->getBrakeTimeIncrease() *
|
||||
m_difficulty->getBrakeTimeIncrease();
|
||||
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor() *
|
||||
m_difficulty->getBrakeFactor() * f);
|
||||
}
|
||||
else // m_speed < 0
|
||||
{
|
||||
@@ -2198,7 +2225,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.
|
||||
@@ -2430,7 +2458,7 @@ void Kart::kartIsInRestNow()
|
||||
f += wi.m_chassisConnectionPointCS.getY()
|
||||
- wi.m_raycastInfo.m_suspensionLength - wi.m_wheelsRadius;
|
||||
}
|
||||
m_graphical_y_offset = f/m_vehicle->getNumWheels()
|
||||
m_graphical_y_offset = f/m_vehicle->getNumWheels()
|
||||
+ getKartProperties()->getGraphicalYOffset();
|
||||
|
||||
m_kart_model->setDefaultSuspension();
|
||||
@@ -2456,7 +2484,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;
|
||||
@@ -2471,7 +2500,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);
|
||||
@@ -2487,7 +2516,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
|
||||
@@ -2544,7 +2574,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
|
||||
float heading = m_skidding->getVisualSkidRotation();
|
||||
float xx = fabsf(m_speed)* getKartProperties()->getDownwardImpulseFactor()*0.0006f;
|
||||
Vec3 center_shift = Vec3(0, m_skidding->getGraphicalJumpOffset()
|
||||
Vec3 center_shift = Vec3(0, m_skidding->getGraphicalJumpOffset()
|
||||
+ lean_height +m_graphical_y_offset+xx, 0);
|
||||
center_shift = getTrans().getBasis() * center_shift;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -145,7 +146,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;
|
||||
|
||||
@@ -167,10 +168,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;
|
||||
|
||||
@@ -218,7 +219,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;
|
||||
|
||||
@@ -236,7 +237,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 kartIsInRestNow();
|
||||
|
||||
@@ -49,7 +49,7 @@ KartGFX::KartGFX(const AbstractKart *kart)
|
||||
|
||||
Vec3 rear_center(0, kart->getKartHeight()*0.35f,
|
||||
-kart->getKartLength()*0.35f);
|
||||
|
||||
|
||||
Vec3 rear_nitro_center(0, kart->getKartHeight()*0.2f,
|
||||
-kart->getKartLength()*0.1f);
|
||||
|
||||
@@ -275,7 +275,8 @@ void KartGFX::updateTerrain(const ParticleKind *pk)
|
||||
if (skidding > 1.0f && on_ground)
|
||||
rate = fabsf(m_kart->getControls().m_steer) > 0.8 ? skidding - 1 : 0;
|
||||
else if (speed >= 0.5f && on_ground)
|
||||
rate = speed/m_kart->getKartProperties()->getMaxSpeed();
|
||||
rate = speed/m_kart->getKartProperties()->getMaxSpeed() *
|
||||
m_kart->getPlayerDifficulty()->getMaxSpeed();
|
||||
else
|
||||
{
|
||||
pe->setCreationRateAbsolute(0);
|
||||
|
||||
@@ -770,7 +770,7 @@ void KartModel::setDefaultSuspension()
|
||||
* \param rotation_dt How far the wheels have rotated since last time.
|
||||
* \param steer The actual steer settings.
|
||||
* \param suspension Suspension height for all four wheels.
|
||||
* \param speed The speed of the kart in meters/sec, used for the
|
||||
* \param speed The speed of the kart in meters/sec, used for the
|
||||
* speed-weighted objects' animations
|
||||
*/
|
||||
void KartModel::update(float dt, float rotation_dt, float steer, float speed)
|
||||
|
||||
@@ -177,7 +177,7 @@ private:
|
||||
float m_min_suspension[4];
|
||||
|
||||
/** Maximum suspension length (i.e. most extended). If the displayed
|
||||
* suspension is any longer, the wheel would look too far away from the
|
||||
* suspension is any longer, the wheel would look too far away from the
|
||||
* chassis. */
|
||||
float m_max_suspension[4];
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_squash_duration = m_downward_impulse_factor =
|
||||
m_bubblegum_fade_in_time = m_bubblegum_speed_fraction =
|
||||
m_bubblegum_time = m_bubblegum_torque = m_jump_animation_time =
|
||||
m_smooth_flying_impulse = m_physical_wheel_position =
|
||||
m_smooth_flying_impulse = m_physical_wheel_position =
|
||||
m_graphical_y_offset =
|
||||
UNDEFINED;
|
||||
|
||||
|
||||
@@ -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. */
|
||||
@@ -151,8 +151,8 @@ private:
|
||||
Vec3 m_bevel_factor;
|
||||
|
||||
/** The position of the physical wheel is a weighted average of the
|
||||
* two ends of the beveled shape. This determines the weight: 0 =
|
||||
* a the widest end, 1 = at the narrowest front end. If the value is
|
||||
* two ends of the beveled shape. This determines the weight: 0 =
|
||||
* a the widest end, 1 = at the narrowest front end. If the value is
|
||||
* < 0, the old physics settings are used which places the raycast
|
||||
* wheels outside of the chassis - but result in a more stable
|
||||
* physics behaviour (which is therefore atm still the default).
|
||||
@@ -528,7 +528,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the torque scaling factor used to keep the karts parallel to
|
||||
* the ground when flying. */
|
||||
float getSmoothFlyingImpulse() const
|
||||
float getSmoothFlyingImpulse() const
|
||||
{
|
||||
return m_smooth_flying_impulse;
|
||||
} // getSmoothFlyingImpulse
|
||||
@@ -928,13 +928,13 @@ public:
|
||||
const Vec3 &getBevelFactor() const { return m_bevel_factor; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns position of the physical wheel is a weighted average of the
|
||||
* two ends of the beveled shape. This determines the weight: 0 =
|
||||
* two ends of the beveled shape. This determines the weight: 0 =
|
||||
* a the widest end, 1 = at the narrowest, front end. If the value is <0,
|
||||
* the old physics position is picked, which placed the raycast wheels
|
||||
* outside of the chassis, but gives more stable physics. */
|
||||
const float getPhysicalWheelPosition() const
|
||||
const float getPhysicalWheelPosition() const
|
||||
{
|
||||
return m_physical_wheel_position;
|
||||
return m_physical_wheel_position;
|
||||
} // getPhysicalWheelPosition
|
||||
}; // KartProperties
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -60,7 +60,8 @@ MaxSpeed::MaxSpeed(AbstractKart *kart)
|
||||
*/
|
||||
void MaxSpeed::reset()
|
||||
{
|
||||
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed();
|
||||
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed() *
|
||||
m_kart->getPlayerDifficulty()->getMaxSpeed();
|
||||
m_min_speed = -1.0f;
|
||||
|
||||
for(unsigned int i=MS_DECREASE_MIN; i<MS_DECREASE_MAX; i++)
|
||||
@@ -240,7 +241,8 @@ void MaxSpeed::update(float dt)
|
||||
}
|
||||
|
||||
m_add_engine_force = 0;
|
||||
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed();
|
||||
m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed() *
|
||||
m_kart->getPlayerDifficulty()->getMaxSpeed();
|
||||
|
||||
// Then add the speed increase from each category
|
||||
// ----------------------------------------------
|
||||
|
||||
199
src/karts/player_difficulty.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
//
|
||||
// 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.
|
||||
*/
|
||||
PlayerDifficulty::PlayerDifficulty(const std::string &filename)
|
||||
{
|
||||
// Set all other values to undefined, so that it can later be tested
|
||||
// if everything is defined properly.
|
||||
m_mass = m_brake_factor = m_brake_time_increase = m_rescue_time =
|
||||
m_explosion_time = m_explosion_invulnerability_time = m_zipper_time =
|
||||
m_zipper_fade_out_time = m_zipper_force = m_zipper_speed_gain =
|
||||
m_zipper_max_speed_increase = m_rubber_band_max_length =
|
||||
m_rubber_band_force = m_rubber_band_duration =
|
||||
m_rubber_band_speed_increase = m_rubber_band_fade_out_time =
|
||||
m_nitro_consumption = m_nitro_max_speed_increase =
|
||||
m_nitro_engine_force = m_nitro_duration = m_nitro_fade_out_time =
|
||||
m_bubblegum_time = m_bubblegum_torque = m_bubblegum_speed_fraction =
|
||||
m_bubblegum_fade_in_time = m_swatter_duration = m_squash_duration =
|
||||
m_squash_slowdown = m_max_speed_reverse_ratio = m_slipstream_length =
|
||||
m_slipstream_width = m_slipstream_collect_time =
|
||||
m_slipstream_use_time = m_slipstream_add_power =
|
||||
m_slipstream_min_speed = m_slipstream_max_speed_increase =
|
||||
m_slipstream_duration = m_slipstream_fade_out_time = 1;
|
||||
|
||||
m_startup_times.resize(RaceManager::DIFFICULTY_COUNT, 1);
|
||||
m_startup_boost.resize(RaceManager::DIFFICULTY_COUNT, 1);
|
||||
|
||||
// The default constructor for stk_config uses filename=""
|
||||
if (filename != "")
|
||||
load(filename, "normal");
|
||||
} // PlayerDifficulty
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Destructor, dereferences the kart model. */
|
||||
PlayerDifficulty::~PlayerDifficulty()
|
||||
{
|
||||
} // ~PlayerDifficulty
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** */
|
||||
std::string PlayerDifficulty::getIdent() const
|
||||
{
|
||||
switch(m_difficulty)
|
||||
{
|
||||
case PLAYER_DIFFICULTY_NORMAL: return "normal"; break;
|
||||
case PLAYER_DIFFICULTY_HANDICAP: return "handicap"; break;
|
||||
default: assert(false);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loads the difficulty properties from a file.
|
||||
* \param filename Filename to load.
|
||||
* \param node Name of the xml node to load the data from
|
||||
*/
|
||||
void PlayerDifficulty::load(const std::string &filename, const std::string &node)
|
||||
{
|
||||
const XMLNode* root = new XMLNode(filename);
|
||||
getAllData(root->getNode(node));
|
||||
if(root)
|
||||
delete root;
|
||||
} // load
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Actually reads in the data from the xml file.
|
||||
* \param root Root of the xml tree.
|
||||
*/
|
||||
void PlayerDifficulty::getAllData(const XMLNode * root)
|
||||
{
|
||||
if(const XMLNode *mass_node = root->getNode("mass"))
|
||||
mass_node->get("value", &m_mass);
|
||||
|
||||
if(const XMLNode *engine_node = root->getNode("engine"))
|
||||
{
|
||||
engine_node->get("brake-factor", &m_brake_factor);
|
||||
engine_node->get("brake-time-increase", &m_brake_time_increase);
|
||||
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
|
||||
engine_node->get("power", &m_engine_power);
|
||||
engine_node->get("max-speed", &m_max_speed);
|
||||
}
|
||||
|
||||
if(const XMLNode *nitro_node = root->getNode("nitro"))
|
||||
{
|
||||
nitro_node->get("consumption", &m_nitro_consumption );
|
||||
nitro_node->get("max-speed-increase", &m_nitro_max_speed_increase);
|
||||
nitro_node->get("engine-force", &m_nitro_engine_force );
|
||||
nitro_node->get("duration", &m_nitro_duration );
|
||||
nitro_node->get("fade-out-time", &m_nitro_fade_out_time );
|
||||
}
|
||||
|
||||
if(const XMLNode *bubble_node = root->getNode("bubblegum"))
|
||||
{
|
||||
bubble_node->get("time", &m_bubblegum_time );
|
||||
bubble_node->get("speed-fraction", &m_bubblegum_speed_fraction);
|
||||
bubble_node->get("torque", &m_bubblegum_torque );
|
||||
bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time );
|
||||
}
|
||||
|
||||
if(const XMLNode *rescue_node = root->getNode("rescue"))
|
||||
rescue_node->get("time", &m_rescue_time);
|
||||
|
||||
if(const XMLNode *explosion_node = root->getNode("explosion"))
|
||||
{
|
||||
explosion_node->get("time", &m_explosion_time);
|
||||
explosion_node->get("invulnerability-time",
|
||||
&m_explosion_invulnerability_time);
|
||||
}
|
||||
|
||||
if(const XMLNode *slipstream_node = root->getNode("slipstream"))
|
||||
{
|
||||
slipstream_node->get("length", &m_slipstream_length );
|
||||
slipstream_node->get("width", &m_slipstream_width );
|
||||
slipstream_node->get("collect-time", &m_slipstream_collect_time );
|
||||
slipstream_node->get("use-time", &m_slipstream_use_time );
|
||||
slipstream_node->get("add-power", &m_slipstream_add_power );
|
||||
slipstream_node->get("min-speed", &m_slipstream_min_speed );
|
||||
slipstream_node->get("max-speed-increase",
|
||||
&m_slipstream_max_speed_increase);
|
||||
slipstream_node->get("duration", &m_slipstream_duration );
|
||||
slipstream_node->get("fade-out-time", &m_slipstream_fade_out_time );
|
||||
}
|
||||
|
||||
if(const XMLNode *plunger_node= root->getNode("plunger"))
|
||||
{
|
||||
plunger_node->get("band-max-length", &m_rubber_band_max_length );
|
||||
plunger_node->get("band-force", &m_rubber_band_force );
|
||||
plunger_node->get("band-duration", &m_rubber_band_duration );
|
||||
plunger_node->get("band-speed-increase",&m_rubber_band_speed_increase);
|
||||
plunger_node->get("band-fade-out-time", &m_rubber_band_fade_out_time );
|
||||
plunger_node->get("in-face-time", &m_plunger_in_face_duration);
|
||||
}
|
||||
|
||||
if(const XMLNode *zipper_node= root->getNode("zipper"))
|
||||
{
|
||||
zipper_node->get("time", &m_zipper_time );
|
||||
zipper_node->get("fade-out-time", &m_zipper_fade_out_time );
|
||||
zipper_node->get("force", &m_zipper_force );
|
||||
zipper_node->get("speed-gain", &m_zipper_speed_gain );
|
||||
zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase);
|
||||
}
|
||||
|
||||
if(const XMLNode *swatter_node= root->getNode("swatter"))
|
||||
{
|
||||
swatter_node->get("duration", &m_swatter_duration );
|
||||
swatter_node->get("squash-duration", &m_squash_duration );
|
||||
swatter_node->get("squash-slowdown", &m_squash_slowdown );
|
||||
}
|
||||
|
||||
if(const XMLNode *startup_node= root->getNode("startup"))
|
||||
{
|
||||
startup_node->get("time", &m_startup_times);
|
||||
startup_node->get("boost", &m_startup_boost);
|
||||
}
|
||||
} // getAllData
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called the first time a kart accelerates after 'ready-set-go'. It searches
|
||||
* through m_startup_times to find the appropriate slot, and returns the
|
||||
* speed-boost from the corresponding entry in m_startup_boost.
|
||||
* If the kart started too slow (i.e. slower than the longest time in
|
||||
* m_startup_times, it returns 0.
|
||||
*/
|
||||
float PlayerDifficulty::getStartupBoost() const
|
||||
{
|
||||
float t = World::getWorld()->getTime();
|
||||
for(unsigned int i=0; i<m_startup_times.size(); i++)
|
||||
{
|
||||
if(t<=m_startup_times[i]) return m_startup_boost[i];
|
||||
}
|
||||
return 0;
|
||||
} // getStartupBoost
|
||||
|
||||
345
src/karts/player_difficulty.hpp
Normal file
@@ -0,0 +1,345 @@
|
||||
//
|
||||
// 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 values that modify the properties of a kart.
|
||||
* This includes physical properties like speed and the effect of items.
|
||||
* The values stored in this class get multiplied with the current
|
||||
* properties of the kart. If all values here are set to 1, nothing changes.
|
||||
*
|
||||
* \ingroup karts
|
||||
*/
|
||||
class PlayerDifficulty
|
||||
{
|
||||
private:
|
||||
/** Actual difficulty */
|
||||
PerPlayerDifficulty m_difficulty;
|
||||
|
||||
// -----------------
|
||||
/** Weight of kart. */
|
||||
float m_mass;
|
||||
|
||||
/** Maximum force from engine for each difficulty. */
|
||||
float m_engine_power;
|
||||
|
||||
/** Braking factor * engine_power braking force. */
|
||||
float m_brake_factor;
|
||||
|
||||
/** Brake_time * m_brake_time_increase will increase the break time
|
||||
* over time. */
|
||||
float m_brake_time_increase;
|
||||
|
||||
/** Time a kart is moved upwards after when it is rescued. */
|
||||
float m_rescue_time;
|
||||
|
||||
/** Time an animated explosion is shown. Longer = more delay for kart. */
|
||||
float m_explosion_time;
|
||||
|
||||
/** How long a kart is invulnerable after it is hit by an explosion. */
|
||||
float m_explosion_invulnerability_time;
|
||||
|
||||
/** Duration a zipper is active. */
|
||||
float m_zipper_time;
|
||||
|
||||
/** Fade out time for a zipper. */
|
||||
float m_zipper_fade_out_time;
|
||||
|
||||
/** Additional force added to the acceleration. */
|
||||
float m_zipper_force;
|
||||
|
||||
/** Initial one time speed gain. */
|
||||
float m_zipper_speed_gain;
|
||||
|
||||
/** Absolute increase of the kart's maximum speed (in m/s). */
|
||||
float m_zipper_max_speed_increase;
|
||||
|
||||
/** Max. length of plunger rubber band. */
|
||||
float m_rubber_band_max_length;
|
||||
/** Force of an attached rubber band. */
|
||||
/** Duration a rubber band works. */
|
||||
float m_rubber_band_force;
|
||||
/** How long the rubber band will fly. */
|
||||
float m_rubber_band_duration;
|
||||
/** Increase of maximum speed of the kart when the rubber band pulls. */
|
||||
float m_rubber_band_speed_increase;
|
||||
/** Fade out time when the rubber band is removed. */
|
||||
float m_rubber_band_fade_out_time;
|
||||
/**Duration of plunger in face depending on difficulty. */
|
||||
float m_plunger_in_face_duration;
|
||||
/** Nitro consumption. */
|
||||
float m_nitro_consumption;
|
||||
/* How much the speed of a kart might exceed its maximum speed (in m/s). */
|
||||
float m_nitro_max_speed_increase;
|
||||
/** Additional engine force to affect the kart. */
|
||||
float m_nitro_engine_force;
|
||||
/** How long the increased nitro max speed will be valid after
|
||||
* the kart stops using nitro (and the fade-out-time starts). */
|
||||
float m_nitro_duration;
|
||||
/** Duration during which the increased maximum speed
|
||||
* due to nitro fades out. */
|
||||
float m_nitro_fade_out_time;
|
||||
/** Bubble gum diration. */
|
||||
float m_bubblegum_time;
|
||||
/** Torque to add when a bubble gum was hit in order to make the kart go
|
||||
* sideways a bit. */
|
||||
float m_bubblegum_torque;
|
||||
/** Fraction of top speed that can be reached maximum after hitting a
|
||||
* bubble gum. */
|
||||
float m_bubblegum_speed_fraction;
|
||||
/** How long to fade in the slowdown for a bubble gum. */
|
||||
float m_bubblegum_fade_in_time;
|
||||
/** How long the swatter lasts. */
|
||||
float m_swatter_duration;
|
||||
/** How long a kart will remain squashed. */
|
||||
float m_squash_duration;
|
||||
/** The slowdown to apply while a kart is squashed. The new maxspeed
|
||||
* is max_speed*m_squash_slowdown. */
|
||||
float m_squash_slowdown;
|
||||
|
||||
/** The maximum speed at each difficulty. */
|
||||
float m_max_speed;
|
||||
|
||||
float m_max_speed_reverse_ratio;
|
||||
|
||||
/** How far behind a kart slipstreaming is effective. */
|
||||
float m_slipstream_length;
|
||||
/** How wide the slipstream area is at the end. */
|
||||
float m_slipstream_width;
|
||||
/** Time after which sstream gives a bonus. */
|
||||
float m_slipstream_collect_time;
|
||||
/** Time slip-stream bonus is effective. */
|
||||
float m_slipstream_use_time;
|
||||
/** Additional power due to sstreaming. */
|
||||
float m_slipstream_add_power;
|
||||
/** Minimum speed for slipstream to take effect. */
|
||||
float m_slipstream_min_speed;
|
||||
/** How much the speed of the kart might exceed its
|
||||
* normal maximum speed. */
|
||||
float m_slipstream_max_speed_increase;
|
||||
/** How long the higher speed lasts after slipstream stopped working. */
|
||||
float m_slipstream_duration;
|
||||
/** How long the slip stream speed increase will gradually be reduced. */
|
||||
float m_slipstream_fade_out_time;
|
||||
|
||||
/** If the kart starts within the specified time at index I after 'go',
|
||||
* it receives the speed boost from m_startup_boost[I]. */
|
||||
std::vector<float> m_startup_times;
|
||||
|
||||
/** The startup boost is the kart starts fast enough. */
|
||||
std::vector<float> m_startup_boost;
|
||||
|
||||
|
||||
void load (const std::string &filename,
|
||||
const std::string &node);
|
||||
|
||||
|
||||
public:
|
||||
PlayerDifficulty (const std::string &filename="");
|
||||
~PlayerDifficulty ();
|
||||
void getAllData (const XMLNode * root);
|
||||
std::string getIdent() const;
|
||||
float getStartupBoost () const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the maximum engine power depending on difficulty. */
|
||||
float getMaxPower () const {return m_engine_power; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get braking information. */
|
||||
float getBrakeFactor () const {return m_brake_factor; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the additional brake factor which depends on time. */
|
||||
float getBrakeTimeIncrease() const { return m_brake_time_increase; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get maximum reverse speed ratio. */
|
||||
float getMaxSpeedReverseRatio () const
|
||||
{return m_max_speed_reverse_ratio; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the maximum speed dependent on the difficult level. */
|
||||
float getMaxSpeed () const { return m_max_speed; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the nitro consumption. */
|
||||
float getNitroConsumption () const {return m_nitro_consumption; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the increase of maximum speed due to nitro. */
|
||||
float getNitroMaxSpeedIncrease () const
|
||||
{return m_nitro_max_speed_increase; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
float getNitroEngineForce () const {return m_nitro_engine_force; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long the increased nitro max speed will be valid after
|
||||
* the kart stops using nitro (and the fade-out-time starts). */
|
||||
float getNitroDuration () const {return m_nitro_duration; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the duration during which the increased maximum speed
|
||||
* due to nitro fades out. */
|
||||
float getNitroFadeOutTime () const {return m_nitro_fade_out_time; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long a bubble gum is active. */
|
||||
float getBubblegumTime() const { return m_bubblegum_time; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the torque to add when a bubble gum was hit . */
|
||||
float getBubblegumTorque() const { return m_bubblegum_torque; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the fraction of top speed that can be reached maximum after
|
||||
* hitting a bubble gum. */
|
||||
float getBubblegumSpeedFraction() const {return m_bubblegum_speed_fraction;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long to fade in the slowdown for a bubble gum. */
|
||||
float getBubblegumFadeInTime() const { return m_bubblegum_fade_in_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time a kart is rised during a rescue. */
|
||||
float getRescueTime () const {return m_rescue_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time an explosion animation is shown. */
|
||||
float getExplosionTime () const {return m_explosion_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long a kart is invulnerable after being hit by an
|
||||
explosion. */
|
||||
float getExplosionInvulnerabilityTime() const
|
||||
{ return m_explosion_invulnerability_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the maximum length of a rubber band before it breaks. */
|
||||
float getRubberBandMaxLength () const {return m_rubber_band_max_length;}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns force a rubber band has when attached to a kart. */
|
||||
float getRubberBandForce () const {return m_rubber_band_force; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the duration a rubber band is active for. */
|
||||
float getRubberBandDuration () const {return m_rubber_band_duration; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the increase of maximum speed while a rubber band is
|
||||
* pulling. */
|
||||
float getRubberBandSpeedIncrease() const
|
||||
{
|
||||
return m_rubber_band_speed_increase;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the fade out time once a rubber band is removed. */
|
||||
float getRubberBandFadeOutTime() const
|
||||
{
|
||||
return m_rubber_band_fade_out_time;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns duration of a plunger in your face. */
|
||||
float getPlungerInFaceTime () const {return m_plunger_in_face_duration;}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time a zipper is active. */
|
||||
float getZipperTime () const {return m_zipper_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time a zipper is active. */
|
||||
float getZipperFadeOutTime () const {return m_zipper_fade_out_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the additional force added applied to the kart. */
|
||||
float getZipperForce () const { return m_zipper_force; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the initial zipper speed gain. */
|
||||
float getZipperSpeedGain () const { return m_zipper_speed_gain; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the increase of the maximum speed of the kart
|
||||
* if a zipper is active. */
|
||||
float getZipperMaxSpeedIncrease () const
|
||||
{ return m_zipper_max_speed_increase;}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how far behind a kart slipstreaming works. */
|
||||
float getSlipstreamLength () const {return m_slipstream_length; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how wide the slipstream area is at the end. */
|
||||
float getSlipstreamWidth () const {return m_slipstream_width; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns time after which slipstream has maximum effect. */
|
||||
float getSlipstreamCollectTime () const
|
||||
{return m_slipstream_collect_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns time after which slipstream has maximum effect. */
|
||||
float getSlipstreamUseTime () const {return m_slipstream_use_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns additional power due to slipstreaming. */
|
||||
float getSlipstreamAddPower () const {return m_slipstream_add_power; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the minimum slipstream speed. */
|
||||
float getSlipstreamMinSpeed () const {return m_slipstream_min_speed; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the increase of the maximum speed of a kart
|
||||
* due to slipstream. */
|
||||
float getSlipstreamMaxSpeedIncrease() const
|
||||
{ return m_slipstream_max_speed_increase; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long the higher speed lasts after slipstream
|
||||
* stopped working. */
|
||||
float getSlipstreamDuration () const { return m_slipstream_duration; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long the slip stream speed increase will gradually
|
||||
* be reduced. */
|
||||
float getSlipstreamFadeOutTime () const
|
||||
{ return m_slipstream_fade_out_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long a swatter will stay attached/ready to be used. */
|
||||
float getSwatterDuration() const { return m_swatter_duration; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long a kart remains squashed. */
|
||||
float getSquashDuration() const {return m_squash_duration; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the slowdown of a kart that is squashed. */
|
||||
float getSquashSlowdown() const {return m_squash_slowdown; }
|
||||
}; // KartProperties
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,8 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
|
||||
{
|
||||
m_referee = new Referee(*m_kart);
|
||||
m_kart->getNode()->addChild(m_referee->getSceneNode());
|
||||
m_timer = m_kart->getKartProperties()->getRescueTime();
|
||||
m_timer = m_kart->getKartProperties()->getRescueTime() *
|
||||
m_kart->getPlayerDifficulty()->getRescueTime();
|
||||
m_velocity = m_kart->getKartProperties()->getRescueHeight() / m_timer;
|
||||
m_xyz = m_kart->getXYZ();
|
||||
|
||||
|
||||
@@ -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("");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -466,7 +466,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;
|
||||
@@ -482,7 +483,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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -181,9 +181,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());
|
||||
|
||||
@@ -202,7 +205,7 @@ void World::init()
|
||||
|
||||
if (UserConfigParams::m_weather_effects)
|
||||
{
|
||||
m_weather = new Weather(m_track->getWeatherLightning(),
|
||||
m_weather = new Weather(m_track->getWeatherLightning(),
|
||||
m_track->getWeatherSound());
|
||||
}
|
||||
} // init
|
||||
@@ -293,11 +296,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)
|
||||
@@ -469,7 +474,7 @@ void World::terminateRace()
|
||||
PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_MARATHONER,
|
||||
"laps", race_manager->getNumLaps());
|
||||
}
|
||||
|
||||
|
||||
Achievement *achiev = PlayerManager::getCurrentAchievementsStatus()->getAchievement(AchievementInfo::ACHIEVE_GOLD_DRIVER);
|
||||
if (achiev)
|
||||
{
|
||||
@@ -501,7 +506,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 )
|
||||
@@ -818,7 +823,7 @@ void World::updateWorld(float dt)
|
||||
#ifdef DEBUG
|
||||
assert(m_magic_number == 0xB01D6543);
|
||||
#endif
|
||||
|
||||
|
||||
if( (!isFinishPhase()) && isRaceOver())
|
||||
{
|
||||
enterRaceOverState();
|
||||
|
||||
@@ -125,7 +125,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;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ void WorldStatus::reset()
|
||||
|
||||
IrrlichtDevice *device = irr_driver->getDevice();
|
||||
|
||||
if (device->getTimer()->isStopped())
|
||||
if (device->getTimer()->isStopped())
|
||||
device->getTimer()->start();
|
||||
} // reset
|
||||
|
||||
@@ -77,7 +77,7 @@ WorldStatus::~WorldStatus()
|
||||
m_track_intro_sound->deleteSFX();
|
||||
IrrlichtDevice *device = irr_driver->getDevice();
|
||||
|
||||
if (device->getTimer()->isStopped())
|
||||
if (device->getTimer()->isStopped())
|
||||
device->getTimer()->start();
|
||||
} // ~WorldStatus
|
||||
|
||||
@@ -170,7 +170,7 @@ void WorldStatus::update(const float dt)
|
||||
|
||||
m_auxiliary_timer = 0.0f;
|
||||
|
||||
if (m_play_racestart_sounds)
|
||||
if (m_play_racestart_sounds)
|
||||
m_prestart_sound->play();
|
||||
|
||||
m_phase = READY_PHASE;
|
||||
@@ -339,7 +339,7 @@ void WorldStatus::pause(Phase phase)
|
||||
m_phase = phase;
|
||||
IrrlichtDevice *device = irr_driver->getDevice();
|
||||
|
||||
if (!device->getTimer()->isStopped())
|
||||
if (!device->getTimer()->isStopped())
|
||||
device->getTimer()->stop();
|
||||
} // pause
|
||||
|
||||
@@ -354,6 +354,6 @@ void WorldStatus::unpause()
|
||||
m_previous_phase = UNDEFINED_PHASE;
|
||||
IrrlichtDevice *device = irr_driver->getDevice();
|
||||
|
||||
if (device->getTimer()->isStopped())
|
||||
if (device->getTimer()->isStopped())
|
||||
device->getTimer()->start();
|
||||
} // unpause
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define GAME_SETUP_HPP
|
||||
|
||||
#include "network/race_config.hpp"
|
||||
#include "network/remote_kart_info.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -43,6 +44,7 @@ class NetworkPlayerProfile
|
||||
std::string kart_name; //!< The selected kart.
|
||||
Online::OnlineProfile* user_profile; //!< Pointer to the lobby profile
|
||||
uint8_t world_kart_id; //!< the kart id in the World class (pointer to AbstractKart)
|
||||
PerPlayerDifficulty difficulty;
|
||||
};
|
||||
|
||||
/*! \class GameSetup
|
||||
|
||||
@@ -112,6 +112,7 @@ void StartGameProtocol::update()
|
||||
NetworkPlayerProfile* profile = players[i];
|
||||
RemoteKartInfo rki(profile->race_id, profile->kart_name,
|
||||
profile->user_profile->getUserName(), profile->race_id, !is_me);
|
||||
rki.setDifficulty(profile->difficulty);
|
||||
rki.setGlobalPlayerId(profile->race_id);
|
||||
rki.setLocalPlayerId(is_me?0:1);
|
||||
rki.setHostId(profile->race_id);
|
||||
@@ -130,6 +131,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++)
|
||||
@@ -139,6 +141,7 @@ void StartGameProtocol::update()
|
||||
NetworkPlayerProfile* profile = players[i];
|
||||
RemoteKartInfo rki(profile->race_id, profile->kart_name,
|
||||
profile->user_profile->getUserName(), profile->race_id, !is_me);
|
||||
rki.setDifficulty(profile->difficulty);
|
||||
rki.setGlobalPlayerId(profile->race_id);
|
||||
// on the server, the race id must be the local one.
|
||||
rki.setLocalPlayerId(m_listener->isServer()?profile->race_id:(is_me?0:1));
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define HEADER_REMOTE_KART_INFO_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <irrString.h>
|
||||
|
||||
enum SoccerTeam
|
||||
@@ -33,6 +34,14 @@ enum SoccerTeam
|
||||
NB_SOCCER_TEAMS
|
||||
};
|
||||
|
||||
/** Game difficulty per player. */
|
||||
enum PerPlayerDifficulty
|
||||
{
|
||||
PLAYER_DIFFICULTY_NORMAL,
|
||||
PLAYER_DIFFICULTY_HANDICAP,
|
||||
PLAYER_DIFFICULTY_COUNT
|
||||
};
|
||||
|
||||
class RemoteKartInfo
|
||||
{
|
||||
std::string m_kart_name;
|
||||
@@ -42,35 +51,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
|
||||
{
|
||||
|
||||
@@ -103,13 +103,13 @@ namespace Online
|
||||
* \param path The path to add to the server.(see API::USER_*)
|
||||
* \param action The action to perform. eg: connect, pool
|
||||
*/
|
||||
void HTTPRequest::setApiURL(const std::string& path,
|
||||
void HTTPRequest::setApiURL(const std::string& path,
|
||||
const std::string &action)
|
||||
{
|
||||
// Old (0.8.1) API: send to client-user.php, and add action as a parameter
|
||||
if(UserConfigParams::m_server_version==1)
|
||||
{
|
||||
setURL( (std::string)UserConfigParams::m_server_multiplayer +
|
||||
setURL( (std::string)UserConfigParams::m_server_multiplayer +
|
||||
"client-user.php" );
|
||||
if(action=="change-password")
|
||||
addParameter("action", "change_password");
|
||||
|
||||
@@ -205,7 +205,8 @@ void Physics::update(float dt)
|
||||
{
|
||||
AbstractKart *kart = p->getUserPointer(1)->getPointerKart();
|
||||
const KartProperties* kp = kart->getKartProperties();
|
||||
kart->setSquash(kp->getSquashDuration(), kp->getSquashSlowdown());
|
||||
kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(),
|
||||
kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown());
|
||||
}
|
||||
else if(obj->isSoccerBall())
|
||||
{
|
||||
@@ -234,7 +235,8 @@ void Physics::update(float dt)
|
||||
{
|
||||
AbstractKart *kart = p->getUserPointer(1)->getPointerKart();
|
||||
const KartProperties* kp = kart->getKartProperties();
|
||||
kart->setSquash(kp->getSquashDuration(), kp->getSquashSlowdown());
|
||||
kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(),
|
||||
kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown());
|
||||
}
|
||||
continue;
|
||||
|
||||
|
||||
@@ -148,9 +148,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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -158,11 +157,21 @@ void RaceManager::setLocalKartInfo(unsigned int player_id,
|
||||
*/
|
||||
void RaceManager::setLocalKartSoccerTeam(unsigned int player_id, SoccerTeam team)
|
||||
{
|
||||
assert(player_id <m_local_player_karts.size());
|
||||
assert(player_id < m_local_player_karts.size());
|
||||
|
||||
m_local_player_karts[player_id].setSoccerTeam(team);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the per-player difficulty for a player.
|
||||
*/
|
||||
void RaceManager::setPlayerDifficulty(unsigned int player_id, PerPlayerDifficulty difficulty)
|
||||
{
|
||||
assert(player_id < m_local_player_karts.size());
|
||||
|
||||
m_local_player_karts[player_id].setDifficulty(difficulty);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns a pointer to the kart which has a given GP rank.
|
||||
* \param n The rank (1 to number of karts) to look for.
|
||||
@@ -324,7 +333,8 @@ void RaceManager::startNew(bool from_overworld)
|
||||
// Create the kart status data structure to keep track of scores, times, ...
|
||||
// ==========================================================================
|
||||
m_kart_status.clear();
|
||||
Log::verbose("RaceManager", "Nb of karts=%u, ai:%lu players:%lu\n", (unsigned int)m_num_karts, m_ai_kart_list.size(), m_player_karts.size());
|
||||
Log::verbose("RaceManager", "Nb of karts=%u, ai:%lu players:%lu\n",
|
||||
(unsigned int) m_num_karts, m_ai_kart_list.size(), m_player_karts.size());
|
||||
|
||||
assert((unsigned int)m_num_karts == m_ai_kart_list.size()+m_player_karts.size());
|
||||
// First add the AI karts (randomly chosen)
|
||||
@@ -339,7 +349,8 @@ 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, UserConfigParams::m_ai_handicap ?
|
||||
PLAYER_DIFFICULTY_HANDICAP : PLAYER_DIFFICULTY_NORMAL));
|
||||
init_gp_rank ++;
|
||||
if(UserConfigParams::m_ftl_debug)
|
||||
{
|
||||
@@ -356,8 +367,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,
|
||||
|
||||
@@ -271,16 +271,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
|
||||
@@ -374,6 +377,10 @@ public:
|
||||
*/
|
||||
void setLocalKartSoccerTeam(unsigned int player_id, SoccerTeam team);
|
||||
|
||||
/** Sets the per-player difficulty for a player.
|
||||
*/
|
||||
void setPlayerDifficulty(unsigned int player_id, PerPlayerDifficulty difficulty);
|
||||
|
||||
/** Sets the number of local players playing on this computer (including
|
||||
* split screen).
|
||||
* \param n Number of local players.
|
||||
@@ -576,6 +583,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; }
|
||||
|
||||
@@ -21,23 +21,14 @@
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/model_view_widget.hpp"
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include "guiengine/widgets/progress_bar_widget.hpp"
|
||||
#include "guiengine/widgets/player_kart_widget.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "guiengine/widgets/kart_stats_widget.hpp"
|
||||
|
||||
#include <IGUIImage.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
class Widget;
|
||||
class BubbleWidget;
|
||||
enum EventPropagation;
|
||||
|
||||
}
|
||||
namespace Online
|
||||
{
|
||||
@@ -46,9 +37,10 @@ namespace Online
|
||||
}
|
||||
|
||||
class InputDevice;
|
||||
class PlayerKartWidget;
|
||||
class KartHoverListener;
|
||||
|
||||
extern int g_root_id;
|
||||
|
||||
/**
|
||||
* \brief screen where players can choose their kart
|
||||
* \ingroup states_screens
|
||||
@@ -63,10 +55,10 @@ protected:
|
||||
* we're adding them to a Screen, and the Screen will take ownership
|
||||
* of these widgets)
|
||||
*/
|
||||
PtrVector<PlayerKartWidget, REF> m_kart_widgets;
|
||||
PtrVector<GUIEngine::PlayerKartWidget, REF> m_kart_widgets;
|
||||
|
||||
friend class GUIEngine::ScreenSingleton<KartSelectionScreen>;
|
||||
friend class PlayerKartWidget;
|
||||
friend class GUIEngine::PlayerKartWidget;
|
||||
|
||||
bool m_multiplayer;
|
||||
|
||||
@@ -77,18 +69,18 @@ protected:
|
||||
|
||||
bool m_must_delete_on_back; //!< To delete the screen if back is pressed
|
||||
|
||||
KartSelectionScreen(const char* filename);
|
||||
|
||||
/** Stores whether any player confirmed their choice; then, some things
|
||||
* are "frozen", for instance the selected kart group tab
|
||||
*/
|
||||
bool m_game_master_confirmed;
|
||||
|
||||
PlayerKartWidget* m_removed_widget;
|
||||
GUIEngine::PlayerKartWidget* m_removed_widget;
|
||||
|
||||
/** Message shown in multiplayer mode */
|
||||
GUIEngine::BubbleWidget* m_multiplayer_message;
|
||||
|
||||
KartSelectionScreen(const char* filename);
|
||||
|
||||
/** Called when all players selected their kart */
|
||||
void allPlayersDone();
|
||||
|
||||
@@ -182,6 +174,7 @@ public:
|
||||
way?) */
|
||||
class FocusDispatcher : public GUIEngine::Widget
|
||||
{
|
||||
protected:
|
||||
KartSelectionScreen* m_parent;
|
||||
int m_reserved_id;
|
||||
|
||||
@@ -204,163 +197,8 @@ public:
|
||||
virtual GUIEngine::EventPropagation focused(const int playerID);
|
||||
}; // FocusDispatcher
|
||||
|
||||
//!----------------------------------------------------------------------------
|
||||
//! PlayerNameSpinner :
|
||||
/** 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();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Remove any red mark set with 'markAsIncorrect' */
|
||||
void markAsCorrect();
|
||||
};
|
||||
|
||||
/** A widget representing the kart selection for a player (i.e. the player's
|
||||
* number, name, the kart view, the kart's name) */
|
||||
class PlayerKartWidget : public GUIEngine::Widget,
|
||||
public GUIEngine::SpinnerWidget::ISpinnerConfirmListener
|
||||
{
|
||||
/** Whether this player confirmed their selection */
|
||||
bool m_ready;
|
||||
|
||||
/** widget coordinates */
|
||||
int player_id_x, player_id_y, player_id_w, player_id_h;
|
||||
int player_name_x, player_name_y, player_name_w, player_name_h;
|
||||
int model_x, model_y, model_w, model_h;
|
||||
int kart_name_x, kart_name_y, kart_name_w, kart_name_h;
|
||||
int m_kart_stats_x, m_kart_stats_y, m_kart_stats_w, m_kart_stats_h;
|
||||
|
||||
/** A reserved ID for this widget if any, -1 otherwise. (If no ID is
|
||||
* reserved, widget will not be in the regular tabbing order */
|
||||
int m_irrlicht_widget_id;
|
||||
|
||||
/** For animation purposes (see method 'move') */
|
||||
int target_x, target_y, target_w, target_h;
|
||||
float x_speed, y_speed, w_speed, h_speed;
|
||||
|
||||
/** Object representing this player */
|
||||
/** Local info about the player. */
|
||||
StateManager::ActivePlayer* m_associated_player;
|
||||
int m_player_id;
|
||||
|
||||
/** Network info about the user. */
|
||||
Online::OnlineProfile* m_associated_user;
|
||||
|
||||
/** Internal name of the spinner; useful to interpret spinner events,
|
||||
* which contain the name of the activated object */
|
||||
std::string spinnerID;
|
||||
|
||||
#ifdef DEBUG
|
||||
long m_magic_number;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
/** Sub-widgets created by this widget */
|
||||
PlayerNameSpinner* m_player_ident_spinner;
|
||||
GUIEngine::KartStatsWidget* m_kart_stats;
|
||||
GUIEngine::ModelViewWidget* m_model_view;
|
||||
GUIEngine::LabelWidget* m_kart_name;
|
||||
|
||||
KartSelectionScreen* m_parent_screen;
|
||||
|
||||
irr::gui::IGUIStaticText* m_ready_text;
|
||||
|
||||
//LabelWidget *getPlayerIDLabel() {return m_player_ID_label;}
|
||||
core::stringw deviceName;
|
||||
std::string m_kartInternalName;
|
||||
|
||||
bool m_not_updated_yet;
|
||||
|
||||
PlayerKartWidget(KartSelectionScreen* parent,
|
||||
StateManager::ActivePlayer* associated_player,
|
||||
Online::OnlineProfile* associated_user,
|
||||
core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
const int irrlicht_idget_id=-1);
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
~PlayerKartWidget();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void setPlayerID(const int newPlayerID);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int getPlayerID() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add the widgets to the current screen */
|
||||
virtual void add();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the associated ActivePlayer object*/
|
||||
StateManager::ActivePlayer* getAssociatedPlayer();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Starts a 'move/resize' animation, by simply passing destination coords.
|
||||
* The animation will then occur on each call to 'onUpdate'. */
|
||||
void move(const int x, const int y, const int w, const int h);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Call when player confirmed his identity and kart */
|
||||
void markAsReady();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player confirmed his kart and indent selection */
|
||||
bool isReady();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Updates the animation (moving/shrinking/etc.) */
|
||||
void onUpdate(float delta);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
virtual GUIEngine::EventPropagation transmitEvent(
|
||||
GUIEngine::Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Sets the size of the widget as a whole, and placed children widgets
|
||||
* inside itself */
|
||||
void setSize(const int x, const int y, const int w, const int h);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Sets which kart was selected for this player */
|
||||
void setKartInternalName(const std::string& whichKart);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const std::string& getKartInternalName() const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** \brief Event callback from ISpinnerConfirmListener */
|
||||
virtual GUIEngine::EventPropagation onSpinnerConfirmed();
|
||||
}; // PlayerKartWidget
|
||||
|
||||
//!----------------------------------------------------------------------------
|
||||
//! KartHoverListener :
|
||||
|
||||
class KartHoverListener : public GUIEngine::DynamicRibbonHoverListener
|
||||
{
|
||||
KartSelectionScreen* m_parent;
|
||||
@@ -380,3 +218,4 @@ public:
|
||||
}; // KartHoverListener
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/widgets/player_kart_widget.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
|
||||
@@ -149,6 +149,12 @@ void OptionsScreenUI::init()
|
||||
stats_label->setVisible(false);
|
||||
stats->setVisible(false);
|
||||
}
|
||||
CheckBoxWidget* difficulty = getWidget<CheckBoxWidget>("perPlayerDifficulty");
|
||||
assert( difficulty != NULL );
|
||||
difficulty->setState( UserConfigParams::m_per_player_difficulty );
|
||||
CheckBoxWidget* ai_handicap = getWidget<CheckBoxWidget>("aiHandicap");
|
||||
assert( ai_handicap != NULL );
|
||||
ai_handicap->setState( UserConfigParams::m_ai_handicap );
|
||||
|
||||
CheckBoxWidget* show_login = getWidget<CheckBoxWidget>("show-login");
|
||||
assert( show_login!= NULL );
|
||||
@@ -299,6 +305,18 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
|
||||
assert( show_login != NULL );
|
||||
UserConfigParams::m_always_show_login_screen = show_login->getState();
|
||||
}
|
||||
else if (name=="perPlayerDifficulty")
|
||||
{
|
||||
CheckBoxWidget* difficulty = getWidget<CheckBoxWidget>("perPlayerDifficulty");
|
||||
assert( difficulty != NULL );
|
||||
UserConfigParams::m_per_player_difficulty = difficulty->getState();
|
||||
}
|
||||
else if (name=="aiHandicap")
|
||||
{
|
||||
CheckBoxWidget* ai_handicap = getWidget<CheckBoxWidget>("aiHandicap");
|
||||
assert( ai_handicap != NULL );
|
||||
UserConfigParams::m_ai_handicap = ai_handicap->getState();
|
||||
}
|
||||
else if (name == "language")
|
||||
{
|
||||
ListWidget* list_widget = getWidget<ListWidget>("language");
|
||||
|
||||
@@ -182,7 +182,7 @@ void BaseUserScreen::selectUser(int index)
|
||||
makeEntryFieldsVisible();
|
||||
getWidget<CheckBoxWidget>("remember-user")->setState(
|
||||
profile->rememberPassword());
|
||||
if(profile->getLastOnlineName().size()>0)
|
||||
if(profile->getLastOnlineName().size() > 0)
|
||||
m_username_tb->setDeactivated();
|
||||
else
|
||||
m_username_tb->setActivated();
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
@@ -64,6 +65,12 @@ private:
|
||||
* display more meaningful sign-out message. */
|
||||
irr::core::stringw m_sign_in_name;
|
||||
|
||||
/** Per player difficulty. */
|
||||
GUIEngine::SpinnerWidget *m_difficulty;
|
||||
|
||||
/** Apply per player difficulty in singleplayer mode. */
|
||||
GUIEngine::CheckBoxWidget *m_singleplayer_difficulty;
|
||||
|
||||
/** Online check box. */
|
||||
GUIEngine::CheckBoxWidget *m_online_cb;
|
||||
|
||||
|
||||
@@ -51,4 +51,4 @@ static std::vector<T> createVector(Args...args)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
namespace STK {
|
||||
|
||||
|
||||
// tuple
|
||||
// tuple
|
||||
template<typename... _Types> class Tuple;
|
||||
|
||||
// empty tuple
|
||||
|
||||