diff --git a/android/README.ANDROID b/android/README.ANDROID index bd8793919..689d09928 100644 --- a/android/README.ANDROID +++ b/android/README.ANDROID @@ -44,7 +44,8 @@ and extract it to stk-code/lib. It contains sources of libraries that are used in STK, but are not availiable in stk-code repository (curl, freetype, openal). You need also Android SDK for android-19 platform (the API for Android 4.4) and -Android NDK r12b. +Android NDK. Note that NDK >= r15b is atm. not supported. Version r12b is +strongly recommended, because it's known that it works without issues. You need to create proper "android-sdk" and "android-ndk" symlinks in the directory with Android project, so that the compilation script will have access diff --git a/data/po/supertuxkart.pot b/data/po/supertuxkart.pot index 08bddec9a..cb8f96d6c 100644 --- a/data/po/supertuxkart.pot +++ b/data/po/supertuxkart.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: supertuxkart\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-08-23 20:00-0400\n" +"POT-Creation-Date: 2017-08-29 19:48-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -181,7 +181,7 @@ msgstr "" #. I18N: track group #. I18N: ./data/gui/easter_egg.stkgui #. I18N: track group -#: src/states_screens/grand_prix_editor_screen.cpp:325 +#: src/states_screens/grand_prix_editor_screen.cpp:330 msgid "Standard" msgstr "" @@ -195,7 +195,7 @@ msgstr "" #. I18N: track group name #: src/states_screens/arenas_screen.cpp:83 #: src/states_screens/easter_egg_screen.cpp:145 -#: src/states_screens/grand_prix_editor_screen.cpp:327 +#: src/states_screens/grand_prix_editor_screen.cpp:332 #: src/states_screens/kart_selection.cpp:286 #: src/states_screens/tracks_and_gp_screen.cpp:148 msgid "Add-Ons" @@ -215,18 +215,18 @@ msgstr "" #: src/states_screens/easter_egg_screen.cpp:137 #: src/states_screens/edit_track_screen.cpp:147 #: src/states_screens/gp_info_screen.cpp:76 -#: src/states_screens/grand_prix_editor_screen.cpp:324 +#: src/states_screens/grand_prix_editor_screen.cpp:329 #: src/states_screens/kart_selection.cpp:278 -#: src/states_screens/options_screen_video.cpp:389 +#: src/states_screens/options_screen_video.cpp:456 #: src/states_screens/tracks_and_gp_screen.cpp:138 -#: src/states_screens/tracks_screen.cpp:142 +#: src/states_screens/tracks_screen.cpp:141 msgid "All" msgstr "" #. I18N: ./data/gui/confirm_dialog.stkgui #. I18N: In a 'are you sure?' dialog #: src/states_screens/edit_gp_screen.cpp:257 -#: src/states_screens/ghost_replay_selection.cpp:116 +#: src/states_screens/ghost_replay_selection.cpp:117 msgid "Yes" msgstr "" @@ -235,8 +235,8 @@ msgstr "" #. I18N: ./data/gui/confirm_resolution_dialog.stkgui #. I18N: In the 'confirm resolution' dialog, that's shown when switching resoluton #. I18N: ./data/gui/edit_track.stkgui -#. I18N: ./data/gui/enter_gp_name_dialog.stkgui -#. I18N: In the 'add new grand prix' dialog +#. I18N: ./data/gui/general_text_field_dialog.stkgui +#. I18N: In the general textfield dialog #. I18N: ./data/gui/online/create_server.stkgui #. I18N: In the server creation screen #. I18N: ./data/gui/online/recovery_input.stkgui @@ -341,11 +341,6 @@ msgstr "" msgid "Texture compression" msgstr "" -#. I18N: ./data/gui/custom_video_settings.stkgui -#. I18N: Video settings -msgid "Use high definition textures" -msgstr "" - #. I18N: ./data/gui/custom_video_settings.stkgui #. I18N: Video settings msgid "Animated Characters" @@ -353,7 +348,12 @@ msgstr "" #. I18N: ./data/gui/custom_video_settings.stkgui #. I18N: Video settings -msgid "Texture filtering" +msgid "Rendered image quality" +msgstr "" + +#. I18N: ./data/gui/custom_video_settings.stkgui +#. I18N: Video settings +msgid "Geometry detail" msgstr "" #. I18N: ./data/gui/custom_video_settings.stkgui @@ -362,6 +362,7 @@ msgid "* Restart STK to apply new settings" msgstr "" #. I18N: ./data/gui/custom_video_settings.stkgui +#. I18N: ./data/gui/multitouch_settings.stkgui msgid "Apply" msgstr "" @@ -428,8 +429,8 @@ msgid "Reverse:" msgstr "" #. I18N: ./data/gui/edit_track.stkgui -#. I18N: ./data/gui/enter_gp_name_dialog.stkgui -#. I18N: In the 'add new grand prix' dialog +#. I18N: ./data/gui/general_text_field_dialog.stkgui +#. I18N: In the general textfield dialog #. I18N: ./data/gui/online/register.stkgui #. I18N: In the registration dialog #. I18N: ./data/gui/user_screen.stkgui @@ -441,11 +442,6 @@ msgstr "" msgid "OK" msgstr "" -#. I18N: ./data/gui/enter_gp_name_dialog.stkgui -#. I18N: In the 'add new grand prix' dialog -msgid "Please enter the name of the grand prix" -msgstr "" - #. I18N: ./data/gui/feature_unlocked.stkgui #. I18N: ./data/gui/grand_prix_lose.stkgui #. I18N: ./data/gui/grand_prix_win.stkgui @@ -550,6 +546,7 @@ msgstr "" #. I18N: ./data/gui/help2.stkgui #. I18N: ./data/gui/help3.stkgui #. I18N: ./data/gui/help4.stkgui +#. I18N: ./data/gui/help5.stkgui msgid "SuperTuxKart Help" msgstr "" @@ -561,6 +558,10 @@ msgstr "" #. I18N: Tab in help menu #. I18N: ./data/gui/help4.stkgui #. I18N: Tab in help menu +#. I18N: ./data/gui/help5.stkgui +#. I18N: Tab in help menu +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen msgid "General" msgstr "" @@ -572,6 +573,8 @@ msgstr "" #. I18N: Tab in help menu #. I18N: ./data/gui/help4.stkgui #. I18N: Tab in help menu +#. I18N: ./data/gui/help5.stkgui +#. I18N: Tab in help menu msgid "Weapons" msgstr "" @@ -583,6 +586,8 @@ msgstr "" #. I18N: Tab in help menu #. I18N: ./data/gui/help4.stkgui #. I18N: Tab in help menu +#. I18N: ./data/gui/help5.stkgui +#. I18N: Tab in help menu msgid "Game Modes" msgstr "" @@ -594,11 +599,26 @@ msgstr "" #. I18N: Tab in help menu #. I18N: ./data/gui/help4.stkgui #. I18N: Tab in help menu +#. I18N: ./data/gui/help5.stkgui +#. I18N: Tab in help menu msgid "Multi-player" msgstr "" #. I18N: ./data/gui/help1.stkgui -msgid "Click here to play the tutorial" +#. I18N: Tab in help menu +#. I18N: ./data/gui/help2.stkgui +#. I18N: Tab in help menu +#. I18N: ./data/gui/help3.stkgui +#. I18N: Tab in help menu +#. I18N: ./data/gui/help4.stkgui +#. I18N: Tab in help menu +#. I18N: ./data/gui/help5.stkgui +#. I18N: Tab in help menu +msgid "Bananas" +msgstr "" + +#. I18N: ./data/gui/help1.stkgui +msgid "Start the tutorial" msgstr "" #. I18N: ./data/gui/help1.stkgui @@ -767,6 +787,29 @@ msgid "" "not be used for this operation." msgstr "" +#. I18N: ./data/gui/help5.stkgui +msgid "" +"Hitting a banana can result in one of the following being attached to the " +"kart:" +msgstr "" + +#. I18N: ./data/gui/help5.stkgui +#. I18N: In the help menu +msgid "Anchor - slows down the kart." +msgstr "" + +#. I18N: ./data/gui/help5.stkgui +#. I18N: In the help menu +msgid "Parachute - slows down the kart less than the anchor." +msgstr "" + +#. I18N: ./data/gui/help5.stkgui +#. I18N: In the help menu +msgid "" +"Bomb - detonates after a short amount of time to throw the kart up in the " +"air. Bump into another kart to transfer the bomb to another player." +msgstr "" + #. I18N: ./data/gui/karts.stkgui #. I18N: In the kart selection (player setup) screen #. I18N: ./data/gui/karts_online.stkgui @@ -825,7 +868,7 @@ msgstr "" #. I18N: ./data/gui/main_menu.stkgui #. I18N: In the main screen -#: src/states_screens/race_gui_overworld.cpp:465 +#: src/states_screens/race_gui_overworld.cpp:511 msgid "Tutorial" msgstr "" @@ -852,6 +895,49 @@ msgstr "" msgid "Quit" msgstr "" +#. I18N: ./data/gui/multitouch_settings.stkgui +msgid "Touch Device Settings" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen +msgid "Device enabled" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen +msgid "Inverted buttons" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen +msgid "Buttons scale" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen +msgid "Accelerometer" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen +msgid "Advanced" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen +msgid "Deadzone center" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +#. I18N: In the multitouch settings screen +msgid "Deadzone edge" +msgstr "" + +#. I18N: ./data/gui/multitouch_settings.stkgui +msgid "Restore defaults" +msgstr "" + #. I18N: ./data/gui/online/change_password.stkgui #. I18N: In the change password dialog msgid "Password Change" @@ -933,8 +1019,8 @@ msgstr "" #. I18N: Difficulty #. I18N: ./data/gui/select_challenge.stkgui #. I18N: Difficulty -#: src/race/race_manager.hpp:544 -#: src/states_screens/ghost_replay_selection.cpp:120 +#: src/race/race_manager.hpp:546 +#: src/states_screens/ghost_replay_selection.cpp:121 msgid "Novice" msgstr "" @@ -944,8 +1030,8 @@ msgstr "" #. I18N: Difficulty #. I18N: ./data/gui/select_challenge.stkgui #. I18N: Difficulty -#: src/race/race_manager.hpp:545 -#: src/states_screens/ghost_replay_selection.cpp:120 +#: src/race/race_manager.hpp:547 +#: src/states_screens/ghost_replay_selection.cpp:121 msgid "Intermediate" msgstr "" @@ -955,8 +1041,8 @@ msgstr "" #. I18N: Difficulty #. I18N: ./data/gui/select_challenge.stkgui #. I18N: Difficulty -#: src/race/race_manager.hpp:546 -#: src/states_screens/ghost_replay_selection.cpp:119 +#: src/race/race_manager.hpp:548 +#: src/states_screens/ghost_replay_selection.cpp:120 msgid "Expert" msgstr "" @@ -964,8 +1050,8 @@ msgstr "" #. I18N: Difficulty #. I18N: ./data/gui/race_setup.stkgui #. I18N: Difficulty -#: src/race/race_manager.hpp:547 -#: src/states_screens/ghost_replay_selection.cpp:118 +#: src/race/race_manager.hpp:549 +#: src/states_screens/ghost_replay_selection.cpp:119 msgid "SuperTux" msgstr "" @@ -1317,9 +1403,9 @@ msgstr "" #. I18N: ./data/gui/options_audio.stkgui #. I18N: Section in the settings menu #: src/states_screens/options_screen_device.cpp:86 -#: src/states_screens/options_screen_input.cpp:140 -#: src/states_screens/options_screen_ui.cpp:122 -#: src/states_screens/options_screen_video.cpp:172 +#: src/states_screens/options_screen_input.cpp:150 +#: src/states_screens/options_screen_ui.cpp:123 +#: src/states_screens/options_screen_video.cpp:238 #: src/states_screens/user_screen.cpp:660 msgid "Audio" msgstr "" @@ -1333,7 +1419,7 @@ msgstr "" #. I18N: In the audio options screen #. I18N: in the graphical options tooltip; #. indicates a graphical feature is enabled -#: src/states_screens/options_screen_video.cpp:384 +#: src/states_screens/options_screen_video.cpp:451 msgid "Enabled" msgstr "" @@ -1352,8 +1438,8 @@ msgstr "" #. I18N: ./data/gui/options_input.stkgui #. I18N: Section in the settings menu #: src/states_screens/options_screen_audio.cpp:68 -#: src/states_screens/options_screen_ui.cpp:124 -#: src/states_screens/options_screen_video.cpp:175 +#: src/states_screens/options_screen_ui.cpp:125 +#: src/states_screens/options_screen_video.cpp:241 #: src/states_screens/user_screen.cpp:662 msgid "Controls" msgstr "" @@ -1393,9 +1479,9 @@ msgstr "" #: src/states_screens/ghost_replay_selection.cpp:78 #: src/states_screens/options_screen_audio.cpp:67 #: src/states_screens/options_screen_device.cpp:88 -#: src/states_screens/options_screen_input.cpp:142 -#: src/states_screens/options_screen_ui.cpp:123 -#: src/states_screens/options_screen_video.cpp:174 +#: src/states_screens/options_screen_input.cpp:152 +#: src/states_screens/options_screen_ui.cpp:124 +#: src/states_screens/options_screen_video.cpp:240 #: src/states_screens/server_selection.cpp:103 msgid "Players" msgstr "" @@ -1418,8 +1504,8 @@ msgstr "" #. I18N: Section in the settings menu #: src/states_screens/options_screen_audio.cpp:66 #: src/states_screens/options_screen_device.cpp:87 -#: src/states_screens/options_screen_input.cpp:141 -#: src/states_screens/options_screen_video.cpp:173 +#: src/states_screens/options_screen_input.cpp:151 +#: src/states_screens/options_screen_video.cpp:239 #: src/states_screens/user_screen.cpp:661 msgid "User Interface" msgstr "" @@ -1458,8 +1544,8 @@ msgstr "" #. I18N: Section in the settings menu #: src/states_screens/options_screen_audio.cpp:65 #: src/states_screens/options_screen_device.cpp:85 -#: src/states_screens/options_screen_input.cpp:139 -#: src/states_screens/options_screen_ui.cpp:121 +#: src/states_screens/options_screen_input.cpp:149 +#: src/states_screens/options_screen_ui.cpp:122 #: src/states_screens/user_screen.cpp:659 msgid "Graphics" msgstr "" @@ -1668,20 +1754,20 @@ msgstr "" msgid "Battle Island" msgstr "" -#. I18N: ../stk-assets/tracks/cave/track.xml -msgid "Cave X" +#. I18N: ../stk-assets/tracks/candela_city/track.xml +msgid "Candela City" msgstr "" -#. I18N: ../stk-assets/tracks/city/track.xml -msgid "Shiny Suburbs" +#. I18N: ../stk-assets/tracks/cave/track.xml +msgid "Cave X" msgstr "" #. I18N: ../stk-assets/tracks/cocoa_temple/track.xml msgid "Cocoa Temple" msgstr "" -#. I18N: ../stk-assets/tracks/farm/track.xml -msgid "Bovine Barnyard" +#. I18N: ../stk-assets/tracks/cornfield_crossing/track.xml +msgid "Cornfield Crossing" msgstr "" #. I18N: ../stk-assets/tracks/fortmagma/track.xml @@ -1872,18 +1958,18 @@ msgstr "" msgid "Completed achievement \"%s\"." msgstr "" -#: src/addons/addons_manager.cpp:104 src/addons/news_manager.cpp:325 -msgid "Can't access stkaddons server..." +#: src/addons/addons_manager.cpp:104 src/addons/news_manager.cpp:322 +msgid "Failed to connect to the SuperTuxKart add-ons server." msgstr "" -#: src/addons/news_manager.cpp:182 +#: src/addons/news_manager.cpp:179 #, c-format msgid "Error downloading news: '%s'." msgstr "" #. I18N: number of laps to race in a challenge #: src/challenges/challenge_data.cpp:266 -#: src/states_screens/race_result_gui.cpp:1422 +#: src/states_screens/race_result_gui.cpp:1424 #, c-format msgid "Laps: %i" msgstr "" @@ -1897,22 +1983,22 @@ msgstr "" msgid "New track '%s' now available" msgstr "" -#: src/challenges/challenge_data.cpp:523 +#: src/challenges/challenge_data.cpp:522 #, c-format msgid "New game mode '%s' now available" msgstr "" -#: src/challenges/challenge_data.cpp:533 +#: src/challenges/challenge_data.cpp:532 #, c-format msgid "New Grand Prix '%s' now available" msgstr "" -#: src/challenges/challenge_data.cpp:537 +#: src/challenges/challenge_data.cpp:536 #, c-format msgid "New difficulty '%s' now available" msgstr "" -#: src/challenges/challenge_data.cpp:547 +#: src/challenges/challenge_data.cpp:546 #, c-format msgid "New kart '%s' now available" msgstr "" @@ -1944,40 +2030,48 @@ msgid "" "created." msgstr "" -#: src/graphics/irr_driver.cpp:1950 -#, c-format -msgid "FPS: %d/%d/%d - PolyCount: %d Solid, %d Shadows - LightDist : %d" +#: src/graphics/irr_driver.cpp:618 +msgid "Video recording started." msgstr "" -#: src/graphics/irr_driver.cpp:1961 +#: src/graphics/irr_driver.cpp:624 +#, c-format +msgid "Video saved in \"%s\"." +msgstr "" + +#: src/graphics/irr_driver.cpp:628 +msgid "Encoding progress:" +msgstr "" + +#: src/graphics/irr_driver.cpp:1801 #, c-format msgid "FPS: %d/%d/%d - %d KTris" msgstr "" -#: src/guiengine/engine.cpp:1289 +#: src/guiengine/engine.cpp:1296 msgid "Loading" msgstr "" -#: src/guiengine/widgets/kart_stats_widget.cpp:89 +#: src/guiengine/widgets/kart_stats_widget.cpp:108 msgid "WEIGHT" msgstr "" -#: src/guiengine/widgets/kart_stats_widget.cpp:94 +#: src/guiengine/widgets/kart_stats_widget.cpp:113 msgid "SPEED" msgstr "" -#: src/guiengine/widgets/kart_stats_widget.cpp:98 +#: src/guiengine/widgets/kart_stats_widget.cpp:117 msgid "POWER" msgstr "" #. I18N: 'handicapped' indicates that per-player handicaps are #. activated for this kart (i.e. it will drive slower) -#: src/guiengine/widgets/player_kart_widget.cpp:361 +#: src/guiengine/widgets/player_kart_widget.cpp:381 #, c-format msgid "%s (handicapped)" msgstr "" -#: src/guiengine/widgets/player_kart_widget.cpp:420 +#: src/guiengine/widgets/player_kart_widget.cpp:440 #, c-format msgid "%s is ready" msgstr "" @@ -2469,11 +2563,11 @@ msgid "Mouse axis %d %s" msgstr "" #. I18N: shown when config file is too old -#: src/input/device_manager.cpp:501 +#: src/input/device_manager.cpp:543 msgid "Please re-configure your key bindings." msgstr "" -#: src/input/device_manager.cpp:502 +#: src/input/device_manager.cpp:544 msgid "Your input config file is not compatible with this version of STK." msgstr "" @@ -2495,51 +2589,51 @@ msgstr "" #. I18N: name of buttons on gamepads #. I18N: name of stick on gamepads -#: src/input/gamepad_config.cpp:181 src/input/gamepad_config.cpp:247 +#: src/input/gamepad_config.cpp:181 src/input/gamepad_config.cpp:244 msgid "Right thumb right" msgstr "" #. I18N: name of buttons on gamepads #. I18N: name of stick on gamepads -#: src/input/gamepad_config.cpp:183 src/input/gamepad_config.cpp:249 +#: src/input/gamepad_config.cpp:183 src/input/gamepad_config.cpp:246 msgid "Right thumb left" msgstr "" #. I18N: name of buttons on gamepads -#. I18N: name of stick on gamepads -#: src/input/gamepad_config.cpp:185 src/input/gamepad_config.cpp:243 +#. I18N: name of trigger on gamepads +#: src/input/gamepad_config.cpp:185 src/input/gamepad_config.cpp:240 msgid "Right thumb down" msgstr "" #. I18N: name of buttons on gamepads #. I18N: name of stick on gamepads -#: src/input/gamepad_config.cpp:187 src/input/gamepad_config.cpp:245 +#: src/input/gamepad_config.cpp:187 src/input/gamepad_config.cpp:242 msgid "Right thumb up" msgstr "" #. I18N: name of buttons on gamepads -#. I18N: name of stick on gamepads -#: src/input/gamepad_config.cpp:189 src/input/gamepad_config.cpp:241 +#: src/input/gamepad_config.cpp:189 src/input/gamepad_config.cpp:248 msgid "Right trigger" msgstr "" #. I18N: name of buttons on gamepads -#: src/input/gamepad_config.cpp:191 src/input/gamepad_config.cpp:255 +#: src/input/gamepad_config.cpp:191 src/input/gamepad_config.cpp:253 msgid "DPad right" msgstr "" #. I18N: name of buttons on gamepads -#: src/input/gamepad_config.cpp:193 src/input/gamepad_config.cpp:257 +#: src/input/gamepad_config.cpp:193 src/input/gamepad_config.cpp:255 msgid "DPad left" msgstr "" #. I18N: name of buttons on gamepads -#: src/input/gamepad_config.cpp:195 src/input/gamepad_config.cpp:253 +#: src/input/gamepad_config.cpp:195 src/input/gamepad_config.cpp:251 msgid "DPad down" msgstr "" #. I18N: name of buttons on gamepads -#: src/input/gamepad_config.cpp:197 src/input/gamepad_config.cpp:251 +#. I18N: name of trigger on gamepads +#: src/input/gamepad_config.cpp:197 src/input/gamepad_config.cpp:249 msgid "DPad up" msgstr "" @@ -2588,55 +2682,63 @@ msgstr "" msgid "Left thumb up" msgstr "" -#: src/input/input_manager.cpp:768 +#: src/input/input_manager.cpp:807 #, c-format msgid "Ignoring '%s'. You needed to join earlier to play!" msgstr "" -#: src/input/input_manager.cpp:798 +#: src/input/input_manager.cpp:837 msgid "Only the Game Master may act at this point!" msgstr "" -#: src/input/wiimote_manager.cpp:389 +#: src/input/wiimote_manager.cpp:388 msgid "" "Connect your wiimote to the Bluetooth manager, then click on Ok. Detailed " "instructions at supertuxkart.net/Wiimote" msgstr "" -#: src/input/wiimote_manager.cpp:392 +#: src/input/wiimote_manager.cpp:391 msgid "" "Press the buttons 1+2 simultaneously on your wiimote to put it in discovery " "mode, then click on Ok. Detailed instructions at supertuxkart.net/Wiimote" msgstr "" -#: src/input/wiimote_manager.cpp:415 +#: src/input/wiimote_manager.cpp:414 #, c-format msgid "Found %d wiimote" msgid_plural "Found %d wiimotes" msgstr[0] "" msgstr[1] "" -#: src/input/wiimote_manager.cpp:420 +#: src/input/wiimote_manager.cpp:419 msgid "Could not detect any wiimote :/" msgstr "" -#: src/karts/controller/local_player_controller.cpp:206 +#: src/karts/controller/local_player_controller.cpp:244 msgid "Penalty time!!" msgstr "" -#: src/karts/controller/local_player_controller.cpp:208 +#: src/karts/controller/local_player_controller.cpp:246 msgid "Don't accelerate before go" msgstr "" -#: src/karts/kart.cpp:852 src/karts/kart.cpp:857 +#: src/karts/controller/spare_tire_ai.cpp:147 +msgid "You can have at most 3 lives!" +msgstr "" + +#: src/karts/controller/spare_tire_ai.cpp:153 +msgid "+1 life." +msgstr "" + +#: src/karts/kart.cpp:903 src/karts/kart.cpp:908 msgid "You won the race!" msgstr "" -#: src/karts/kart.cpp:857 +#: src/karts/kart.cpp:908 msgid "You finished the race!" msgstr "" -#: src/main.cpp:1413 +#: src/main.cpp:1500 msgid "" "SuperTuxKart may connect to a server to download add-ons and notify you of " "updates. We also collect anonymous hardware statistics to help with the " @@ -2646,12 +2748,16 @@ msgid "" "edit \"Connect to the Internet\" and \"Send anonymous HW statistics\")." msgstr "" -#: src/main.cpp:1563 +#: src/main.cpp:1654 +msgid "Your screen resolution is too low to run STK." +msgstr "" + +#: src/main.cpp:1668 msgid "" "Your driver version is too old. Please install the latest video drivers." msgstr "" -#: src/main.cpp:1580 +#: src/main.cpp:1685 #, c-format msgid "" "Your OpenGL version appears to be too old. Please verify if an update for " @@ -2663,81 +2769,89 @@ msgstr "" msgid "Eggs: %d / %d" msgstr "" -#: src/modes/follow_the_leader.cpp:61 src/modes/follow_the_leader.cpp:284 +#: src/modes/follow_the_leader.cpp:62 src/modes/follow_the_leader.cpp:285 msgid "Leader" msgstr "" -#: src/modes/linear_world.cpp:284 +#: src/modes/linear_world.cpp:287 msgid "Final lap!" msgstr "" -#: src/modes/linear_world.cpp:311 +#: src/modes/linear_world.cpp:314 #, c-format msgid "Lap %i" msgstr "" -#: src/modes/linear_world.cpp:366 +#: src/modes/linear_world.cpp:369 #, c-format msgctxt "fastest_lap" msgid "%s by %s" msgstr "" -#: src/modes/linear_world.cpp:371 +#: src/modes/linear_world.cpp:374 msgid "New fastest lap" msgstr "" -#: src/modes/linear_world.cpp:890 +#: src/modes/linear_world.cpp:891 msgid "WRONG WAY!" msgstr "" -#: src/modes/world.cpp:1207 +#: src/modes/three_strikes_battle.cpp:664 +#, c-format +msgid "%i spare tire kart has been spawned!" +msgid_plural "%i spare tire karts have been spawned!" +msgstr[0] "" +msgstr[1] "" + +#: src/modes/world.cpp:1202 msgid "You have been eliminated!" msgstr "" -#: src/modes/world.cpp:1210 +#: src/modes/world.cpp:1205 #, c-format msgid "'%s' has been eliminated." msgstr "" -#: src/network/protocols/server_lobby_room_protocol.cpp:237 -msgid "Failed to register server" +#: src/network/protocols/server_lobby.cpp:318 +#, c-format +msgid "Failed to register server: %s" msgstr "" -#: src/network/servers_manager.cpp:197 +#: src/network/servers_manager.cpp:198 msgid "No LAN server detected" msgstr "" -#: src/online/online_player_profile.cpp:420 +#: src/online/online_player_profile.cpp:419 #, c-format msgid "%s is now online." msgstr "" -#: src/online/online_player_profile.cpp:424 +#: src/online/online_player_profile.cpp:423 #, c-format msgid "%s and %s are now online." msgstr "" -#: src/online/online_player_profile.cpp:429 +#: src/online/online_player_profile.cpp:428 #, c-format msgid "%s, %s and %s are now online." msgstr "" #. I18N: Only used for count > 3 -#: src/online/online_player_profile.cpp:435 +#: src/online/online_player_profile.cpp:434 #, c-format msgid "%d friend is now online." msgid_plural "%d friends are now online." msgstr[0] "" msgstr[1] "" -#: src/online/online_player_profile.cpp:472 +#: src/online/online_player_profile.cpp:471 #, c-format msgid "You have %d new friend request!" msgid_plural "You have %d new friend requests!" msgstr[0] "" msgstr[1] "" -#: src/online/online_player_profile.cpp:478 +#: src/online/online_player_profile.cpp:477 msgid "You have a new friend request!" msgstr "" @@ -2777,11 +2891,11 @@ msgstr "" msgid "Soccer" msgstr "" -#: src/replay/replay_recorder.cpp:182 +#: src/replay/replay_recorder.cpp:183 msgid "Incomplete replay file will not be saved." msgstr "" -#: src/replay/replay_recorder.cpp:218 +#: src/replay/replay_recorder.cpp:219 #, c-format msgid "Replay saved in \"%s\"." msgstr "" @@ -2844,7 +2958,7 @@ msgid "Please wait while addons are updated" msgstr "" #: src/states_screens/addons_screen.cpp:551 -#: src/states_screens/main_menu_screen.cpp:554 +#: src/states_screens/main_menu_screen.cpp:571 msgid "" "Sorry, an error occurred while contacting the add-ons website. Make sure you " "are connected to the Internet and that SuperTuxKart is not blocked by a " @@ -2866,8 +2980,8 @@ msgstr "" #: src/states_screens/arenas_screen.cpp:327 #: src/states_screens/easter_egg_screen.cpp:225 #: src/states_screens/easter_egg_screen.cpp:256 -#: src/states_screens/kart_selection.cpp:864 -#: src/states_screens/kart_selection.cpp:1450 +#: src/states_screens/kart_selection.cpp:859 +#: src/states_screens/kart_selection.cpp:1464 #: src/states_screens/race_setup_screen.cpp:99 msgid "Locked : solve active challenges to gain access to more!" msgstr "" @@ -2904,7 +3018,7 @@ msgstr "" msgid "The maxinum number of players has to be between 2 and 12." msgstr "" -#: src/states_screens/credits.cpp:217 +#: src/states_screens/credits.cpp:180 msgid "translator-credits" msgstr "" @@ -3010,74 +3124,74 @@ msgid_plural "Confirm resolution within %i seconds" msgstr[0] "" msgstr[1] "" +#. I18N: Geometry level disabled : lowest level, no details #. I18N: in the graphical options tooltip; #. indicates a graphical feature is disabled -#: src/states_screens/dialogs/custom_video_settings.cpp:62 -#: src/states_screens/dialogs/custom_video_settings.cpp:86 -#: src/states_screens/options_screen_video.cpp:387 +#: src/states_screens/dialogs/custom_video_settings.cpp:66 +#: src/states_screens/dialogs/custom_video_settings.cpp:78 +#: src/states_screens/dialogs/custom_video_settings.cpp:95 +#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:59 +#: src/states_screens/options_screen_video.cpp:454 msgid "Disabled" msgstr "" #. I18N: animations setting (only karts with human players are animated) -#: src/states_screens/dialogs/custom_video_settings.cpp:64 +#: src/states_screens/dialogs/custom_video_settings.cpp:68 msgid "Human players only" msgstr "" -#. I18N: animations setting (all karts are animated) -#: src/states_screens/dialogs/custom_video_settings.cpp:66 +#: src/states_screens/dialogs/custom_video_settings.cpp:71 msgid "Enabled for all" msgstr "" -#: src/states_screens/dialogs/custom_video_settings.cpp:76 -msgid "Bilinear" -msgstr "" - -#: src/states_screens/dialogs/custom_video_settings.cpp:77 -msgid "Trilinear" -msgstr "" - -#: src/states_screens/dialogs/custom_video_settings.cpp:78 -msgid "Anisotropic x2" -msgstr "" - -#: src/states_screens/dialogs/custom_video_settings.cpp:79 -msgid "Anisotropic x4" -msgstr "" - +#. I18N: Geometry level low : few details are displayed +#. I18N: in the graphical options tooltip; +#. indicates the rendered image quality is low #: src/states_screens/dialogs/custom_video_settings.cpp:80 -msgid "Anisotropic x8" +#: src/states_screens/dialogs/custom_video_settings.cpp:89 +#: src/states_screens/dialogs/custom_video_settings.cpp:96 +#: src/states_screens/options_screen_video.cpp:467 +msgid "Low" msgstr "" -#: src/states_screens/dialogs/custom_video_settings.cpp:81 -msgid "Anisotropic x16" -msgstr "" - -#: src/states_screens/dialogs/custom_video_settings.cpp:87 -msgid "low" +#. I18N: Geometry level high : everything is displayed +#. I18N: in the graphical options tooltip; +#. indicates the rendered image quality is high +#: src/states_screens/dialogs/custom_video_settings.cpp:82 +#: src/states_screens/dialogs/custom_video_settings.cpp:90 +#: src/states_screens/dialogs/custom_video_settings.cpp:97 +#: src/states_screens/options_screen_video.cpp:470 +msgid "High" msgstr "" +#. I18N: in the graphical options tooltip; +#. indicates the rendered image quality is very low #: src/states_screens/dialogs/custom_video_settings.cpp:88 -msgid "high" +#: src/states_screens/options_screen_video.cpp:464 +msgid "Very Low" msgstr "" -#: src/states_screens/dialogs/enter_gp_name_dialog.cpp:125 -msgid "Name is empty." -msgstr "" - -#: src/states_screens/dialogs/enter_gp_name_dialog.cpp:132 -msgid "Another grand prix with this name already exists." -msgstr "" - -#: src/states_screens/dialogs/enter_gp_name_dialog.cpp:137 -msgid "Name is too long." +#. I18N: in the graphical options tooltip; +#. indicates the rendered image quality is very high +#: src/states_screens/dialogs/custom_video_settings.cpp:91 +#: src/states_screens/options_screen_video.cpp:473 +msgid "Very High" msgstr "" #: src/states_screens/dialogs/message_dialog.cpp:129 #: src/states_screens/edit_gp_screen.cpp:257 -#: src/states_screens/ghost_replay_selection.cpp:116 +#: src/states_screens/ghost_replay_selection.cpp:117 msgid "No" msgstr "" +#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:60 +msgid "Tablet" +msgstr "" + +#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:61 +msgid "Phone" +msgstr "" + #: src/states_screens/dialogs/recovery_dialog.cpp:121 msgid "Username and/or email address invalid." msgstr "" @@ -3176,7 +3290,7 @@ msgstr "" #: src/states_screens/easter_egg_screen.cpp:270 #: src/states_screens/tracks_and_gp_screen.cpp:292 -#: src/states_screens/tracks_screen.cpp:242 +#: src/states_screens/tracks_screen.cpp:241 msgid "Random Track" msgstr "" @@ -3195,8 +3309,8 @@ msgid "Reversed" msgstr "" #: src/states_screens/edit_gp_screen.cpp:124 -#: src/states_screens/ghost_replay_selection.cpp:174 -#: src/states_screens/grand_prix_editor_screen.cpp:109 +#: src/states_screens/ghost_replay_selection.cpp:177 +#: src/states_screens/grand_prix_editor_screen.cpp:112 #, c-format msgid "Are you sure you want to remove '%s'?" msgstr "" @@ -3215,7 +3329,7 @@ msgstr "" msgid "An error occurred while trying to save your grand prix." msgstr "" -#: src/states_screens/edit_track_screen.cpp:237 +#: src/states_screens/edit_track_screen.cpp:235 msgid "Select a track" msgstr "" @@ -3252,13 +3366,17 @@ msgstr "" msgid "Finish Time" msgstr "" +#: src/states_screens/ghost_replay_selection.cpp:83 +msgid "User" +msgstr "" + #: src/states_screens/gp_info_screen.cpp:74 msgid "Default" msgstr "" #. I18N: if no kart animations are enabled #: src/states_screens/gp_info_screen.cpp:75 -#: src/states_screens/options_screen_video.cpp:393 +#: src/states_screens/options_screen_video.cpp:460 msgid "None" msgstr "" @@ -3271,62 +3389,80 @@ msgstr "" msgid "Reload" msgstr "" -#: src/states_screens/grand_prix_editor_screen.cpp:164 +#: src/states_screens/grand_prix_cutscene.cpp:75 +#: src/states_screens/grand_prix_editor_screen.cpp:101 +#: src/states_screens/grand_prix_editor_screen.cpp:118 +msgid "Please enter the name of the grand prix" +msgstr "" + +#: src/states_screens/grand_prix_editor_screen.cpp:169 msgid "Please select a Grand Prix" msgstr "" -#: src/states_screens/grand_prix_editor_screen.cpp:326 +#: src/states_screens/grand_prix_editor_screen.cpp:331 msgid "User defined" msgstr "" +#: src/states_screens/grand_prix_editor_screen.cpp:344 +msgid "Name is empty." +msgstr "" + +#: src/states_screens/grand_prix_editor_screen.cpp:352 +msgid "Another grand prix with this name already exists." +msgstr "" + +#: src/states_screens/grand_prix_editor_screen.cpp:358 +msgid "Name is too long." +msgstr "" + #. I18N: when failing a GP #: src/states_screens/grand_prix_lose.cpp:154 msgid "Better luck next time!" msgstr "" -#: src/states_screens/grand_prix_win.cpp:127 +#: src/states_screens/grand_prix_win.cpp:166 #: src/states_screens/race_result_gui.cpp:194 msgid "You completed a challenge!" msgstr "" -#: src/states_screens/grand_prix_win.cpp:284 +#: src/states_screens/grand_prix_win.cpp:322 msgid "You completed the Grand Prix!" msgstr "" -#: src/states_screens/kart_selection.cpp:845 -#: src/states_screens/kart_selection.cpp:1468 +#: src/states_screens/kart_selection.cpp:840 +#: src/states_screens/kart_selection.cpp:1482 msgid "Random Kart" msgstr "" -#: src/states_screens/kart_selection.cpp:859 +#: src/states_screens/kart_selection.cpp:854 msgid "Locked" msgstr "" -#: src/states_screens/kart_selection.cpp:929 +#: src/states_screens/kart_selection.cpp:944 msgid "" "Everyone:\n" "Press the 'Select' button to join the game" msgstr "" -#: src/states_screens/main_menu_screen.cpp:493 +#: src/states_screens/main_menu_screen.cpp:510 msgid "" "You can not play online without internet access. If you want to play online, " "go to options, select tab 'User Interface', and edit \"Connect to the " "Internet\"." msgstr "" -#: src/states_screens/main_menu_screen.cpp:517 +#: src/states_screens/main_menu_screen.cpp:534 msgid "" "You can not download addons without internet access. If you want to download " "addons, go to options, select tab 'User Interface', and edit \"Connect to " "the Internet\"." msgstr "" -#: src/states_screens/main_menu_screen.cpp:549 +#: src/states_screens/main_menu_screen.cpp:566 msgid "The add-ons module is currently disabled in the Options screen" msgstr "" -#: src/states_screens/main_menu_screen.cpp:561 +#: src/states_screens/main_menu_screen.cpp:578 msgid "Please wait while the add-ons are loading" msgstr "" @@ -3389,13 +3525,13 @@ msgstr "" #. I18N: button to disable a gamepad configuration #: src/states_screens/options_screen_device.cpp:96 -#: src/states_screens/options_screen_device.cpp:575 +#: src/states_screens/options_screen_device.cpp:579 msgid "Disable Device" msgstr "" #. I18N: button to enable a gamepad configuration #: src/states_screens/options_screen_device.cpp:98 -#: src/states_screens/options_screen_device.cpp:576 +#: src/states_screens/options_screen_device.cpp:580 msgid "Enable Device" msgstr "" @@ -3497,7 +3633,7 @@ msgstr "" msgid "* A red item means a conflict in the current configuration" msgstr "" -#: src/states_screens/options_screen_device.cpp:467 +#: src/states_screens/options_screen_device.cpp:471 msgid "" "Warning: The 'Shift' is not a recommended key. When 'Shift' is pressed down, " "all keys that contain a character that is different in upper-case will stop " @@ -3505,33 +3641,33 @@ msgid "" msgstr "" #. I18N: shown before deleting an input configuration -#: src/states_screens/options_screen_device.cpp:563 +#: src/states_screens/options_screen_device.cpp:567 msgid "Are you sure you want to permanently delete this configuration?" msgstr "" -#: src/states_screens/options_screen_input.cpp:97 +#: src/states_screens/options_screen_input.cpp:100 #, c-format msgid "Keyboard %i" msgstr "" -#: src/states_screens/options_screen_ui.cpp:158 +#: src/states_screens/options_screen_ui.cpp:159 msgid "" "In multiplayer mode, players can select handicapped (more difficult) " "profiles on the kart selection screen" msgstr "" #. I18N: in the language choice, to select the same language as the OS -#: src/states_screens/options_screen_ui.cpp:190 +#: src/states_screens/options_screen_ui.cpp:191 msgid "System Language" msgstr "" #. I18N: custom video settings -#: src/states_screens/options_screen_video.cpp:366 +#: src/states_screens/options_screen_video.cpp:433 msgid "Custom" msgstr "" #. I18N: if some kart animations are enabled -#: src/states_screens/options_screen_video.cpp:391 +#: src/states_screens/options_screen_video.cpp:458 msgid "Me Only" msgstr "" @@ -3539,94 +3675,93 @@ msgstr "" #. tooltip = tooltip + L"\n" + _("Pixel shaders: %s", #. UserConfigParams::m_pixel_shaders ? enabled : disabled); #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:399 +#: src/states_screens/options_screen_video.cpp:479 #, c-format msgid "Animated Scenery: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:402 +#: src/states_screens/options_screen_video.cpp:482 #, c-format msgid "Weather Effects: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:405 +#: src/states_screens/options_screen_video.cpp:485 #, c-format msgid "Animated Characters: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:410 +#: src/states_screens/options_screen_video.cpp:490 #, c-format msgid "Dynamic lights: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:413 +#: src/states_screens/options_screen_video.cpp:493 #, c-format msgid "Motion blur: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:416 +#: src/states_screens/options_screen_video.cpp:496 #, c-format msgid "Anti-aliasing: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:419 +#: src/states_screens/options_screen_video.cpp:499 #, c-format msgid "Ambient occlusion: %s" msgstr "" -#: src/states_screens/options_screen_video.cpp:423 +#: src/states_screens/options_screen_video.cpp:503 #, c-format msgid "Shadows: %s" msgstr "" -#: src/states_screens/options_screen_video.cpp:425 +#: src/states_screens/options_screen_video.cpp:505 #, c-format msgid "Shadows: %i" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:428 +#: src/states_screens/options_screen_video.cpp:508 #, c-format msgid "Bloom: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:432 +#: src/states_screens/options_screen_video.cpp:512 #, c-format msgid "Glow (outlines): %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:436 +#: src/states_screens/options_screen_video.cpp:516 #, c-format msgid "Light shaft (God rays): %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:440 +#: src/states_screens/options_screen_video.cpp:520 #, c-format msgid "Depth of field: %s" msgstr "" #. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:444 +#: src/states_screens/options_screen_video.cpp:524 #, c-format msgid "Global illumination: %s" msgstr "" -#. I18N: in graphical options -#: src/states_screens/options_screen_video.cpp:448 +#: src/states_screens/options_screen_video.cpp:529 #, c-format -msgid "Use high definition textures: %s" +msgid "Rendered image quality: %s" msgstr "" -#: src/states_screens/race_gui.cpp:306 src/states_screens/race_gui.cpp:308 +#: src/states_screens/race_gui.cpp:358 src/states_screens/race_gui.cpp:360 msgid "Challenge Failed" msgstr "" @@ -3651,42 +3786,42 @@ msgid "GOAL!" msgstr "" #. I18N: string used to show the author of the music. (e.g. "Sunny Song" by "John Doe") -#: src/states_screens/race_gui_base.cpp:496 +#: src/states_screens/race_gui_base.cpp:517 msgid "by" msgstr "" -#: src/states_screens/race_gui_base.cpp:604 +#: src/states_screens/race_gui_base.cpp:626 msgid "Collect nitro!" msgstr "" -#: src/states_screens/race_gui_base.cpp:606 +#: src/states_screens/race_gui_base.cpp:628 msgid "Follow the leader!" msgstr "" #. I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it -#: src/states_screens/race_gui_base.cpp:772 +#: src/states_screens/race_gui_base.cpp:806 #, c-format msgid "Top %i" msgstr "" #. I18N: Shown at the end of a race -#: src/states_screens/race_gui_overworld.cpp:108 +#: src/states_screens/race_gui_overworld.cpp:143 msgid "Lap" msgstr "" -#: src/states_screens/race_gui_overworld.cpp:109 +#: src/states_screens/race_gui_overworld.cpp:144 msgid "Rank" msgstr "" -#: src/states_screens/race_gui_overworld.cpp:472 -msgid "Press fire to play the tutorial" +#: src/states_screens/race_gui_overworld.cpp:518 +msgid "Press fire to start the tutorial" msgstr "" -#: src/states_screens/race_gui_overworld.cpp:511 +#: src/states_screens/race_gui_overworld.cpp:557 msgid "Type: Grand Prix" msgstr "" -#: src/states_screens/race_gui_overworld.cpp:548 +#: src/states_screens/race_gui_overworld.cpp:594 msgid "Press fire to start the challenge" msgstr "" @@ -3718,52 +3853,52 @@ msgstr "" msgid "Back to the menu" msgstr "" -#: src/states_screens/race_result_gui.cpp:373 +#: src/states_screens/race_result_gui.cpp:372 msgid "Do you really want to abort the Grand Prix?" msgstr "" -#: src/states_screens/race_result_gui.cpp:498 -#: src/states_screens/race_result_gui.cpp:861 +#: src/states_screens/race_result_gui.cpp:499 +#: src/states_screens/race_result_gui.cpp:865 msgid "Eliminated" msgstr "" -#: src/states_screens/race_result_gui.cpp:1028 +#: src/states_screens/race_result_gui.cpp:1012 msgid "Red Team Wins" msgstr "" -#: src/states_screens/race_result_gui.cpp:1032 +#: src/states_screens/race_result_gui.cpp:1016 msgid "Blue Team Wins" msgstr "" -#: src/states_screens/race_result_gui.cpp:1037 +#: src/states_screens/race_result_gui.cpp:1021 msgid "It's a draw" msgstr "" #. I18N: indicates a player that scored in their own goal in result screen -#: src/states_screens/race_result_gui.cpp:1106 +#: src/states_screens/race_result_gui.cpp:1098 #: src/states_screens/race_result_gui.cpp:1154 msgid "(Own Goal)" msgstr "" -#: src/states_screens/race_result_gui.cpp:1219 +#: src/states_screens/race_result_gui.cpp:1220 #, c-format msgid "Track %i/%i" msgstr "" -#: src/states_screens/race_result_gui.cpp:1303 +#: src/states_screens/race_result_gui.cpp:1304 msgid "Grand Prix progress:" msgstr "" -#: src/states_screens/race_result_gui.cpp:1344 +#: src/states_screens/race_result_gui.cpp:1346 msgid "Highscores" msgstr "" -#: src/states_screens/race_result_gui.cpp:1430 +#: src/states_screens/race_result_gui.cpp:1432 #, c-format msgid "Difficulty: %s" msgstr "" -#: src/states_screens/race_result_gui.cpp:1438 +#: src/states_screens/race_result_gui.cpp:1440 #, c-format msgid "Best lap time: %s" msgstr "" @@ -3835,7 +3970,7 @@ msgid "Internet access is disabled, please enable it in the options" msgstr "" #: src/states_screens/server_selection.cpp:79 -#: src/states_screens/server_selection.cpp:248 +#: src/states_screens/server_selection.cpp:247 msgid "Fetching servers" msgstr "" @@ -3849,11 +3984,11 @@ msgid "Locked!" msgstr "" #: src/states_screens/tracks_and_gp_screen.cpp:278 -#: src/states_screens/tracks_screen.cpp:228 +#: src/states_screens/tracks_screen.cpp:227 msgid "Locked: solve active challenges to gain access to more!" msgstr "" -#: src/states_screens/tracks_screen.cpp:195 +#: src/states_screens/tracks_screen.cpp:194 msgid "Only official tracks are supported." msgstr "" @@ -3871,12 +4006,12 @@ msgid "Max players supported: %d" msgstr "" #. I18N: In the track info screen -#: src/states_screens/track_info_screen.cpp:214 +#: src/states_screens/track_info_screen.cpp:213 msgid "Drive in reverse" msgstr "" #. I18N: In the track info screen -#: src/states_screens/track_info_screen.cpp:219 +#: src/states_screens/track_info_screen.cpp:218 msgid "Random item location" msgstr "" diff --git a/src/graphics/vao_manager.cpp b/src/graphics/vao_manager.cpp index 969f55e9d..e553162d0 100644 --- a/src/graphics/vao_manager.cpp +++ b/src/graphics/vao_manager.cpp @@ -83,12 +83,12 @@ VAOManager::~VAOManager() } static void -resizeBufferIfNecessary(size_t &lastIndex, size_t newLastIndex, size_t bufferSize, size_t stride, GLenum type, GLuint &id, void *&Pointer) +resizeBufferIfNecessary(size_t &lastIndex, size_t newLastIndex, size_t& bufferSize, size_t stride, GLenum type, GLuint &id, void *&Pointer) { - if (newLastIndex * stride >= bufferSize) + if (newLastIndex >= bufferSize) { while (newLastIndex >= bufferSize) - bufferSize = 2 * bufferSize + 1; + bufferSize = bufferSize == 0 ? 1 : bufferSize * 2; GLuint newVBO; glGenBuffers(1, &newVBO); glBindBuffer(type, newVBO); diff --git a/src/input/multitouch_device.cpp b/src/input/multitouch_device.cpp index cbd6f8610..9d1c8e4eb 100644 --- a/src/input/multitouch_device.cpp +++ b/src/input/multitouch_device.cpp @@ -43,14 +43,7 @@ MultitouchDevice::MultitouchDevice() assert(m_android_device != NULL); #endif - for (MultitouchEvent& event : m_events) - { - event.id = 0; - event.touched = false; - event.x = 0; - event.y = 0; - } - + reset(); updateConfigParams(); } // MultitouchDevice @@ -183,6 +176,28 @@ void MultitouchDevice::clearButtons() m_buttons.clear(); } // clearButtons +// ---------------------------------------------------------------------------- +/** Sets all buttons and events to default state + */ +void MultitouchDevice::reset() +{ + for (MultitouchButton* button : m_buttons) + { + button->pressed = false; + button->event_id = 0; + button->axis_x = 0.0f; + button->axis_y = 0.0f; + } + + for (MultitouchEvent& event : m_events) + { + event.id = 0; + event.touched = false; + event.x = 0; + event.y = 0; + } +} // reset + // ---------------------------------------------------------------------------- /** The function that is executed when touch event occurs. It updates the * buttons state when it's needed. diff --git a/src/input/multitouch_device.hpp b/src/input/multitouch_device.hpp index 47c644f22..8dd21d153 100644 --- a/src/input/multitouch_device.hpp +++ b/src/input/multitouch_device.hpp @@ -111,6 +111,7 @@ public: void addButton(MultitouchButtonType type, int x, int y, int width, int height); void clearButtons(); + void reset(); /** Returns the number of created buttons */ unsigned int getButtonsCount() {return m_buttons.size();} diff --git a/src/items/flyable.cpp b/src/items/flyable.cpp index e0b122844..e18b37f18 100644 --- a/src/items/flyable.cpp +++ b/src/items/flyable.cpp @@ -67,13 +67,14 @@ Flyable::Flyable(AbstractKart *kart, PowerupManager::PowerupType type, m_type = type; m_has_hit_something = false; m_shape = NULL; + m_animation = NULL; m_mass = mass; m_adjust_up_velocity = true; m_time_since_thrown = 0; m_position_offset = Vec3(0,0,0); m_owner_has_temporary_immunity = true; m_do_terrain_info = true; - m_max_lifespan = -1; + m_max_lifespan = -1; // Add the graphical model #ifndef SERVER_ONLY @@ -353,6 +354,24 @@ void Flyable::getLinearKartItemIntersection (const Vec3 &origin, + ( target_y_speed); } // getLinearKartItemIntersection +//----------------------------------------------------------------------------- + +void Flyable::setAnimation(AbstractKartAnimation *animation) +{ + if (animation) + { + assert(m_animation == NULL); + Physics::getInstance()->removeBody(m_body); + } + else // animation = NULL + { + assert(m_animation != NULL); + m_body->setWorldTransform(getTrans()); + Physics::getInstance()->addBody(m_body); + } + m_animation = animation; +} // addAnimation + //----------------------------------------------------------------------------- /** Updates this flyable. It calls Moveable::update. If this function returns * true, the flyable will be deleted by the projectile manager. @@ -361,6 +380,13 @@ void Flyable::getLinearKartItemIntersection (const Vec3 &origin, */ bool Flyable::updateAndDelete(float dt) { + if (hasAnimation()) + { + m_animation->update(dt); + Moveable::update(dt); + return false; + } // if animation + m_time_since_thrown += dt; if(m_max_lifespan > -1 && m_time_since_thrown > m_max_lifespan) hit(NULL); diff --git a/src/items/flyable.hpp b/src/items/flyable.hpp index 8daa0fdb5..3b46b7ae6 100644 --- a/src/items/flyable.hpp +++ b/src/items/flyable.hpp @@ -34,6 +34,7 @@ using namespace irr; #include "tracks/terrain_info.hpp" class AbstractKart; +class AbstractKartAnimation; class HitEffect; class PhysicalObject; class XMLNode; @@ -64,6 +65,11 @@ private: * terrain yourself (e.g. order of operations is important) * set this to false with a call do setDoTerrainInfo(). */ bool m_do_terrain_info; + + /** If the flyable is in a cannon, this is the pointer to the cannon + * animation. NULL otherwise. */ + AbstractKartAnimation *m_animation; + protected: /** Kart which shot this flyable. */ AbstractKart* m_owner; @@ -162,11 +168,16 @@ public: static void init (const XMLNode &node, scene::IMesh *model, PowerupManager::PowerupType type); virtual bool updateAndDelete(float); + virtual void setAnimation(AbstractKartAnimation *animation); virtual HitEffect* getHitEffect() const; bool isOwnerImmunity(const AbstractKart *kart_hit) const; virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL); void explode(AbstractKart* kart, PhysicalObject* obj=NULL, bool secondary_hits=true); + unsigned int getOwnerId(); + // ------------------------------------------------------------------------ + /** Returns if this flyable has an animation playing (e.g. cannon). */ + bool hasAnimation() const { return m_animation != NULL; } // ------------------------------------------------------------------------ /** If true the up velocity of the flyable will be adjust so that the * flyable stays at a height close to the average height. @@ -194,15 +205,16 @@ public: void reset () { Moveable::reset(); } // ------------------------------------------------------------------------ /** Returns the type of flyable. */ - PowerupManager::PowerupType - getType() const {return m_type;} + PowerupManager::PowerupType getType() const {return m_type;} // ------------------------------------------------------------------------ /** Sets wether Flyable should update TerrainInfo as part of its update * call, or if the inheriting object will update TerrainInfo itself * (or perhaps not at all if it is not needed). */ void setDoTerrainInfo(bool d) { m_do_terrain_info = d; } // ------------------------------------------------------------------------ - unsigned int getOwnerId(); + /** Returns the size (extend) of the mesh. */ + const Vec3 &getExtend() const { return m_extend; } + // ------------------------------------------------------------------------ }; // Flyable #endif diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 2f69e3c43..8dd90e353 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -29,6 +29,7 @@ #include "modes/linear_world.hpp" #include "physics/btKart.hpp" #include "physics/triangle_mesh.hpp" +#include "tracks/check_manager.hpp" #include "tracks/drive_graph.hpp" #include "tracks/drive_node.hpp" #include "tracks/track.hpp" @@ -103,7 +104,7 @@ RubberBall::RubberBall(AbstractKart *kart) DriveGraph::get()->getNode(getCurrentGraphNode())->getNormal(); TerrainInfo::update(getXYZ(), -normal); initializeControlPoints(m_owner->getXYZ()); - + CheckManager::get()->addFlyableToCannons(this); } // RubberBall // ---------------------------------------------------------------------------- @@ -114,6 +115,7 @@ RubberBall::~RubberBall() if(m_ping_sfx->getStatus()==SFXBase::SFX_PLAYING) m_ping_sfx->stop(); m_ping_sfx->deleteSFX(); + CheckManager::get()->removeFlyableFromCannons(this); } // ~RubberBall // ---------------------------------------------------------------------------- @@ -145,6 +147,17 @@ void RubberBall::initializeControlPoints(const Vec3 &xyz) m_t_increase = m_speed/m_length_cp_1_2; } // initializeControlPoints +// ---------------------------------------------------------------------------- +void RubberBall::setAnimation(AbstractKartAnimation *animation) +{ + if (!animation) + { + initializeControlPoints(getXYZ()); + m_height_timer = 0; + } + Flyable::setAnimation(animation); +} // setAnimation + // ---------------------------------------------------------------------------- /** Determines the first kart that is still in the race. */ @@ -310,6 +323,7 @@ bool RubberBall::updateAndDelete(float dt) // FIXME: what does the rubber ball do in case of battle mode?? if(!world) return true; + if(m_delete_timer>0) { m_delete_timer -= dt; @@ -323,6 +337,14 @@ bool RubberBall::updateAndDelete(float dt) } } + if (hasAnimation()) + { + // Flyable will call update() of the animation to + // update the ball's position. + m_previous_xyz = getXYZ(); + return Flyable::updateAndDelete(dt); + } + // Update the target in case that the first kart was overtaken (or has // finished the race). computeTarget(); diff --git a/src/items/rubber_ball.hpp b/src/items/rubber_ball.hpp index 2d354136b..5575786e7 100644 --- a/src/items/rubber_ball.hpp +++ b/src/items/rubber_ball.hpp @@ -204,6 +204,7 @@ public: static void init(const XMLNode &node, scene::IMesh *rubberball); virtual bool updateAndDelete(float dt); virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL); + virtual void setAnimation(AbstractKartAnimation *animation); static float getTimeBetweenRubberBalls() {return m_time_between_balls;} // ------------------------------------------------------------------------ /** This object does not create an explosion, all affects on diff --git a/src/karts/abstract_kart_animation.cpp b/src/karts/abstract_kart_animation.cpp index 54cc9b09c..f78fdeeba 100644 --- a/src/karts/abstract_kart_animation.cpp +++ b/src/karts/abstract_kart_animation.cpp @@ -24,6 +24,11 @@ #include "karts/skidding.hpp" #include "physics/physics.hpp" +/** Constructor. Note that kart can be NULL in case that the animation is + * used for a basket ball in a cannon animation. + * \param kart Pointer to the kart that is animated, or NULL if the + * the animation is meant for a basket ball etc. + */ AbstractKartAnimation::AbstractKartAnimation(AbstractKart *kart, const std::string &name) { @@ -37,7 +42,7 @@ AbstractKartAnimation::AbstractKartAnimation(AbstractKart *kart, // up animations) if this should happen. In debug mode this condition // is caught by setKartAnimation(), and useful error messages are // printed - if (kart->getKartAnimation()) + if (kart && kart->getKartAnimation()) { AbstractKartAnimation* ka = kart->getKartAnimation(); kart->setKartAnimation(NULL); @@ -46,21 +51,23 @@ AbstractKartAnimation::AbstractKartAnimation(AbstractKart *kart, #endif // Register this animation with the kart (which will free it // later). - kart->setKartAnimation(this); - Physics::getInstance()->removeKart(m_kart); - kart->getSkidding()->reset(); - kart->getSlipstream()->reset(); - if(kart->isSquashed()) + if (kart) { - // A time of 0 reset the squashing - kart->setSquash(0.0f, 0.0f); + kart->setKartAnimation(this); + Physics::getInstance()->removeKart(m_kart); + kart->getSkidding()->reset(); + kart->getSlipstream()->reset(); + if (kart->isSquashed()) + { + // A time of 0 reset the squashing + kart->setSquash(0.0f, 0.0f); + } + + // Reset the wheels (and any other animation played for that kart) + // This avoid the effect that some wheels might be way below the kart + // which is very obvious in the rescue animation. + m_kart->getKartModel()->resetVisualWheelPosition(); } - - // Reset the wheels (and any other animation played for that kart) - // This avoid the effect that some wheels might be way below the kart - // which is very obvious in the rescue animation. - m_kart->getKartModel()->resetVisualWheelPosition(); - } // AbstractKartAnimation // ---------------------------------------------------------------------------- @@ -70,7 +77,7 @@ AbstractKartAnimation::~AbstractKartAnimation() // is deleted (at the end of a race), which means that // world is in the process of being deleted. In this case // we can't call getPhysics() anymore. - if(m_timer < 0) + if(m_timer < 0 && m_kart) { m_kart->getBody()->setAngularVelocity(btVector3(0,0,0)); Physics::getInstance()->addKart(m_kart); @@ -91,7 +98,7 @@ void AbstractKartAnimation::update(float dt) m_timer -= dt; if(m_timer<0) { - m_kart->setKartAnimation(NULL); + if(m_kart) m_kart->setKartAnimation(NULL); delete this; } } // update diff --git a/src/karts/cannon_animation.cpp b/src/karts/cannon_animation.cpp index cd3caced9..68a31f073 100644 --- a/src/karts/cannon_animation.cpp +++ b/src/karts/cannon_animation.cpp @@ -21,6 +21,7 @@ #include "animations/animation_base.hpp" #include "animations/ipo.hpp" #include "animations/three_d_animation.hpp" +#include "items/flyable.hpp" #include "karts/abstract_kart.hpp" #include "karts/kart_properties.hpp" #include "modes/world.hpp" @@ -28,7 +29,8 @@ #include "LinearMath/btTransform.h" /** The constructor for the cannon animation. - * \param kart The kart to be animated. + * \param kart The kart to be animated. Can also be NULL if a basket ball + * etc is animated (e.g. cannon animation). * \param ipo The IPO (blender interpolation curve) which the kart * should follow. * \param start_left, start_right: Left and right end points of the line @@ -45,9 +47,41 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo, float skid_rot) : AbstractKartAnimation(kart, "CannonAnimation") { - m_curve = new AnimationBase(ipo); - m_timer = ipo->getEndTime(); - + m_flyable = NULL; + init(ipo, start_left, start_right, end_left, end_right, skid_rot); +} // CannonAnimation + +// ---------------------------------------------------------------------------- +/** Constructor for a flyable. It sets the kart data to NULL. + */ +CannonAnimation::CannonAnimation(Flyable *flyable, Ipo *ipo, + const Vec3 &start_left, const Vec3 &start_right, + const Vec3 &end_left, const Vec3 &end_right ) + : AbstractKartAnimation(NULL, "CannonAnimation") +{ + m_flyable = flyable; + init(ipo, start_left, start_right, end_left, end_right, /*skid_rot*/0); +} // CannonAnimation(Flyable*...) + +// ---------------------------------------------------------------------------- +/** Common initialisation for kart-based and flyable-based animations. + * \param ipo The IPO (blender interpolation curve) which the kart + * should follow. + * \param start_left, start_right: Left and right end points of the line + * that the kart just crossed. + * \param end_left, end_right: Left and right end points of the line at + * which the kart finishes. + * \param skid_rot Visual rotation of the kart due to skidding (while this + * value can be queried, the AbstractkartAnimation constructor + * resets the value to 0, so it needs to be passed in. + */ +void CannonAnimation::init(Ipo *ipo, const Vec3 &start_left, + const Vec3 &start_right, const Vec3 &end_left, + const Vec3 &end_right, float skid_rot) +{ + m_curve = new AnimationBase(ipo); + m_timer = ipo->getEndTime(); + // First make sure that left and right points are indeed correct // ------------------------------------------------------------- Vec3 my_start_left = start_left; @@ -57,12 +91,17 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo, // (the curve's origin must be in the middle of the line. m_curve->getAt(0, &p0); m_curve->getAt(0.1f, &p1); - Vec3 p2 = 0.5f*(p0 + p1) + m_kart->getNormal(); + Vec3 p2; + if (m_kart) + p2 = 0.5f*(p0 + p1) + m_kart->getNormal(); + else + p2 = 0.5f*(p0 + p1) + m_flyable->getNormal(); + if (start_left.sideofPlane(p0, p1, p2) < 0) { // Left and right start line needs to be swapped my_start_left = start_right; - my_start_right = start_left; + my_start_right = start_left; } // First adjust start and end points to take on each side half the kart @@ -70,8 +109,9 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo, Vec3 direction = my_start_right - my_start_left; direction.normalize(); - float kw = m_kart->getKartModel()->getWidth(); - Vec3 adj_start_left = my_start_left + (0.5f*kw) * direction; + float kw = m_kart ? m_kart->getKartModel()->getWidth() + : m_flyable->getExtend().getX(); + Vec3 adj_start_left = my_start_left + (0.5f*kw) * direction; Vec3 adj_start_right = my_start_right - (0.5f*kw) * direction; // Store the length of the start and end line, which is used @@ -99,16 +139,17 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo, // This delta is rotated with the kart and added to the interpolated curve // position to get the actual kart position during the animation. Vec3 curve_xyz; + Vec3 xyz = m_kart ? m_kart->getXYZ() : m_flyable->getXYZ(); m_curve->update(0, &curve_xyz); - m_delta = kart->getXYZ() - curve_xyz; - + m_delta = xyz - curve_xyz; + // Compute on which fraction of the start line the kart is, to get the // second component of the kart position: distance along start line Vec3 v = adj_start_left - adj_start_right; float l = v.length(); v /= l; - float f = v.dot(adj_start_left - kart->getXYZ()); + float f = v.dot(adj_start_left - xyz); if (f <= 0) f = 0; else if (f >= l) @@ -138,28 +179,36 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo, Vec3 tangent; m_curve->getDerivativeAt(0, &tangent); // Get the current kart orientation - Vec3 forward = m_kart->getTrans().getBasis().getColumn(2); + const btTransform &trans = m_kart ? m_kart->getTrans() + : m_flyable->getBody()->getWorldTransform(); + Vec3 forward = trans.getBasis().getColumn(2); Vec3 v1(tangent), v2(forward); v1.setY(0); v2.setY(0); - m_delta_heading = shortestArcQuatNormalize2(v1, v2) - * btQuaternion(Vec3(0,1,0), skid_rot); + m_delta_heading = shortestArcQuatNormalize2(v1, v2) + * btQuaternion(Vec3(0, 1, 0), skid_rot); // The previous call to m_curve->update will set the internal timer // of the curve to dt. Reset it to 0 to make sure the timer is in // synch with the timer of the CanonAnimation m_curve->reset(); -} // CannonAnimation +} // init // ---------------------------------------------------------------------------- CannonAnimation::~CannonAnimation() { delete m_curve; - - btTransform pos = m_kart->getTrans(); - m_kart->getBody()->setCenterOfMassTransform(pos); - Vec3 v(0, 0, m_kart->getKartProperties()->getEngineMaxSpeed()); - m_kart->setVelocity(pos.getBasis()*v); + if (m_kart) + { + btTransform pos = m_kart->getTrans(); + m_kart->getBody()->setCenterOfMassTransform(pos); + Vec3 v(0, 0, m_kart->getKartProperties()->getEngineMaxSpeed()); + m_kart->setVelocity(pos.getBasis()*v); + } + else + { + m_flyable->setAnimation(NULL); + } } // ~CannonAnimation // ---------------------------------------------------------------------------- @@ -184,7 +233,9 @@ void CannonAnimation::update(float dt) m_curve->getDerivativeAt(m_curve->getAnimationDuration() - m_timer, &tangent); // Get the current kart orientation - Vec3 forward = m_kart->getTrans().getBasis().getColumn(2); + const btTransform &trans = m_kart ? m_kart->getTrans() + : m_flyable->getBody()->getWorldTransform(); + Vec3 forward = trans.getBasis().getColumn(2); // Heading // ------- @@ -200,10 +251,14 @@ void CannonAnimation::update(float dt) // ------------------ // While start and end line have to have the same 'up' vector, karts can // sometimes be not parallel to them. So slowly adjust this over time - Vec3 up = m_kart->getTrans().getBasis().getColumn(1); + Vec3 up = trans.getBasis().getColumn(1); up.normalize(); - Vec3 gravity = -m_kart->getBody()->getGravity(); - gravity.normalize(); + Vec3 gravity = m_kart ? -m_kart->getBody()->getGravity() + : -m_flyable->getBody()->getGravity(); + if (gravity.length2() > 0) + gravity.normalize(); + else + gravity.setValue(0, 1, 0); // Adjust only 5% towards the real up vector. This will smoothly // adjust the kart while the kart is in the air Vec3 target_up_vector = (gravity*0.05f + up*0.95f).normalize(); @@ -220,27 +275,33 @@ void CannonAnimation::update(float dt) // The timer counts backwards, so the fraction goes from 1 to 0 float f = m_timer / m_curve->getAnimationDuration(); - - btQuaternion zero(gravity, 0); - btQuaternion current_delta_heading = zero.slerp(m_delta_heading, f); - - btQuaternion all_heading = m_kart->getRotation()*current_delta_heading*heading; - - m_kart->setRotation(q_up * all_heading); - - - // Then compute the new location of the kart - // ----------------------------------------- float f_current_width = m_start_line_length * f + m_end_line_length * (1.0f - f); - // Adjust the horizontal location based on steering - m_fraction_of_line += m_kart->getSteerPercent()*dt*2.0f; - btClamp(m_fraction_of_line, -1.0f, 1.0f); + // Then compute the new location of the kart + // ----------------------------------------- + btQuaternion all_heading; + if (m_kart) + { + btQuaternion zero(gravity, 0); + btQuaternion current_delta_heading = zero.slerp(m_delta_heading, f); + all_heading = m_kart->getRotation()*current_delta_heading*heading; + m_kart->setRotation(q_up * all_heading); - // horiz_delta is in kart coordinates, the rotation by q will - // transform it to the global coordinate system - Vec3 horiz_delta = Vec3(0.5f*m_fraction_of_line * f_current_width, 0, 0); + // Adjust the horizontal location based on steering + m_fraction_of_line += m_kart->getSteerPercent()*dt*2.0f; + btClamp(m_fraction_of_line, -1.0f, 1.0f); + } // if m_kart + else + { + // If a rubber ball is in this cannon, reduce its height over + // time so that it starts closer to the ground when released + float height = m_delta.getY(); + float radius = m_flyable->getExtend().getY(); + height = (height - radius) * 0.95f + radius; + m_delta.setY(height); + all_heading.setValue(0, 0, 0, 1); + } // Determine direction orthogonal to the curve for the sideway movement // of the kart. @@ -251,5 +312,8 @@ void CannonAnimation::update(float dt) Vec3 curve_xyz; m_curve->update(dt, &curve_xyz); - m_kart->setXYZ(curve_xyz+rotated_delta); + if (m_kart) + m_kart->setXYZ(curve_xyz + rotated_delta); + else + m_flyable->setXYZ(curve_xyz + rotated_delta); } // update diff --git a/src/karts/cannon_animation.hpp b/src/karts/cannon_animation.hpp index f36098d32..37853da81 100644 --- a/src/karts/cannon_animation.hpp +++ b/src/karts/cannon_animation.hpp @@ -26,6 +26,7 @@ class AbstractKart; class AnimationBase; +class Flyable; class Ipo; @@ -46,6 +47,10 @@ protected: /** Stores the curve interpolation for the cannon. */ AnimationBase *m_curve; + /** If this animation is used for a flyable (e.g. basket ball) instead + * of a kart, m_flyable is defined and m_kart is NULL. */ + Flyable *m_flyable; + /** Length of the (adjusted, i.e. taking kart width into account) * start line. */ float m_start_line_length; @@ -61,12 +66,19 @@ protected: /** The initial heading of the kart when crossing the line. This is * used to smoothly orient the kart towards the normal of the cuve. */ btQuaternion m_delta_heading; + + void init(Ipo *ipo, const Vec3 &start_left, const Vec3 &start_right, + const Vec3 &end_left, const Vec3 &end_right, float skid_rot); + public: CannonAnimation(AbstractKart *kart, Ipo *ipo, const Vec3 &start_left, const Vec3 &start_right, const Vec3 &end_left, const Vec3 &end_right, float skid_rot); - virtual ~CannonAnimation(); + CannonAnimation(Flyable *flyable, Ipo *ipo, + const Vec3 &start_left, const Vec3 &start_right, + const Vec3 &end_left, const Vec3 &end_right); + virtual ~CannonAnimation(); virtual void update(float dt); }; // CannonAnimation diff --git a/src/main.cpp b/src/main.cpp index 719da100c..4675bbe93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1132,7 +1132,7 @@ int handleCmdLine() if(CommandLine::has("--track", &s) || CommandLine::has("-t", &s)) { race_manager->setTrack(s); - Log::verbose("main", "You choose to start in track '%s'.", + Log::verbose("main", "You chose to start in track '%s'.", s.c_str()); Track* t = track_manager->getTrack(s); @@ -1142,7 +1142,7 @@ int handleCmdLine() } else if (t->isArena()) { - //if it's arena, don't create ai karts + //if it's arena, don't create AI karts const std::vector l; race_manager->setDefaultAIKartList(l); // Add 1 for the player kart @@ -1151,7 +1151,7 @@ int handleCmdLine() } else if (t->isSoccer()) { - //if it's soccer, don't create ai karts + //if it's soccer, don't create AI karts const std::vector l; race_manager->setDefaultAIKartList(l); // Add 1 for the player kart @@ -1218,7 +1218,7 @@ int handleCmdLine() } else { - Log::verbose("main", "You choose to have %d laps.", laps); + Log::verbose("main", "You chose to have %d laps.", laps); race_manager->setNumLaps(laps); } } // --laps @@ -1330,7 +1330,7 @@ int handleCmdLine() if (request->isSuccess()) { - Log::info("Main", "Logged in from command line."); + Log::info("Main", "Logged in from command-line."); } } @@ -1390,9 +1390,9 @@ void initRest() font_manager->loadFonts(); GUIEngine::init(device, driver, StateManager::get()); - // This only initialises the non-network part of the addons manager. The - // online section of the addons manager will be initialised from a - // separate thread running in network http. + // This only initialises the non-network part of the add-ons manager. The + // online section of the add-ons manager will be initialised from a + // separate thread running in network HTTP. addons_manager = new AddonsManager(); Online::ProfileManager::create(); @@ -1477,7 +1477,7 @@ void askForInternetPermission() // Typically internet is disabled here (just better safe // than sorry). If internet should be allowed, the news // manager needs to be started (which in turn activates - // the addons manager). + // the add-ons manager). bool need_to_start_news_manager = UserConfigParams::m_internet_status != Online::RequestManager::IPERM_ALLOWED; @@ -1615,8 +1615,8 @@ int main(int argc, char *argv[] ) addons_manager->checkInstalledAddons(); - // Load addons.xml to get info about addons even when not - // allowed to access the internet + // Load addons.xml to get info about add-ons even when not + // allowed to access the Internet if (UserConfigParams::m_internet_status != Online::RequestManager::IPERM_ALLOWED) { @@ -1630,7 +1630,7 @@ int main(int argc, char *argv[] ) } catch (std::runtime_error& e) { - Log::warn("Addons", "Exception thrown when initializing addons manager : %s", e.what()); + Log::warn("Addons", "Exception thrown when initializing add-ons manager : %s", e.what()); } } } @@ -1652,7 +1652,7 @@ int main(int argc, char *argv[] ) { MessageDialog *dialog = new MessageDialog(_("Your screen resolution is too " - "small to run STK."), + "low to run STK."), /*from queue*/ true); GUIEngine::DialogQueue::get()->pushDialog(dialog); } @@ -1898,7 +1898,7 @@ static void cleanSuperTuxKart() // But still give them some additional time to finish. It avoids a // race condition where a thread might access the file manager after it // was deleted (in cleanUserConfig below), but before STK finishes and - // the os takes all threads down. + // the OS takes all threads down. if(!NewsManager::get()->waitForReadyToDeleted(2.0f)) { @@ -1918,12 +1918,12 @@ static void cleanSuperTuxKart() } SFXManager::destroy(); - // Music manager can not be deleted before the sfx thread is stopped - // (since sfx commands can contain music information, which are + // Music manager can not be deleted before the SFX thread is stopped + // (since SFX commands can contain music information, which are // deleted by the music manager). delete music_manager; - // The addons manager might still be called from a currenty running request + // The add-ons manager might still be called from a currenty running request // in the request manager, so it can not be deleted earlier. if(addons_manager) delete addons_manager; diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 097345b2b..c48bfdede 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -436,6 +436,8 @@ World::~World() irr_driver->onUnloadWorld(); + projectile_manager->cleanup(); + // In case that a race is aborted (e.g. track not found) track is 0. if(Track::getCurrentTrack()) Track::getCurrentTrack()->cleanup(); @@ -486,8 +488,6 @@ World::~World() Camera::removeAllCameras(); - projectile_manager->cleanup(); - // In case that the track is not found, Physics was not instantiated, // but kill handles this correctly. Physics::kill(); diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index a052c7a92..3c69d9833 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -87,6 +87,13 @@ RaceGUI::RaceGUI() const float map_size = 100.0f; const float top_margin = 3.5f * m_font_height; + if (UserConfigParams::m_multitouch_enabled && + UserConfigParams::m_multitouch_mode != 0 && + race_manager->getNumLocalPlayers() == 1) + { + m_multitouch_gui = new RaceGUIMultitouch(this); + } + // Check if we have enough space for minimap when touch steering is enabled if (m_multitouch_gui != NULL) { @@ -139,6 +146,7 @@ RaceGUI::RaceGUI() //----------------------------------------------------------------------------- RaceGUI::~RaceGUI() { + delete m_multitouch_gui; } // ~Racegui diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index f89eda495..9966b2041 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -101,13 +101,6 @@ RaceGUIBase::RaceGUIBase() m_referee = NULL; m_multitouch_gui = NULL; - - if (UserConfigParams::m_multitouch_enabled && - UserConfigParams::m_multitouch_mode != 0 && - race_manager->getNumLocalPlayers() == 1) - { - m_multitouch_gui = new RaceGUIMultitouch(this); - } } // RaceGUIBase // ---------------------------------------------------------------------------- @@ -161,6 +154,11 @@ void RaceGUIBase::reset() m_plunger_speed = core::vector2df(0,0); m_plunger_state = PLUNGER_STATE_INIT; clearAllMessages(); + + if (m_multitouch_gui != NULL) + { + m_multitouch_gui->reset(); + } } // reset //----------------------------------------------------------------------------- @@ -173,7 +171,6 @@ RaceGUIBase::~RaceGUIBase() // If the referee is currently being shown, // remove it from the scene graph. delete m_referee; - delete m_multitouch_gui; } // ~RaceGUIBase //----------------------------------------------------------------------------- diff --git a/src/states_screens/race_gui_multitouch.cpp b/src/states_screens/race_gui_multitouch.cpp index 0a906eb49..84c49e3b5 100644 --- a/src/states_screens/race_gui_multitouch.cpp +++ b/src/states_screens/race_gui_multitouch.cpp @@ -76,6 +76,18 @@ RaceGUIMultitouch::~RaceGUIMultitouch() } // ~RaceGUIMultitouch +//----------------------------------------------------------------------------- +/** Sets the multitouch race gui to its initial state + */ +void RaceGUIMultitouch::reset() +{ + if (m_device != NULL) + { + m_device->reset(); + } +} // reset + + //----------------------------------------------------------------------------- /** Clears all previously created buttons in the multitouch device */ diff --git a/src/states_screens/race_gui_multitouch.hpp b/src/states_screens/race_gui_multitouch.hpp index 876551a94..c691ca078 100644 --- a/src/states_screens/race_gui_multitouch.hpp +++ b/src/states_screens/race_gui_multitouch.hpp @@ -62,6 +62,7 @@ public: unsigned int getMinimapBottom() {return m_minimap_bottom;} void setGuiAction(bool enabled = true) {m_gui_action = enabled;} + void reset(); }; // RaceGUIMultitouch diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index 9a1ce79eb..c2d8b0099 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -86,6 +86,13 @@ RaceGUIOverworld::RaceGUIOverworld() float scaling = irr_driver->getFrameSize().Height / 420.0f; const float map_size = 250.0f; + + if (UserConfigParams::m_multitouch_enabled && + UserConfigParams::m_multitouch_mode != 0 && + race_manager->getNumLocalPlayers() == 1) + { + m_multitouch_gui = new RaceGUIMultitouch(this); + } // Check if we have enough space for minimap when touch steering is enabled if (m_multitouch_gui != NULL) @@ -156,6 +163,7 @@ RaceGUIOverworld::RaceGUIOverworld() //----------------------------------------------------------------------------- RaceGUIOverworld::~RaceGUIOverworld() { + delete m_multitouch_gui; } // ~RaceGUIOverworld //----------------------------------------------------------------------------- diff --git a/src/tracks/check_cannon.cpp b/src/tracks/check_cannon.cpp index b6df51bf2..b28fdf399 100644 --- a/src/tracks/check_cannon.cpp +++ b/src/tracks/check_cannon.cpp @@ -25,6 +25,7 @@ #include "graphics/show_curve.hpp" #include "graphics/stk_tex_manager.hpp" #include "io/xml_node.hpp" +#include "items/flyable.hpp" #include "karts/abstract_kart.hpp" #include "karts/cannon_animation.hpp" #include "karts/skidding.hpp" @@ -88,9 +89,12 @@ CheckCannon::CheckCannon(const XMLNode &node, unsigned int index) : video::SColor(128, 128, 128, 128); } buffer->recalculateBoundingBox(); - buffer->getMaterial().setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(128, 255, 105, 180))); - buffer->getMaterial().setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0))); - buffer->getMaterial().setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0))); + buffer->getMaterial().setTexture(0, STKTexManager::getInstance() + ->getUnicolorTexture(video::SColor(128, 255, 105, 180))); + buffer->getMaterial().setTexture(1, STKTexManager::getInstance() + ->getUnicolorTexture(video::SColor(0, 0, 0, 0))); + buffer->getMaterial().setTexture(2, STKTexManager::getInstance() + ->getUnicolorTexture(video::SColor(0, 0, 0, 0))); buffer->getMaterial().BackfaceCulling = false; //mesh->setBoundingBox(buffer->getBoundingBox()); m_debug_target_node = irr_driver->addMesh(mesh, "checkdebug"); @@ -114,6 +118,8 @@ CheckCannon::~CheckCannon() } // ~CheckCannon // ---------------------------------------------------------------------------- +/** Changes the colour of a check cannon depending on state. + */ void CheckCannon::changeDebugColor(bool is_active) { #if defined(DEBUG) && !defined(SERVER_ONLY) @@ -133,6 +139,55 @@ void CheckCannon::changeDebugColor(bool is_active) #endif } // changeDebugColor +// ---------------------------------------------------------------------------- +/** Adds a flyable to be tested for crossing a cannon checkline. + * \param flyable The flyable to be tested. + */ +void CheckCannon::addFlyable(Flyable *flyable) +{ + m_all_flyables.push_back(flyable); + m_flyable_previous_position.push_back(flyable->getXYZ()); +} // addFlyable + +// ---------------------------------------------------------------------------- +/** Removes a flyable from the tests if it crosses a checkline. Used when + * the flyable is removed (e.g. explodes). + */ +void CheckCannon::removeFlyable(Flyable *flyable) +{ + std::vector::iterator i = std::find(m_all_flyables.begin(), + m_all_flyables.end(), + flyable); + assert(i != m_all_flyables.end()); + int index = i - m_all_flyables.begin(); // get the index + m_all_flyables.erase(i); + m_flyable_previous_position.erase(m_flyable_previous_position.begin() + index); +} // removeFlyable + +// ---------------------------------------------------------------------------- +/** Overriden to also check all flyables registered with the cannon. + */ +void CheckCannon::update(float dt) +{ + CheckLine::update(dt); + for (unsigned int i = 0; i < m_all_flyables.size(); i++) + { + setIgnoreHeight(true); + bool triggered = isTriggered(m_flyable_previous_position[i], + m_all_flyables[i]->getXYZ(), + /*kart index - ignore*/ -1 ); + setIgnoreHeight(false); + m_flyable_previous_position[i] = m_all_flyables[i]->getXYZ(); + if(!triggered) continue; + + // Cross the checkline - add the cannon animation + CannonAnimation *animation = + new CannonAnimation(m_all_flyables[i], m_curve->clone(), + getLeftPoint(), getRightPoint(), + m_target_left, m_target_right); + m_all_flyables[i]->setAnimation(animation); + } // for i in all flyables +} // update // ---------------------------------------------------------------------------- /** Called when the check line is triggered. This function creates a cannon * animation object and attaches it to the kart. diff --git a/src/tracks/check_cannon.hpp b/src/tracks/check_cannon.hpp index 0708d944a..dec83aafc 100644 --- a/src/tracks/check_cannon.hpp +++ b/src/tracks/check_cannon.hpp @@ -21,8 +21,10 @@ #include "animations/animation_base.hpp" #include "tracks/check_line.hpp" +#include "utils/cpp2011.hpp" class CheckManager; +class Flyable; class Ipo; class ShowCurve; class XMLNode; @@ -51,12 +53,18 @@ private: /** Used to display debug information about checklines. */ scene::IMeshSceneNode *m_debug_target_node; #endif + std::vector m_all_flyables; + std::vector m_flyable_previous_position; public: CheckCannon(const XMLNode &node, unsigned int index); virtual ~CheckCannon(); - virtual void trigger(unsigned int kart_index); - virtual void changeDebugColor(bool is_active); + virtual void trigger(unsigned int kart_index) OVERRIDE; + virtual void changeDebugColor(bool is_active) OVERRIDE; + virtual void update(float dt) OVERRIDE; + + void addFlyable(Flyable *flyable); + void removeFlyable(Flyable *flyable); }; // CheckLine #endif diff --git a/src/tracks/check_cylinder.cpp b/src/tracks/check_cylinder.cpp index 669d271ae..c3ad9f35a 100644 --- a/src/tracks/check_cylinder.cpp +++ b/src/tracks/check_cylinder.cpp @@ -46,16 +46,16 @@ CheckCylinder::CheckCylinder(const XMLNode &node, unsigned int index, TriggerIte } // CheckCylinder // ---------------------------------------------------------------------------- -/** True if going from old_pos to new_pos enters or leaves this sphere. This +/** True if going from old_pos to new_pos enters or leaves this cylinder. This * function is called from update (of the checkline structure). It also * updates the flag about which karts are inside * \param old_pos Position in previous frame. * \param new_pos Position in current frame. - * \param kart_id Index of the kart, can be used to store kart specific + * \param kart_id Index of the kart, can be used to store kart specific * additional data. */ bool CheckCylinder::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int kart_id) + int kart_id) { // TODO: this is the code for a sphere, rewrite for cylinder Vec3 old_pos_xz(old_pos.x(), 0.0f, old_pos.z()); diff --git a/src/tracks/check_cylinder.hpp b/src/tracks/check_cylinder.hpp index 4af674561..6c6f9802a 100644 --- a/src/tracks/check_cylinder.hpp +++ b/src/tracks/check_cylinder.hpp @@ -52,7 +52,7 @@ public: TriggerItemListener* listener); virtual ~CheckCylinder() {}; virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int kart_id); + int kart_id); // ------------------------------------------------------------------------ /** Returns if kart indx is currently inside of the sphere. */ bool isInside(int index) const { return m_is_inside[index]; } diff --git a/src/tracks/check_goal.cpp b/src/tracks/check_goal.cpp index 496048f41..538f18916 100644 --- a/src/tracks/check_goal.cpp +++ b/src/tracks/check_goal.cpp @@ -55,7 +55,8 @@ void CheckGoal::update(float dt) if (world) { - if (isTriggered(m_previous_ball_position, world->getBallPosition(), -1)) + if (isTriggered(m_previous_ball_position, world->getBallPosition(), + /*kart index - ignore*/-1) ) { if (UserConfigParams::m_check_debug) { @@ -86,7 +87,7 @@ void CheckGoal::trigger(unsigned int i) // ---------------------------------------------------------------------------- bool CheckGoal::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int kartIndex) + int kart_index) { core::vector2df cross_point; diff --git a/src/tracks/check_goal.hpp b/src/tracks/check_goal.hpp index d1c36cb7c..a310ca60c 100644 --- a/src/tracks/check_goal.hpp +++ b/src/tracks/check_goal.hpp @@ -65,7 +65,7 @@ public: virtual void update(float dt) OVERRIDE; virtual void trigger(unsigned int kart_index) OVERRIDE; virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int indx) OVERRIDE; + int indx) OVERRIDE; virtual void reset(const Track &track) OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/tracks/check_lap.cpp b/src/tracks/check_lap.cpp index ab2d4bb1c..ee0f8ce8a 100644 --- a/src/tracks/check_lap.cpp +++ b/src/tracks/check_lap.cpp @@ -53,13 +53,13 @@ void CheckLap::reset(const Track &track) // ---------------------------------------------------------------------------- /** True if going from old_pos to new_pos crosses this checkline. This function * is called from update (of the checkline structure). - * \param old_pos Position in previous frame. - * \param new_pos Position in current frame. + * \param old_pos Position in previous frame. + * \param new_pos Position in current frame. * \param kart_index Index of the kart, can be used to store kart specific - * additional data. + * additional data. */ bool CheckLap::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int kart_index) + int kart_index) { World* w = World::getWorld(); LinearWorld* lin_world = dynamic_cast(w); diff --git a/src/tracks/check_lap.hpp b/src/tracks/check_lap.hpp index b6d19a78a..d8b6f82f3 100644 --- a/src/tracks/check_lap.hpp +++ b/src/tracks/check_lap.hpp @@ -40,7 +40,7 @@ public: CheckLap(const XMLNode &node, unsigned int index); virtual ~CheckLap() {}; virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int indx); + int indx); virtual void reset(const Track &track); }; // CheckLine diff --git a/src/tracks/check_line.cpp b/src/tracks/check_line.cpp index bc817dc53..197b586b0 100644 --- a/src/tracks/check_line.cpp +++ b/src/tracks/check_line.cpp @@ -40,6 +40,7 @@ CheckLine::CheckLine(const XMLNode &node, unsigned int index) : CheckStructure(node, index) { + m_ignore_height = false; // Note that when this is called the karts have not been allocated // in world, so we can't call world->getNumKarts() m_previous_sign.resize(race_manager->getNumberOfKarts()); @@ -169,13 +170,14 @@ void CheckLine::changeDebugColor(bool is_active) // ---------------------------------------------------------------------------- /** True if going from old_pos to new_pos crosses this checkline. This function * is called from update (of the checkline structure). - * \param old_pos Position in previous frame. - * \param new_pos Position in current frame. - * \param indx Index of the kart, can be used to store kart specific - * additional data. + * \param old_pos Position in previous frame. + * \param new_pos Position in current frame. + * \param kart_indx Index of the kart, can be used to store kart specific + * additional data. If set to a negative number it will + * be ignored (used for e.g. soccer ball, and basket ball). */ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int kart_index) + int kart_index) { World* w = World::getWorld(); core::vector2df p=new_pos.toIrrVector2d(); @@ -184,7 +186,7 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, bool previous_sign; - if (kart_index == UINT_MAX) + if (kart_index < 0) { core::vector2df p = old_pos.toIrrVector2d(); previous_sign = (m_line.getPointOrientation(p) >= 0); @@ -196,18 +198,20 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, // If the sign has changed, i.e. the infinite line was crossed somewhere, // check if the finite line was actually crossed: + core::vector2df cross_point; if (sign != previous_sign && m_line.intersectWith(core::line2df(old_pos.toIrrVector2d(), new_pos.toIrrVector2d()), - m_cross_point) ) + cross_point) ) { // Now check the minimum height: the kart position must be within a // reasonable distance in the Z axis - 'reasonable' for now to be // between -1 and 4 units (negative numbers are unlikely, but help // in case that the kart is 'somewhat' inside of the track, or the // checklines are a bit off in Z direction. - result = new_pos.getY()-m_min_height-m_under_min_height; + result = m_ignore_height || + (new_pos.getY()-m_min_height-m_under_min_height ); if(UserConfigParams::m_check_debug && !result) { if(World::getWorld()->getNumKarts()>0) @@ -219,20 +223,20 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, Log::info("CheckLine", "Kart %d crosses line, but wrong height " "(%f vs %f).", kart_index, new_pos.getY(), m_min_height); - } } else result = false; - if (kart_index != UINT_MAX) - m_previous_sign[kart_index] = sign; - - if (result && kart_index != UINT_MAX) + if (kart_index >= 0) { - LinearWorld* lw = dynamic_cast(w); - if (lw != NULL) - lw->setLastTriggeredCheckline(kart_index, m_index); + m_previous_sign[kart_index] = sign; + if (result) + { + LinearWorld* lw = dynamic_cast(w); + if (lw != NULL) + lw->setLastTriggeredCheckline(kart_index, m_index); + } } return result; } // isTriggered diff --git a/src/tracks/check_line.hpp b/src/tracks/check_line.hpp index 3b06e2ca8..8eee967af 100644 --- a/src/tracks/check_line.hpp +++ b/src/tracks/check_line.hpp @@ -46,7 +46,10 @@ private: /** The line that is tested for being crossed. */ core::line2df m_line; - core::vector2df m_cross_point; + /** True if this line should ignore the height test. This is required + * e.g. for basketball cannons, since the ball can be too height to + * otherwise trigger the cannon. */ + bool m_ignore_height; /** The minimum height of the checkline. */ float m_min_height; @@ -79,17 +82,18 @@ public: CheckLine(const XMLNode &node, unsigned int index); virtual ~CheckLine(); virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int indx); + int indx); virtual void reset(const Track &track); virtual void resetAfterKartMove(unsigned int kart_index); virtual void changeDebugColor(bool is_active); + // ------------------------------------------------------------------------ /** Returns the actual line data for this checkpoint. */ const core::line2df &getLine2D() const {return m_line;} // ------------------------------------------------------------------------ - /** Returns the 2d point at which the line was crossed. Note that this - * value is ONLY valid after isTriggered is called and inside of - * trigger(). */ - const core::vector2df &getCrossPoint() const { return m_cross_point; } + /** Sets if this check line should not do a height test for testing + * if a line is crossed. Used for basket calls in cannon (the ball can + * be too heigh to otherwise trigger he cannon). */ + void setIgnoreHeight(bool b) { m_ignore_height = b; } }; // CheckLine #endif diff --git a/src/tracks/check_manager.cpp b/src/tracks/check_manager.cpp index 502a84006..19c9a85c3 100644 --- a/src/tracks/check_manager.cpp +++ b/src/tracks/check_manager.cpp @@ -131,6 +131,37 @@ void CheckManager::resetAfterKartMove(AbstractKart *kart) (*i)->resetAfterKartMove(kart->getWorldKartId()); } // resetAfterKartMove +// ---------------------------------------------------------------------------- +/** Adds a flyable object to be tested against cannons. This will allow + * bowling- and rubber-balls to fly in a cannon. + * \param flyable Pointer to the flyable to be added. + */ +void CheckManager::addFlyableToCannons(Flyable *flyable) +{ + for (unsigned int i = 0; i < m_all_checks.size(); i++) + { + CheckCannon *cc = dynamic_cast(m_all_checks[i]); + if (cc) + cc->addFlyable(flyable); + } +} // addFlyable + +// ---------------------------------------------------------------------------- +/** Removes a flyable from all cannons. Used when this flyable is removed + * (e.g. explodes). + * \param flyable Pointer to the flyable to be removed. + */ +void CheckManager::removeFlyableFromCannons(Flyable *flyable) +{ + for (unsigned int i = 0; i < m_all_checks.size(); i++) + { + CheckCannon *cc = dynamic_cast(m_all_checks[i]); + if (cc) + cc->removeFlyable(flyable); + } + +} // addFlyable + // ---------------------------------------------------------------------------- /** Updates all animations. Called one per time step. * \param dt Time since last call. diff --git a/src/tracks/check_manager.hpp b/src/tracks/check_manager.hpp index 93b97cdf8..88664c110 100644 --- a/src/tracks/check_manager.hpp +++ b/src/tracks/check_manager.hpp @@ -27,6 +27,7 @@ class AbstractKart; class CheckStructure; +class Flyable; class Track; class XMLNode; class Vec3; @@ -46,6 +47,8 @@ private: ~CheckManager(); public: void add(CheckStructure* strct) { m_all_checks.push_back(strct); } + void addFlyableToCannons(Flyable *flyable); + void removeFlyableFromCannons(Flyable *flyable); void load(const XMLNode &node); void update(float dt); void reset(const Track &track); diff --git a/src/tracks/check_sphere.cpp b/src/tracks/check_sphere.cpp index bd07fcf24..2ba2e32ad 100644 --- a/src/tracks/check_sphere.cpp +++ b/src/tracks/check_sphere.cpp @@ -53,11 +53,11 @@ CheckSphere::CheckSphere(const XMLNode &node, unsigned int index) * updates the flag about which karts are inside * \param old_pos Position in previous frame. * \param new_pos Position in current frame. - * \param kart_id Index of the kart, can be used to store kart specific + * \param kart_id Index of the kart, can be used to store kart specific * additional data. */ bool CheckSphere::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int kart_id) + int kart_id) { float old_dist2 = (old_pos-m_center_point).length2(); float new_dist2 = (new_pos-m_center_point).length2(); diff --git a/src/tracks/check_sphere.hpp b/src/tracks/check_sphere.hpp index 4780ed681..b11e05fd9 100644 --- a/src/tracks/check_sphere.hpp +++ b/src/tracks/check_sphere.hpp @@ -48,7 +48,7 @@ public: CheckSphere(const XMLNode &node, unsigned int index); virtual ~CheckSphere() {}; virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int kart_id); + int kart_id); // ------------------------------------------------------------------------ /** Returns if kart indx is currently inside of the sphere. */ bool isInside(int index) const { return m_is_inside[index]; } diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index 921c7b3bc..bb7e29661 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -115,7 +115,7 @@ public: * additional data. */ virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, - unsigned int indx)=0; + int indx)=0; virtual void trigger(unsigned int kart_index); virtual void reset(const Track &track);