Merge branch 'game_protocol'
This commit is contained in:
commit
c2b5e566c0
@ -36,6 +36,8 @@ mass.png by Auria, released under CC-0
|
||||
|
||||
power.png by Auria, based on https://openclipart.org/detail/193925/check-engine and https://openclipart.org/detail/144799/power-icon, released under CC-0
|
||||
|
||||
crown.png by glitch, from https://openclipart.org/detail/210257/misc-game-crown, released under public domain
|
||||
|
||||
====
|
||||
|
||||
Glass Skin by Auria, under CC-BY-SA 3+
|
||||
|
BIN
data/gui/crown.png
Normal file
BIN
data/gui/crown.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="99%" layout="vertical-row" >
|
||||
|
||||
<header width="80%"
|
||||
I18N="In the kart selection (player setup) screen"
|
||||
text="Choose a Kart"
|
||||
align="center" text_align="center" />
|
||||
|
||||
<placeholder id="playerskarts" width="100%" align="center" proportion="4">
|
||||
<!-- Contents is added programatically -->
|
||||
</placeholder>
|
||||
|
||||
<spacer height="15" width="25"/>
|
||||
|
||||
<box proportion="2" width="100%" layout="vertical-row" padding="2">
|
||||
<ribbon_grid id="karts" proportion="1" square_items="true" width="100%" align="center"
|
||||
child_width="90" child_height="90" max_rows="3"/>
|
||||
</box>
|
||||
|
||||
<!-- Groups will be added dynamically at runtime -->
|
||||
<tabs width="98%" x="1%" height="5%" id="kartgroups">
|
||||
</tabs>
|
||||
<spacer width="100%" height="2%"/>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
</stkgui>
|
@ -2,69 +2,70 @@
|
||||
<stkgui>
|
||||
<div x="0" y="0" width="100%" height="100%" layout="vertical-row" >
|
||||
<header id="title" text_align="center" width="80%" align="center" I18N="In the server creation screen" text="Server Creation"/>
|
||||
<spacer height="15" width="10"/>
|
||||
<box proportion="4" width="90%" layout="vertical-row" align="center">
|
||||
<div width="90%" align="center" layout="vertical-row" y="2%" height="96%">
|
||||
<div width="100%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Name of the server"/>
|
||||
<textbox proportion="1" id="name" I18N="In the server creation screen"/>
|
||||
</div>
|
||||
<box proportion="1" width="90%" layout="vertical-row" align="center">
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Max. number of players"/>
|
||||
<gauge id="max_players" proportion="1" min_value="2" max_value="12"/>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Password (optional)"/>
|
||||
<textbox proportion="1" id="password" I18N="In the server creation screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<label width="100%" height="fit" text_align="left" I18N="In the server creation screen" text="Difficulty"/>
|
||||
<!--<gauge id="difficulty" proportion="1" min_value="1" max_value="4"/>-->
|
||||
<ribbon id="difficulty" height="135" width="90%" align="center">
|
||||
<icon-button id="novice" width="128" height="128" icon="gui/difficulty_easy.png"
|
||||
I18N="Difficulty" text="Novice"/>
|
||||
<icon-button id="intermediate" width="128" height="128" icon="gui/difficulty_medium.png"
|
||||
I18N="Difficulty" text="Intermediate"/>
|
||||
<icon-button id="expert" width="128" height="128" icon="gui/difficulty_hard.png"
|
||||
I18N="Difficulty" text="Expert"/>
|
||||
<icon-button id="best" width="128" height="128" icon="gui/difficulty_best.png"
|
||||
I18N="Difficulty" text="SuperTux"/>
|
||||
</ribbon>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<label width="100%" height="fit" text_align="left" I18N="In the server creation screen" text="Game mode"/>
|
||||
<ribbon id="gamemode" height="135" width="50%" align="center">
|
||||
<icon-button id="normal" width="128" height="128" icon="gui/mode_normal.png"
|
||||
I18N="Multiplayer game mode" text="Normal Race"/>
|
||||
<icon-button id="timetrial" width="128" height="128" icon="gui/mode_tt.png"
|
||||
I18N="Multiplayer game mode" text="Time Trial"/>
|
||||
</ribbon>
|
||||
<!--
|
||||
<scrollable_toolbar id="gamemode" height="135" width="90%" label_location="bottom" align="center"
|
||||
child_width="135" child_height="135" />
|
||||
-->
|
||||
</div>
|
||||
|
||||
<label id="info" proportion="1" width="100%" align="center" text_align="center" word_wrap="true" text=""/>
|
||||
|
||||
<buttonbar id="options" x="0" y="0" width="25%" height="12%" align="center">
|
||||
<icon-button id="create" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="In the server creation screen" text="Create" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="In the server creation screen" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Name of the server"/>
|
||||
<textbox proportion="1" id="name" I18N="In the server creation screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Max. number of players"/>
|
||||
<gauge id="max_players" proportion="1" min_value="2"/>
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Password (optional)"/>
|
||||
<textbox proportion="1" id="password" I18N="In the server creation screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="20"/>
|
||||
|
||||
<label width="100%" height="fit" text_align="left" I18N="In the server creation screen" text="Difficulty"/>
|
||||
<ribbon id="difficulty" height="15%" width="90%" align="center">
|
||||
<icon-button id="novice" width="128" height="128" icon="gui/difficulty_easy.png"
|
||||
I18N="Difficulty" text="Novice"/>
|
||||
<icon-button id="intermediate" width="128" height="128" icon="gui/difficulty_medium.png"
|
||||
I18N="Difficulty" text="Intermediate"/>
|
||||
<icon-button id="expert" width="128" height="128" icon="gui/difficulty_hard.png"
|
||||
I18N="Difficulty" text="Expert"/>
|
||||
<icon-button id="best" width="128" height="128" icon="gui/difficulty_best.png"
|
||||
I18N="Difficulty" text="SuperTux"/>
|
||||
</ribbon>
|
||||
<label width="100%" height="fit" text_align="left" I18N="In the server creation screen" text="Game mode"/>
|
||||
<ribbon id="gamemode" height="15%" width="90%" align="center">
|
||||
<icon-button id="normal" width="128" height="128" icon="gui/mode_normal.png"
|
||||
I18N="Multiplayer game mode" text="Normal Race"/>
|
||||
<icon-button id="timetrial" width="128" height="128" icon="gui/mode_tt.png"
|
||||
I18N="Multiplayer game mode" text="Time Trial"/>
|
||||
<icon-button id="3strikes" width="128" height="128" icon="gui/mode_3strikes.png"
|
||||
I18N="Multiplayer game mode" text="3 Strikes Battle"/>
|
||||
<icon-button id="soccer" width="128" height="128" icon="gui/mode_soccer.png"
|
||||
I18N="Multiplayer game mode" text="Soccer"/>
|
||||
</ribbon>
|
||||
|
||||
<spacer height="10" width="20"/>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="more-options" proportion="1" text_align="left"/>
|
||||
<spinner id="more-options-spinner" proportion="1" wrap_around="true"/>
|
||||
</div>
|
||||
|
||||
<label id="info" proportion="1" width="100%" align="center" text_align="center" word_wrap="true" text=""/>
|
||||
|
||||
<buttonbar id="options" x="0" y="0" width="25%" height="12%" align="center">
|
||||
<icon-button id="create" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="In the server creation screen" text="Create" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="In the server creation screen" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
|
||||
<spacer width="10" height="20"/>
|
||||
|
||||
</box>
|
||||
<spacer height="15" width="10"/>
|
||||
<spacer width="10" height="10"/>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
@ -1,60 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="0" y="0" width="100%" height="100%" layout="vertical-row" >
|
||||
<header text_align="center" width="80%" align="center" I18N="In networking lobby" text="Lobby"/>
|
||||
<header id="lobby-text" text_align="center" width="80%" align="center" I18N="In networking lobby" text="Lobby"/>
|
||||
<spacer height="15" width="10"/>
|
||||
<div proportion="1" x="2%" width="96%" layout="vertical-row">
|
||||
<div proportion="4" x="2%" width="96%" layout="vertical-row">
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<box id="info" proportion="2" height="100%" layout="vertical-row">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the networking lobby" text="Server name:"/>
|
||||
<label proportion="2" text_align="left" id="server_name" text=""/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the networking lobby" text="Difficulty:"/>
|
||||
<label proportion="2" text_align="left" id="server_difficulty" text=""/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the networking lobby" text="Game mode:"/>
|
||||
<label proportion="2" text_align="left" id="server_game_mode" text=""/>
|
||||
</div>
|
||||
<label word_wrap="true" id="text" proportion="3" width="100%" height="100%" text_valign="top"/>
|
||||
</box>
|
||||
<spacer width="20" height="20"/>
|
||||
<box proportion="1" height="100%" layout="vertical-row">
|
||||
<list id="players" width="100%" height="100%"/>
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<spacer width="20" height="20"/>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<box proportion="2" height="100%" layout="vertical-row">
|
||||
<list id="chat" width="100%" height="100%"/>
|
||||
</box>
|
||||
<spacer width="20" height="20"/>
|
||||
<box id="actions" proportion="1" height="100%" layout="vertical-row">
|
||||
<!-- <label I18N="In networking lobby" word_wrap="true" text="actions" align="center" text-align="center"/>
|
||||
-->
|
||||
<icon-button id="start" width="64" height="64" icon="gui/green_check.png" align="center"
|
||||
I18N="In the network lobby" text="Start Race"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="10" height="7%"/>
|
||||
|
||||
<bottombar x="2%" width="96%" height="10%" layout="horizontal-row">
|
||||
<label text_align="left" align="center" height="100%" id="online_status" proportion="1" text=""/>
|
||||
|
||||
<spacer width="10" height="10" />
|
||||
|
||||
<buttonbar id="menu_bottomrow" x="0" y="0" width="20%" height="100%" align="center">
|
||||
<icon-button id="exit" width="64" height="64" icon="gui/main_quit.png" extend_label="50"
|
||||
I18N="In the networking lobby" text="Exit" label_location="hover"/>
|
||||
<spacer height="10"/>
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<spacer width="20" height="20"/>
|
||||
<box proportion="2" height="100%" layout="vertical-row">
|
||||
<textbox id="chat" width="100%" height="30%"/>
|
||||
<spacer height="20"/>
|
||||
<button id="send" height="30%" width="fit" I18N="In the network lobby" text="Send" />
|
||||
</box>
|
||||
<spacer width="40"/>
|
||||
<buttonbar id="actions" proportion="1" width="75%" height="75%">
|
||||
<icon-button id="start" width="64" height="64" icon="gui/green_check.png" align="center"
|
||||
I18N="In the network lobby" text="Start race"/>
|
||||
<icon-button id="exit" width="64" height="64" icon="gui/main_quit.png" align="center"
|
||||
I18N="In the network lobby" text="Exit"/>
|
||||
</buttonbar>
|
||||
</bottombar>
|
||||
</div>
|
||||
<spacer height="10"/>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
</stkgui>
|
||||
|
@ -4,9 +4,20 @@
|
||||
<header text_align="center" width="80%" align="center" text="Online"/>
|
||||
<spacer height="15" width="10"/>
|
||||
<button id="user-id" width="20%" height="fit" align="center"/>
|
||||
<spacer height="20"/>
|
||||
|
||||
<box width="50%" height="10%" layout="horizontal-row" align="center" valign="center">
|
||||
<spacer proportion="1"/>
|
||||
<label I18N="In the networking menu" align="center"
|
||||
text="Enable splitscreen or player handicaps" text_align="right"/>
|
||||
<spacer width="25"/>
|
||||
<checkbox id="enable-splitscreen" align="center" />
|
||||
<spacer proportion="1"/>
|
||||
</box>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<icon id="logo" align="center" proportion="4" width="100%" icon="gui/logo.png"/>
|
||||
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<buttonbar id="menu_toprow" proportion="3" width="90%" align="center">
|
||||
|
@ -26,6 +26,10 @@
|
||||
<label proportion="1" text_align="left" I18N="In the networking lobby" text="Game mode:"/>
|
||||
<label proportion="2" text_align="left" id="server_game_mode" text=""/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_password" text_align="left" proportion="1" text="Password"/>
|
||||
<textbox id="password" proportion="2" height="fit"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="50"/>
|
||||
|
@ -11,5 +11,13 @@
|
||||
<box proportion="1" width="98%" align="center" layout="vertical-row" padding="6">
|
||||
<list id="server_list" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
<div width="99%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="private_server" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" height="100%" text_align="left"
|
||||
I18N="In the server selection screen" text="Show only private server(s)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
46
data/gui/online/splitscreen_player_dialog.stkgui
Normal file
46
data/gui/online/splitscreen_player_dialog.stkgui
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="5%" width="96%" height="85%" layout="vertical-row" >
|
||||
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
|
||||
I18N="Splitscreen player in network" text="Add player"/>
|
||||
|
||||
<spacer height="20" width="50"/>
|
||||
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="name-text" proportion="1" text_align="left" I18N="Splitscreen player in network" text="Name"/>
|
||||
<spinner id="name-spinner" width="50%" align="center" wrap_around="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="50"/>
|
||||
|
||||
<div id="handicap-row" width="80%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="handicap-text" proportion="1" text_align="left" I18N="Splitscreen player in network" text="Handicap"/>
|
||||
<checkbox id="handicap" align="center" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="50"/>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="message-label" proportion="1" text_align="left" I18N="Splitscreen player in network"
|
||||
text="Press the 'All players ready' button after the player list is ready."/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="50"/>
|
||||
|
||||
<buttonbar id="options" width="90%" height="20%" align="center">
|
||||
<icon-button id="add" width="64" height="64" icon="gui/blue_plus.png"
|
||||
I18N="Splitscreen player in network" text="Add player" label_location="bottom"/>
|
||||
<icon-button id="connect" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Splitscreen player in network" text="All players ready" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Splitscreen player in network" text="Cancel" label_location="bottom"/>
|
||||
<icon-button id="reset" width="64" height="64" icon="gui/remove.png"
|
||||
I18N="Splitscreen player in network" text="Clear added player" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
</div>
|
||||
</stkgui>
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="5%" width="96%" height="90%" layout="vertical-row" >
|
||||
|
||||
<header id="title" width="96%" height="fit" text_align="center" I18N="Networking screen" text="Waiting for the others..."/>
|
||||
|
||||
<spacer height="40" width="50"/>
|
||||
|
||||
<label proportion="1" width="100%" text_align="left" id="lblDetails"/>
|
||||
</div>
|
||||
</stkgui>
|
@ -80,6 +80,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-lobby-chat"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" id="label-lobby-chat" I18N="In the ui settings" text="Enable chatting in networking lobby"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="18" width="4"/>
|
||||
|
||||
<!-- ************ LANGUAGE CHOICE ************ -->
|
||||
|
@ -2,7 +2,7 @@
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
<div x="1%" y="1%" width="98%" height="96%" layout="vertical-row" >
|
||||
<div id="all-track" x="1%" y="1%" width="60%" height="96%" layout="vertical-row" >
|
||||
<header width="80%" I18N="In the track selection screen" text="All Tracks"
|
||||
align="center" text_align="center" />
|
||||
|
||||
@ -17,5 +17,32 @@
|
||||
<tabs width="100%" height="5%" id="trackgroups"> </tabs>
|
||||
|
||||
<spacer width="100%" height="2%" />
|
||||
<box id="rect-box" width="100%" height="20%" padding="15" layout="vertical-row">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="lap-text" proportion="1" I18N="In the track screen" text_align="right"/>
|
||||
<spacer width="40"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row">
|
||||
<spinner id="lap-spinner" width="50%" min_value="1" max_value="20" align="center"
|
||||
wrap_around="true" />
|
||||
</div>
|
||||
</div>
|
||||
<spacer height="10"/>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="reverse-text" proportion="1" I18N="In the track screen" text_align="right"/>
|
||||
<spacer width="40"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row">
|
||||
<div width="50%" height="fit" text-align="center" layout="vertical-row" >
|
||||
<checkbox id="reverse" align="center"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</box>
|
||||
</div>
|
||||
<div id="vote" x="63%" y="1%" width="37%" height="96%" layout="vertical-row">
|
||||
<div width="95%" proportion="2" layout="horizontal-row">
|
||||
<box proportion="2" height="100%" layout="vertical-row">
|
||||
<label id="vote-text" word_wrap="true" id="text" proportion="3" width="100%" height="100%" text_valign="top"/>
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
@ -1,8 +1,7 @@
|
||||
<spshader>
|
||||
<shader-info name="roadBlending" fallback-shader="solid" use-tangents="Y"/>
|
||||
<first-pass vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_road_blending.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
fragment-shader="sp_road_blending.frag">
|
||||
</first-pass>
|
||||
<!--
|
||||
<shadow-pass vertex-shader="sp_shadow.vert"
|
||||
|
@ -160,9 +160,16 @@
|
||||
away if there is an explosion. -->
|
||||
<explosion impulse-objects="500.0" />
|
||||
|
||||
<!-- Networking - the current networking code is outdated and will not
|
||||
work anymore - so for now don't enable this. -->
|
||||
<networking enable="false"/>
|
||||
<!-- Networking
|
||||
state-frequency: how many states the server will send per second.
|
||||
positional-smoothing: smoothing factor used in exponential smoothing
|
||||
depending on error.
|
||||
rotational-smoothing: slerp factor used in exponential smoothing
|
||||
of rotations depending on error.
|
||||
-->
|
||||
<networking state-frequency="10"
|
||||
positional-smoothing="0.25:0.95 1.0:0.85"
|
||||
rotational-smoothing="0.25:0.95 1.0:0.85" />
|
||||
|
||||
<!-- The field od views for 1-4 player split screen. fov-3 is
|
||||
actually not used (since 3 player split screen uses the
|
||||
@ -482,4 +489,11 @@
|
||||
-->
|
||||
<texture-compression quality="64"/>
|
||||
|
||||
<!-- List of default ports used, by default STK use random ports
|
||||
for client and server, disable it in user config to allow
|
||||
port forward. The server discovery port has to be the same
|
||||
across all clients and servers.
|
||||
-->
|
||||
<network server-discovery-port="2757" client-port="2758" server-port="2759"/>
|
||||
|
||||
</config>
|
||||
|
42
doc/physics_order
Normal file
42
doc/physics_order
Normal file
@ -0,0 +1,42 @@
|
||||
This shows in which order input handling, physics computations and
|
||||
other kart related items are updated in each frame.
|
||||
|
||||
main_loop:
|
||||
getDT() : Determine nexts DT --> simulation
|
||||
is [T, T+DT] with T=now.
|
||||
RewindManager::addNextTimeStep() : Adds a default TimeStepInfo entry to the
|
||||
RewindQueue which will store events for the
|
||||
current time step (e.g. key presses, and
|
||||
network data).
|
||||
irr_driver::update() : Rendering and input handling.
|
||||
Controller::action() : Store user action in m_controls of
|
||||
kart. Clients send event to server.
|
||||
RaceEventManager::update() : A thin wrapper around world used in networked
|
||||
races.
|
||||
RewindManager::playEventsTill() : Plays all events in [T, T+DT]: copies unhandled
|
||||
network events that must be handled at the
|
||||
current time to the current TimeStepInfo. Can do
|
||||
complete rewind and replay till T is reached again!
|
||||
World::updateWorld()
|
||||
RewindManager::update() : Store current state on server if necessary and
|
||||
broadcast it to clients.
|
||||
Karts::update()
|
||||
Moveable::update() : Copy physics data from bullet to STK.
|
||||
updateSpeed() : Get physics speed and set it in kart.
|
||||
Controller::update() : Set kart steering based on user/AI input.
|
||||
Slipstream::update() : call Kart::handleZipper if required.
|
||||
updatePhysics()
|
||||
HandleStartBoost : Trigger boost if required.
|
||||
updateEnginePower...() : Sets engine power/brakes for bullet vehicle.
|
||||
Skidding::update() : Update skidding values (which will
|
||||
affect steering).
|
||||
setSteering : Sets the bullet steering based on
|
||||
kart's current steering.
|
||||
updateSliding() : Test for sliding which can reduce the wheels
|
||||
friction/grip, causing the physics to slide.
|
||||
MaxSpeed::update() : Cap speed of kart if kart is too fast.
|
||||
!physicsafter : !Print debug values
|
||||
Physics::update() : Time step bullet as often as necessary. This is
|
||||
using the steering etc information set above.
|
||||
ProtocolManager::update() : Synchronous protocol updates.
|
||||
World::updateTime() : Increase time from T to T+DT.
|
@ -48,9 +48,9 @@ CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params)
|
||||
}
|
||||
else
|
||||
FileSystem = io::createFileSystem();
|
||||
core::stringc s = "Irrlicht Engine version ";
|
||||
s.append(getVersion());
|
||||
os::Printer::log(s.c_str(), ELL_INFORMATION);
|
||||
//core::stringc s = "Irrlicht Engine version ";
|
||||
//s.append(getVersion());
|
||||
//os::Printer::log(s.c_str(), ELL_INFORMATION);
|
||||
|
||||
checkVersion(params.SDK_version_do_not_use);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -129,10 +129,10 @@ void PlayerManager::onSTKQuit()
|
||||
* RequestManager.
|
||||
*/
|
||||
|
||||
Online::XMLRequest *PlayerManager::requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password)
|
||||
void PlayerManager::requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password)
|
||||
{
|
||||
return getCurrentPlayer()->requestSignIn(username, password);
|
||||
getCurrentPlayer()->requestSignIn(username, password);
|
||||
} // requestSignIn
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -111,8 +111,8 @@ public:
|
||||
static void resumeSavedSession();
|
||||
static void onSTKQuit();
|
||||
static void requestSignOut();
|
||||
static Online::XMLRequest *requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password);
|
||||
static void requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current player. */
|
||||
|
@ -138,8 +138,8 @@ public:
|
||||
virtual Online::OnlineProfile* getProfile() const = 0;
|
||||
virtual void requestPoll() const = 0;
|
||||
virtual void requestSavedSession() = 0;
|
||||
virtual Online::XMLRequest* requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password) = 0;
|
||||
virtual void requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password) = 0;
|
||||
virtual void signIn(bool success, const XMLNode * input) = 0;
|
||||
virtual void signOut(bool success, const XMLNode * input,
|
||||
const irr::core::stringw &info) = 0;
|
||||
|
@ -117,8 +117,23 @@ void STKConfig::load(const std::string &filename)
|
||||
Log::fatal("StkConfig", "Wrong number of item switches defined in stk_config");
|
||||
}
|
||||
|
||||
if (m_positional_smoothing.size() == 0)
|
||||
{
|
||||
Log::fatal("StkConfig", "No positional smoothing defined in stk_config.");
|
||||
}
|
||||
if (m_rotational_smoothing.size() == 0)
|
||||
{
|
||||
Log::fatal("StkConfig", "No rotationalsmoothing defined in stk_config.");
|
||||
}
|
||||
|
||||
if (m_client_port == 0 || m_server_port == 0 || m_server_discovery_port == 0 ||
|
||||
m_client_port == m_server_port || m_client_port == m_server_discovery_port ||
|
||||
m_server_port == m_server_discovery_port)
|
||||
{
|
||||
Log::fatal("StkConfig", "Invalid default port values.");
|
||||
}
|
||||
CHECK_NEG(m_max_karts, "<karts max=..." );
|
||||
CHECK_NEG(m_item_switch_time, "item-switch-time" );
|
||||
CHECK_NEG(m_item_switch_ticks, "item switch-time" );
|
||||
CHECK_NEG(m_bubblegum_counter, "bubblegum disappear counter");
|
||||
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
|
||||
CHECK_NEG(m_max_skidmarks, "max-skidmarks" );
|
||||
@ -131,7 +146,7 @@ void STKConfig::load(const std::string &filename)
|
||||
CHECK_NEG(m_delay_finish_time, "delay-finish-time" );
|
||||
CHECK_NEG(m_music_credit_time, "music-credit-time" );
|
||||
CHECK_NEG(m_leader_time_per_kart, "leader time-per-kart" );
|
||||
CHECK_NEG(m_penalty_time, "penalty-time" );
|
||||
CHECK_NEG(m_penalty_ticks, "penalty-time" );
|
||||
CHECK_NEG(m_max_display_news, "max-display-news" );
|
||||
CHECK_NEG(m_replay_max_time, "replay max-time" );
|
||||
CHECK_NEG(m_replay_delta_angle, "replay delta-angle" );
|
||||
@ -140,6 +155,7 @@ void STKConfig::load(const std::string &filename)
|
||||
CHECK_NEG(m_smooth_angle_limit, "physics smooth-angle-limit" );
|
||||
CHECK_NEG(m_default_track_friction, "physics default-track-friction");
|
||||
CHECK_NEG(m_physics_fps, "physics fps" );
|
||||
CHECK_NEG(m_network_state_frequeny, "network state-frequency" );
|
||||
CHECK_NEG(m_default_moveable_friction, "physics default-moveable-friction");
|
||||
|
||||
// Square distance to make distance checks cheaper (no sqrt)
|
||||
@ -157,10 +173,11 @@ void STKConfig::init_defaults()
|
||||
m_bomb_time = m_bomb_time_increase =
|
||||
m_explosion_impulse_objects = m_music_credit_time =
|
||||
m_delay_finish_time = m_skid_fadeout_time =
|
||||
m_near_ground = m_item_switch_time =
|
||||
m_smooth_angle_limit = m_penalty_time =
|
||||
m_default_track_friction = m_default_moveable_friction =
|
||||
UNDEFINED;
|
||||
m_near_ground =
|
||||
m_smooth_angle_limit = m_default_track_friction =
|
||||
m_default_moveable_friction = UNDEFINED;
|
||||
m_item_switch_ticks = -100;
|
||||
m_penalty_ticks = -100;
|
||||
m_physics_fps = -100;
|
||||
m_bubblegum_counter = -100;
|
||||
m_shield_restrict_weapons = false;
|
||||
@ -175,8 +192,8 @@ void STKConfig::init_defaults()
|
||||
m_replay_delta_angle = -100;
|
||||
m_replay_delta_pos2 = -100;
|
||||
m_replay_dt = -100;
|
||||
m_network_state_frequeny = -100;
|
||||
m_title_music = NULL;
|
||||
m_enable_networking = true;
|
||||
m_smooth_normals = false;
|
||||
m_same_powerup_mode = POWERUP_MODE_ONLY_IF_SAME;
|
||||
m_ai_acceleration = 1.0f;
|
||||
@ -185,6 +202,9 @@ void STKConfig::init_defaults()
|
||||
m_cutscene_fov = 0.61f;
|
||||
m_max_skinning_bones = 1024;
|
||||
m_tc_quality = 16;
|
||||
m_server_discovery_port = 2757;
|
||||
m_client_port = 2758;
|
||||
m_server_port = 2759;
|
||||
|
||||
m_score_increase.clear();
|
||||
m_leader_intervals.clear();
|
||||
@ -256,7 +276,9 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
|
||||
if (const XMLNode *startup_node= root->getNode("startup"))
|
||||
{
|
||||
startup_node->get("penalty", &m_penalty_time );
|
||||
float f;
|
||||
startup_node->get("penalty", &f);
|
||||
m_penalty_ticks = time2Ticks(f);
|
||||
}
|
||||
|
||||
if (const XMLNode *news_node= root->getNode("news"))
|
||||
@ -337,7 +359,9 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
if(const XMLNode *switch_node= root->getNode("switch"))
|
||||
{
|
||||
switch_node->get("items", &m_switch_items );
|
||||
switch_node->get("time", &m_item_switch_time);
|
||||
float f;
|
||||
if( switch_node->get("time", &f) )
|
||||
m_item_switch_ticks = stk_config->time2Ticks(f);
|
||||
}
|
||||
|
||||
if(const XMLNode *bubblegum_node= root->getNode("bubblegum"))
|
||||
@ -356,8 +380,12 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
ai_node->get("acceleration", &m_ai_acceleration);
|
||||
}
|
||||
|
||||
if(const XMLNode *networking_node= root->getNode("networking"))
|
||||
networking_node->get("enable", &m_enable_networking);
|
||||
if (const XMLNode *networking_node = root->getNode("networking"))
|
||||
{
|
||||
networking_node->get("state-frequency", &m_network_state_frequeny);
|
||||
networking_node->get("positional-smoothing", &m_positional_smoothing );
|
||||
networking_node->get("rotational-smoothing", &m_rotational_smoothing );
|
||||
}
|
||||
|
||||
if(const XMLNode *replay_node = root->getNode("replay"))
|
||||
{
|
||||
@ -384,6 +412,19 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
tc->get("quality", &m_tc_quality);
|
||||
}
|
||||
|
||||
if (const XMLNode *tc = root->getNode("network"))
|
||||
{
|
||||
unsigned server_discovery_port = 0;
|
||||
unsigned client_port = 0;
|
||||
unsigned server_port = 0;
|
||||
tc->get("server-discovery-port", &server_discovery_port);
|
||||
tc->get("client-port", &client_port);
|
||||
tc->get("server-port", &server_port);
|
||||
m_server_discovery_port = (uint16_t)server_discovery_port;
|
||||
m_client_port = (uint16_t)client_port;
|
||||
m_server_port = (uint16_t)server_port;
|
||||
}
|
||||
|
||||
// Get the default KartProperties
|
||||
// ------------------------------
|
||||
const XMLNode *node = root -> getNode("general-kart-defaults");
|
||||
|
@ -27,6 +27,7 @@
|
||||
*/
|
||||
|
||||
#include "network/remote_kart_info.hpp"
|
||||
#include "utils/interpolation_array.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include "utils/constants.hpp"
|
||||
@ -69,13 +70,13 @@ public:
|
||||
float m_bomb_time; /**<Time before a bomb explodes. */
|
||||
float m_bomb_time_increase; /**<Time added to bomb timer when it's
|
||||
passed on. */
|
||||
float m_item_switch_time; /**< Time items will be switched. */
|
||||
int m_item_switch_ticks; /**< Time items will be switched. */
|
||||
int m_bubblegum_counter; /**< How many times bubble gums must be
|
||||
driven over before they disappear. */
|
||||
bool m_shield_restrict_weapons; /**<Wether weapon usage is punished. */
|
||||
float m_explosion_impulse_objects; /**<Impulse of explosion on moving
|
||||
objects, e.g. road cones, ... */
|
||||
float m_penalty_time; /**< Penalty time when starting too
|
||||
int m_penalty_ticks; /**< Penalty time when starting too
|
||||
early. */
|
||||
float m_delay_finish_time; /**<Delay after a race finished before
|
||||
the results are displayed. */
|
||||
@ -84,9 +85,20 @@ public:
|
||||
int m_max_karts; /**<Maximum number of karts. */
|
||||
bool m_smooth_normals; /**< If normals for raycasts for wheels
|
||||
should be interpolated. */
|
||||
/** If the angle between a normal on a vertex and the normal of the
|
||||
* triangle are more than this value, the physics will use the normal
|
||||
* of the triangle in smoothing normal. */
|
||||
|
||||
/** How many state updates per second the server will send. */
|
||||
int m_network_state_frequeny;
|
||||
|
||||
/** Smoothing of prediction errors for position, defined as an
|
||||
* InterpolationArray. */
|
||||
InterpolationArray m_positional_smoothing;
|
||||
/** Smoothing of prediction errors for rotations, defined as an
|
||||
* InterpolationArray. */
|
||||
InterpolationArray m_rotational_smoothing;
|
||||
|
||||
/** If the angle between a normal on a vertex and the normal of the
|
||||
* triangle are more than this value, the physics will use the normal
|
||||
* of the triangle in smoothing normal. */
|
||||
float m_smooth_angle_limit;
|
||||
|
||||
/** Default friction for the track and any track/library object. */
|
||||
@ -107,7 +119,6 @@ public:
|
||||
m_max_track_version; /**<version supported by this binary. */
|
||||
int m_max_display_news; /**<How often a news message is displayed
|
||||
before it is ignored. */
|
||||
bool m_enable_networking;
|
||||
|
||||
/** Disable steering if skidding is stopped. This can help in making
|
||||
* skidding more controllable (since otherwise when trying to steer while
|
||||
@ -159,6 +170,11 @@ public:
|
||||
|
||||
unsigned m_tc_quality;
|
||||
|
||||
/** Client and server port use random ports if enabled in user config. */
|
||||
uint16_t m_server_discovery_port;
|
||||
uint16_t m_client_port;
|
||||
uint16_t m_server_port;
|
||||
|
||||
/** Lists of TTF files used in STK. */
|
||||
std::vector<std::string> m_normal_ttf;
|
||||
std::vector<std::string> m_digit_ttf;
|
||||
|
@ -181,146 +181,6 @@ void GroupUserConfigParam::addChild(UserConfigParam* child)
|
||||
m_attributes.push_back(child);
|
||||
} // addChild
|
||||
|
||||
|
||||
// ============================================================================
|
||||
template<typename T, typename U>
|
||||
ListUserConfigParam<T, U>::ListUserConfigParam(const char* param_name,
|
||||
const char* comment)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T, typename U>
|
||||
ListUserConfigParam<T,U>::ListUserConfigParam(const char* param_name,
|
||||
const char* comment,
|
||||
int nb_elements,
|
||||
...)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
|
||||
// add the default list
|
||||
va_list arguments;
|
||||
va_start ( arguments, nb_elements );
|
||||
for ( int i = 0; i < nb_elements; i++ )
|
||||
m_elements.push_back(T(va_arg ( arguments, U )));
|
||||
va_end ( arguments ); // Cleans up the list
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T, typename U>
|
||||
ListUserConfigParam<T, U>::ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T, typename U>
|
||||
ListUserConfigParam<T, U>::ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment,
|
||||
int nb_elements,
|
||||
...)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
|
||||
// add the default list
|
||||
va_list arguments;
|
||||
va_start ( arguments, nb_elements );
|
||||
for ( int i = 0; i < nb_elements; i++ )
|
||||
m_elements.push_back(va_arg ( arguments, T ));
|
||||
va_end ( arguments ); // Cleans up the list
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, typename U>
|
||||
void ListUserConfigParam<T, U>::write(std::ofstream& stream) const
|
||||
{
|
||||
const int elts_amount = (int)m_elements.size();
|
||||
|
||||
// comment
|
||||
if(m_comment.size() > 0) stream << " <!-- " << m_comment.c_str();
|
||||
stream << " -->\n <" << m_param_name.c_str() << "\n";
|
||||
|
||||
stream << " Size=\"" << elts_amount << "\"\n";
|
||||
// actual elements
|
||||
for (int n=0; n<elts_amount; n++)
|
||||
{
|
||||
stream << " " << n << "=\"" << m_elements[n].c_str() << "\"\n";
|
||||
}
|
||||
stream << " >\n";
|
||||
stream << " </" << m_param_name.c_str() << ">\n\n";
|
||||
} // write
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
template<typename T, typename U>
|
||||
void ListUserConfigParam<T, U>::findYourDataInAChildOf(const XMLNode* node)
|
||||
{
|
||||
const XMLNode* child = node->getNode( m_param_name );
|
||||
if (child == NULL)
|
||||
{
|
||||
//Log::error("User Config", "Couldn't find parameter group %s", m_param_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
int attr_count = 0;
|
||||
child->get( "Size", &attr_count);
|
||||
for (int n=0; n<attr_count; n++)
|
||||
{
|
||||
T elt;
|
||||
std::string str;
|
||||
child->get( StringUtils::toString(n), &str);
|
||||
StringUtils::fromString<T>(str, elt);
|
||||
|
||||
// check if the element is already there :
|
||||
bool there = false;
|
||||
for (unsigned int i = 0; i < m_elements.size(); i++)
|
||||
{
|
||||
if (elt == m_elements[i])
|
||||
{
|
||||
there = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!there)
|
||||
{
|
||||
m_elements.push_back(elt);
|
||||
}
|
||||
}
|
||||
|
||||
} // findYourDataInAChildOf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, typename U>
|
||||
void ListUserConfigParam<T, U>::findYourDataInAnAttributeOf(const XMLNode* node)
|
||||
{
|
||||
} // findYourDataInAnAttributeOf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, typename U>
|
||||
void ListUserConfigParam<T,U>::addElement(T element)
|
||||
{
|
||||
m_elements.push_back(element);
|
||||
} // findYourDataInAnAttributeOf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, typename U>
|
||||
core::stringc ListUserConfigParam<T, U>::toString() const
|
||||
{
|
||||
return "";
|
||||
} // toString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, typename U>
|
||||
MapUserConfigParam<T, U>::MapUserConfigParam(const char* param_name,
|
||||
@ -334,26 +194,12 @@ MapUserConfigParam<T, U>::MapUserConfigParam(const char* param_name,
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, typename U>
|
||||
MapUserConfigParam<T, U>::MapUserConfigParam(const char* param_name,
|
||||
const char* comment,
|
||||
int nb_elements,
|
||||
...)
|
||||
const char* comment, std::map<T, U> default_value)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
all_params.push_back(this);
|
||||
if (comment != NULL) m_comment = comment;
|
||||
|
||||
// add the default list
|
||||
va_list arguments;
|
||||
va_start(arguments, nb_elements);
|
||||
|
||||
struct pair_type { T key; U value; };
|
||||
|
||||
for (int i = 0; i < nb_elements; i++)
|
||||
{
|
||||
pair_type key_value_pair = va_arg(arguments, pair_type);
|
||||
m_elements.insert(std::pair<T, U>(key_value_pair.key, key_value_pair.value));
|
||||
}
|
||||
va_end(arguments); // Cleans up the list
|
||||
m_elements = default_value;
|
||||
} // MapUserConfigParam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -370,27 +216,14 @@ MapUserConfigParam<T, U>::MapUserConfigParam(const char* param_name,
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, typename U>
|
||||
MapUserConfigParam<T, U>::MapUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment,
|
||||
int nb_elements,
|
||||
...)
|
||||
GroupUserConfigParam* group, const char* comment,
|
||||
std::map<T, U> default_value)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
group->addChild(this);
|
||||
if (comment != NULL) m_comment = comment;
|
||||
|
||||
// add the default list
|
||||
va_list arguments;
|
||||
va_start(arguments, nb_elements);
|
||||
|
||||
struct pair_type { T key; U value; };
|
||||
|
||||
for (int i = 0; i < nb_elements; i++)
|
||||
{
|
||||
pair_type key_value_pair = va_arg(arguments, pair_type);
|
||||
m_elements.insert(std::pair<T, U>(key_value_pair.key, key_value_pair.value));
|
||||
}
|
||||
va_end(arguments); // Cleans up the list
|
||||
m_elements = default_value;
|
||||
} // MapUserConfigParam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -401,7 +234,7 @@ void MapUserConfigParam<T, U>::write(std::ofstream& stream) const
|
||||
if (m_comment.size() > 0) stream << " <!-- " << m_comment.c_str();
|
||||
stream << " -->\n <" << m_param_name.c_str() << "\n";
|
||||
|
||||
for (const auto& kv : m_elements)
|
||||
for (const auto& kv : m_elements)
|
||||
{
|
||||
stream << " " << kv.first << "=\"" << kv.second << "\"\n";
|
||||
}
|
||||
@ -410,7 +243,6 @@ void MapUserConfigParam<T, U>::write(std::ofstream& stream) const
|
||||
} // write
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
template<typename T, typename U>
|
||||
void MapUserConfigParam<T, U>::findYourDataInAChildOf(const XMLNode* node)
|
||||
{
|
||||
|
@ -37,6 +37,7 @@
|
||||
cause an undefined game action now
|
||||
6: Added stick configurations.
|
||||
*/
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
@ -98,44 +99,6 @@ public:
|
||||
}; // GroupUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T, typename U>
|
||||
class ListUserConfigParam : public UserConfigParam
|
||||
{
|
||||
std::vector<T> m_elements;
|
||||
|
||||
public:
|
||||
ListUserConfigParam(const char* param_name,
|
||||
const char* comment = NULL);
|
||||
ListUserConfigParam(const char* param_name,
|
||||
const char* comment,
|
||||
int nb_elts,
|
||||
...);
|
||||
ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment = NULL);
|
||||
ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment,
|
||||
int nb_elts,
|
||||
...);
|
||||
|
||||
void write(std::ofstream& stream) const;
|
||||
void findYourDataInAChildOf(const XMLNode* node);
|
||||
void findYourDataInAnAttributeOf(const XMLNode* node);
|
||||
|
||||
void addElement(T element);
|
||||
|
||||
irr::core::stringc toString() const;
|
||||
|
||||
operator std::vector<T>() const
|
||||
{ return m_elements; }
|
||||
float& operator=(const std::vector<T>& v)
|
||||
{ m_elements = std::vector<T>(v); return m_elements; }
|
||||
float& operator=(const ListUserConfigParam& v)
|
||||
{ m_elements = std::vector<T>(v); return m_elements; }
|
||||
}; // ListUserConfigParam
|
||||
typedef ListUserConfigParam<std::string, const char*> StringListUserConfigParam;
|
||||
|
||||
template<typename T, typename U>
|
||||
class MapUserConfigParam : public UserConfigParam
|
||||
{
|
||||
@ -146,16 +109,14 @@ public:
|
||||
const char* comment = NULL);
|
||||
MapUserConfigParam(const char* param_name,
|
||||
const char* comment,
|
||||
int nb_elts,
|
||||
...);
|
||||
std::map<T, U> default_value);
|
||||
MapUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment = NULL);
|
||||
MapUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment,
|
||||
int nb_elts,
|
||||
...);
|
||||
std::map<T, U> default_value);
|
||||
|
||||
void write(std::ofstream& stream) const;
|
||||
void findYourDataInAChildOf(const XMLNode* node);
|
||||
@ -165,10 +126,18 @@ public:
|
||||
|
||||
irr::core::stringc toString() const;
|
||||
|
||||
operator std::map<T,U>() const
|
||||
operator std::map<T, U>() const
|
||||
{
|
||||
return m_elements;
|
||||
}
|
||||
typename std::map<T, U>::iterator begin()
|
||||
{
|
||||
return m_elements.begin();
|
||||
}
|
||||
typename std::map<T, U>::iterator end()
|
||||
{
|
||||
return m_elements.end();
|
||||
}
|
||||
std::map<T, U>& operator=(const std::map<T,U>& v)
|
||||
{
|
||||
m_elements = std::map<T, U>(v);
|
||||
@ -183,8 +152,9 @@ public:
|
||||
{
|
||||
return m_elements[key];
|
||||
}
|
||||
}; // ListUserConfigParam
|
||||
typedef MapUserConfigParam<int, int> IntToIntUserConfigParam;
|
||||
}; // MapUserConfigParam
|
||||
typedef MapUserConfigParam<uint32_t, uint32_t> UIntToUIntUserConfigParam;
|
||||
typedef MapUserConfigParam<std::string, uint32_t> StringToUIntUserConfigParam;
|
||||
// ============================================================================
|
||||
class IntUserConfigParam : public UserConfigParam
|
||||
{
|
||||
@ -205,7 +175,7 @@ public:
|
||||
|
||||
irr::core::stringc toString() const;
|
||||
void revertToDefaults() { m_value = m_default_value; }
|
||||
|
||||
int getDefaultValue() { return m_default_value; }
|
||||
operator int() const { return m_value; }
|
||||
int& operator++(int dummy) { m_value++; return m_value; }
|
||||
int& operator=(const int& v) { m_value = v; return m_value; }
|
||||
@ -713,72 +683,70 @@ namespace UserConfigParams
|
||||
* can store. */
|
||||
PARAM_PREFIX float m_profiler_buffer_duration PARAM_DEFAULT(20.0f);
|
||||
|
||||
// not saved to file
|
||||
|
||||
// ---- Networking
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_server_max_players
|
||||
PARAM_DEFAULT( IntUserConfigParam(16, "server_max_players",
|
||||
"Maximum number of players on the server.") );
|
||||
|
||||
PARAM_PREFIX StringListUserConfigParam m_stun_servers
|
||||
PARAM_DEFAULT( StringListUserConfigParam("Stun_servers", "The stun servers"
|
||||
" that will be used to know the public address.",
|
||||
24,
|
||||
"provserver.televolution.net",
|
||||
"sip1.lakedestiny.cordiaip.com",
|
||||
"stun1.voiceeclipse.net",
|
||||
"stun01.sipphone.com",
|
||||
"stun.callwithus.com",
|
||||
"stun.counterpath.net",
|
||||
"stun.endigovoip.com",
|
||||
"stun.ekiga.net",
|
||||
"stun.ideasip.com",
|
||||
"stun.internetcalls.com",
|
||||
"stun.ipns.com",
|
||||
"stun.noc.ams-ix.net",
|
||||
"stun.phonepower.com",
|
||||
"stun.phoneserve.com",
|
||||
"stun.rnktel.com",
|
||||
"stun.softjoys.com",
|
||||
"stunserver.org",
|
||||
"stun.sipgate.net",
|
||||
"stun.stunprotocol.org",
|
||||
"stun.voip.aebc.com",
|
||||
"stun.voipbuster.com",
|
||||
"stun.voxalot.com",
|
||||
"stun.voxgratia.org",
|
||||
"stun.xten.com") );
|
||||
|
||||
// ---- Gamemode setup
|
||||
PARAM_PREFIX IntToIntUserConfigParam m_num_karts_per_gamemode
|
||||
PARAM_DEFAULT(IntToIntUserConfigParam("num_karts_per_gamemode",
|
||||
"The Number of karts per gamemode.",
|
||||
1,
|
||||
std::make_pair(1100, 4)
|
||||
PARAM_PREFIX StringToUIntUserConfigParam m_stun_list
|
||||
PARAM_DEFAULT(StringToUIntUserConfigParam("stun_list",
|
||||
"The stun servers that will be used to know the public address,"
|
||||
" LHS: server address, RHS: ping time.",
|
||||
{
|
||||
{ "numb.viagenie.ca", 0u },
|
||||
{ "stun.12connect.com", 0u },
|
||||
{ "stun.callwithus.com", 0u },
|
||||
{ "stun.cope.es", 0u },
|
||||
{ "stun.counterpath.net", 0u },
|
||||
{ "stun.ekiga.net", 0u },
|
||||
{ "stun.ivao.aero", 0u },
|
||||
{ "stun.schlund.de", 0u },
|
||||
{ "stun.stunprotocol.org", 0u },
|
||||
{ "stun.voip.aebc.com", 0u }
|
||||
}
|
||||
));
|
||||
|
||||
PARAM_PREFIX GroupUserConfigParam m_network_group
|
||||
PARAM_DEFAULT(GroupUserConfigParam("Network", "Network Settings"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_log_packets
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "log-network-packets",
|
||||
"If all network packets should be logged") );
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "log-network-packets",
|
||||
&m_network_group, "If all network packets should be logged"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_random_ports
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true, "randrom-ports",
|
||||
&m_network_group, "Use random ports for client and server connection"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_lobby_chat
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "lobby-chat",
|
||||
&m_network_group, "Enable chatting in networking lobby, if off than "
|
||||
"no chat message will be displayed from any players."));
|
||||
PARAM_PREFIX FloatUserConfigParam m_voting_timeout
|
||||
PARAM_DEFAULT(FloatUserConfigParam(10.0f, "voting-timeout",
|
||||
&m_network_group, "Timeout in seconds for voting tracks in server."));
|
||||
PARAM_PREFIX IntUserConfigParam m_server_max_players
|
||||
PARAM_DEFAULT(IntUserConfigParam(12, "server_max_players",
|
||||
&m_network_group, "Maximum number of players on the server."));
|
||||
|
||||
PARAM_PREFIX StringToUIntUserConfigParam m_server_ban_list
|
||||
PARAM_DEFAULT(StringToUIntUserConfigParam("server_ban_list",
|
||||
"LHS: IP in x.x.x.x format, RHS: online id, if 0 than all players "
|
||||
"from this IP will be banned.",
|
||||
{ { "0.0.0.0", 0u } }
|
||||
));
|
||||
|
||||
// ---- Gamemode setup
|
||||
PARAM_PREFIX UIntToUIntUserConfigParam m_num_karts_per_gamemode
|
||||
PARAM_DEFAULT(UIntToUIntUserConfigParam("num_karts_per_gamemode",
|
||||
"The Number of karts per gamemode.",
|
||||
{
|
||||
{ 0u, 4u },
|
||||
{ 1002u, 5u },
|
||||
{ 1100u, 4u },
|
||||
{ 1101u, 4u },
|
||||
{ 2000u, 4u },
|
||||
{ 2001u, 4u }
|
||||
}
|
||||
));
|
||||
|
||||
// ---- Graphic Quality
|
||||
PARAM_PREFIX GroupUserConfigParam m_graphics_quality
|
||||
PARAM_DEFAULT( GroupUserConfigParam("GFX",
|
||||
"Graphics Quality Settings") );
|
||||
|
||||
// On OSX 10.4 and before there may be driver issues with FBOs, so to be
|
||||
// safe disable them by default
|
||||
#ifdef __APPLE__
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
|
||||
#define FBO_DEFAULT false
|
||||
#else
|
||||
#define FBO_DEFAULT true
|
||||
#endif
|
||||
#else
|
||||
#define FBO_DEFAULT true
|
||||
#endif
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_particles_effects
|
||||
PARAM_DEFAULT( IntUserConfigParam(2, "particles-effecs",
|
||||
&m_graphics_quality, "Particles effects: 0 disabled, 1 only important, 2 enabled") );
|
||||
@ -842,17 +810,6 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_crashed
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "crashed") );
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
// No console on windows
|
||||
# define CONSOLE_DEFAULT false
|
||||
#else
|
||||
# define CONSOLE_DEFAULT true
|
||||
#endif
|
||||
// No console on windows
|
||||
PARAM_PREFIX BoolUserConfigParam m_log_errors_to_console
|
||||
PARAM_DEFAULT( BoolUserConfigParam(
|
||||
CONSOLE_DEFAULT, "log_errors", "Enable logging to console.") );
|
||||
|
||||
// ---- Camera
|
||||
PARAM_PREFIX GroupUserConfigParam m_camera
|
||||
PARAM_DEFAULT( GroupUserConfigParam("camera",
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "graphics/stk_tex_manager.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/skin.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <array>
|
||||
@ -209,7 +210,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
|
||||
const unsigned int cur_tex = m_spritebank->getTextureCount() -1;
|
||||
#ifndef SERVER_ONLY
|
||||
if (bits->buffer != NULL)
|
||||
if (bits->buffer != NULL && !ProfileWorld::isNoGraphics())
|
||||
{
|
||||
video::ITexture* tex = m_spritebank->getTexture(cur_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName());
|
||||
@ -335,7 +336,7 @@ void FontWithFace::setDPI()
|
||||
if (UserConfigParams::m_hidpi_enabled)
|
||||
{
|
||||
float scale = screen_height / 480.0f;
|
||||
m_face_dpi = getScalingFactorTwo() * getScalingFactorOne() * scale;
|
||||
m_face_dpi = int(getScalingFactorTwo() * getScalingFactorOne() * scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
@ -31,14 +32,15 @@
|
||||
#include "race/race_manager.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
const float burst_time = 0.1f;
|
||||
|
||||
/** Creates an explosion effect. */
|
||||
Explosion::Explosion(const Vec3& coord, const char* explosion_sound, const char * particle_file)
|
||||
: HitSFX(coord, explosion_sound)
|
||||
{
|
||||
// short emision time, explosion, not constant flame
|
||||
m_remaining_time = burst_time;
|
||||
|
||||
m_explosion_ticks = stk_config->time2Ticks(2.0f);
|
||||
m_remaining_ticks = stk_config->time2Ticks(0.1f);
|
||||
m_emission_frames = 0;
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
@ -84,22 +86,22 @@ Explosion::~Explosion()
|
||||
* \param dt Time step size.
|
||||
* \return true If the explosion is finished.
|
||||
*/
|
||||
bool Explosion::updateAndDelete(float dt)
|
||||
bool Explosion::updateAndDelete(int ticks)
|
||||
{
|
||||
// The explosion sfx is shorter than the particle effect,
|
||||
// so no need to save the result of the update call.
|
||||
HitSFX::updateAndDelete(dt);
|
||||
HitSFX::updateAndDelete(ticks);
|
||||
|
||||
m_emission_frames++;
|
||||
m_remaining_time -= dt;
|
||||
m_remaining_ticks -= ticks;
|
||||
|
||||
// Do nothing more if the animation is still playing
|
||||
if (m_remaining_time>0) return false;
|
||||
if (m_remaining_ticks>0) return false;
|
||||
|
||||
// Otherwise check that the sfx has finished, otherwise the
|
||||
// sfx will get aborted 'in the middle' when this explosion
|
||||
// object is removed.
|
||||
if (m_remaining_time > -explosion_time)
|
||||
if (m_remaining_ticks > -m_explosion_ticks)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
// if framerate is very low, emit for at least a few frames, in case
|
||||
@ -122,3 +124,4 @@ bool Explosion::updateAndDelete(float dt)
|
||||
|
||||
return false; // not finished
|
||||
} // updateAndDelete
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define HEADER_EXPLOSION_HPP
|
||||
|
||||
#include "graphics/hit_sfx.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
namespace irr
|
||||
@ -33,23 +34,26 @@ class Vec3;
|
||||
class SFXBase;
|
||||
class ParticleEmitter;
|
||||
|
||||
const float explosion_time = 2.0f;
|
||||
|
||||
/**
|
||||
* \ingroup graphics
|
||||
*/
|
||||
class Explosion : public HitSFX
|
||||
{
|
||||
private:
|
||||
float m_remaining_time;
|
||||
int m_remaining_ticks;
|
||||
int m_emission_frames;
|
||||
ParticleEmitter* m_emitter;
|
||||
int m_explosion_ticks;
|
||||
|
||||
|
||||
public:
|
||||
Explosion(const Vec3& coord, const char* explosion_sound, const char * particle_file );
|
||||
~Explosion();
|
||||
bool updateAndDelete(float delta_t);
|
||||
bool hasEnded () { return m_remaining_time <= -explosion_time; }
|
||||
bool updateAndDelete(int ticks) OVERRIDE;
|
||||
bool hasEnded ()
|
||||
{
|
||||
return m_remaining_ticks <= -m_explosion_ticks;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
/** Updates a hit effect. Called once per frame.
|
||||
* \param dt Time step size.
|
||||
* \return True if the hit effect is finished and can be removed. */
|
||||
virtual bool updateAndDelete(float dt) = 0;
|
||||
virtual bool updateAndDelete(int ticks) = 0;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets that this SFX affects a player kart, which can be used to
|
||||
|
@ -61,7 +61,7 @@ void HitSFX::setLocalPlayerKartHit()
|
||||
* \param dt Time step size.
|
||||
* \return true If the explosion is finished.
|
||||
*/
|
||||
bool HitSFX::updateAndDelete(float dt)
|
||||
bool HitSFX::updateAndDelete(int ticks)
|
||||
{
|
||||
SFXBase::SFXStatus status = m_sfx->getStatus();
|
||||
return status!= SFXBase::SFX_PLAYING;
|
||||
|
@ -36,7 +36,7 @@ private:
|
||||
public:
|
||||
HitSFX(const Vec3& coord, const char* explosion_sound);
|
||||
~HitSFX();
|
||||
virtual bool updateAndDelete(float dt) OVERRIDE;
|
||||
virtual bool updateAndDelete(int ticks) OVERRIDE;
|
||||
virtual void setLocalPlayerKartHit() OVERRIDE;
|
||||
|
||||
}; // HitSFX
|
||||
|
@ -303,7 +303,6 @@ core::recti IrrDriver::getSplitscreenWindow(int WindowNum)
|
||||
|
||||
const int x_grid_Position = WindowNum % cols;
|
||||
const int y_grid_Position = int(floor((WindowNum) / cols));
|
||||
int wid = (int)irr_driver->getActualScreenSize().Width;
|
||||
|
||||
//To prevent the viewport going over the right side, we use std::min to ensure the right corners are never larger than the total width
|
||||
return core::recti(
|
||||
@ -715,8 +714,8 @@ void IrrDriver::initDevice()
|
||||
// set cursor visible by default (what's the default is not too clearly documented,
|
||||
// so let's decide ourselves...)
|
||||
m_device->getCursorControl()->setVisible(true);
|
||||
m_pointer_shown = true;
|
||||
#endif
|
||||
m_pointer_shown = true;
|
||||
} // initDevice
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -786,16 +785,19 @@ void IrrDriver::getOpenGLData(std::string *vendor, std::string *renderer,
|
||||
//-----------------------------------------------------------------------------
|
||||
void IrrDriver::showPointer()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (!m_pointer_shown)
|
||||
{
|
||||
m_pointer_shown = true;
|
||||
this->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
#endif
|
||||
} // showPointer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void IrrDriver::hidePointer()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
// always visible in artist debug mode, to be able to use the context menu
|
||||
if (UserConfigParams::m_artist_debug_mode)
|
||||
{
|
||||
@ -808,6 +810,7 @@ void IrrDriver::hidePointer()
|
||||
m_pointer_shown = false;
|
||||
this->getDevice()->getCursorControl()->setVisible(false);
|
||||
}
|
||||
#endif
|
||||
} // hidePointer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -152,7 +152,9 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
node->get("ignore", &m_ignore );
|
||||
|
||||
node->get("max-speed", &m_max_speed_fraction );
|
||||
node->get("slowdown-time", &m_slowdown_time );
|
||||
float f = stk_config->ticks2Time(m_slowdown_ticks);
|
||||
node->get("slowdown-time", &f );
|
||||
m_slowdown_ticks = stk_config->time2Ticks(f);
|
||||
node->get("colorizable", &m_colorizable );
|
||||
node->get("colorization-factor", &m_colorization_factor);
|
||||
node->get("hue-settings", &m_hue_settings );
|
||||
@ -484,7 +486,7 @@ void Material::init()
|
||||
m_colorization_factor = 0.0f;
|
||||
m_colorization_mask = "";
|
||||
m_max_speed_fraction = 1.0f;
|
||||
m_slowdown_time = 1.0f;
|
||||
m_slowdown_ticks = stk_config->time2Ticks(1.0f);
|
||||
m_sfx_name = "";
|
||||
m_sfx_min_speed = 0.0f;
|
||||
m_sfx_max_speed = 30;
|
||||
|
@ -155,7 +155,7 @@ private:
|
||||
RandomGenerator m_random_hue;
|
||||
|
||||
/** How much the top speed is reduced per second. */
|
||||
float m_slowdown_time;
|
||||
int m_slowdown_ticks;
|
||||
|
||||
/** Maximum speed at which no more slow down occurs. */
|
||||
float m_max_speed_fraction;
|
||||
@ -287,7 +287,7 @@ public:
|
||||
/** Returns how long it will take for a slowdown to take effect.
|
||||
* It is the time it takes till the full slowdown applies to
|
||||
* karts. So a short time will slowdown a kart much faster. */
|
||||
float getSlowDownTime() const { return m_slowdown_time; }
|
||||
int getSlowDownTicks() const { return m_slowdown_ticks; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this material is under some other mesh and therefore
|
||||
* requires another raycast to find the surface it is under (used for
|
||||
|
@ -42,11 +42,13 @@
|
||||
*/
|
||||
SlipStream::SlipStream(AbstractKart* kart)
|
||||
{
|
||||
m_node = NULL;
|
||||
m_kart = kart;
|
||||
m_moving = NULL;
|
||||
m_moving_fast = NULL;
|
||||
m_moving_bonus = NULL;
|
||||
m_node = NULL;
|
||||
m_node_fast = NULL;
|
||||
m_bonus_node = NULL;
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL())
|
||||
@ -210,7 +212,7 @@ void SlipStream::reset()
|
||||
{
|
||||
m_slipstream_mode = SS_NONE;
|
||||
m_slipstream_time = 0;
|
||||
m_bonus_time = 0;
|
||||
m_bonus_time = 0;
|
||||
|
||||
// Reset a potential max speed increase
|
||||
m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM, 0, 0, 0, 0);
|
||||
@ -612,7 +614,7 @@ void SlipStream::updateQuad()
|
||||
/** Update, called once per timestep.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void SlipStream::update(float dt)
|
||||
void SlipStream::update(int ticks)
|
||||
{
|
||||
const KartProperties *kp = m_kart->getKartProperties();
|
||||
|
||||
@ -628,6 +630,7 @@ void SlipStream::update(float dt)
|
||||
updateQuad();
|
||||
}
|
||||
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
@ -731,7 +734,7 @@ void SlipStream::update(float dt)
|
||||
// (additional target_kart_length because that kart's center
|
||||
// is not the center of rotation of the slipstreaming quad)
|
||||
Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ();
|
||||
float l = kp_target->getSlipstreamLength()*1.1;//Outer quad margin
|
||||
float l = kp_target->getSlipstreamLength()*1.1f;//Outer quad margin
|
||||
float speed_factor = m_target_kart->getSpeed()
|
||||
/kp_target->getSlipstreamBaseSpeed();
|
||||
l = l*speed_factor + m_target_kart->getKartLength()
|
||||
@ -821,12 +824,13 @@ void SlipStream::update(float dt)
|
||||
|
||||
m_slipstream_time = 0.0f;
|
||||
m_bonus_active = true;
|
||||
int fade_out = kp->getSlipstreamFadeOutTicks();
|
||||
m_kart->instantSpeedIncrease(MaxSpeed::MS_INCREASE_SLIPSTREAM,
|
||||
kp->getSlipstreamMaxSpeedIncrease(),
|
||||
kp->getSlipstreamMaxSpeedIncrease(),
|
||||
kp->getSlipstreamAddPower(),
|
||||
m_bonus_time,
|
||||
kp->getSlipstreamFadeOutTime());
|
||||
stk_config->ticks2Time(fade_out) );
|
||||
}
|
||||
|
||||
if(!is_sstreaming)
|
||||
|
@ -123,7 +123,7 @@ public:
|
||||
SlipStream (AbstractKart* kart);
|
||||
virtual ~SlipStream ();
|
||||
void reset();
|
||||
virtual void update(float dt);
|
||||
virtual void update(int ticks);
|
||||
bool isSlipstreamReady() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -56,9 +56,9 @@ SPDynamicDrawCall::SPDynamicDrawCall(scene::E_PRIMITIVE_TYPE pt,
|
||||
glBufferData(GL_ARRAY_BUFFER, 4 * 48, NULL, GL_DYNAMIC_DRAW);
|
||||
glGenBuffers(1, &m_ibo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_ibo);
|
||||
glBufferData(GL_ARRAY_BUFFER, 32, NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, 44, NULL, GL_DYNAMIC_DRAW);
|
||||
SPInstancedData id = SPInstancedData(m_trans, 0.0f, 0.0f, 0.0f, 0);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 32, &id);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 44, &id);
|
||||
SPTextureManager::get()->increaseGLCommandFunctionCount(1);
|
||||
SPTextureManager::get()->addGLCommandFunction
|
||||
(std::bind(&SPDynamicDrawCall::initTextureDyDc, this));
|
||||
@ -120,26 +120,23 @@ SPDynamicDrawCall::SPDynamicDrawCall(scene::E_PRIMITIVE_TYPE pt,
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_ibo);
|
||||
// Origin
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 32, (void*)0);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 44, (void*)0);
|
||||
glVertexAttribDivisorARB(8, 1);
|
||||
// Rotation (quaternion .xyz)
|
||||
// Rotation (quaternion in 4 32bit floats)
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 4, GL_INT_2_10_10_10_REV,
|
||||
GraphicsRestrictions::isDisabled
|
||||
(GraphicsRestrictions::GR_CORRECT_10BIT_NORMALIZATION) ?
|
||||
GL_FALSE : GL_TRUE, 32, (void*)12);
|
||||
glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, 44, (void*)12);
|
||||
glVertexAttribDivisorARB(9, 1);
|
||||
// Scale (3 half floats and .w for quaternion .w)
|
||||
// Scale (3 half floats and .w unused)
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 32, (void*)16);
|
||||
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 44, (void*)28);
|
||||
glVertexAttribDivisorARB(10, 1);
|
||||
// Texture translation
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 32, (void*)24);
|
||||
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 44, (void*)36);
|
||||
glVertexAttribDivisorARB(11, 1);
|
||||
// Misc data (skinning offset and hue change)
|
||||
glEnableVertexAttribArray(12);
|
||||
glVertexAttribIPointer(12, 2, GL_SHORT, 32, (void*)28);
|
||||
glVertexAttribIPointer(12, 2, GL_SHORT, 44, (void*)40);
|
||||
glVertexAttribDivisorARB(12, 1);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
@ -164,4 +161,4 @@ bool SPDynamicDrawCall::initTextureDyDc()
|
||||
return true;
|
||||
} // initTextureDyDc
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ void SPShader::bindTextures(const std::array<GLuint, 6>& tex,
|
||||
void SPShader::addAllUniforms(RenderPass rp)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
GLint total_uniforms;
|
||||
GLint total_uniforms = 0;
|
||||
glGetProgramiv(m_program[rp], GL_ACTIVE_UNIFORMS, &total_uniforms);
|
||||
static const std::map<GLenum, std::type_index> supported_types =
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ STKTexture::STKTexture(video::IImage* img, const std::string& name)
|
||||
STKTexture::~STKTexture()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_texture_name != 0)
|
||||
if (m_texture_name != 0 && !ProfileWorld::isNoGraphics())
|
||||
{
|
||||
glDeleteTextures(1, &m_texture_name);
|
||||
}
|
||||
|
@ -309,11 +309,12 @@ namespace GUIEngine
|
||||
For icon buttons. A different icon to show when the item is focused.
|
||||
|
||||
\n
|
||||
\subsection prop4 PROP_TEXT_ALIGN
|
||||
<em> Name in XML files: </em> \c "text_align"
|
||||
\subsection prop4 PROP_TEXT_ALIGN, PROP_TEXT_VALIGN
|
||||
<em> Name in XML files: </em> \c "text_align", "text_valign"
|
||||
|
||||
used exclusively by label components. Value can be "right" or "center" (left
|
||||
used if not specified).
|
||||
used if not specified) for "text_align", or "top"/"center"/"bottom" for
|
||||
valign.
|
||||
|
||||
\n
|
||||
\subsection prop5 PROP_WORD_WRAP
|
||||
|
@ -375,7 +375,10 @@ void EventHandler::processGUIAction(const PlayerAction action,
|
||||
|
||||
case PA_RESCUE:
|
||||
case PA_MENU_CANCEL:
|
||||
if (pressedDown) GUIEngine::getStateManager()->escapePressed();
|
||||
if (pressedDown&& !isWithinATextBox())
|
||||
{
|
||||
GUIEngine::getStateManager()->escapePressed();
|
||||
}
|
||||
break;
|
||||
|
||||
case PA_FIRE:
|
||||
@ -813,7 +816,7 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event)
|
||||
|
||||
const int playerID = input_manager->getPlayerKeyboardID();
|
||||
if (input_manager->masterPlayerOnly() && playerID != PLAYER_ID_GAME_MASTER) break;
|
||||
if (!w->isFocusedForPlayer(playerID)) w->setFocusForPlayer(playerID);
|
||||
if (playerID != -1 && !w->isFocusedForPlayer(playerID)) w->setFocusForPlayer(playerID);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -48,14 +48,9 @@ using namespace irr;
|
||||
*/
|
||||
namespace GUIEngine
|
||||
{
|
||||
#define DEFINE_SCREEN_SINGLETON( ClassName ) \
|
||||
template<> ClassName* GUIEngine::ScreenSingleton< ClassName >::singleton = NULL
|
||||
|
||||
/**
|
||||
* \brief Declares a class to be a singleton.
|
||||
* Normally, all screens will be singletons.
|
||||
* Note that you need to use the 'DEFINE_SCREEN_SINGLETON' macro in a .
|
||||
* cpp file to actually define the instance (as this can't be done in a .h)
|
||||
* \ingroup guiengine
|
||||
*/
|
||||
template<typename SCREEN>
|
||||
@ -83,6 +78,8 @@ namespace GUIEngine
|
||||
}
|
||||
|
||||
};
|
||||
template <typename SCREEN> SCREEN*
|
||||
ScreenSingleton<SCREEN>::singleton = nullptr;
|
||||
|
||||
/**
|
||||
* \brief Represents a single GUI screen.
|
||||
|
@ -210,6 +210,7 @@ if(prop_name != NULL) widget.m_properties[prop_flag] = core::stringc(prop_name).
|
||||
READ_PROPERTY(icon, PROP_ICON);
|
||||
READ_PROPERTY(focus_icon, PROP_FOCUS_ICON);
|
||||
READ_PROPERTY(text_align, PROP_TEXT_ALIGN);
|
||||
READ_PROPERTY(text_valign, PROP_TEXT_VALIGN);
|
||||
READ_PROPERTY(min_value, PROP_MIN_VALUE);
|
||||
READ_PROPERTY(max_value, PROP_MAX_VALUE);
|
||||
READ_PROPERTY(square_items, PROP_SQUARE);
|
||||
|
@ -1675,7 +1675,7 @@ void Skin::renderSections(PtrVector<Widget>* within_vector)
|
||||
|
||||
if (widget.m_type == WTYPE_DIV)
|
||||
{
|
||||
if (widget.m_show_bounding_box)
|
||||
if (widget.m_show_bounding_box && widget.isVisible())
|
||||
{
|
||||
if (widget.m_is_bounding_box_round)
|
||||
{
|
||||
|
@ -309,7 +309,9 @@ bool Widget::isVisible() const
|
||||
{
|
||||
if (m_element != NULL)
|
||||
{
|
||||
assert(m_element->isVisible() == m_is_visible);
|
||||
// repair mismatch
|
||||
if (m_element->isVisible() != m_is_visible)
|
||||
m_element->setVisible(m_is_visible);
|
||||
}
|
||||
return m_is_visible;
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ namespace GUIEngine
|
||||
PROP_ICON,
|
||||
PROP_FOCUS_ICON,
|
||||
PROP_TEXT_ALIGN,
|
||||
PROP_TEXT_VALIGN,
|
||||
PROP_MIN_VALUE,
|
||||
PROP_MAX_VALUE,
|
||||
PROP_MAX_WIDTH,
|
||||
@ -325,7 +326,7 @@ namespace GUIEngine
|
||||
* it visible implicitely calls setActive(true). If you mix visiblity and (de)activated calls,
|
||||
* undefined behavior may ensue (like invisible but clickable buttons).
|
||||
*/
|
||||
void setVisible(bool visible);
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
/** Returns if the element is visible. */
|
||||
bool isVisible() const;
|
||||
@ -658,6 +659,7 @@ namespace GUIEngine
|
||||
|
||||
/** Gets called when the widget is active and got clicked. (Only works for button widgets for now.) */
|
||||
virtual void onClick() { }
|
||||
virtual irr::core::dimension2di getDimension() const { return irr::core::dimension2di(m_w, m_h); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -823,6 +823,9 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
||||
|
||||
calculateScrollPos();
|
||||
|
||||
if (CursorPos > (s32)Text.size())
|
||||
CursorPos = Text.size();
|
||||
|
||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
||||
switch(event.KeyInput.Key)
|
||||
{
|
||||
|
@ -76,7 +76,9 @@ void BubbleWidget::replaceText()
|
||||
else if (m_properties[PROP_TEXT_ALIGN] == "right") align = EGUIA_LOWERRIGHT;
|
||||
else if (translations->isRTLText(message)) align = EGUIA_LOWERRIGHT;
|
||||
|
||||
EGUI_ALIGNMENT valign = EGUIA_CENTER ; //TODO: make label v-align configurable through XML file?
|
||||
EGUI_ALIGNMENT valign = EGUIA_CENTER;
|
||||
if (m_properties[PROP_TEXT_VALIGN] == "top") valign = EGUIA_UPPERLEFT;
|
||||
if (m_properties[PROP_TEXT_VALIGN] == "bottom") valign = EGUIA_LOWERRIGHT;
|
||||
|
||||
// find expanded bubble size
|
||||
int text_height = irrwidget->getTextHeight();
|
||||
|
@ -44,6 +44,9 @@ void CheckBoxWidget::add()
|
||||
m_id = m_element->getID();
|
||||
m_element->setTabOrder(m_id);
|
||||
m_element->setTabGroup(false);
|
||||
|
||||
if (!m_is_visible)
|
||||
m_element->setVisible(false);
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
EventPropagation CheckBoxWidget::transmitEvent(Widget* w,
|
||||
|
@ -155,7 +155,7 @@ void DynamicRibbonWidget::add()
|
||||
|
||||
if (UserConfigParams::m_hidpi_enabled)
|
||||
{
|
||||
m_arrows_w *= 1.5f;
|
||||
m_arrows_w = int(m_arrows_w*1.5f);
|
||||
}
|
||||
|
||||
const int button_h = m_arrows_w;
|
||||
|
@ -416,3 +416,13 @@ void IconButtonWidget::setLabelFont()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void IconButtonWidget::setVisible(bool visible)
|
||||
{
|
||||
Widget::setVisible(visible);
|
||||
|
||||
if (m_label != NULL)
|
||||
m_label->setVisible(visible);
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ namespace irr
|
||||
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
@ -161,6 +162,14 @@ namespace GUIEngine
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the texture of this button. */
|
||||
const video::ITexture* getTexture();
|
||||
// --------------------------------------------------------------------
|
||||
virtual void setVisible(bool visible) OVERRIDE;
|
||||
// --------------------------------------------------------------------
|
||||
virtual void elementRemoved() OVERRIDE
|
||||
{
|
||||
Widget::elementRemoved();
|
||||
m_label = NULL;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,10 @@ void LabelWidget::add()
|
||||
EGUI_ALIGNMENT align = EGUIA_UPPERLEFT;
|
||||
if (m_properties[PROP_TEXT_ALIGN] == "center") align = EGUIA_CENTER;
|
||||
else if (m_properties[PROP_TEXT_ALIGN] == "right") align = EGUIA_LOWERRIGHT;
|
||||
EGUI_ALIGNMENT valign = EGUIA_CENTER ; //TODO: make label v-align configurable through XML file?
|
||||
|
||||
EGUI_ALIGNMENT valign = EGUIA_CENTER ;
|
||||
if (m_properties[PROP_TEXT_VALIGN] == "top") valign = EGUIA_UPPERLEFT;
|
||||
if (m_properties[PROP_TEXT_VALIGN] == "bottom") valign = EGUIA_LOWERRIGHT;
|
||||
|
||||
IGUIStaticText* irrwidget;
|
||||
if (m_scroll_speed != 0)
|
||||
@ -107,6 +110,9 @@ void LabelWidget::add()
|
||||
|
||||
if (m_scroll_speed <= 0)
|
||||
m_element->setNotClipped(true);
|
||||
|
||||
if (!m_is_visible)
|
||||
m_element->setVisible(false);
|
||||
} // add
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -108,7 +108,9 @@ namespace GUIEngine
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void setPlayerID(const int newPlayerID);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
PlayerNameSpinner* getPlayerNameSpinner() const
|
||||
{ return m_player_ident_spinner; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int getPlayerID() const;
|
||||
|
@ -63,7 +63,17 @@ public:
|
||||
m_listeners[n].onTextUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.Key == IRR_KEY_RETURN)
|
||||
{
|
||||
for (unsigned int n=0; n<m_listeners.size(); n++)
|
||||
{
|
||||
if (m_listeners[n].onEnterPressed(Text))
|
||||
{
|
||||
Text = L"";
|
||||
CursorPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ namespace GUIEngine
|
||||
public:
|
||||
virtual ~ITextBoxWidgetListener() {}
|
||||
virtual void onTextUpdated() = 0;
|
||||
virtual bool onEnterPressed(const irr::core::stringw& text) { return false; }
|
||||
};
|
||||
|
||||
/** \brief A text field widget.
|
||||
|
@ -28,18 +28,21 @@
|
||||
#include "guiengine/screen_keyboard.hpp"
|
||||
#include "input/device_manager.hpp"
|
||||
#include "input/gamepad_device.hpp"
|
||||
#include "input/input.hpp"
|
||||
#include "input/keyboard_device.hpp"
|
||||
#include "input/multitouch_device.hpp"
|
||||
#include "input/input.hpp"
|
||||
#include "input/wiimote_manager.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "race/history.hpp"
|
||||
#include "replay/replay_recorder.hpp"
|
||||
#include "states_screens/dialogs/splitscreen_player_dialog.hpp"
|
||||
#include "states_screens/kart_selection.hpp"
|
||||
#include "states_screens/main_menu_screen.hpp"
|
||||
#include "states_screens/options_screen_device.hpp"
|
||||
@ -84,6 +87,10 @@ InputManager::InputManager() : m_mode(BOOTSTRAP),
|
||||
// -----------------------------------------------------------------------------
|
||||
void InputManager::update(float dt)
|
||||
{
|
||||
#ifdef ENABLE_WIIUSE
|
||||
wiimote_manager->update();
|
||||
#endif
|
||||
|
||||
if(m_timer_in_use)
|
||||
{
|
||||
m_timer -= dt;
|
||||
@ -290,14 +297,14 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
case IRR_KEY_F11:
|
||||
if(value && shift_is_pressed && world && RewindManager::isEnabled())
|
||||
{
|
||||
printf("Enter rewind to time:");
|
||||
printf("Enter rewind to time in ticks:");
|
||||
char s[256];
|
||||
fgets(s, 256, stdin);
|
||||
float t;
|
||||
int t;
|
||||
StringUtils::fromString(s,t);
|
||||
RewindManager::get()->rewindTo(t);
|
||||
Log::info("Rewind", "Rewinding from %f to %f",
|
||||
world->getTime(), t);
|
||||
RewindManager::get()->rewindTo(t, world->getTimeTicks());
|
||||
Log::info("Rewind", "Rewinding from %d to %d",
|
||||
world->getTimeTicks(), t);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -705,6 +712,31 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
|
||||
// when a device presses fire or rescue
|
||||
if (m_device_manager->getAssignMode() == DETECT_NEW)
|
||||
{
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
NetworkConfig::get()->isAddingNetworkPlayers())
|
||||
{
|
||||
// Ignore release event
|
||||
if (value == 0)
|
||||
return;
|
||||
InputDevice *device = NULL;
|
||||
if (type == Input::IT_KEYBOARD)
|
||||
{
|
||||
//Log::info("InputManager", "New Player Joining with Key %d", button);
|
||||
device = m_device_manager->getKeyboardFromBtnID(button);
|
||||
}
|
||||
else if (type == Input::IT_STICKBUTTON ||
|
||||
type == Input::IT_STICKMOTION )
|
||||
{
|
||||
device = m_device_manager->getGamePadFromIrrID(deviceID);
|
||||
}
|
||||
if (device && (action == PA_FIRE || action == PA_MENU_SELECT))
|
||||
{
|
||||
if (!GUIEngine::ModalDialog::isADialogActive())
|
||||
new SplitscreenPlayerDialog(device);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Player is unjoining
|
||||
if ((player != NULL) && (action == PA_RESCUE ||
|
||||
action == PA_MENU_CANCEL ) )
|
||||
@ -744,7 +776,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
|
||||
|
||||
if (device != NULL)
|
||||
{
|
||||
KartSelectionScreen::getRunningInstance()->joinPlayer(device);
|
||||
KartSelectionScreen::getRunningInstance()->joinPlayer(device, NULL/*player profile*/);
|
||||
}
|
||||
}
|
||||
return; // we're done here, ignore devices that aren't
|
||||
@ -1195,7 +1227,7 @@ EventPropagation InputManager::input(const SEvent& event)
|
||||
|
||||
float factor = UserConfigParams::m_multitouch_tilt_factor;
|
||||
factor = std::max(factor, 0.1f);
|
||||
device->updateAxisX(event.AccelerometerEvent.Y / factor);
|
||||
device->updateAxisX(float(event.AccelerometerEvent.Y) / factor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ void Attachment::set(AttachmentType type, int ticks,
|
||||
{
|
||||
BareNetworkString *buffer = new BareNetworkString(2);
|
||||
saveState(buffer);
|
||||
rwm->addEvent(this, buffer);
|
||||
rwm->addEvent(this, buffer, /*confirmed*/true);
|
||||
}
|
||||
#endif
|
||||
} // set
|
||||
@ -269,7 +269,13 @@ void Attachment::saveState(BareNetworkString *buffer) const
|
||||
void Attachment::rewindTo(BareNetworkString *buffer)
|
||||
{
|
||||
uint8_t type = buffer->getUInt8();
|
||||
|
||||
AttachmentType new_type = AttachmentType(type & 0x7f); // mask out bit 7
|
||||
// FIXME Sometimes type == 255 is returned, reason unknown
|
||||
if (new_type > ATTACH_NOTHING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is no attachment, clear the attachment if necessary and exit
|
||||
if(new_type==ATTACH_NOTHING)
|
||||
@ -360,8 +366,9 @@ void Attachment::hitBanana(Item *item, int new_attachment)
|
||||
// default time. This is necessary to avoid that a kart lands on the
|
||||
// same banana again once the explosion animation is finished, giving
|
||||
// the kart the same penalty twice.
|
||||
float f = std::max(item->getDisableTime(), kp->getExplosionDuration() + 2.0f);
|
||||
item->setDisableTime(f);
|
||||
int ticks = std::max(item->getDisableTicks(),
|
||||
stk_config->time2Ticks(kp->getExplosionDuration() + 2.0f));
|
||||
item->setDisableTicks(ticks);
|
||||
break;
|
||||
}
|
||||
case ATTACH_ANVIL:
|
||||
@ -484,7 +491,7 @@ void Attachment::handleCollisionWithKart(AbstractKart *other)
|
||||
} // handleCollisionWithKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Attachment::update(float dt)
|
||||
void Attachment::update(int ticks)
|
||||
{
|
||||
if(m_type==ATTACH_NOTHING) return;
|
||||
|
||||
@ -493,7 +500,7 @@ void Attachment::update(float dt)
|
||||
if (m_type == ATTACH_BOMB && m_kart->getKartAnimation() != NULL)
|
||||
return;
|
||||
|
||||
m_ticks_left--; // dt always physics time step
|
||||
m_ticks_left -= ticks;
|
||||
|
||||
|
||||
bool is_shield = m_type == ATTACH_BUBBLEGUM_SHIELD ||
|
||||
@ -516,6 +523,7 @@ void Attachment::update(float dt)
|
||||
m_node->setVisible((division & 0x1) == 0);
|
||||
}
|
||||
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
if (m_node_scale < m_wanted_node_scale)
|
||||
{
|
||||
m_node_scale += dt*1.5f;
|
||||
@ -527,7 +535,7 @@ void Attachment::update(float dt)
|
||||
|
||||
if(m_plugin)
|
||||
{
|
||||
bool discard = m_plugin->updateAndTestFinished(dt);
|
||||
bool discard = m_plugin->updateAndTestFinished(ticks);
|
||||
if(discard)
|
||||
{
|
||||
clear(); // also removes the plugin
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
~Attachment();
|
||||
void clear ();
|
||||
void hitBanana(Item *item, int new_attachment=-1);
|
||||
void update (float dt);
|
||||
void update(int ticks);
|
||||
void handleCollisionWithKart(AbstractKart *other);
|
||||
void set (AttachmentType type, int ticks,
|
||||
AbstractKart *previous_kart=NULL);
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Updates a plugin. This is called once each time frame. If the
|
||||
* function returns true, the attachment is discarded. */
|
||||
virtual bool updateAndTestFinished(float dt) = 0;
|
||||
virtual bool updateAndTestFinished(int ticks) = 0;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when the animation of the Attachment's node is done. */
|
||||
|
@ -76,7 +76,7 @@ Bowling::Bowling(AbstractKart *kart)
|
||||
getBody()->setCollisionFlags(flag);
|
||||
|
||||
// should not live forever, auto-destruct after 20 seconds
|
||||
m_max_lifespan = 20;
|
||||
m_max_lifespan = stk_config->time2Ticks(20);
|
||||
|
||||
m_roll_sfx = SFXManager::get()->createSoundSource("bowling_roll");
|
||||
m_roll_sfx->play();
|
||||
@ -118,9 +118,9 @@ void Bowling::init(const XMLNode &node, scene::IMesh *bowling)
|
||||
* \param dt Time step size.
|
||||
* \returns True of this object should be removed.
|
||||
*/
|
||||
bool Bowling::updateAndDelete(float dt)
|
||||
bool Bowling::updateAndDelete(int ticks)
|
||||
{
|
||||
bool can_be_deleted = Flyable::updateAndDelete(dt);
|
||||
bool can_be_deleted = Flyable::updateAndDelete(ticks);
|
||||
if(can_be_deleted)
|
||||
return true;
|
||||
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
Bowling(AbstractKart* kart);
|
||||
virtual ~Bowling();
|
||||
static void init(const XMLNode &node, scene::IMesh *bowling);
|
||||
virtual bool updateAndDelete(float dt);
|
||||
virtual bool updateAndDelete(int ticks);
|
||||
virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL);
|
||||
virtual HitEffect *getHitEffect() const;
|
||||
|
||||
|
@ -70,7 +70,7 @@ Flyable::Flyable(AbstractKart *kart, PowerupManager::PowerupType type,
|
||||
m_animation = NULL;
|
||||
m_mass = mass;
|
||||
m_adjust_up_velocity = true;
|
||||
m_time_since_thrown = 0;
|
||||
m_ticks_since_thrown = 0;
|
||||
m_position_offset = Vec3(0,0,0);
|
||||
m_owner_has_temporary_immunity = true;
|
||||
m_do_terrain_info = true;
|
||||
@ -371,23 +371,33 @@ void Flyable::setAnimation(AbstractKartAnimation *animation)
|
||||
m_animation = animation;
|
||||
} // addAnimation
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called once per rendered frame. It is used to only update any graphical
|
||||
* effects.
|
||||
* \param dt Time step size (since last call).
|
||||
*/
|
||||
void Flyable::updateGraphics(float dt)
|
||||
{
|
||||
Moveable::updateGraphics(dt, Vec3(0, 0, 0), btQuaternion(0, 0, 0, 1));
|
||||
} // updateGraphics
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates this flyable. It calls Moveable::update. If this function returns
|
||||
* true, the flyable will be deleted by the projectile manager.
|
||||
* \param dt Time step size.
|
||||
* \returns True if this object can be deleted.
|
||||
*/
|
||||
bool Flyable::updateAndDelete(float dt)
|
||||
bool Flyable::updateAndDelete(int ticks)
|
||||
{
|
||||
if (hasAnimation())
|
||||
{
|
||||
m_animation->update(dt);
|
||||
Moveable::update(dt);
|
||||
m_animation->update(stk_config->ticks2Time(ticks));
|
||||
Moveable::update(ticks);
|
||||
return false;
|
||||
} // if animation
|
||||
|
||||
m_time_since_thrown += dt;
|
||||
if(m_max_lifespan > -1 && m_time_since_thrown > m_max_lifespan)
|
||||
m_ticks_since_thrown += ticks;
|
||||
if(m_max_lifespan > -1 && m_ticks_since_thrown > m_max_lifespan)
|
||||
hit(NULL);
|
||||
|
||||
if(m_has_hit_something) return true;
|
||||
@ -465,7 +475,7 @@ bool Flyable::updateAndDelete(float dt)
|
||||
setVelocity(v);
|
||||
} // if m_adjust_up_velocity
|
||||
|
||||
Moveable::update(dt);
|
||||
Moveable::update(ticks);
|
||||
|
||||
return false;
|
||||
} // updateAndDelete
|
||||
@ -478,8 +488,8 @@ bool Flyable::updateAndDelete(float dt)
|
||||
bool Flyable::isOwnerImmunity(const AbstractKart* kart_hit) const
|
||||
{
|
||||
return m_owner_has_temporary_immunity &&
|
||||
kart_hit == m_owner &&
|
||||
m_time_since_thrown < 2.0f;
|
||||
kart_hit == m_owner &&
|
||||
m_ticks_since_thrown < stk_config->time2Ticks(2.0f);
|
||||
} // isOwnerImmunity
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -22,17 +22,18 @@
|
||||
#ifndef HEADER_FLYABLE_HPP
|
||||
#define HEADER_FLYABLE_HPP
|
||||
|
||||
#include "items/powerup_manager.hpp"
|
||||
#include "karts/moveable.hpp"
|
||||
#include "tracks/terrain_info.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
#include <irrString.h>
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class IMesh; }
|
||||
}
|
||||
#include <irrString.h>
|
||||
using namespace irr;
|
||||
|
||||
#include "items/powerup_manager.hpp"
|
||||
#include "karts/moveable.hpp"
|
||||
#include "tracks/terrain_info.hpp"
|
||||
|
||||
class AbstractKart;
|
||||
class AbstractKartAnimation;
|
||||
class HitEffect;
|
||||
@ -127,11 +128,11 @@ protected:
|
||||
|
||||
/** Time since thrown. used so a kart can't hit himself when trying
|
||||
* something, and also to put some time limit to some collectibles */
|
||||
float m_time_since_thrown;
|
||||
int m_ticks_since_thrown;
|
||||
|
||||
/** Set to something > -1 if this flyable should auto-destrcut after
|
||||
* a while. */
|
||||
float m_max_lifespan;
|
||||
* that may ticks. */
|
||||
int m_max_lifespan;
|
||||
|
||||
/** If set to true, the kart that throwns this flyable can't collide
|
||||
* with it for a short time. */
|
||||
@ -167,7 +168,8 @@ public:
|
||||
virtual ~Flyable ();
|
||||
static void init (const XMLNode &node, scene::IMesh *model,
|
||||
PowerupManager::PowerupType type);
|
||||
virtual bool updateAndDelete(float);
|
||||
void updateGraphics(float dt) OVERRIDE;
|
||||
virtual bool updateAndDelete(int ticks);
|
||||
virtual void setAnimation(AbstractKartAnimation *animation);
|
||||
virtual HitEffect* getHitEffect() const;
|
||||
bool isOwnerImmunity(const AbstractKart *kart_hit) const;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "modes/easter_egg_hunt.hpp"
|
||||
#include "modes/three_strikes_battle.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "tracks/arena_graph.hpp"
|
||||
#include "tracks/drive_graph.hpp"
|
||||
#include "tracks/drive_node.hpp"
|
||||
@ -117,8 +118,8 @@ void Item::initItem(ItemType type, const Vec3 &xyz)
|
||||
m_item_id = -1;
|
||||
m_collected = false;
|
||||
m_original_type = ITEM_NONE;
|
||||
m_deactive_time = 0;
|
||||
m_time_till_return = 0.0f; // not strictly necessary, see isCollected()
|
||||
m_deactive_ticks = 0;
|
||||
m_ticks_till_return = 0; // not strictly necessary, see isCollected()
|
||||
m_emitter = NULL;
|
||||
m_rotate = (type!=ITEM_BUBBLEGUM) && (type!=ITEM_TRIGGER);
|
||||
switch(m_type)
|
||||
@ -264,8 +265,8 @@ Item::~Item()
|
||||
void Item::reset()
|
||||
{
|
||||
m_collected = false;
|
||||
m_time_till_return = 0.0f;
|
||||
m_deactive_time = 0.0f;
|
||||
m_ticks_till_return = 0;
|
||||
m_deactive_ticks = 0;
|
||||
switch(m_type)
|
||||
{
|
||||
case ITEM_BUBBLEGUM:
|
||||
@ -295,24 +296,24 @@ void Item::reset()
|
||||
*/
|
||||
void Item::setParent(AbstractKart* parent)
|
||||
{
|
||||
m_event_handler = parent;
|
||||
m_emitter = parent;
|
||||
m_deactive_time = 1.5f;
|
||||
m_event_handler = parent;
|
||||
m_emitter = parent;
|
||||
m_deactive_ticks = stk_config->time2Ticks(1.5f);
|
||||
} // setParent
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updated the item - rotates it, takes care of items coming back into
|
||||
* the game after it has been collected.
|
||||
* \param dt Time step size.
|
||||
* \param ticks Number of physics time steps - should be 1.
|
||||
*/
|
||||
void Item::update(float dt)
|
||||
void Item::update(int ticks)
|
||||
{
|
||||
if(m_deactive_time > 0) m_deactive_time -= dt;
|
||||
if(m_deactive_ticks > 0) m_deactive_ticks -= ticks;
|
||||
|
||||
if(m_collected)
|
||||
{
|
||||
m_time_till_return -= dt;
|
||||
if(m_time_till_return<0)
|
||||
m_ticks_till_return -= ticks;
|
||||
if(m_ticks_till_return<0)
|
||||
{
|
||||
m_collected=false;
|
||||
|
||||
@ -321,13 +322,14 @@ void Item::update(float dt)
|
||||
m_node->setScale(core::vector3df(1,1,1));
|
||||
}
|
||||
} // time till return <0 --> is fully visible again
|
||||
else if ( m_time_till_return <=1.0f )
|
||||
else if ( m_ticks_till_return <= stk_config->time2Ticks(1.0f) )
|
||||
{
|
||||
if (m_node != NULL)
|
||||
{
|
||||
// Make it visible by scaling it from 0 to 1:
|
||||
m_node->setVisible(true);
|
||||
m_node->setScale(core::vector3df(1,1,1)*(1-m_time_till_return));
|
||||
float t = stk_config->ticks2Time(m_ticks_till_return);
|
||||
m_node->setScale(core::vector3df(1,1,1)*(1-t));
|
||||
}
|
||||
} // time till return < 1
|
||||
} // if collected
|
||||
@ -336,7 +338,11 @@ void Item::update(float dt)
|
||||
|
||||
if(!m_rotate || m_node == NULL) return;
|
||||
// have it rotate
|
||||
m_rotation_angle += dt * M_PI ;
|
||||
if (!RewindManager::get()->isRewinding())
|
||||
{
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
m_rotation_angle += dt * M_PI;
|
||||
}
|
||||
if (m_rotation_angle > M_PI * 2) m_rotation_angle -= M_PI * 2;
|
||||
|
||||
btMatrix3x3 m;
|
||||
@ -362,7 +368,7 @@ void Item::collected(const AbstractKart *kart, float t)
|
||||
m_event_handler = kart;
|
||||
if(m_type==ITEM_EASTER_EGG)
|
||||
{
|
||||
m_time_till_return=99999;
|
||||
m_ticks_till_return=stk_config->time2Ticks(99999);
|
||||
EasterEggHunt *world = dynamic_cast<EasterEggHunt*>(World::getWorld());
|
||||
assert(world);
|
||||
world->collectedEasterEgg(kart);
|
||||
@ -377,16 +383,16 @@ void Item::collected(const AbstractKart *kart, float t)
|
||||
// Deactivates the item for a certain amount of time. It is used to
|
||||
// prevent bubble gum from hitting a kart over and over again (in each
|
||||
// frame) by giving it time to drive away.
|
||||
m_deactive_time = 0.5f;
|
||||
m_deactive_ticks = stk_config->time2Ticks(0.5f);
|
||||
// Set the time till reappear to -1 seconds --> the item will
|
||||
// reappear immediately.
|
||||
m_time_till_return = -1;
|
||||
m_ticks_till_return = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note if the time is negative, in update the m_collected flag will
|
||||
// be automatically set to false again.
|
||||
m_time_till_return = t;
|
||||
m_ticks_till_return = stk_config->time2Ticks(t);
|
||||
if (m_node != NULL)
|
||||
{
|
||||
m_node->setVisible(false);
|
||||
@ -400,7 +406,7 @@ void Item::collected(const AbstractKart *kart, float t)
|
||||
|
||||
if (dynamic_cast<ThreeStrikesBattle*>(World::getWorld()) != NULL)
|
||||
{
|
||||
m_time_till_return *= 3;
|
||||
m_ticks_till_return *= 3;
|
||||
}
|
||||
} // isCollected
|
||||
|
||||
|
@ -111,7 +111,7 @@ private:
|
||||
bool m_collected;
|
||||
|
||||
/** Time till a collected item reappears. */
|
||||
float m_time_till_return;
|
||||
int m_ticks_till_return;
|
||||
|
||||
/** Scene node of this item. */
|
||||
LODNode *m_node;
|
||||
@ -131,7 +131,7 @@ private:
|
||||
bool m_rotate;
|
||||
|
||||
/** Optionally set this if this item was laid by a particular kart. in
|
||||
* this case the 'm_deactive_time' will also be set - see below. */
|
||||
* this case the 'm_deactive_ticks' will also be set - see below. */
|
||||
const AbstractKart *m_event_handler;
|
||||
|
||||
/** Kart that emitted this item if any */
|
||||
@ -139,7 +139,7 @@ private:
|
||||
|
||||
/** Optionally if item was placed by a kart, a timer can be used to
|
||||
* temporarly deactivate collision so a kart is not hit by its own item */
|
||||
float m_deactive_time;
|
||||
int m_deactive_ticks;
|
||||
|
||||
/** Counts how often an item is used before it disappears. Used for
|
||||
* bubble gum to make them disappear after a while. A value >0
|
||||
@ -176,7 +176,7 @@ public:
|
||||
Item(const Vec3& xyz, float distance,
|
||||
TriggerItemListener* trigger);
|
||||
virtual ~Item ();
|
||||
void update (float delta);
|
||||
void update(int ticks);
|
||||
virtual void collected(const AbstractKart *kart, float t=2.0f);
|
||||
void setParent(AbstractKart* parent);
|
||||
void reset();
|
||||
@ -195,7 +195,7 @@ public:
|
||||
*/
|
||||
bool hitKart(const Vec3 &xyz, const AbstractKart *kart=NULL) const
|
||||
{
|
||||
if (m_event_handler == kart && m_deactive_time > 0)
|
||||
if (m_event_handler == kart && m_deactive_ticks > 0)
|
||||
return false;
|
||||
Vec3 lc = quatRotate(m_original_rotation, xyz - m_xyz);
|
||||
// Don't be too strict if the kart is a bit above the item
|
||||
@ -216,7 +216,7 @@ protected:
|
||||
bool hitLine(const core::line3df &line,
|
||||
const AbstractKart *kart=NULL) const
|
||||
{
|
||||
if(m_event_handler==kart && m_deactive_time >0) return false;
|
||||
if(m_event_handler==kart && m_deactive_ticks >0) return false;
|
||||
|
||||
Vec3 closest = line.getClosestPoint(m_xyz.toIrrVector());
|
||||
return hitKart(closest, kart);
|
||||
@ -251,10 +251,10 @@ public:
|
||||
* details.
|
||||
* \param f Time till the item can be used again.
|
||||
*/
|
||||
void setDisableTime(float f) { m_time_till_return = f; }
|
||||
void setDisableTicks(int t) { m_ticks_till_return = t; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time the item is disabled for. */
|
||||
float getDisableTime() const { return m_time_till_return; }
|
||||
int getDisableTicks() const { return m_ticks_till_return; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the XYZ position of the item. */
|
||||
const Vec3& getXYZ() const { return m_xyz; }
|
||||
|
@ -156,7 +156,7 @@ void ItemManager::removeTextures()
|
||||
* of each race. */
|
||||
ItemManager::ItemManager()
|
||||
{
|
||||
m_switch_time = -1.0f;
|
||||
m_switch_ticks = -1;
|
||||
// The actual loading is done in loadDefaultItems
|
||||
|
||||
// Prepare the switch to array, which stores which item should be
|
||||
@ -266,7 +266,7 @@ Item* ItemManager::newItem(Item::ItemType type, const Vec3& xyz,
|
||||
|
||||
insertItem(item);
|
||||
if(parent != NULL) item->setParent(parent);
|
||||
if(m_switch_time>=0)
|
||||
if(m_switch_ticks>=0)
|
||||
{
|
||||
Item::ItemType new_type = m_switch_to[item->getType()];
|
||||
item->switchTo(new_type, m_item_mesh[(int)new_type],
|
||||
@ -333,7 +333,7 @@ void ItemManager::checkItemHit(AbstractKart* kart)
|
||||
if((*i)->hitKart(kart->getXYZ(), kart))
|
||||
{
|
||||
// if we're not playing online, pick the item.
|
||||
if (!RaceEventManager::getInstance()->isRunning())
|
||||
if (!NetworkConfig::get()->isNetworking())
|
||||
collectedItem(*i, kart);
|
||||
else if (NetworkConfig::get()->isServer())
|
||||
{
|
||||
@ -354,14 +354,14 @@ void ItemManager::checkItemHit(AbstractKart* kart)
|
||||
void ItemManager::reset()
|
||||
{
|
||||
// If items are switched, switch them back first.
|
||||
if(m_switch_time>=0)
|
||||
if(m_switch_ticks>=0)
|
||||
{
|
||||
for(AllItemTypes::iterator i =m_all_items.begin();
|
||||
i!=m_all_items.end(); i++)
|
||||
{
|
||||
if(*i) (*i)->switchBack();
|
||||
}
|
||||
m_switch_time = -1.0f;
|
||||
m_switch_ticks = -1;
|
||||
|
||||
}
|
||||
|
||||
@ -388,36 +388,36 @@ void ItemManager::reset()
|
||||
}
|
||||
} // whilem_all_items.end() i
|
||||
|
||||
m_switch_time = -1;
|
||||
m_switch_ticks = -1;
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates all items, and handles switching items back if the switch time
|
||||
* is over.
|
||||
* \param dt Time step.
|
||||
* \param ticks Number of physics time steps - should be 1.
|
||||
*/
|
||||
void ItemManager::update(float dt)
|
||||
void ItemManager::update(int ticks)
|
||||
{
|
||||
// If switch time is over, switch all items back
|
||||
if(m_switch_time>=0)
|
||||
if(m_switch_ticks>=0)
|
||||
{
|
||||
m_switch_time -= dt;
|
||||
if(m_switch_time<0)
|
||||
m_switch_ticks -= ticks;
|
||||
if(m_switch_ticks<0)
|
||||
{
|
||||
for(AllItemTypes::iterator i =m_all_items.begin();
|
||||
i!=m_all_items.end(); i++)
|
||||
{
|
||||
if(*i) (*i)->switchBack();
|
||||
} // for m_all_items
|
||||
} // m_switch_time < 0
|
||||
} // m_switch_time>=0
|
||||
} // m_switch_ticks < 0
|
||||
} // m_switch_ticks>=0
|
||||
|
||||
for(AllItemTypes::iterator i =m_all_items.begin();
|
||||
i!=m_all_items.end(); i++)
|
||||
{
|
||||
if(*i)
|
||||
{
|
||||
(*i)->update(dt);
|
||||
(*i)->update(ticks);
|
||||
if( (*i)->isUsedUp())
|
||||
{
|
||||
deleteItem( *i );
|
||||
@ -472,16 +472,16 @@ void ItemManager::switchItems()
|
||||
|
||||
Item::ItemType new_type = m_switch_to[(*i)->getType()];
|
||||
|
||||
if(m_switch_time<0)
|
||||
if(m_switch_ticks<0)
|
||||
(*i)->switchTo(new_type, m_item_mesh[(int)new_type], m_item_lowres_mesh[(int)new_type]);
|
||||
else
|
||||
(*i)->switchBack();
|
||||
} // for m_all_items
|
||||
|
||||
// if the items are already switched (m_switch_time >=0)
|
||||
// then switch back, and set m_switch_time to -1 to indicate
|
||||
// if the items are already switched (m_switch_ticks >=0)
|
||||
// then switch back, and set m_switch_ticks to -1 to indicate
|
||||
// that the items are now back to normal.
|
||||
m_switch_time = m_switch_time < 0 ? stk_config->m_item_switch_time : -1;
|
||||
m_switch_ticks = m_switch_ticks < 0 ? stk_config->m_item_switch_ticks : -1;
|
||||
|
||||
} // switchItems
|
||||
|
||||
|
@ -90,7 +90,7 @@ private:
|
||||
|
||||
/** Remaining time that items should remain switched. If the
|
||||
* value is <0, it indicates that the items are not switched atm. */
|
||||
float m_switch_time;
|
||||
int m_switch_ticks;
|
||||
|
||||
void insertItem(Item *item);
|
||||
void deleteItem(Item *item);
|
||||
@ -106,7 +106,7 @@ public:
|
||||
AbstractKart* parent=NULL);
|
||||
Item* newItem (const Vec3& xyz, float distance,
|
||||
TriggerItemListener* listener);
|
||||
void update (float delta);
|
||||
void update (int ticks);
|
||||
void checkItemHit (AbstractKart* kart);
|
||||
void reset ();
|
||||
void collectedItem (Item *item, AbstractKart *kart,
|
||||
|
@ -122,24 +122,24 @@ void Plunger::init(const XMLNode &node, scene::IMesh *plunger_model)
|
||||
* \param dt Time step size.
|
||||
* \returns True of this object should be removed.
|
||||
*/
|
||||
bool Plunger::updateAndDelete(float dt)
|
||||
bool Plunger::updateAndDelete(int ticks)
|
||||
{
|
||||
// In keep-alive mode, just update the rubber band
|
||||
if(m_keep_alive >= 0)
|
||||
{
|
||||
m_keep_alive -= dt;
|
||||
m_keep_alive -= ticks;
|
||||
if(m_keep_alive<=0)
|
||||
{
|
||||
setHasHit();
|
||||
return true;
|
||||
}
|
||||
if(m_rubber_band != NULL) m_rubber_band->update(dt);
|
||||
if(m_rubber_band != NULL) m_rubber_band->update(ticks);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Else: update the flyable and rubber band
|
||||
bool ret = Flyable::updateAndDelete(dt);
|
||||
if(m_rubber_band != NULL) m_rubber_band->update(dt);
|
||||
bool ret = Flyable::updateAndDelete(ticks);
|
||||
if(m_rubber_band != NULL) m_rubber_band->update(ticks);
|
||||
|
||||
return ret;
|
||||
|
||||
@ -179,11 +179,12 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keep_alive = m_owner->getKartProperties()->getPlungerBandDuration();
|
||||
m_keep_alive = stk_config->time2Ticks(m_owner->getKartProperties()
|
||||
->getPlungerBandDuration() );
|
||||
|
||||
// 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
|
||||
// because the ref count reaches zero.
|
||||
// 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 because the ref count reaches zero.
|
||||
scene::ISceneNode *node = getNode();
|
||||
if(node)
|
||||
{
|
||||
|
@ -40,8 +40,10 @@ class Plunger : public Flyable
|
||||
private:
|
||||
/** The rubber band attached to a plunger. */
|
||||
RubberBand *m_rubber_band;
|
||||
/** Timer to keep the plunger alive while the rubber band is working. */
|
||||
float m_keep_alive;
|
||||
|
||||
/** Ticks to keep the plunger alive while the rubber band is working. */
|
||||
int m_keep_alive;
|
||||
|
||||
btVector3 m_initial_velocity;
|
||||
|
||||
bool m_reverse_mode;
|
||||
@ -49,7 +51,7 @@ public:
|
||||
Plunger(AbstractKart *kart);
|
||||
~Plunger();
|
||||
static void init(const XMLNode &node, scene::IMesh* missile);
|
||||
virtual bool updateAndDelete(float dt);
|
||||
virtual bool updateAndDelete(int ticks);
|
||||
virtual void hitTrack ();
|
||||
virtual bool hit (AbstractKart *kart, PhysicalObject *obj=NULL);
|
||||
|
||||
@ -57,7 +59,7 @@ public:
|
||||
/** Sets the keep-alive value. Setting it to 0 will remove the plunger
|
||||
* at the next update - which is used if the rubber band snaps.
|
||||
*/
|
||||
void setKeepAlive(float t) {m_keep_alive = t;}
|
||||
void setKeepAlive(int ticks) {m_keep_alive = ticks;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** No hit effect when it ends. */
|
||||
virtual HitEffect *getHitEffect() const {return NULL; }
|
||||
|
@ -62,10 +62,25 @@ void ProjectileManager::cleanup()
|
||||
} // cleanup
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** General projectile update call. */
|
||||
void ProjectileManager::update(float dt)
|
||||
/** Called once per rendered frame. It is used to only update any graphical
|
||||
* effects, and calls updateGraphics in any flyable objects.
|
||||
* \param dt Time step size (since last call).
|
||||
*/
|
||||
void ProjectileManager::updateGraphics(float dt)
|
||||
{
|
||||
updateServer(dt);
|
||||
for (auto p = m_active_projectiles.begin();
|
||||
p != m_active_projectiles.end(); ++p)
|
||||
{
|
||||
(*p)->updateGraphics(dt);
|
||||
}
|
||||
|
||||
} // updateGraphics
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** General projectile update call. */
|
||||
void ProjectileManager::update(int ticks)
|
||||
{
|
||||
updateServer(ticks);
|
||||
|
||||
HitEffects::iterator he = m_active_hit_effects.begin();
|
||||
while(he!=m_active_hit_effects.end())
|
||||
@ -77,7 +92,7 @@ void ProjectileManager::update(float dt)
|
||||
he = next;
|
||||
}
|
||||
// Update this hit effect. If it can be removed, remove it.
|
||||
else if((*he)->updateAndDelete(dt))
|
||||
else if((*he)->updateAndDelete(ticks))
|
||||
{
|
||||
delete *he;
|
||||
HitEffects::iterator next = m_active_hit_effects.erase(he);
|
||||
@ -90,12 +105,12 @@ void ProjectileManager::update(float dt)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Updates all rockets on the server (or no networking). */
|
||||
void ProjectileManager::updateServer(float dt)
|
||||
void ProjectileManager::updateServer(int ticks)
|
||||
{
|
||||
Projectiles::iterator p = m_active_projectiles.begin();
|
||||
while(p!=m_active_projectiles.end())
|
||||
{
|
||||
bool can_be_deleted = (*p)->updateAndDelete(dt);
|
||||
bool can_be_deleted = (*p)->updateAndDelete(ticks);
|
||||
if(can_be_deleted)
|
||||
{
|
||||
HitEffect *he = (*p)->getHitEffect();
|
||||
|
@ -52,13 +52,14 @@ private:
|
||||
* being shown or have a sfx playing. */
|
||||
HitEffects m_active_hit_effects;
|
||||
|
||||
void updateServer(float dt);
|
||||
void updateServer(int ticks);
|
||||
public:
|
||||
ProjectileManager() {}
|
||||
~ProjectileManager() {}
|
||||
void loadData ();
|
||||
void cleanup ();
|
||||
void update (float dt);
|
||||
void update (int ticks);
|
||||
void updateGraphics (float dt);
|
||||
Flyable* newProjectile (AbstractKart *kart,
|
||||
PowerupManager::PowerupType type);
|
||||
void Deactivate (Flyable *p) {}
|
||||
|
@ -42,7 +42,7 @@ float RubberBall::m_st_squash_duration;
|
||||
float RubberBall::m_st_squash_slowdown;
|
||||
float RubberBall::m_st_target_distance;
|
||||
float RubberBall::m_st_target_max_angle;
|
||||
float RubberBall::m_st_delete_time;
|
||||
int RubberBall::m_st_delete_ticks;
|
||||
float RubberBall::m_st_max_height_difference;
|
||||
float RubberBall::m_st_fast_ping_distance;
|
||||
float RubberBall::m_st_early_target_factor;
|
||||
@ -75,7 +75,7 @@ RubberBall::RubberBall(AbstractKart *kart)
|
||||
|
||||
// Do not adjust the up velocity
|
||||
setAdjustUpVelocity(false);
|
||||
m_max_lifespan = 9999;
|
||||
m_max_lifespan = stk_config->time2Ticks(9999);
|
||||
m_target = NULL;
|
||||
m_aiming_at_target = false;
|
||||
m_fast_ping = false;
|
||||
@ -89,7 +89,7 @@ RubberBall::RubberBall(AbstractKart *kart)
|
||||
m_previous_xyz = m_owner->getXYZ();
|
||||
m_previous_height = 2.0f; //
|
||||
// A negative value indicates that the timer is not active
|
||||
m_delete_timer = -1.0f;
|
||||
m_delete_ticks = -1;
|
||||
m_tunnel_count = 0;
|
||||
|
||||
LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
@ -173,13 +173,13 @@ void RubberBall::computeTarget()
|
||||
{
|
||||
// If the firing kart itself is the first kart (that is
|
||||
// still driving), prepare to remove the rubber ball
|
||||
if(m_target==m_owner && m_delete_timer < 0)
|
||||
if(m_target==m_owner && m_delete_ticks < 0)
|
||||
{
|
||||
#ifdef PRINT_BALL_REMOVE_INFO
|
||||
Log::debug("[RubberBall]",
|
||||
"ball %d removed because owner is target.", m_id);
|
||||
#endif
|
||||
m_delete_timer = m_st_delete_time;
|
||||
m_delete_ticks = m_st_delete_ticks;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -192,7 +192,7 @@ void RubberBall::computeTarget()
|
||||
Log::debug("[RubberBall]" "ball %d removed because no more active target.",
|
||||
m_id);
|
||||
#endif
|
||||
m_delete_timer = m_st_delete_time;
|
||||
m_delete_ticks = m_st_delete_ticks;
|
||||
m_target = m_owner;
|
||||
} // computeTarget
|
||||
|
||||
@ -268,7 +268,7 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
||||
m_st_min_interpolation_distance = 30.0f;
|
||||
m_st_target_distance = 50.0f;
|
||||
m_st_target_max_angle = 25.0f;
|
||||
m_st_delete_time = 10.0f;
|
||||
m_st_delete_ticks = stk_config->time2Ticks(10.0f);
|
||||
m_st_max_height_difference = 10.0f;
|
||||
m_st_fast_ping_distance = 50.0f;
|
||||
m_st_early_target_factor = 1.0f;
|
||||
@ -288,8 +288,10 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
||||
if(!node.get("target-distance", &m_st_target_distance))
|
||||
Log::warn("powerup",
|
||||
"No target-distance specified for rubber ball.");
|
||||
if(!node.get("delete-time", &m_st_delete_time))
|
||||
float f;
|
||||
if(!node.get("delete-time", &f))
|
||||
Log::warn("powerup", "No delete-time specified for rubber ball.");
|
||||
m_st_delete_ticks = stk_config->time2Ticks(f);
|
||||
if(!node.get("target-max-angle", &m_st_target_max_angle))
|
||||
Log::warn("powerup", "No target-max-angle specified for rubber ball.");
|
||||
m_st_target_max_angle *= DEGREE_TO_RAD;
|
||||
@ -318,17 +320,17 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
||||
* \param dt Time step size.
|
||||
* \returns True if the rubber ball should be removed.
|
||||
*/
|
||||
bool RubberBall::updateAndDelete(float dt)
|
||||
bool RubberBall::updateAndDelete(int ticks)
|
||||
{
|
||||
LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
// FIXME: what does the rubber ball do in case of battle mode??
|
||||
if(!world) return true;
|
||||
|
||||
|
||||
if(m_delete_timer>0)
|
||||
if(m_delete_ticks>0)
|
||||
{
|
||||
m_delete_timer -= dt;
|
||||
if(m_delete_timer<=0)
|
||||
m_delete_ticks -= 1;
|
||||
if(m_delete_ticks<=0)
|
||||
{
|
||||
hit(NULL);
|
||||
#ifdef PRINT_BALL_REMOVE_INFO
|
||||
@ -343,7 +345,7 @@ bool RubberBall::updateAndDelete(float dt)
|
||||
// Flyable will call update() of the animation to
|
||||
// update the ball's position.
|
||||
m_previous_xyz = getXYZ();
|
||||
return Flyable::updateAndDelete(dt);
|
||||
return Flyable::updateAndDelete(ticks);
|
||||
}
|
||||
|
||||
// Update the target in case that the first kart was overtaken (or has
|
||||
@ -355,9 +357,9 @@ bool RubberBall::updateAndDelete(float dt)
|
||||
// since it still needs to be adjusted for the height of the terrain.
|
||||
Vec3 next_xyz;
|
||||
if(m_aiming_at_target)
|
||||
moveTowardsTarget(&next_xyz, dt);
|
||||
moveTowardsTarget(&next_xyz, ticks);
|
||||
else
|
||||
interpolate(&next_xyz, dt);
|
||||
interpolate(&next_xyz, ticks);
|
||||
|
||||
// If the ball is close to the ground, we have to start the raycast
|
||||
// slightly higher (to avoid that the ball tunnels through the floor).
|
||||
@ -374,7 +376,7 @@ bool RubberBall::updateAndDelete(float dt)
|
||||
// Flyable::update for rubber balls.
|
||||
TerrainInfo::update(next_xyz + getNormal()*vertical_offset, -getNormal());
|
||||
|
||||
m_height_timer += dt;
|
||||
m_height_timer += stk_config->ticks2Time(ticks);
|
||||
float height = updateHeight()+m_extend.getY()*0.5f;
|
||||
|
||||
if(UserConfigParams::logFlyable())
|
||||
@ -426,7 +428,7 @@ bool RubberBall::updateAndDelete(float dt)
|
||||
// Determine new distance along track
|
||||
TrackSector::update(next_xyz);
|
||||
|
||||
return Flyable::updateAndDelete(dt);
|
||||
return Flyable::updateAndDelete(ticks);
|
||||
} // updateAndDelete
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -434,9 +436,9 @@ bool RubberBall::updateAndDelete(float dt)
|
||||
* once the rubber ball is close to its target. It restricts the angle by
|
||||
* which the rubber ball can change its direction per frame.
|
||||
* \param next_xyz The position the ball should move to.
|
||||
* \param dt Time step size.
|
||||
* \param ticks Number of physics steps - should be 1.
|
||||
*/
|
||||
void RubberBall::moveTowardsTarget(Vec3 *next_xyz, float dt)
|
||||
void RubberBall::moveTowardsTarget(Vec3 *next_xyz, int ticks)
|
||||
{
|
||||
// If the rubber ball is already close to a target, i.e. aiming
|
||||
// at it directly, stop interpolating, instead fly straight
|
||||
@ -447,7 +449,11 @@ void RubberBall::moveTowardsTarget(Vec3 *next_xyz, float dt)
|
||||
if(diff.length2()==0)
|
||||
*next_xyz = getXYZ() - getNormal()*m_previous_height;
|
||||
else
|
||||
*next_xyz = getXYZ() - getNormal()*m_previous_height +(dt*m_speed / diff.length())*diff;
|
||||
{
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
*next_xyz = getXYZ() - getNormal()*m_previous_height
|
||||
+ (dt*m_speed / diff.length())*diff;
|
||||
}
|
||||
|
||||
// If ball is close to the target, then explode
|
||||
if (diff.length() < m_target->getKartLength())
|
||||
@ -467,10 +473,11 @@ void RubberBall::moveTowardsTarget(Vec3 *next_xyz, float dt)
|
||||
* \param next_xyz Returns the new position.
|
||||
* \param The time step size.
|
||||
*/
|
||||
void RubberBall::interpolate(Vec3 *next_xyz, float dt)
|
||||
void RubberBall::interpolate(Vec3 *next_xyz, int ticks)
|
||||
{
|
||||
// If we have reached or overshot the next control point, move to the
|
||||
// the next section of the spline
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
m_t += m_t_increase * dt;
|
||||
if(m_t > 1.0f)
|
||||
{
|
||||
@ -673,7 +680,7 @@ void RubberBall::updateDistanceToTarget()
|
||||
// original target, and start deleting it.
|
||||
if(m_distance_to_target > 0.9f * Track::getCurrentTrack()->getTrackLength())
|
||||
{
|
||||
m_delete_timer = m_st_delete_time;
|
||||
m_delete_ticks = m_st_delete_ticks;
|
||||
#ifdef PRINT_BALL_REMOVE_INFO
|
||||
Log::debug("[RubberBall]", "ball %d lost target (overtook?).",
|
||||
m_id);
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "items/flyable.hpp"
|
||||
#include "tracks/track_sector.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
class AbstractKart;
|
||||
class SFXBase;
|
||||
@ -79,7 +80,7 @@ private:
|
||||
/** If the ball overtakes its target or starts to aim at the kart which
|
||||
* originally shot the rubber ball, after this amount of time the
|
||||
* ball will be deleted. */
|
||||
static float m_st_delete_time;
|
||||
static int m_st_delete_ticks;
|
||||
|
||||
/** Timer before another rubber ball can be picked up. This is to ensure
|
||||
* that there are not too many rubber balls on the track in races with many
|
||||
@ -166,7 +167,7 @@ private:
|
||||
* originally shot the rubber ball, after a certain amount of time the
|
||||
* ball will be deleted. This timer tracks this time. If it is < 0
|
||||
* it indicates that the ball is targeting another kart atm. */
|
||||
float m_delete_timer;
|
||||
int m_delete_ticks;
|
||||
|
||||
/** The current maximum height of the ball. This value will be
|
||||
* reduced if the ball gets closer to the target. */
|
||||
@ -192,8 +193,8 @@ private:
|
||||
float *f=NULL);
|
||||
void getNextControlPoint();
|
||||
float updateHeight();
|
||||
void interpolate(Vec3 *next_xyz, float dt);
|
||||
void moveTowardsTarget(Vec3 *next_xyz, float dt);
|
||||
void interpolate(Vec3 *next_xyz, int ticks);
|
||||
void moveTowardsTarget(Vec3 *next_xyz, int ticks);
|
||||
void initializeControlPoints(const Vec3 &xyz);
|
||||
float getTunnelHeight(const Vec3 &next_xyz,
|
||||
const float vertical_offset) const;
|
||||
@ -202,7 +203,7 @@ public:
|
||||
RubberBall (AbstractKart* kart);
|
||||
virtual ~RubberBall();
|
||||
static void init(const XMLNode &node, scene::IMesh *rubberball);
|
||||
virtual bool updateAndDelete(float dt);
|
||||
virtual bool updateAndDelete(int ticks) OVERRIDE;
|
||||
virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL);
|
||||
virtual void setAnimation(AbstractKartAnimation *animation);
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -146,7 +146,7 @@ void RubberBand::updatePosition()
|
||||
* so, an explosion is triggered.
|
||||
* \param dt: Time step size.
|
||||
*/
|
||||
void RubberBand::update(float dt)
|
||||
void RubberBand::update(int ticks)
|
||||
{
|
||||
const KartProperties *kp = m_owner->getKartProperties();
|
||||
|
||||
@ -155,7 +155,7 @@ void RubberBand::update(float dt)
|
||||
// Rubber band snaps
|
||||
m_plunger->hit(NULL);
|
||||
// This causes the plunger to be removed at the next update
|
||||
m_plunger->setKeepAlive(0.0f);
|
||||
m_plunger->setKeepAlive(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ void RubberBand::update(float dt)
|
||||
// Rubber band snaps
|
||||
m_plunger->hit(NULL);
|
||||
// This causes the plunger to be removed at the next update
|
||||
m_plunger->setKeepAlive(0.0f);
|
||||
m_plunger->setKeepAlive(0);
|
||||
}
|
||||
|
||||
// Apply forces (if applicable)
|
||||
@ -187,7 +187,7 @@ void RubberBand::update(float dt)
|
||||
// Rubber band snaps
|
||||
m_plunger->hit(NULL);
|
||||
// This causes the plunger to be removed at the next update
|
||||
m_plunger->setKeepAlive(0.0f);
|
||||
m_plunger->setKeepAlive(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -196,8 +196,8 @@ void RubberBand::update(float dt)
|
||||
m_owner->increaseMaxSpeed(MaxSpeed::MS_INCREASE_RUBBER,
|
||||
kp->getPlungerBandSpeedIncrease(),
|
||||
/*engine_force*/ 0.0f,
|
||||
/*duration*/0.1f,
|
||||
kp->getPlungerBandFadeOutTime());
|
||||
/*duration*/stk_config->time2Ticks(0.1f),
|
||||
kp->getPlungerBandFadeOutTicks());
|
||||
if(m_attached_state==RB_TO_KART)
|
||||
m_hit_kart->getBody()->applyCentralForce(diff*(-force));
|
||||
}
|
||||
@ -260,7 +260,7 @@ void RubberBand::hit(AbstractKart *kart_hit, const Vec3 *track_xyz)
|
||||
if(kart_hit->isShielded())
|
||||
{
|
||||
kart_hit->decreaseShieldTime();
|
||||
m_plunger->setKeepAlive(0.0f);
|
||||
m_plunger->setKeepAlive(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ private:
|
||||
public:
|
||||
RubberBand(Plunger *plunger, AbstractKart *kart);
|
||||
~RubberBand();
|
||||
void update(float dt);
|
||||
void update(int ticks);
|
||||
void hit(AbstractKart *kart_hit, const Vec3 *track_xyz=NULL);
|
||||
}; // RubberBand
|
||||
#endif
|
||||
|
@ -114,8 +114,9 @@ Swatter::~Swatter()
|
||||
* \param dt Time step size.
|
||||
* \return True if the attachment should be discarded.
|
||||
*/
|
||||
bool Swatter::updateAndTestFinished(float dt)
|
||||
bool Swatter::updateAndTestFinished(int ticks)
|
||||
{
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
if (!m_discard_now)
|
||||
{
|
||||
if (m_removing_bomb)
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "config/stk_config.hpp"
|
||||
#include "items/attachment_plugin.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
@ -79,7 +80,7 @@ public:
|
||||
Swatter(AbstractKart *kart, bool was_bomb,
|
||||
scene::ISceneNode* bomb_scene_node);
|
||||
virtual ~Swatter();
|
||||
bool updateAndTestFinished(float dt);
|
||||
bool updateAndTestFinished(int ticks) OVERRIDE;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the swatter is currently aiming, i.e. can be used to
|
||||
|
@ -253,7 +253,7 @@ public:
|
||||
virtual float getFinishTime() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the kart has a plunger attached to its face. */
|
||||
virtual float getBlockedByPlungerTime() const = 0;
|
||||
virtual int getBlockedByPlungerTicks() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets that the view is blocked by a plunger. The duration depends on
|
||||
* the difficulty, see KartPorperties getPlungerInFaceTime. */
|
||||
@ -282,10 +282,9 @@ public:
|
||||
virtual float getCurrentMaxSpeed() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how much increased speed time is left over in the given
|
||||
* category. Not pure abstract, since there is no need to implement this
|
||||
* e.g. in Ghost.
|
||||
* category.
|
||||
* \param category Which category to report on. */
|
||||
virtual float getSpeedIncreaseTimeLeft(unsigned int category) const = 0;
|
||||
virtual int getSpeedIncreaseTicksLeft(unsigned int category) const = 0;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the kart AI boost state.
|
||||
@ -333,7 +332,7 @@ public:
|
||||
* \param max_speed_fraction Fraction of top speed to allow only.
|
||||
* \param fade_in_time How long till maximum speed is capped. */
|
||||
virtual void setSlowdown(unsigned int category, float max_speed_fraction,
|
||||
float fade_in_time) = 0;
|
||||
int fade_in_time) = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the remaining collected energy. */
|
||||
virtual float getEnergy() const = 0;
|
||||
@ -394,7 +393,7 @@ public:
|
||||
/** Return whether nitro is being used despite the nitro button not being
|
||||
* pressed due to minimal use time requirements
|
||||
*/
|
||||
virtual float isOnMinNitroTime() const = 0;
|
||||
virtual bool isOnMinNitroTime() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current material the kart is on. */
|
||||
virtual const Material *getMaterial() const = 0;
|
||||
@ -445,7 +444,7 @@ public:
|
||||
/** Returns if the kart is invulnerable. */
|
||||
virtual bool isInvulnerable() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void setInvulnerableTime(float t) = 0;
|
||||
virtual void setInvulnerableTicks(int ticks) = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the kart is protected by a shield. */
|
||||
virtual bool isShielded() const = 0;
|
||||
@ -496,10 +495,6 @@ public:
|
||||
/** Set a text that is displayed on top of a kart.
|
||||
*/
|
||||
virtual void setOnScreenText(const wchar_t *text) = 0;
|
||||
// -------------------------------------------------------------------------
|
||||
/** Counter which is used for displaying wrong way message after a delay */
|
||||
virtual float getWrongwayCounter() = 0;
|
||||
virtual void setWrongwayCounter(float counter) = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns whether this kart wins or loses. */
|
||||
virtual bool getRaceResult() const = 0;
|
||||
|
@ -53,7 +53,7 @@ void AIBaseController::reset()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AIBaseController::update(float dt)
|
||||
void AIBaseController::update(int ticks)
|
||||
{
|
||||
m_stuck = false;
|
||||
}
|
||||
@ -193,7 +193,7 @@ void AIBaseController::setSteering(float angle, float dt)
|
||||
if (steer_fraction > 1.0f) steer_fraction = 1.0f;
|
||||
else if(steer_fraction < -1.0f) steer_fraction = -1.0f;
|
||||
|
||||
if(m_kart->getBlockedByPlungerTime()>0)
|
||||
if(m_kart->getBlockedByPlungerTicks()>0)
|
||||
{
|
||||
if (steer_fraction > 0.5f) steer_fraction = 0.5f;
|
||||
else if(steer_fraction < -0.5f) steer_fraction = -0.5f;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define HEADER_AI_BASE_CONTROLLER_HPP
|
||||
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
class AIProperties;
|
||||
class Track;
|
||||
@ -71,9 +72,10 @@ protected:
|
||||
/** This can be called to detect if the kart is stuck (i.e. repeatedly
|
||||
* hitting part of the track). */
|
||||
bool isStuck() const { return m_stuck; }
|
||||
// ------------------------------------------------------------------------
|
||||
void determineTurnRadius(const Vec3 &end, Vec3 *center,
|
||||
float *radius) const;
|
||||
virtual void update (float delta);
|
||||
virtual void update(int ticks);
|
||||
virtual void setSteering (float angle, float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return true if AI can skid now. */
|
||||
@ -83,21 +85,28 @@ public:
|
||||
AIBaseController(AbstractKart *kart);
|
||||
virtual ~AIBaseController() {};
|
||||
virtual void reset();
|
||||
virtual bool disableSlipstreamBonus() const;
|
||||
virtual void crashed(const Material *m);
|
||||
virtual bool disableSlipstreamBonus() const OVERRIDE;
|
||||
virtual void crashed(const Material *m) OVERRIDE;
|
||||
static void enableDebug() {m_ai_debug = true; }
|
||||
static void setTestAI(int n) {m_test_ai = n; }
|
||||
static int getTestAI() { return m_test_ai; }
|
||||
virtual void crashed(const AbstractKart *k) {};
|
||||
virtual void handleZipper(bool play_sound) {};
|
||||
virtual void finishedRace(float time) {};
|
||||
virtual void crashed(const AbstractKart *k) OVERRIDE {};
|
||||
virtual void handleZipper(bool play_sound) OVERRIDE {};
|
||||
virtual void finishedRace(float time) OVERRIDE {};
|
||||
virtual void collectedItem(const Item &item, int add_info=-1,
|
||||
float previous_energy=0) {};
|
||||
virtual void setPosition(int p) {};
|
||||
virtual bool isPlayerController() const { return false; }
|
||||
virtual bool isLocalPlayerController() const { return false; }
|
||||
virtual void action(PlayerAction action, int value) {};
|
||||
float previous_energy=0) OVERRIDE {};
|
||||
virtual void setPosition(int p) OVERRIDE {};
|
||||
virtual bool isPlayerController() const OVERRIDE { return false; }
|
||||
virtual bool isLocalPlayerController() const OVERRIDE { return false; }
|
||||
virtual bool action(PlayerAction action, int value, bool dry_run=false) OVERRIDE
|
||||
{
|
||||
return true;
|
||||
};
|
||||
virtual void skidBonusTriggered() {};
|
||||
// ------------------------------------------------------------------------
|
||||
/** Not used for AIs. */
|
||||
virtual void saveState(BareNetworkString *buffer) const OVERRIDE {}
|
||||
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE {}
|
||||
|
||||
}; // AIBaseController
|
||||
|
||||
|
@ -195,11 +195,11 @@ void AIBaseLapController::computePath()
|
||||
/** Updates the ai base controller each time step. Note that any calls to
|
||||
* isStuck() must be done before update is called, since update will call
|
||||
* AIBaseController::update() which will reset the isStuck flag!
|
||||
* \param dt Time step size.
|
||||
* \param ticks Number of physics time steps - should be 1.
|
||||
*/
|
||||
void AIBaseLapController::update(float dt)
|
||||
void AIBaseLapController::update(int ticks)
|
||||
{
|
||||
AIBaseController::update(dt);
|
||||
AIBaseController::update(ticks);
|
||||
if(DriveGraph::get())
|
||||
{
|
||||
// Update the current node:
|
||||
@ -252,7 +252,7 @@ float AIBaseLapController::steerToAngle(const unsigned int sector,
|
||||
//Desired angle minus current angle equals how many angles to turn
|
||||
float steer_angle = angle - m_kart->getHeading();
|
||||
|
||||
if(m_kart->getBlockedByPlungerTime()>0)
|
||||
if(m_kart->getBlockedByPlungerTicks()>0)
|
||||
steer_angle += add_angle*0.2f;
|
||||
else
|
||||
steer_angle += add_angle;
|
||||
|
@ -53,9 +53,9 @@ protected:
|
||||
* graph nodes. */
|
||||
std::vector<std::vector<int> > m_all_look_aheads;
|
||||
|
||||
virtual void update (float delta) ;
|
||||
virtual void update(int ticks);
|
||||
virtual unsigned int getNextSector(unsigned int index);
|
||||
virtual void newLap (int lap);
|
||||
virtual void newLap(int lap);
|
||||
//virtual void setControllerName(const std::string &name);
|
||||
|
||||
float steerToAngle (const unsigned int sector, const float angle);
|
||||
|
@ -59,8 +59,8 @@ void ArenaAI::reset()
|
||||
m_reverse_point = Vec3(0, 0, 0);
|
||||
m_time_since_last_shot = 0.0f;
|
||||
m_time_since_driving = 0.0f;
|
||||
m_time_since_off_road = 0.0f;
|
||||
m_time_since_reversing = 0.0f;
|
||||
m_ticks_since_off_road = 0;
|
||||
m_ticks_since_reversing = 0;
|
||||
m_time_since_uturn = 0.0f;
|
||||
m_turn_radius = 0.0f;
|
||||
m_steering_angle = 0.0f;
|
||||
@ -74,9 +74,9 @@ void ArenaAI::reset()
|
||||
/** This is the main entry point for the AI.
|
||||
* It is called once per frame for each AI and determines the behaviour of
|
||||
* the AI, e.g. steering, accelerating/braking, firing.
|
||||
* \param dt Time step size.
|
||||
* \param ticks Number of physics time steps - should be 1.
|
||||
*/
|
||||
void ArenaAI::update(float dt)
|
||||
void ArenaAI::update(int ticks)
|
||||
{
|
||||
// This is used to enable firing an item backwards.
|
||||
m_controls->setLookBack(false);
|
||||
@ -96,30 +96,31 @@ void ArenaAI::update(float dt)
|
||||
|
||||
if (!isKartOnRoad() && m_kart->isOnGround())
|
||||
{
|
||||
m_time_since_off_road += dt;
|
||||
m_ticks_since_off_road += ticks;
|
||||
}
|
||||
else if (m_time_since_off_road != 0.0f)
|
||||
else if (m_ticks_since_off_road != 0)
|
||||
{
|
||||
m_time_since_off_road = 0.0f;
|
||||
m_ticks_since_off_road = 0;
|
||||
}
|
||||
|
||||
// If the kart needs to be rescued, do it now (and nothing else)
|
||||
if (m_time_since_off_road > 5.0f && m_kart->isOnGround())
|
||||
if (m_ticks_since_off_road > stk_config->time2Ticks(5.0f) &&
|
||||
m_kart->isOnGround() )
|
||||
{
|
||||
m_time_since_off_road = 0.0f;
|
||||
m_ticks_since_off_road = 0;
|
||||
new RescueAnimation(m_kart);
|
||||
AIBaseController::update(dt);
|
||||
AIBaseController::update(ticks);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWaiting())
|
||||
{
|
||||
AIBaseController::update(dt);
|
||||
AIBaseController::update(ticks);
|
||||
return;
|
||||
}
|
||||
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
checkIfStuck(dt);
|
||||
if (gettingUnstuck(dt))
|
||||
if (gettingUnstuck(ticks))
|
||||
return;
|
||||
|
||||
findTarget();
|
||||
@ -156,7 +157,7 @@ void ArenaAI::update(float dt)
|
||||
setSteering(m_steering_angle, dt);
|
||||
}
|
||||
|
||||
AIBaseController::update(dt);
|
||||
AIBaseController::update(ticks);
|
||||
|
||||
} // update
|
||||
|
||||
@ -385,22 +386,23 @@ void ArenaAI::doUTurn(const float dt)
|
||||
* \param dt Time step size.
|
||||
* \return True if getting stuck is needed to be done.
|
||||
*/
|
||||
bool ArenaAI::gettingUnstuck(const float dt)
|
||||
bool ArenaAI::gettingUnstuck(int ticks)
|
||||
{
|
||||
if (!m_is_stuck || m_is_uturn) return false;
|
||||
|
||||
resetAfterStop();
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
setSteering(0.0f, dt);
|
||||
m_controls->setBrake(true);
|
||||
|
||||
m_time_since_reversing += dt;
|
||||
m_ticks_since_reversing += ticks;
|
||||
|
||||
if (m_time_since_reversing >= 1.0f)
|
||||
if (m_ticks_since_reversing >= stk_config->time2Ticks(1.0f))
|
||||
{
|
||||
m_is_stuck = false;
|
||||
m_time_since_reversing = 0.0f;
|
||||
m_ticks_since_reversing = 0;
|
||||
}
|
||||
AIBaseController::update(dt);
|
||||
AIBaseController::update(ticks);
|
||||
return true;
|
||||
|
||||
} // gettingUnstuck
|
||||
|
@ -89,7 +89,7 @@ private:
|
||||
* until facing in front of it. */
|
||||
Vec3 m_reverse_point;
|
||||
|
||||
/** Indicates that the kart is currently stuck, and m_time_since_reversing
|
||||
/** Indicates that the kart is currently stuck, and m_ticks_since_reversing
|
||||
* is counting down. */
|
||||
bool m_is_stuck;
|
||||
|
||||
@ -105,7 +105,7 @@ private:
|
||||
float m_time_since_last_shot;
|
||||
|
||||
/** This is a timer that counts down when the kart is reversing to get unstuck. */
|
||||
float m_time_since_reversing;
|
||||
float m_ticks_since_reversing;
|
||||
|
||||
/** This is a timer that counts down when the kart is starting to drive. */
|
||||
float m_time_since_driving;
|
||||
@ -114,7 +114,7 @@ private:
|
||||
float m_time_since_uturn;
|
||||
|
||||
/** This is a timer that counts when the kart start going off road. */
|
||||
float m_time_since_off_road;
|
||||
int m_ticks_since_off_road;
|
||||
|
||||
/** Used to determine braking and nitro usage. */
|
||||
float m_turn_radius;
|
||||
@ -142,7 +142,7 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
void doUTurn(const float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
bool gettingUnstuck(const float dt);
|
||||
bool gettingUnstuck(int ticks);
|
||||
// ------------------------------------------------------------------------
|
||||
bool updateAimingPosition(Vec3* target_point);
|
||||
// ------------------------------------------------------------------------
|
||||
@ -183,11 +183,11 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~ArenaAI() {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void update (float delta) OVERRIDE;
|
||||
virtual void update(int ticks) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset () OVERRIDE;
|
||||
virtual void reset() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void newLap (int lap) OVERRIDE {}
|
||||
virtual void newLap(int lap) OVERRIDE {}
|
||||
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <irrString.h>
|
||||
using namespace irr;
|
||||
|
||||
class BareNetworkString;
|
||||
|
||||
/**
|
||||
* \defgroup controller Karts/controller
|
||||
* Contains kart controllers, which are either human players or AIs
|
||||
@ -31,6 +33,7 @@ using namespace irr;
|
||||
#include "states_screens/state_manager.hpp"
|
||||
|
||||
class AbstractKart;
|
||||
class BareNetworString;
|
||||
class Item;
|
||||
class KartControl;
|
||||
class Material;
|
||||
@ -58,7 +61,7 @@ public:
|
||||
Controller (AbstractKart *kart);
|
||||
virtual ~Controller () {};
|
||||
virtual void reset () = 0;
|
||||
virtual void update (float dt) = 0;
|
||||
virtual void update (int ticks) = 0;
|
||||
virtual void handleZipper (bool play_sound) = 0;
|
||||
virtual void collectedItem (const Item &item, int add_info=-1,
|
||||
float previous_energy=0) = 0;
|
||||
@ -74,6 +77,9 @@ public:
|
||||
* rubber-banding. */
|
||||
virtual bool isPlayerController () const = 0;
|
||||
virtual bool disableSlipstreamBonus() const = 0;
|
||||
virtual void saveState(BareNetworkString *buffer) const = 0;
|
||||
virtual void rewindTo(BareNetworkString *buffer) = 0;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Sets the controller name for this controller. */
|
||||
virtual void setControllerName(const std::string &name)
|
||||
@ -83,7 +89,7 @@ public:
|
||||
const std::string &getControllerName() const { return m_controller_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Default: ignore actions. Only PlayerController get them. */
|
||||
virtual void action(PlayerAction action, int value) = 0;
|
||||
virtual bool action(PlayerAction action, int value, bool dry_run=false) = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Callback whenever a new lap is triggered. Used by the AI
|
||||
* to trigger a recomputation of the way to use. */
|
||||
|
@ -172,7 +172,7 @@ void EndController::action(PlayerAction action, int value)
|
||||
} // action
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void EndController::update(float dt)
|
||||
void EndController::update(int ticks)
|
||||
{
|
||||
// This is used to enable firing an item backwards.
|
||||
m_controls->setLookBack(false);
|
||||
@ -180,7 +180,7 @@ void EndController::update(float dt)
|
||||
m_controls->setBrake(false);
|
||||
m_controls->setAccel(1.0f);
|
||||
|
||||
AIBaseLapController::update(dt);
|
||||
AIBaseLapController::update(ticks);
|
||||
|
||||
// In case of battle mode: don't do anything
|
||||
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES ||
|
||||
@ -198,6 +198,7 @@ void EndController::update(float dt)
|
||||
calcSteps();
|
||||
|
||||
/*Response handling functions*/
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
handleSteering(dt);
|
||||
handleRescue(dt);
|
||||
} // update
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
EndController(AbstractKart *kart,
|
||||
Controller *prev_controller);
|
||||
~EndController();
|
||||
virtual void update (float delta) ;
|
||||
virtual void update (int ticks) ;
|
||||
virtual void reset ();
|
||||
virtual void action (PlayerAction action, int value);
|
||||
virtual void newLap (int lap);
|
||||
|
@ -35,7 +35,7 @@ void GhostController::reset()
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void GhostController::update(float dt)
|
||||
void GhostController::update(int ticks)
|
||||
{
|
||||
m_current_time = World::getWorld()->getTime();
|
||||
// Find (if necessary) the next index to use
|
||||
@ -82,9 +82,10 @@ void GhostController::addReplayTime(float time)
|
||||
} // addReplayTime
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void GhostController::action(PlayerAction action, int value)
|
||||
bool GhostController::action(PlayerAction action, int value, bool dry_run)
|
||||
{
|
||||
// Watching replay use only
|
||||
if (action == PA_LOOK_BACK)
|
||||
m_controls->setLookBack(value!=0);
|
||||
return true;
|
||||
} // action
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
GhostController(AbstractKart *kart, core::stringw display_name);
|
||||
virtual ~GhostController() {};
|
||||
virtual void reset() OVERRIDE;
|
||||
virtual void update (float dt) OVERRIDE;
|
||||
virtual void update (int ticks) OVERRIDE;
|
||||
virtual bool disableSlipstreamBonus() const OVERRIDE { return true; }
|
||||
virtual void crashed(const Material *m) OVERRIDE {}
|
||||
virtual void crashed(const AbstractKart *k) OVERRIDE {}
|
||||
@ -58,9 +58,13 @@ public:
|
||||
virtual void setPosition(int p) OVERRIDE {}
|
||||
virtual bool isPlayerController() const OVERRIDE { return false; }
|
||||
virtual bool isLocalPlayerController() const OVERRIDE { return false; }
|
||||
virtual void action(PlayerAction action, int value) OVERRIDE;
|
||||
virtual bool action(PlayerAction action, int value,
|
||||
bool dry_run=false) OVERRIDE;
|
||||
virtual void skidBonusTriggered() OVERRIDE {}
|
||||
virtual void newLap(int lap) OVERRIDE {}
|
||||
virtual void saveState(BareNetworkString *buffer) const {};
|
||||
virtual void rewindTo(BareNetworkString *buffer) {};
|
||||
|
||||
void addReplayTime(float time);
|
||||
// ------------------------------------------------------------------------
|
||||
bool isReplayEnd() const
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "karts/controller/kart_control.hpp"
|
||||
|
||||
#include "network/protocols/game_protocol.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
|
||||
|
||||
@ -38,7 +39,7 @@ void KartControl::rewind(BareNetworkString *buffer)
|
||||
if(buffer->getTotalSize()>1)
|
||||
{
|
||||
// Full state including accel and steering was saved
|
||||
setFromBuffer(buffer);
|
||||
rewindTo(buffer);
|
||||
}
|
||||
else // only a button event was stored
|
||||
{
|
||||
@ -46,140 +47,58 @@ void KartControl::rewind(BareNetworkString *buffer)
|
||||
}
|
||||
} // rewind
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets this KartControl form the given value (basically a copy). This
|
||||
* function uses the explicit setSteer() etc function, which means that
|
||||
* rewind information will be collected.
|
||||
*/
|
||||
void KartControl::set(const KartControl &c)
|
||||
{
|
||||
setAccel(c.getAccel());
|
||||
setBrake(c.getBrake());
|
||||
setFire(c.getFire());
|
||||
setLookBack(c.getLookBack());
|
||||
setNitro(c.getNitro());
|
||||
setRescue(c.getRescue());
|
||||
setSkidControl(c.getSkidControl());
|
||||
setSteer(c.getSteer());
|
||||
} // set
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the current steering value. */
|
||||
void KartControl::setSteer(float f)
|
||||
{
|
||||
float old_steer = m_steer;
|
||||
m_steer = f;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_steer != m_steer )
|
||||
{
|
||||
// Save full status
|
||||
BareNetworkString *buffer = new BareNetworkString(getLength());
|
||||
copyToBuffer(buffer);
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // setSteer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets the acceleration. */
|
||||
void KartControl::setAccel(float f)
|
||||
{
|
||||
float old_accel = m_accel;
|
||||
m_accel = f;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_accel != m_accel )
|
||||
{
|
||||
BareNetworkString *buffer = new BareNetworkString(getLength());
|
||||
copyToBuffer(buffer);
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // setAccel
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets if the kart is braking. */
|
||||
void KartControl::setBrake(bool b)
|
||||
{
|
||||
bool old_brake = m_brake;
|
||||
m_brake = b;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_brake != m_brake )
|
||||
{
|
||||
// Only store the buttons in this case
|
||||
BareNetworkString *buffer = new BareNetworkString(1);
|
||||
buffer->addUInt8(getButtonsCompressed());
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // setBrake
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets if the kart activates nitro. */
|
||||
void KartControl::setNitro(bool b)
|
||||
{
|
||||
bool old_nitro = m_nitro;
|
||||
m_nitro = b;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_nitro != m_nitro )
|
||||
{
|
||||
BareNetworkString *buffer = new BareNetworkString(1);
|
||||
buffer->addUInt8(getButtonsCompressed());
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // setNitro
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets the skid control for this kart. */
|
||||
void KartControl::setSkidControl(SkidControl sc)
|
||||
{
|
||||
SkidControl old_skid = m_skid;
|
||||
m_skid = sc;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_skid != m_skid )
|
||||
{
|
||||
BareNetworkString *buffer = new BareNetworkString(1);
|
||||
buffer->addUInt8(getButtonsCompressed());
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // seSkidControl
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns if this kart wants to get rescued. */
|
||||
void KartControl::setRescue(bool b)
|
||||
{
|
||||
bool old_rescue = m_rescue;
|
||||
m_rescue = b;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_rescue != m_rescue)
|
||||
{
|
||||
BareNetworkString *buffer = new BareNetworkString(1);
|
||||
buffer->addUInt8(getButtonsCompressed());
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // setRescue
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets if the kart wants to fire. */
|
||||
void KartControl::setFire(bool b)
|
||||
{
|
||||
bool old_fire = m_fire;
|
||||
m_fire = b;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_fire != m_fire )
|
||||
{
|
||||
BareNetworkString *buffer = new BareNetworkString(1);
|
||||
buffer->addUInt8(getButtonsCompressed());
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // setFire
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets if the kart wants to look (and therefore also fires) backwards. */
|
||||
void KartControl::setLookBack(bool b)
|
||||
{
|
||||
bool old_look = m_look_back;
|
||||
m_look_back = b;
|
||||
if (RewindManager::isEnabled() && !RewindManager::get()->isRewinding() &&
|
||||
old_look != m_look_back)
|
||||
{
|
||||
BareNetworkString *buffer = new BareNetworkString(1);
|
||||
buffer->addUInt8(getButtonsCompressed());
|
||||
RewindManager::get()->addEvent(this, buffer);
|
||||
}
|
||||
} // setLookBack
|
||||
|
@ -61,7 +61,6 @@ public:
|
||||
void setRescue(bool b);
|
||||
void setFire(bool b);
|
||||
void setLookBack(bool b);
|
||||
void set(const KartControl &c);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
KartControl()
|
||||
@ -101,7 +100,7 @@ public:
|
||||
static int getLength() { return 9; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Copies the important data from this objects into a memory buffer. */
|
||||
void copyToBuffer(BareNetworkString *buffer) const
|
||||
void saveState(BareNetworkString *buffer) const
|
||||
{
|
||||
buffer->add(m_steer);
|
||||
buffer->add(m_accel);
|
||||
@ -110,7 +109,7 @@ public:
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Restores this object from a previously saved memory buffer. */
|
||||
void setFromBuffer(BareNetworkString *buffer)
|
||||
void rewindTo(BareNetworkString *buffer)
|
||||
{
|
||||
m_steer = buffer->getFloat();
|
||||
m_accel = buffer->getFloat();
|
||||
|
@ -38,7 +38,8 @@
|
||||
#include "karts/rescue_animation.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/race_event_manager.hpp"
|
||||
#include "network/protocols/game_protocol.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "race/history.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
@ -138,36 +139,50 @@ void LocalPlayerController::resetInputState()
|
||||
* if between 1 and 32767, it indicates an analog value,
|
||||
* and if it's 0 it indicates that the corresponding button
|
||||
* was released.
|
||||
* \param dry_run If set it will return if this action will trigger a
|
||||
* state change or not.
|
||||
* \return True if dry_run==true and a state change would be triggered.
|
||||
* If dry_run==false, it returns true.
|
||||
*/
|
||||
void LocalPlayerController::action(PlayerAction action, int value)
|
||||
bool LocalPlayerController::action(PlayerAction action, int value,
|
||||
bool dry_run)
|
||||
{
|
||||
PlayerController::action(action, value);
|
||||
// If this event does not change the control state (e.g.
|
||||
// it's a (auto) repeat event), do nothing. This especially
|
||||
// optimises traffic to the server and other clients.
|
||||
if (!PlayerController::action(action, value, /*dry_run*/true)) return false;
|
||||
|
||||
// If this is a client, send the action to the server
|
||||
if (World::getWorld()->isNetworkWorld() &&
|
||||
NetworkConfig::get()->isClient() &&
|
||||
RaceEventManager::getInstance()->isRunning() )
|
||||
// Register event with history
|
||||
if(!history->replayHistory())
|
||||
history->addEvent(m_kart->getWorldKartId(), action, value);
|
||||
|
||||
// If this is a client, send the action to networking layer
|
||||
if (World::getWorld()->isNetworkWorld() &&
|
||||
NetworkConfig::get()->isClient() &&
|
||||
!RewindManager::get()->isRewinding() )
|
||||
{
|
||||
RaceEventManager::getInstance()->controllerAction(this, action, value);
|
||||
GameProtocol::lock()
|
||||
->controllerAction(m_kart->getWorldKartId(),
|
||||
action, value,
|
||||
m_steer_val_l, m_steer_val_r);
|
||||
}
|
||||
|
||||
return PlayerController::action(action, value, /*dry_run*/false);
|
||||
} // action
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Handles steering for a player kart.
|
||||
*/
|
||||
void LocalPlayerController::steer(float dt, int steer_val)
|
||||
void LocalPlayerController::steer(int ticks, int steer_val)
|
||||
{
|
||||
if(UserConfigParams::m_gamepad_debug)
|
||||
{
|
||||
Log::debug("LocalPlayerController", "steering: steer_val %d ", steer_val);
|
||||
RaceGUIBase* gui_base = World::getWorld()->getRaceGUI();
|
||||
gui_base->clearAllMessages();
|
||||
gui_base->addMessage(StringUtils::insertValues(L"steer_val %i", steer_val),
|
||||
m_kart, 1.0f,
|
||||
video::SColor(255, 255, 0, 255), false);
|
||||
}
|
||||
PlayerController::steer(dt, steer_val);
|
||||
PlayerController::steer(ticks, steer_val);
|
||||
|
||||
if(UserConfigParams::m_gamepad_debug)
|
||||
{
|
||||
@ -179,7 +194,7 @@ void LocalPlayerController::steer(float dt, int steer_val)
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the player kart, called once each timestep.
|
||||
*/
|
||||
void LocalPlayerController::update(float dt)
|
||||
void LocalPlayerController::update(int ticks)
|
||||
{
|
||||
if (UserConfigParams::m_gamepad_debug)
|
||||
{
|
||||
@ -188,7 +203,7 @@ void LocalPlayerController::update(float dt)
|
||||
Log::debug("LocalPlayerController", "irr_driver", "-------------------------------------");
|
||||
}
|
||||
|
||||
PlayerController::update(dt);
|
||||
PlayerController::update(ticks);
|
||||
|
||||
// look backward when the player requests or
|
||||
// if automatic reverse camera is active
|
||||
|
@ -54,14 +54,15 @@ private:
|
||||
SFXBuffer *m_grab_sound;
|
||||
SFXBuffer *m_full_sound;
|
||||
|
||||
virtual void steer(float, int) OVERRIDE;
|
||||
virtual void steer(int, int) OVERRIDE;
|
||||
virtual void displayPenaltyWarning() OVERRIDE;
|
||||
public:
|
||||
LocalPlayerController(AbstractKart *kart,
|
||||
const int local_playerID);
|
||||
~LocalPlayerController();
|
||||
void update (float) OVERRIDE;
|
||||
void action (PlayerAction action, int value) OVERRIDE;
|
||||
void update (int ticks) OVERRIDE;
|
||||
bool action (PlayerAction action, int value,
|
||||
bool dry_run=false) OVERRIDE;
|
||||
virtual void handleZipper (bool play_sound) OVERRIDE;
|
||||
void collectedItem (const Item &item, int add_info=-1,
|
||||
float previous_energy=0) OVERRIDE;
|
||||
|
@ -38,7 +38,7 @@
|
||||
PlayerController::PlayerController(AbstractKart *kart)
|
||||
: Controller(kart)
|
||||
{
|
||||
m_penalty_time = 0.0f;
|
||||
m_penalty_ticks = 0;
|
||||
} // PlayerController
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -53,13 +53,13 @@ PlayerController::~PlayerController()
|
||||
*/
|
||||
void PlayerController::reset()
|
||||
{
|
||||
m_steer_val_l = 0;
|
||||
m_steer_val_r = 0;
|
||||
m_steer_val = 0;
|
||||
m_prev_brake = 0;
|
||||
m_prev_accel = 0;
|
||||
m_prev_nitro = false;
|
||||
m_penalty_time = 0;
|
||||
m_steer_val_l = 0;
|
||||
m_steer_val_r = 0;
|
||||
m_steer_val = 0;
|
||||
m_prev_brake = 0;
|
||||
m_prev_accel = 0;
|
||||
m_prev_nitro = false;
|
||||
m_penalty_ticks = 0;
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -85,98 +85,144 @@ void PlayerController::resetInputState()
|
||||
* releasing right, the steering must switch to left again. Similarly it
|
||||
* handles 'press left, press right, release left' (in which case still
|
||||
* right must be selected). Similarly for braking and acceleration.
|
||||
* \param action The action to be executed.
|
||||
* \param value If 32768, it indicates a digital value of 'fully set'
|
||||
* if between 1 and 32767, it indicates an analog value,
|
||||
* and if it's 0 it indicates that the corresponding button
|
||||
* was released.
|
||||
* This function can be run in two modes: first, if 'dry_run' is set,
|
||||
* it will return true if this action will cause a state change. This
|
||||
* is sued in networking to avoid sending events to the server (and then
|
||||
* to other clients) if they are just (e.g. auto) repeated events/
|
||||
* \param action The action to be executed.
|
||||
* \param value If 32768, it indicates a digital value of 'fully set'
|
||||
* if between 1 and 32767, it indicates an analog value,
|
||||
* and if it's 0 it indicates that the corresponding button
|
||||
* was released.
|
||||
* \param dry_run If set, it will only test if the parameter will trigger
|
||||
* a state change. If not set, the appropriate actions
|
||||
* (i.e. input state change) will be done.
|
||||
* \return If dry_run is set, will return true if this action will
|
||||
* cause a state change. If dry_run is not set, will return
|
||||
* false.
|
||||
*/
|
||||
void PlayerController::action(PlayerAction action, int value)
|
||||
bool PlayerController::action(PlayerAction action, int value, bool dry_run)
|
||||
{
|
||||
|
||||
/** If dry_run (parameter) is true, this macro tests if this action would
|
||||
* trigger a state change in the specified variable (without actually
|
||||
* doing it). If it will trigger a state change, the macro will
|
||||
* immediatley return to the caller. If dry_run is false, it will only
|
||||
* assign the new value to the variable (and not return to the user
|
||||
* early). The do-while(0) helps using this macro e.g. in the 'then'
|
||||
* clause of an if statement. */
|
||||
#define SET_OR_TEST(var, value) \
|
||||
do \
|
||||
{ \
|
||||
if(dry_run) \
|
||||
{ \
|
||||
if (var != (value) ) return true; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
var = value; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/** Basically the same as the above macro, but is uses getter/setter
|
||||
* functions. The name of the setter/getter is set'name'(value) and
|
||||
* get'name'(). */
|
||||
#define SET_OR_TEST_GETTER(name, value) \
|
||||
do \
|
||||
{ \
|
||||
if(dry_run) \
|
||||
{ \
|
||||
if (m_controls->get##name() != (value) ) return true; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
m_controls->set##name(value); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case PA_STEER_LEFT:
|
||||
m_steer_val_l = value;
|
||||
SET_OR_TEST(m_steer_val_l, value);
|
||||
if (value)
|
||||
{
|
||||
m_steer_val = value;
|
||||
if(m_controls->getSkidControl()==KartControl::SC_NO_DIRECTION)
|
||||
m_controls->setSkidControl(KartControl::SC_LEFT);
|
||||
SET_OR_TEST(m_steer_val, value);
|
||||
if (m_controls->getSkidControl() == KartControl::SC_NO_DIRECTION)
|
||||
SET_OR_TEST_GETTER(SkidControl, KartControl::SC_LEFT);
|
||||
}
|
||||
else
|
||||
m_steer_val = m_steer_val_r;
|
||||
|
||||
SET_OR_TEST(m_steer_val, m_steer_val_r);
|
||||
break;
|
||||
case PA_STEER_RIGHT:
|
||||
m_steer_val_r = -value;
|
||||
SET_OR_TEST(m_steer_val_r, -value);
|
||||
if (value)
|
||||
{
|
||||
m_steer_val = -value;
|
||||
if(m_controls->getSkidControl()==KartControl::SC_NO_DIRECTION)
|
||||
m_controls->setSkidControl(KartControl::SC_RIGHT);
|
||||
SET_OR_TEST(m_steer_val, -value);
|
||||
if (m_controls->getSkidControl() == KartControl::SC_NO_DIRECTION)
|
||||
SET_OR_TEST_GETTER(SkidControl, KartControl::SC_RIGHT);
|
||||
}
|
||||
else
|
||||
m_steer_val = m_steer_val_l;
|
||||
SET_OR_TEST(m_steer_val, m_steer_val_l);
|
||||
|
||||
break;
|
||||
case PA_ACCEL:
|
||||
m_prev_accel = value;
|
||||
if (value && !(m_penalty_time > 0.0f))
|
||||
SET_OR_TEST(m_prev_accel, value);
|
||||
if (value && !(m_penalty_ticks > 0))
|
||||
{
|
||||
m_controls->setAccel(value/32768.0f);
|
||||
m_controls->setBrake(false);
|
||||
m_controls->setNitro(m_prev_nitro);
|
||||
SET_OR_TEST_GETTER(Accel, value/32768.0f);
|
||||
SET_OR_TEST_GETTER(Brake, false);
|
||||
SET_OR_TEST_GETTER(Nitro, m_prev_nitro);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_controls->setAccel(0.0f);
|
||||
m_controls->setBrake(m_prev_brake);
|
||||
m_controls->setNitro(false);
|
||||
SET_OR_TEST_GETTER(Accel, 0.0f);
|
||||
SET_OR_TEST_GETTER(Brake, m_prev_brake);
|
||||
SET_OR_TEST_GETTER(Nitro, false);
|
||||
}
|
||||
break;
|
||||
case PA_BRAKE:
|
||||
m_prev_brake = value!=0;
|
||||
SET_OR_TEST(m_prev_brake, value!=0);
|
||||
// let's consider below that to be a deadzone
|
||||
if(value > 32768/2)
|
||||
{
|
||||
m_controls->setBrake(true);
|
||||
m_controls->setAccel(0.0f);
|
||||
m_controls->setNitro(false);
|
||||
SET_OR_TEST_GETTER(Brake, true);
|
||||
SET_OR_TEST_GETTER(Accel, 0.0f);
|
||||
SET_OR_TEST_GETTER(Nitro, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_controls->setBrake(false);
|
||||
m_controls->setAccel(m_prev_accel/32768.0f);
|
||||
SET_OR_TEST_GETTER(Brake, false);
|
||||
SET_OR_TEST_GETTER(Accel, m_prev_accel/32768.0f);
|
||||
// Nitro still depends on whether we're accelerating
|
||||
m_controls->setNitro(m_prev_nitro && m_prev_accel);
|
||||
SET_OR_TEST_GETTER(Nitro, m_prev_nitro && m_prev_accel);
|
||||
}
|
||||
break;
|
||||
case PA_NITRO:
|
||||
// This basically keeps track whether the button still is being pressed
|
||||
m_prev_nitro = (value != 0);
|
||||
SET_OR_TEST(m_prev_nitro, value != 0 );
|
||||
// Enable nitro only when also accelerating
|
||||
m_controls->setNitro( ((value!=0) && m_controls->getAccel()) );
|
||||
SET_OR_TEST_GETTER(Nitro, ((value!=0) && m_controls->getAccel()) );
|
||||
break;
|
||||
case PA_RESCUE:
|
||||
m_controls->setRescue(value!=0);
|
||||
SET_OR_TEST_GETTER(Rescue, value!=0);
|
||||
break;
|
||||
case PA_FIRE:
|
||||
m_controls->setFire(value!=0);
|
||||
SET_OR_TEST_GETTER(Fire, value!=0);
|
||||
break;
|
||||
case PA_LOOK_BACK:
|
||||
m_controls->setLookBack(value!=0);
|
||||
SET_OR_TEST_GETTER(LookBack, value!=0);
|
||||
break;
|
||||
case PA_DRIFT:
|
||||
if(value==0)
|
||||
m_controls->setSkidControl(KartControl::SC_NONE);
|
||||
if (value == 0)
|
||||
SET_OR_TEST_GETTER(SkidControl, KartControl::SC_NONE);
|
||||
else
|
||||
{
|
||||
if(m_steer_val==0)
|
||||
m_controls->setSkidControl(KartControl::SC_NO_DIRECTION);
|
||||
if (m_steer_val == 0)
|
||||
SET_OR_TEST_GETTER(SkidControl, KartControl::SC_NO_DIRECTION);
|
||||
else
|
||||
m_controls->setSkidControl(m_steer_val<0
|
||||
? KartControl::SC_RIGHT
|
||||
: KartControl::SC_LEFT );
|
||||
SET_OR_TEST_GETTER(SkidControl, m_steer_val<0
|
||||
? KartControl::SC_RIGHT
|
||||
: KartControl::SC_LEFT );
|
||||
}
|
||||
break;
|
||||
case PA_PAUSE_RACE:
|
||||
@ -185,13 +231,25 @@ void PlayerController::action(PlayerAction action, int value)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dry_run) return false;
|
||||
return true;
|
||||
#undef SET_OR_TEST
|
||||
#undef SET_OR_TEST_GETTER
|
||||
} // action
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerController::actionFromNetwork(PlayerAction p_action, int value,
|
||||
int value_l, int value_r)
|
||||
{
|
||||
m_steer_val_l = value_l;
|
||||
m_steer_val_r = value_r;
|
||||
action(p_action, value);
|
||||
} // actionFromNetwork
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Handles steering for a player kart.
|
||||
*/
|
||||
void PlayerController::steer(float dt, int steer_val)
|
||||
void PlayerController::steer(int ticks, int steer_val)
|
||||
{
|
||||
// Get the old value, compute the new steering value,
|
||||
// and set it at the end of this function
|
||||
@ -206,6 +264,7 @@ void PlayerController::steer(float dt, int steer_val)
|
||||
// Amount the steering is changed for digital devices.
|
||||
// If the steering is 'back to straight', a different steering
|
||||
// change speed is used.
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
const float STEER_CHANGE = ( (steer_val<=0 && steer<0) ||
|
||||
(steer_val>=0 && steer>0) )
|
||||
? dt/m_kart->getKartProperties()->getTurnTimeResetSteer()
|
||||
@ -239,7 +298,6 @@ void PlayerController::steer(float dt, int steer_val)
|
||||
if(steer>0.0f) steer=0.0f;
|
||||
} // if steer<=0.0f
|
||||
} // no key is pressed
|
||||
|
||||
m_controls->setSteer(std::min(1.0f, std::max(-1.0f, steer)) );
|
||||
|
||||
} // steer
|
||||
@ -256,13 +314,9 @@ void PlayerController::skidBonusTriggered()
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the player kart, called once each timestep.
|
||||
*/
|
||||
void PlayerController::update(float dt)
|
||||
void PlayerController::update(int ticks)
|
||||
{
|
||||
// Don't do steering if it's replay. In position only replay it doesn't
|
||||
// matter, but if it's physics replay the gradual steering causes
|
||||
// incorrect results, since the stored values are already adjusted.
|
||||
if (!history->replayHistory())
|
||||
steer(dt, m_steer_val);
|
||||
steer(ticks, m_steer_val);
|
||||
|
||||
if (World::getWorld()->getPhase() == World::GOAL_PHASE)
|
||||
{
|
||||
@ -279,11 +333,11 @@ void PlayerController::update(float dt)
|
||||
// Only give penalty time in SET_PHASE.
|
||||
// Penalty time check makes sure it doesn't get rendered on every
|
||||
// update.
|
||||
if (m_penalty_time == 0.0 &&
|
||||
if (m_penalty_ticks == 0 &&
|
||||
World::getWorld()->getPhase() == WorldStatus::SET_PHASE)
|
||||
{
|
||||
displayPenaltyWarning();
|
||||
m_penalty_time = stk_config->m_penalty_time;
|
||||
m_penalty_ticks = stk_config->m_penalty_ticks;
|
||||
} // if penalty_time = 0
|
||||
|
||||
m_controls->setBrake(false);
|
||||
@ -293,9 +347,9 @@ void PlayerController::update(float dt)
|
||||
return;
|
||||
} // if isStartPhase
|
||||
|
||||
if (m_penalty_time>0.0)
|
||||
if (m_penalty_ticks>0)
|
||||
{
|
||||
m_penalty_time-=dt;
|
||||
m_penalty_ticks-=ticks;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -316,3 +370,18 @@ void PlayerController::handleZipper(bool play_sound)
|
||||
{
|
||||
m_kart->showZipperFire();
|
||||
} // handleZipper
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerController::saveState(BareNetworkString *buffer) const
|
||||
{
|
||||
buffer->addUInt32(m_steer_val).addUInt32(m_steer_val_l)
|
||||
.addUInt32(m_steer_val_r);
|
||||
} // copyToBuffer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerController::rewindTo(BareNetworkString *buffer)
|
||||
{
|
||||
m_steer_val = buffer->getUInt32();
|
||||
m_steer_val_l = buffer->getUInt32();
|
||||
m_steer_val_r = buffer->getUInt32();
|
||||
} // rewindTo
|
@ -32,9 +32,9 @@ protected:
|
||||
bool m_prev_brake;
|
||||
bool m_prev_nitro;
|
||||
|
||||
float m_penalty_time;
|
||||
int m_penalty_ticks;
|
||||
|
||||
virtual void steer(float, int);
|
||||
virtual void steer(int ticks, int steer_val);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when this kart started too early and got a start penalty. */
|
||||
virtual void displayPenaltyWarning() {}
|
||||
@ -43,12 +43,17 @@ protected:
|
||||
public:
|
||||
PlayerController(AbstractKart *kart);
|
||||
virtual ~PlayerController ();
|
||||
virtual void update (float) OVERRIDE;
|
||||
virtual void action (PlayerAction action, int value) OVERRIDE;
|
||||
virtual void update (int ticks) OVERRIDE;
|
||||
virtual bool action (PlayerAction action, int value,
|
||||
bool dry_run = false ) OVERRIDE;
|
||||
virtual void actionFromNetwork(PlayerAction action, int value,
|
||||
int value_l, int value_r);
|
||||
virtual void skidBonusTriggered() OVERRIDE;
|
||||
virtual void reset () OVERRIDE;
|
||||
virtual void handleZipper(bool play_sound) OVERRIDE;
|
||||
virtual void resetInputState();
|
||||
virtual void saveState(BareNetworkString *buffer) const OVERRIDE;
|
||||
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void collectedItem(const Item &item, int add_info=-1,
|
||||
float previous_energy=0 ) OVERRIDE
|
||||
|
@ -161,7 +161,7 @@ void SkiddingAI::reset()
|
||||
{
|
||||
m_time_since_last_shot = 0.0f;
|
||||
m_start_kart_crash_direction = 0;
|
||||
m_start_delay = -1.0f;
|
||||
m_start_delay = -1;
|
||||
m_time_since_stuck = 0.0f;
|
||||
m_kart_ahead = NULL;
|
||||
m_distance_ahead = 0.0f;
|
||||
@ -218,8 +218,9 @@ unsigned int SkiddingAI::getNextSector(unsigned int index)
|
||||
* It is called once per frame for each AI and determines the behaviour of
|
||||
* the AI, e.g. steering, accelerating/braking, firing.
|
||||
*/
|
||||
void SkiddingAI::update(float dt)
|
||||
void SkiddingAI::update(int ticks)
|
||||
{
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
// This is used to enable firing an item backwards.
|
||||
m_controls->setLookBack(false);
|
||||
m_controls->setNitro(false);
|
||||
@ -293,14 +294,14 @@ void SkiddingAI::update(float dt)
|
||||
if(isStuck() && !m_kart->getKartAnimation())
|
||||
{
|
||||
new RescueAnimation(m_kart);
|
||||
AIBaseLapController::update(dt);
|
||||
AIBaseLapController::update(ticks);
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_world->isStartPhase() )
|
||||
{
|
||||
handleRaceStart();
|
||||
AIBaseLapController::update(dt);
|
||||
AIBaseLapController::update(ticks);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -309,7 +310,7 @@ void SkiddingAI::update(float dt)
|
||||
|
||||
m_kart->setSlowdown(MaxSpeed::MS_DECREASE_AI,
|
||||
m_ai_properties->getSpeedCap(m_distance_to_player),
|
||||
/*fade_in_time*/0.0f);
|
||||
/*fade_in_time*/0);
|
||||
//Detect if we are going to crash with the track and/or kart
|
||||
checkCrashes(m_kart->getXYZ());
|
||||
determineTrackDirection();
|
||||
@ -351,8 +352,8 @@ void SkiddingAI::update(float dt)
|
||||
if(!commands_set)
|
||||
{
|
||||
/*Response handling functions*/
|
||||
handleAcceleration(dt);
|
||||
handleSteering(dt); //Item handling relocated there to be direction aware
|
||||
handleAcceleration(ticks);
|
||||
handleSteering(dt);
|
||||
handleRescue(dt);
|
||||
handleBraking();
|
||||
// If a bomb is attached, nitro might already be set.
|
||||
@ -364,7 +365,7 @@ void SkiddingAI::update(float dt)
|
||||
if(m_controls->getNitro() &&
|
||||
m_kart->getPowerup()->getType()==PowerupManager::POWERUP_ZIPPER &&
|
||||
m_kart->getSpeed()>1.0f &&
|
||||
m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0 &&
|
||||
m_kart->getSpeedIncreaseTicksLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0 &&
|
||||
!m_avoid_item_close)
|
||||
{
|
||||
// Make sure that not all AI karts use the zipper at the same
|
||||
@ -379,7 +380,7 @@ void SkiddingAI::update(float dt)
|
||||
}
|
||||
|
||||
/*And obviously general kart stuff*/
|
||||
AIBaseLapController::update(dt);
|
||||
AIBaseLapController::update(ticks);
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -857,7 +858,7 @@ bool SkiddingAI::handleSelectedItem(Vec3 kart_aim_direction, Vec3 *aim_point)
|
||||
// If the item is unavailable keep on testing. It is not necessary
|
||||
// to test if an item has turned bad, this was tested before this
|
||||
// function is called.
|
||||
if(m_item_to_collect->getDisableTime()>0)
|
||||
if(m_item_to_collect->getDisableTicks()>0)
|
||||
return false;
|
||||
|
||||
const Vec3 &xyz = m_item_to_collect->getXYZ();
|
||||
@ -1047,7 +1048,7 @@ void SkiddingAI::evaluateItems(const Item *item, Vec3 kart_aim_direction,
|
||||
const KartProperties *kp = m_kart->getKartProperties();
|
||||
|
||||
// Ignore items that are currently disabled
|
||||
if(item->getDisableTime()>0) return;
|
||||
if(item->getDisableTicks()>0) return;
|
||||
|
||||
// If the item type is not handled here, ignore it
|
||||
Item::ItemType type = item->getType();
|
||||
@ -1841,12 +1842,12 @@ void SkiddingAI::computeNearestKarts()
|
||||
/** Determines if the AI should accelerate or not.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void SkiddingAI::handleAcceleration( const float dt)
|
||||
void SkiddingAI::handleAcceleration(int ticks)
|
||||
{
|
||||
//Do not accelerate until we have delayed the start enough
|
||||
if( m_start_delay > 0.0f )
|
||||
if( m_start_delay > 0 )
|
||||
{
|
||||
m_start_delay -= dt;
|
||||
m_start_delay -= ticks;
|
||||
m_controls->setAccel(0.0f);
|
||||
return;
|
||||
}
|
||||
@ -1857,7 +1858,7 @@ void SkiddingAI::handleAcceleration( const float dt)
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_kart->getBlockedByPlungerTime()>0)
|
||||
if(m_kart->getBlockedByPlungerTicks()>0)
|
||||
{
|
||||
if(m_kart->getSpeed() < m_kart->getCurrentMaxSpeed() / 2)
|
||||
m_controls->setAccel(0.05f);
|
||||
@ -1873,14 +1874,15 @@ void SkiddingAI::handleAcceleration( const float dt)
|
||||
//-----------------------------------------------------------------------------
|
||||
void SkiddingAI::handleRaceStart()
|
||||
{
|
||||
if( m_start_delay < 0.0f )
|
||||
if( m_start_delay < 0 )
|
||||
{
|
||||
// Each kart starts at a different, random time, and the time is
|
||||
// smaller depending on the difficulty.
|
||||
m_start_delay = m_ai_properties->m_min_start_delay
|
||||
m_start_delay = stk_config->time2Ticks(
|
||||
m_ai_properties->m_min_start_delay
|
||||
+ (float) rand() / RAND_MAX
|
||||
* (m_ai_properties->m_max_start_delay -
|
||||
m_ai_properties->m_min_start_delay);
|
||||
m_ai_properties->m_min_start_delay) );
|
||||
|
||||
float false_start_probability =
|
||||
m_superpower == RaceManager::SUPERPOWER_NOLOK_BOSS
|
||||
@ -1889,7 +1891,7 @@ void SkiddingAI::handleRaceStart()
|
||||
// Now check for a false start. If so, add 1 second penalty time.
|
||||
if(rand() < RAND_MAX * false_start_probability)
|
||||
{
|
||||
m_start_delay+=stk_config->m_penalty_time;
|
||||
m_start_delay+=stk_config->m_penalty_ticks;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1970,7 +1972,8 @@ void SkiddingAI::handleNitroAndZipper()
|
||||
}
|
||||
|
||||
//Nitro continue to be advantageous during the fadeout
|
||||
float nitro_time = ( m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_NITRO)
|
||||
int nitro_ticks = m_kart->getSpeedIncreaseTicksLeft(MaxSpeed::MS_INCREASE_NITRO);
|
||||
float nitro_time = ( stk_config->ticks2Time(nitro_ticks)
|
||||
+ m_kart->getKartProperties()->getNitroFadeOutTime() );
|
||||
float nitro_max_time = m_kart->getKartProperties()->getNitroDuration()
|
||||
+ m_kart->getKartProperties()->getNitroFadeOutTime();
|
||||
@ -1982,9 +1985,9 @@ void SkiddingAI::handleNitroAndZipper()
|
||||
//Nitro skill 2 : Don't use nitro if there is more than 1,2 seconds of effect/fadeout left. Use it when at
|
||||
// max speed or under 5 of speed (after rescue, etc.). Use it to pass bombs.
|
||||
// Tries to builds a reserve of 4 energy to use towards the end
|
||||
//Nitro skill 3 : Same as level 2, but don't use until 0,5 seconds of effect/fadeout left, and don't use close
|
||||
//Nitro skill 3 : Same as level 2, but don't use until 0.5 seconds of effect/fadeout left, and don't use close
|
||||
// to bad items, and has a target reserve of 8 energy
|
||||
//Nitro skill 4 : Same as level 3, but don't use until 0,05 seconds of effect/fadeout left and ignore the plunger
|
||||
//Nitro skill 4 : Same as level 3, but don't use until 0.05 seconds of effect/fadeout left and ignore the plunger
|
||||
// and has a target reserve of 12 energy
|
||||
|
||||
m_controls->setNitro(false);
|
||||
@ -2011,7 +2014,7 @@ void SkiddingAI::handleNitroAndZipper()
|
||||
if(!m_kart->isOnGround() || m_kart->hasFinishedRace()) return;
|
||||
|
||||
// Don't use nitro or zipper when the AI has a plunger in the face!
|
||||
if(m_kart->getBlockedByPlungerTime()>0)
|
||||
if(m_kart->getBlockedByPlungerTicks()>0)
|
||||
{
|
||||
if ((nitro_skill < 4) && (ai_skill < 5))
|
||||
{
|
||||
@ -2082,7 +2085,7 @@ void SkiddingAI::handleNitroAndZipper()
|
||||
{
|
||||
float finish = m_world->getEstimatedFinishTime(m_kart->getWorldKartId()) - m_world->getTime();
|
||||
float max_time_effect = nitro_max_time / m_kart->getKartProperties()->getNitroConsumption()
|
||||
* m_kart->getEnergy()*2; //the minimum burst consumes around 0,5 energy
|
||||
* m_kart->getEnergy()*2; //the minimum burst consumes around 0.5 energy
|
||||
|
||||
// The burster forces the AI to consume its reserve by series of 2 bursts
|
||||
// Otherwise the bursting differences of the various nitro skill wouldn't matter here
|
||||
@ -2148,7 +2151,7 @@ void SkiddingAI::handleNitroAndZipper()
|
||||
|
||||
// Use zipper
|
||||
if(ai_skill >= 2 && m_kart->getSpeed()>1.0f &&
|
||||
m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0)
|
||||
m_kart->getSpeedIncreaseTicksLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0)
|
||||
{
|
||||
DriveNode::DirectionType dir;
|
||||
unsigned int last;
|
||||
@ -2856,7 +2859,7 @@ void SkiddingAI::setSteering(float angle, float dt)
|
||||
else if(steer_fraction < -1.0f) steer_fraction = -1.0f;
|
||||
|
||||
// Restrict steering when a plunger is in the face
|
||||
if(m_kart->getBlockedByPlungerTime()>0)
|
||||
if(m_kart->getBlockedByPlungerTicks()>0)
|
||||
{
|
||||
if (steer_fraction > 0.5f) steer_fraction = 0.5f;
|
||||
else if(steer_fraction < -0.5f) steer_fraction = -0.5f;
|
||||
|
@ -51,8 +51,6 @@
|
||||
#include <line3d.h>
|
||||
|
||||
class LinearWorld;
|
||||
class DriveGraph;
|
||||
class ShowCurve;
|
||||
class Track;
|
||||
|
||||
namespace irr
|
||||
@ -145,8 +143,8 @@ private:
|
||||
/** Distance to the kard behind. */
|
||||
float m_distance_behind;
|
||||
|
||||
/** The actual start delay used. */
|
||||
float m_start_delay;
|
||||
/** The actual start delay used in ticks. */
|
||||
int m_start_delay;
|
||||
|
||||
/** Time an item has been collected and not used. */
|
||||
float m_time_since_last_shot;
|
||||
@ -242,7 +240,7 @@ private:
|
||||
*specific action (more like, associated with inaction).
|
||||
*/
|
||||
void handleRaceStart();
|
||||
void handleAcceleration(const float dt);
|
||||
void handleAcceleration(int ticks);
|
||||
void handleSteering(float dt);
|
||||
void handleItems(const float dt, const Vec3 *aim_point,
|
||||
int last_node);
|
||||
@ -278,7 +276,7 @@ protected:
|
||||
public:
|
||||
SkiddingAI(AbstractKart *kart);
|
||||
~SkiddingAI();
|
||||
virtual void update (float delta) ;
|
||||
virtual void update (int ticks);
|
||||
virtual void reset ();
|
||||
virtual const irr::core::stringw& getNamePostfix() const;
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ void SoccerAI::reset()
|
||||
* after goal.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void SoccerAI::update(float dt)
|
||||
void SoccerAI::update(int ticks)
|
||||
{
|
||||
#ifdef BALL_AIM_DEBUG
|
||||
Vec3 red = m_world->getBallAimPosition(SOCCER_TEAM_RED);
|
||||
@ -125,11 +125,11 @@ void SoccerAI::update(float dt)
|
||||
resetAfterStop();
|
||||
m_controls->setBrake(false);
|
||||
m_controls->setAccel(0.0f);
|
||||
AIBaseController::update(dt);
|
||||
AIBaseController::update(ticks);
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaAI::update(dt);
|
||||
ArenaAI::update(ticks);
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -100,12 +100,9 @@ private:
|
||||
|
||||
public:
|
||||
SoccerAI(AbstractKart *kart);
|
||||
// ------------------------------------------------------------------------
|
||||
~SoccerAI();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void update (float delta) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset () OVERRIDE;
|
||||
virtual void update (int ticks) OVERRIDE;
|
||||
virtual void reset() OVERRIDE;
|
||||
|
||||
};
|
||||
|
||||
|
@ -56,8 +56,8 @@ SpareTireAI::SpareTireAI(AbstractKart *kart)
|
||||
void SpareTireAI::reset()
|
||||
{
|
||||
BattleAI::reset();
|
||||
m_idx = 0;
|
||||
m_timer = 0.0f;
|
||||
m_idx = 0;
|
||||
m_timer = 0;
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -65,12 +65,12 @@ void SpareTireAI::reset()
|
||||
* \ref m_timer reaches zero which it will be decreased here.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void SpareTireAI::update(float dt)
|
||||
void SpareTireAI::update(int ticks)
|
||||
{
|
||||
BattleAI::update(dt);
|
||||
m_kart->setSlowdown(MaxSpeed::MS_DECREASE_AI, 0.5f, /*fade_in_time*/0.0f);
|
||||
m_timer -= dt;
|
||||
if (m_timer < 0.0f)
|
||||
BattleAI::update(ticks);
|
||||
m_kart->setSlowdown(MaxSpeed::MS_DECREASE_AI, 0.5f, /*fade_in_time*/0);
|
||||
m_timer -= ticks;
|
||||
if (m_timer < 0)
|
||||
unspawn();
|
||||
} // update
|
||||
|
||||
@ -108,10 +108,10 @@ void SpareTireAI::findTarget()
|
||||
* moving around.
|
||||
* \param time_to_last Time before calling \ref unspawn.
|
||||
*/
|
||||
void SpareTireAI::spawn(float time_to_last)
|
||||
void SpareTireAI::spawn(int ticks_to_last)
|
||||
{
|
||||
findDefaultPath();
|
||||
m_timer = time_to_last;
|
||||
m_timer = ticks_to_last;
|
||||
|
||||
Physics::getInstance()->addKart(m_kart);
|
||||
m_kart->startEngineSFX();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user