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

This commit is contained in:
hiker 2018-04-19 10:57:37 +10:00
commit 98555a8f35
130 changed files with 3420 additions and 1702 deletions

View File

@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8.4)
# root CMakeLists for the SuperTuxKart project
project(SuperTuxKart)
set(PROJECT_VERSION "git")
add_definitions( -DSUPERTUXKART_VERSION="${PROJECT_VERSION}" )
if(NOT (CMAKE_MAJOR_VERSION VERSION_LESS 3))
cmake_policy(SET CMP0043 OLD)

View File

@ -64,13 +64,13 @@ mesa-common-dev pkg-config zlib1g-dev
```
### In-game recorder
In order to build the in-game recorder for STK, you have to install
To build the in-game recorder for STK, you have to install
libopenglrecorder from your distribution, or compile it yourself from [here](https://github.com/Benau/libopenglrecorder).
Compilation instruction is explained there. If you don't need this feature, pass `-DBUILD_RECORDER=off` to cmake.
### Compiling
Run the following commands inside `stk-code` directory to compile SuperTuxKart:
To compile SuperTuxKart, run the following commands inside `stk-code` directory:
```bash
mkdir cmake_build
@ -80,6 +80,21 @@ make -j4
```
STK can then be run from the build directory with `bin/supertuxkart`
#### Keeping your build up to date
To recompile the latest code without redownloading the entire source, first run the ```svn up``` command inside the 'stk-assets' directory, then run the following commands inside the 'stk-code' directory:
```bash
git pull
cd cmake_build
cmake ..
make -j4
```
##### Build Speed Optimization
"-j4" is an example, for a faster build, use "-jx" instead, where "x" is the amount of CPU threads you have, minus one.
### Further options
To create a debug version of STK, run:
@ -106,7 +121,7 @@ location, specify `CMAKE_INSTALL_PREFIX` when running cmake, e.g.:
To Build SuperTuxKart on Windows, follow these instructions:
1. Download and install Visual Studio from here: [Visual Studio - Download](https://www.visualstudio.com/downloads/). The free Visual Studio Community edition works fine.
2. Download the SuperTuxKart source package from either [SuperTuxKart download area - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart/0.9.2) or [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control), and unpack it.
2. Download the SuperTuxKart source package from either [SuperTuxKart download area - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart/) or [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control), and unpack it.
*Note: If you downloaded the source package from here: [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control), then both `stk-code` and `stk-assets` **must** be in the same directory, otherwise the build can result in failure*
3. Download the Windows dependencies package from either [SuperTuxKart download area: Dependencies - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/Windows/)
or [SuperTuxKart on GitHub - Dependencies](https://github.com/supertuxkart/dependencies), and unpack it; then, copy the `dependencies` directory from either the `windows` or the `windows_64bit` directories into the `stk-code` directory, rename it to `dependencies-64bit` if you want to compile a 64bit build.

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.supertuxkart.stk"
package="org.supertuxkart.stk_dbg"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
@ -12,7 +12,8 @@
android:hasCode="false"
android:isGame="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true">
android:hardwareAccelerated="true"
android:resizeableActivity="false">
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
@ -32,7 +33,7 @@
</application>
<uses-sdk android:minSdkVersion="19"
android:targetSdkVersion="21" />
android:targetSdkVersion="26" />
<uses-feature android:glEsVersion="0x00020000" />
<uses-feature android:name="android.software.leanback" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

View File

@ -181,6 +181,9 @@ convert_image()
return
fi
SCALE_CMD=""
QUALITY_CMD=""
if [ $W -gt $TEXTURE_SIZE ] || [ $H -gt $TEXTURE_SIZE ]; then
if [ $W -gt $H ]; then
SCALED_W=$TEXTURE_SIZE

View File

@ -23,32 +23,32 @@ export ARCH_ARMV7=arm
export HOST_ARMV7=arm-linux-androideabi
export NDK_PLATFORM_ARMV7=android-19
export MIN_SDK_VERSION_ARMV7=19
export TARGET_SDK_VERSION_ARMV7=21
export COMPILE_SDK_VERSION_ARMV7=21
export TARGET_SDK_VERSION_ARMV7=26
export COMPILE_SDK_VERSION_ARMV7=26
export NDK_ABI_AARCH64=arm64-v8a
export ARCH_AARCH64=arm64
export HOST_AARCH64=aarch64-linux-android
export NDK_PLATFORM_AARCH64=android-21
export MIN_SDK_VERSION_AARCH64=21
export TARGET_SDK_VERSION_AARCH64=21
export COMPILE_SDK_VERSION_AARCH64=21
export TARGET_SDK_VERSION_AARCH64=26
export COMPILE_SDK_VERSION_AARCH64=26
export NDK_ABI_X86=x86
export ARCH_X86=x86
export HOST_X86=i686-linux-android
export NDK_PLATFORM_X86=android-19
export MIN_SDK_VERSION_X86=19
export TARGET_SDK_VERSION_X86=21
export COMPILE_SDK_VERSION_X86=21
export TARGET_SDK_VERSION_X86=26
export COMPILE_SDK_VERSION_X86=26
export NDK_ABI_X86_64=x86_64
export ARCH_X86_64=x86_64
export HOST_X86_64=x86_64-linux-android
export NDK_PLATFORM_X86_64=android-21
export MIN_SDK_VERSION_X86_64=21
export TARGET_SDK_VERSION_X86_64=21
export COMPILE_SDK_VERSION_X86_64=21
export TARGET_SDK_VERSION_X86_64=26
export COMPILE_SDK_VERSION_X86_64=26
export APP_NAME_RELEASE="SuperTuxKart"
export PACKAGE_NAME_RELEASE="org.supertuxkart.stk"

View File

@ -1,6 +1,6 @@
= SuperTuxKart =
A Kart Racing Game Featuring Tux & Friends
- Version git
- Version $STKVERSION$
- Visit us at supertuxkart.net
- SuperTuxKart is released under GPL 3.0
- Assets are released under Creative Commons and other licenses

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<challenge version="2">
<track id="stk_enterprise" laps="3"/>
<mode major="single" minor="followtheleader"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="110"/>
<hard>

View File

@ -24,7 +24,11 @@ title_font, by Marianne Gagnon (Auria), released under CC-BY-SA 3+
screen*.png, by Marianne Gagnon (Auria), including elements from the public domain Tango icon set
Gauge and bar by Totoplus62, released under CC-BY-SA 3
speed.png by Alayan, with elements by Totoplus62, released under CC-BY-SA 3
speed*.png by Alayan, released under CC-0
gauge*.png by Alayan, released under CC-0
menu_story by tavariz91, released under CC-0

View File

@ -2,7 +2,7 @@
Icons firstly made for SuperTuxKart UI on Android.
Files: blur_bg_button ; blur_bg_button_focus ; directionnal_wheel ; drift ; nitro ; nitro_empty ; pause ; thunderbird_reset ; wing_mirror
Files: blur_bg_button ; blur_bg_button_focus ; steering_wheel ; drift ; nitro ; nitro_empty ; pause ; thunderbird_reset ; wing_mirror
- CC BY-SA 4.0 / author: Néd J. Édoire
# License information:

View File

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -2,18 +2,21 @@
<stkgui>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
<spacer height="2%" width="25"/>
<box width="100%" height="75%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a type of control that you prefer" align="center" text_align="left" />
<box width="100%" height="80%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a type of control that you prefer" align="center" text_align="left" word_wrap="true"/>
<spacer height="15%" width="10"/>
<spacer height="7%" width="10"/>
<ribbon id="control_type" height="60%" width="100%" align="center">
<ribbon id="control_type" proportion="1" width="100%" align="center">
<icon-button id="accelerometer" width="fit" height="fit" icon="gui/difficulty_medium.png"
I18N="Control type" text="Accelerometer"/>
<icon-button id="steering_wheel" width="fit" height="fit" icon="gui/difficulty_hard.png"
I18N="Control type" text="Steering wheel"/>
</ribbon>
<spacer height="12%" width="10"/>
<label width="100%" text="You can change it later in touch device settings." text_align="left" word_wrap="true"/>
</box>
<spacer height="7%" width="10"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -312,21 +312,27 @@
max-speed-increase="5" duration="1" fade-out-time="2" max="20" />
<!-- Slipstream
base-speed: the speed for which length and width are valid.
They are upscaled when faster and downscaled when slower.
length: How far behind a kart slipstream works
(note : this helps OTHER karts)
width: how wide slipstream works furthest away from the kart.
collect-time: How many seconds of sstream give maximum benefit
use-time: How long the benefit will last.
add-power: Additional power due to sstreaming. 1 = +100%
inner-factor: The proportion of the slipstreaming area with
twice faster slipstream "credits" collection.
min-collect-time: How many seconds of sstream are needed to get a bonus
it can be accumulated faster if in the inner quad)
max-collect-time: How many seconds of sstream bonus can be accumulated at most
add-power: Additional power due to sstreaming.
min-speed: Minimum speed necessary for slipstream to take effect.
max-speed-increase: How much the speed of the kart might exceed
its normal maximum speed.
duration: How long the higher speed lasts after slipstream stopped
working.
duration-factor: A multiplicator to how long the higher speed lasts
1 means it last as long the total time collected
fade-out-time: How long the slip stream speed increase will
gradually be reduced. -->
<slipstream length="10" width="2" collect-time="2" use-time="5"
add-power="3" min-speed="10" max-speed-increase="5"
duration="1" fade-out-time="2" />
<slipstream base-speed="20" length="8" width="4" inner-factor="0.5"
min-collect-time="3" max-collect-time="8" add-power="300" min-speed="8"
max-speed-increase="5" duration-factor="1" fade-out-time="2" />
</characteristic>
<!-- The different difficulties (like easy, medium, hard) -->
@ -360,9 +366,8 @@
invulnerability-time="7" />
<nitro engine-force="350" max-speed-increase="4.5" duration="1.5"
fade-out-time="2.5" />
<slipstream length="11" collect-time="1.5" use-time="2.5" add-power="3.2"
min-speed="9" max-speed-increase="4" duration="1.2"
fade-out-time="2.3" />
<slipstream length="*0.9" collect-time="*0.9"
duration-factor="*1" fade-out-time="*1" />
</characteristic>
<characteristic name="medium">
<engine power="*0.63" max-speed="*1" brake-factor="*0.73"
@ -374,8 +379,7 @@
<explosion time="1.8" radius="5"
invulnerability-time="6" />
<nitro engine-force="425" consumption="1.4" duration="1" />
<slipstream use-time="3.3" add-power="2.8" duration="0.9"
fade-out-time="1.6" />
<slipstream duration-factor="*0.8" fade-out-time="*1" />
</characteristic>
<characteristic name="heavy">
<engine power="*1" max-speed="*1" brake-factor="*0.66"
@ -390,8 +394,8 @@
invulnerability-time="6" />
<nitro engine-force="600" consumption="2" max-speed-increase="8"
duration="0.7" fade-out-time="1.3" />
<slipstream length="8.5" use-time="4" add-power="2.7" min-speed="10.5"
max-speed-increase="8" duration="0.7" fade-out-time="1" />
<slipstream length="*1.1" collect-time="*1.1"
duration-factor="*0.6" fade-out-time="*1" />
</characteristic>
</kart-types>

File diff suppressed because it is too large Load Diff

View File

@ -4,14 +4,14 @@
#
# Translators:
# , 2015
# Viktar Vauchkevich, 2017
# Viktar Vauchkevich, 2017-2018
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-01-18 18:02+0000\n"
"Last-Translator: Viktar Vauchkevich\n"
"Language-Team: Belarusian (http://www.transifex.com/supertuxkart/supertuxkart/language/be/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -49,7 +49,7 @@ msgstr "Марафонец"
#. I18N: ./data/achievements.xml
msgid "Make a race with 5 laps or more."
msgstr "Зрабі гонку на 5 ці больш кругоў."
msgstr "Зрабі гонку на 5 ці больш колаў."
#. I18N: ./data/achievements.xml
msgid "Skid-row"
@ -57,7 +57,7 @@ msgstr "Дрыфтэр"
#. I18N: ./data/achievements.xml
msgid "Make 5 skidding in a single lap."
msgstr "Зрабі 5 заносаў за 1 круг."
msgstr "Зрабі 5 заносаў за 1 кола."
#. I18N: ./data/achievements.xml
msgid "Gold driver"
@ -274,7 +274,7 @@ msgstr "Стваральнікі"
#. I18N: ./data/gui/custom_video_settings.stkgui
msgid "Graphics Settings"
msgstr "Настаўленні графікі"
msgstr "Налады графікі"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
@ -299,7 +299,7 @@ msgstr "Зіхаценне (Bloom)"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Light shaft (God rays)"
msgstr "Промні святла"
msgstr "Промні святла (гало)"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
@ -354,17 +354,17 @@ msgstr "Анімацыя персанажаў"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Rendered image quality"
msgstr ""
msgstr "Якасць апрацаванай выявы"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Geometry detail"
msgstr ""
msgstr "Дэталі геаметрыі"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "* Restart STK to apply new settings"
msgstr "* Перазапусціце STK, каб ужыць новыя настаўленні"
msgstr "* Перазапусціце STK, каб ужыць новыя налады"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: ./data/gui/multitouch_settings.stkgui
@ -620,11 +620,11 @@ msgstr "Сумесная гульня"
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Bananas"
msgstr ""
msgstr "Бананы"
#. I18N: ./data/gui/help1.stkgui
msgid "Start the tutorial"
msgstr ""
msgstr "Пачаць навучанне"
#. I18N: ./data/gui/help1.stkgui
#. I18N: In the help menu
@ -656,7 +656,7 @@ msgstr "Калі вы бачыце замок, то гэта азначае, ш
#. I18N: ./data/gui/help1.stkgui
#. I18N: in the help menu
msgid "The 'skidding' key allows you to skid in sharp turns and get a boost."
msgstr "Кнопка «заноса» дазваляе слізгаць у крутым павароце і атрымаць паскарэнне."
msgstr "Кнопка «заносу» дазваляе слізгаць у крутым павароце і атрымаць паскарэнне."
#. I18N: ./data/gui/help1.stkgui
#. I18N: in the help screen
@ -796,24 +796,24 @@ msgstr "Пасля настройкі прылад увода вы гатовы
msgid ""
"Hitting a banana can result in one of the following being attached to the "
"kart:"
msgstr ""
msgstr "Наезд на банан прывядзе да далучэння да карта аднаго з наступных прадметаў:"
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
msgid "Anchor - slows down the kart."
msgstr ""
msgstr "Якар запавольвае карт."
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
msgid "Parachute - slows down the kart less than the anchor."
msgstr ""
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 ""
msgstr "Бомба ўзрываецца пасля кароткага прамежку часу і падкідвае карт у паветра. Ударце іншы карт каб перадаць бомбу іншаму гульцу."
#. I18N: ./data/gui/karts.stkgui
#. I18N: In the kart selection (player setup) screen
@ -902,46 +902,46 @@ msgstr "Выйсці"
#. I18N: ./data/gui/multitouch_settings.stkgui
msgid "Touch Device Settings"
msgstr ""
msgstr "Налады сэнсарнай прылады"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Device enabled"
msgstr ""
msgstr "Пралада ўключаная"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Inverted buttons"
msgstr ""
msgstr "Інвертаваныя кнопкі"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Buttons scale"
msgstr ""
msgstr "Маштаб кнопак"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Accelerometer"
msgstr ""
msgstr "Паскарэнне"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Advanced"
msgstr ""
msgstr "Пашыраныя"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Deadzone"
msgstr ""
msgstr "Мёртвая зона"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Sensitivity"
msgstr ""
msgstr "Адчувальнасць"
#. I18N: ./data/gui/multitouch_settings.stkgui
msgid "Restore defaults"
msgstr ""
msgstr "Аднавіць агаданыя"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
@ -1232,7 +1232,7 @@ msgstr "Хуткая гульня"
#. I18N: Section in the profile screen
#: src/states_screens/online_profile_base.cpp:113
msgid "Account Settings"
msgstr "Настаўленні конта"
msgstr "Налады конту"
#. I18N: ./data/gui/online/profile_settings.stkgui
#. I18N: In the online account settings screen
@ -1248,7 +1248,7 @@ msgstr "Змяніць"
#. I18N: ./data/gui/online/recovery_input.stkgui
#. I18N: In the recovery dialog
msgid "Account Recovery"
msgstr "Аднаўленне конта"
msgstr "Аднаўленне конту"
#. I18N: ./data/gui/online/recovery_info.stkgui
#. I18N: In the recovery dialog
@ -1326,7 +1326,7 @@ msgid ""
"You can play without creating an online account by selecting an offline "
"account. Though then you can not connect to friends, vote for addons etc. "
"Please read our privacy statement at http://privacy.supertuxkart.net"
msgstr "Вы можаце гуляць без стварэння анлайн-конта, выбраўшы афлайн-конт. Але пры гэтым вы не зможаце злучыцца з сябрамі, галасаваць за дадаткі і інш. Азнаёмцеся з нашай заявай аб канфідэнцыйнасці на http://privacy.supertuxkart.net"
msgstr "Вы можаце гуляць без стварэння анлайн-конту, выбраўшы афлайн-конт. Але пры гэтым вы не зможаце злучыцца з сябрамі, галасаваць за дадаткі і інш. Азнаёмцеся з нашай заявай аб канфідэнцыйнасці на http://privacy.supertuxkart.net"
#. I18N: ./data/gui/online/registration_terms.stkgui
#. I18N: In the registration dialog
@ -1564,7 +1564,7 @@ msgstr "Узровень графічных эфектаў"
#. I18N: ./data/gui/options_video.stkgui
#. I18N: In the video settings
msgid "Custom settings..."
msgstr "Свае настаўленні"
msgstr "Асабістыя налады…"
#. I18N: ./data/gui/options_video.stkgui
#. I18N: In the video settings
@ -1762,7 +1762,7 @@ msgstr "Баявая выспа"
#. I18N: ../stk-assets/tracks/candela_city/track.xml
msgid "Candela City"
msgstr ""
msgstr "Горад Кандэла"
#. I18N: ../stk-assets/tracks/cave/track.xml
msgid "Cave X"
@ -1774,7 +1774,7 @@ msgstr "Храм какавы"
#. I18N: ../stk-assets/tracks/cornfield_crossing/track.xml
msgid "Cornfield Crossing"
msgstr ""
msgstr "Кукурузнае перакрыжаванне"
#. I18N: ../stk-assets/tracks/fortmagma/track.xml
msgid "Fort Magma"
@ -1799,7 +1799,7 @@ msgstr "Ледзяное футбольнае поле"
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
msgid "What's wrong, little hippies? Your great gnu leader is missing?"
msgstr "Штосці не так, маленькі хіпі? Твой вялікі гну лідар знік?"
msgstr "Штосці не так, маленькі хіпі? Твой вялікі лідар гну знік?"
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
@ -1825,7 +1825,7 @@ msgstr "Але ты, гаротны валацуга, ніколі не змож
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
msgstr ""
msgstr "Лас-Дунас-Арэна"
#. I18N: ../stk-assets/tracks/lighthouse/track.xml
msgid "Around the lighthouse"
@ -1921,7 +1921,7 @@ msgstr "Хекслі"
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
msgstr ""
msgstr "Кікі"
#. I18N: ../stk-assets/karts/konqi/kart.xml
msgid "Konqi"
@ -1970,7 +1970,7 @@ msgstr "Завершанае дасягненне «%s»."
#: src/addons/addons_manager.cpp:104 src/addons/news_manager.cpp:322
msgid "Failed to connect to the SuperTuxKart add-ons server."
msgstr ""
msgstr "Не атрымалася злучыцца з северам дадаткаў SuperTuxKart."
#: src/addons/news_manager.cpp:179
#, c-format
@ -2042,16 +2042,16 @@ msgstr "Ваш файл канфігурацыі занадта стары. Ён
#: src/graphics/irr_driver.cpp:535
msgid "Video recording started."
msgstr ""
msgstr "Пачаўся запіс відэа."
#: src/graphics/irr_driver.cpp:541
#, c-format
msgid "Video saved in \"%s\"."
msgstr ""
msgstr "Відэа захаванае ў «%s»."
#: src/graphics/irr_driver.cpp:545
msgid "Encoding progress:"
msgstr ""
msgstr "Прагрэс кадавання:"
#: src/graphics/irr_driver.cpp:1682
#, c-format
@ -2726,11 +2726,11 @@ msgstr "Не едзьце да сігналу!"
#: src/karts/controller/spare_tire_ai.cpp:147
msgid "You can have at most 3 lives!"
msgstr ""
msgstr "Вы можаце мець максімум 3 жыцці!"
#: src/karts/controller/spare_tire_ai.cpp:153
msgid "+1 life."
msgstr ""
msgstr "+1 жыццё."
#: src/karts/kart.cpp:908 src/karts/kart.cpp:913
msgid "You won the race!"
@ -2753,7 +2753,7 @@ msgstr "SuperTuxKart можа падлучацца да сервера, каб
#: src/main.cpp:1654
msgid "Your screen resolution is too low to run STK."
msgstr ""
msgstr "Разрозненне вашага экрана занадта малое для STK."
#: src/main.cpp:1668
msgid ""
@ -2803,10 +2803,10 @@ msgstr "НЯПРАВІЛЬНЫ НАПРАМАК!"
#, c-format
msgid "%i spare tire kart has been spawned!"
msgid_plural "%i spare tire karts have been spawned!"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
msgstr[0] "%i запаска для карта з'явілася!"
msgstr[1] "%i запаскі для карта з'явіліся!"
msgstr[2] "%i запасак для карта з'явілася!"
msgstr[3] "%i запасак для карта з'явілася!"
#: src/modes/world.cpp:1202
msgid "You have been eliminated!"
@ -2820,7 +2820,7 @@ msgstr "«%s» дыскваліфікаваны."
#: src/network/protocols/server_lobby.cpp:318
#, c-format
msgid "Failed to register server: %s"
msgstr ""
msgstr "Не атрымалася зарэгістраваць сервер: %s"
#: src/network/servers_manager.cpp:198
msgid "No LAN server detected"
@ -3149,7 +3149,7 @@ msgstr "Адключана"
#: src/states_screens/dialogs/custom_video_settings.cpp:67
#: src/states_screens/options_screen_video.cpp:462
msgid "Important only"
msgstr ""
msgstr "Толькі важнае"
#. I18N: animations setting (only karts with human players are animated)
#: src/states_screens/dialogs/custom_video_settings.cpp:74
@ -3168,7 +3168,7 @@ msgstr "Для ўсіх"
#: src/states_screens/dialogs/custom_video_settings.cpp:102
#: src/states_screens/options_screen_video.cpp:469
msgid "Low"
msgstr ""
msgstr "Нізкі"
#. I18N: Geometry level high : everything is displayed
#. I18N: in the graphical options tooltip;
@ -3178,21 +3178,21 @@ msgstr ""
#: src/states_screens/dialogs/custom_video_settings.cpp:103
#: src/states_screens/options_screen_video.cpp:472
msgid "High"
msgstr ""
msgstr "Высокі"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very low
#: src/states_screens/dialogs/custom_video_settings.cpp:94
#: src/states_screens/options_screen_video.cpp:466
msgid "Very Low"
msgstr ""
msgstr "Вельмі нізкі"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very high
#: src/states_screens/dialogs/custom_video_settings.cpp:97
#: src/states_screens/options_screen_video.cpp:475
msgid "Very High"
msgstr ""
msgstr "Вельмі высокі"
#: src/states_screens/dialogs/message_dialog.cpp:129
#: src/states_screens/edit_gp_screen.cpp:257
@ -3202,11 +3202,11 @@ msgstr "Не"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:60
msgid "Tablet"
msgstr ""
msgstr "Планшэт"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:61
msgid "Phone"
msgstr ""
msgstr "Тэлефон"
#: src/states_screens/dialogs/recovery_dialog.cpp:121
msgid "Username and/or email address invalid."
@ -3220,7 +3220,7 @@ msgid ""
"the box below, you are confirming that you understand these terms. If you "
"have any questions or comments regarding these terms, one of the members of "
"the development team would gladly assist you."
msgstr ""
msgstr "Калі ласка, азнаёмцеся з умовамі карыстання SuperTuxKart на «%s». Вы павінны пагадзіцца з гэтымі ўмовамі для таго, каб зарэгістраваць конт для STK. Усталяваўшы сцяжок ніжэй, вы пацвярджаеце, што вы разумееце гэтыя ўмовы. Калі вы маеце пытанні ці каменты адносна ўмоў, адзін з чальцоў каманды распрацоўнікаў з задавальненнем дапаможа вам."
#: src/states_screens/dialogs/select_challenge.cpp:52
#, c-format
@ -3390,7 +3390,7 @@ msgstr "Час фінішу"
#: src/states_screens/ghost_replay_selection.cpp:83
msgid "User"
msgstr ""
msgstr "Карыстальнік"
#: src/states_screens/gp_info_screen.cpp:74
msgid "Default"
@ -3674,7 +3674,7 @@ msgstr "Клавіятура %i"
#: src/states_screens/options_screen_input.cpp:138
msgid "Touch Device"
msgstr ""
msgstr "Сэнсарная прылада"
#: src/states_screens/options_screen_ui.cpp:159
msgid ""
@ -3785,7 +3785,7 @@ msgstr "Глабальнае асвятленне: %s"
#: src/states_screens/options_screen_video.cpp:534
#, c-format
msgid "Rendered image quality: %s"
msgstr ""
msgstr "Якасць апрацаванай выявы: %s"
#: src/states_screens/race_gui.cpp:358 src/states_screens/race_gui.cpp:360
msgid "Challenge Failed"
@ -3842,7 +3842,7 @@ msgstr "Ранг"
#: src/states_screens/race_gui_overworld.cpp:518
msgid "Press fire to start the tutorial"
msgstr ""
msgstr "Націсніце Атаку, каб пачаць навучанне"
#: src/states_screens/race_gui_overworld.cpp:557
msgid "Type: Grand Prix"
@ -3989,7 +3989,7 @@ msgstr "Некарэктны Email!"
msgid ""
"You will receive an email with further instructions regarding account "
"activation. Please be patient and be sure to check your spam folder."
msgstr "Вы атрымаеце электронны ліст з далейшымі інструкцыямі для актывацыі конта. Калі ласка, будзьце церпялівымі і не забудзьце праверыць тэчку са спамам."
msgstr "Вы атрымаеце электронны ліст з далейшымі інструкцыямі для актывацыі конту. Калі ласка, будзьце церпялівымі і не забудзьце праверыць тэчку са спамам."
#: src/states_screens/register_screen.cpp:402
#: src/states_screens/user_screen.cpp:338
@ -4133,7 +4133,7 @@ msgstr "Ой! Калі ў вас праблемы, націсніце <%s> дл
msgid ""
"Accelerate and press the <%s> key while turning to skid. Skidding for a "
"short while can help you turn faster to take sharp turns."
msgstr "Разганіцеся і націсніце <%s> пад час заноса. Коўзанне дапаможа вам прайсць крутыя павароты хутчэй."
msgstr "Разганіцеся і націсніце <%s> пад час заносу. Коўзанне дапаможа вам прайсць крутыя павароты хутчэй."
#: ../stk-assets/tracks/tutorial/scripting.as:77
#: ../stk-assets/tracks/tutorial/triggers.as:78

View File

@ -6,7 +6,7 @@
# Alan Monfort <alan.monfort@free.fr>, 2015-2016
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013
# Gwenn M <tornoz@laposte.net>, 2015
# Irriep Nala Novram <allannkorh@yahoo.fr>, 2017
# Irriep Nala Novram <allannkorh@yahoo.fr>, 2017-2018
# Irriep Nala Novram <allannkorh@yahoo.fr>, 2016
# Irriep Nala Novram <allannkorh@yahoo.fr>, 2016
msgid ""
@ -14,8 +14,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-01-08 18:45+0000\n"
"Last-Translator: Irriep Nala Novram <allannkorh@yahoo.fr>\n"
"Language-Team: Breton (http://www.transifex.com/supertuxkart/supertuxkart/language/br/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -624,11 +624,11 @@ msgstr "Liesc'hoarier"
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Bananas"
msgstr ""
msgstr "Bananez"
#. I18N: ./data/gui/help1.stkgui
msgid "Start the tutorial"
msgstr ""
msgstr "Kregiñ gant an tutorial"
#. I18N: ./data/gui/help1.stkgui
#. I18N: In the help menu
@ -931,21 +931,21 @@ msgstr ""
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Advanced"
msgstr ""
msgstr "Aroakaet"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Deadzone"
msgstr ""
msgstr "Zonennvarv"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Sensitivity"
msgstr ""
msgstr "Kizidigezh"
#. I18N: ./data/gui/multitouch_settings.stkgui
msgid "Restore defaults"
msgstr ""
msgstr "Adderaouekaat"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
@ -1766,7 +1766,7 @@ msgstr "Enezenn ar gad"
#. I18N: ../stk-assets/tracks/candela_city/track.xml
msgid "Candela City"
msgstr ""
msgstr "Kêr Gandela"
#. I18N: ../stk-assets/tracks/cave/track.xml
msgid "Cave X"
@ -1925,7 +1925,7 @@ msgstr "Heksley"
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
msgstr ""
msgstr "Kiki"
#. I18N: ../stk-assets/karts/konqi/kart.xml
msgid "Konqi"
@ -2732,7 +2732,7 @@ msgstr ""
#: src/karts/controller/spare_tire_ai.cpp:153
msgid "+1 life."
msgstr ""
msgstr "+1 vuhez."
#: src/karts/kart.cpp:908 src/karts/kart.cpp:913
msgid "You won the race!"
@ -3160,7 +3160,7 @@ msgstr "Gweredekaet evit an holl anezho"
#: src/states_screens/dialogs/custom_video_settings.cpp:102
#: src/states_screens/options_screen_video.cpp:469
msgid "Low"
msgstr ""
msgstr "Izel"
#. I18N: Geometry level high : everything is displayed
#. I18N: in the graphical options tooltip;
@ -3170,21 +3170,21 @@ msgstr ""
#: src/states_screens/dialogs/custom_video_settings.cpp:103
#: src/states_screens/options_screen_video.cpp:472
msgid "High"
msgstr ""
msgstr "Uhel"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very low
#: src/states_screens/dialogs/custom_video_settings.cpp:94
#: src/states_screens/options_screen_video.cpp:466
msgid "Very Low"
msgstr ""
msgstr "Izel-kenañ"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very high
#: src/states_screens/dialogs/custom_video_settings.cpp:97
#: src/states_screens/options_screen_video.cpp:475
msgid "Very High"
msgstr ""
msgstr "Uhel-kenañ"
#: src/states_screens/dialogs/message_dialog.cpp:129
#: src/states_screens/edit_gp_screen.cpp:257
@ -3194,11 +3194,11 @@ msgstr "Ket"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:60
msgid "Tablet"
msgstr ""
msgstr "Tabletezenn"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:61
msgid "Phone"
msgstr ""
msgstr "Pellgomz"
#: src/states_screens/dialogs/recovery_dialog.cpp:121
msgid "Username and/or email address invalid."
@ -3382,7 +3382,7 @@ msgstr "Amzer echuiñ"
#: src/states_screens/ghost_replay_selection.cpp:83
msgid "User"
msgstr ""
msgstr "Implijer"
#: src/states_screens/gp_info_screen.cpp:74
msgid "Default"

View File

@ -4,7 +4,7 @@
#
# Translators:
# Jakub Vaněk <vanek.jakub4@seznam.cz>, 2015-2016
# Pavel Borecki <pavel.borecki@gmail.com>, 2015-2017
# Pavel Borecki <pavel.borecki@gmail.com>, 2015-2018
# ToMáš Marný, 2015
# ToMáš Marný, 2015-2016
msgid ""
@ -12,8 +12,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: ToMáš Marný\n"
"PO-Revision-Date: 2018-01-02 07:15+0000\n"
"Last-Translator: Pavel Borecki <pavel.borecki@gmail.com>\n"
"Language-Team: Czech (http://www.transifex.com/supertuxkart/supertuxkart/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -2049,7 +2049,7 @@ msgstr "Zahájeno nahrávání videa."
#: src/graphics/irr_driver.cpp:541
#, c-format
msgid "Video saved in \"%s\"."
msgstr "Video uloženo do \"%s\"."
msgstr "Video uloženo do „%s“."
#: src/graphics/irr_driver.cpp:545
msgid "Encoding progress:"
@ -2058,7 +2058,7 @@ msgstr "Průběh enkódování:"
#: src/graphics/irr_driver.cpp:1682
#, c-format
msgid "FPS: %d/%d/%d - %d KTris"
msgstr "FPS: %d/%d/%d - %d tisíc trojúhelníků"
msgstr "Sním./s.: %d/%d/%d %d tisíc trojúhelníků"
#: src/guiengine/engine.cpp:1296
msgid "Loading"
@ -2687,7 +2687,7 @@ msgstr "Levý palec nahoru"
#: src/input/input_manager.cpp:807
#, c-format
msgid "Ignoring '%s'. You needed to join earlier to play!"
msgstr "Ignoruji '%s'. Musíte se do hry připojit dříve!"
msgstr "„%s“ je ignorováno. Abyste se mohli zúčastnit, je třeba se do hry připojit dříve!"
#: src/input/input_manager.cpp:837
msgid "Only the Game Master may act at this point!"
@ -2697,13 +2697,13 @@ msgstr "V tomto okamžiku může jednat pouze hráč zakládající hru!"
msgid ""
"Connect your wiimote to the Bluetooth manager, then click on Ok. Detailed "
"instructions at supertuxkart.net/Wiimote"
msgstr "Připojte svůj Wiimote ovladač do správce Bluetooth a poté klikněte na tlačítko Budiž. Podrobný návod je na supertuxkart.net/Wiimote"
msgstr "Připojte svůj Wiimote ovladač do správce Bluetooth a poté klikněte na tlačítko OK. Podrobný návod je na supertuxkart.net/Wiimote"
#: 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 "Stiskněte současně tlačítka 1 + 2 na vašem Wiimote ovladači, přepnete jej do režimu vyhledávání, poté klikněte na tlačítko Budiž. Podrobný návod je na supertuxkart.net/Wiimote"
msgstr "Stiskněte současně tlačítka 1 + 2 na svém Wiimote ovladači, přepnete jej do režimu vyhledávání, poté klikněte na tlačítko Budiž. Podrobný návod je na supertuxkart.net/Wiimote"
#: src/input/wiimote_manager.cpp:414
#, c-format
@ -2775,7 +2775,7 @@ msgstr "Vejce: %d / %d"
#: src/modes/follow_the_leader.cpp:62 src/modes/follow_the_leader.cpp:285
msgid "Leader"
msgstr "Vůdce"
msgstr "Vedoucí"
#: src/modes/linear_world.cpp:287
msgid "Final lap!"
@ -2866,7 +2866,7 @@ msgstr "Máte novou žádost o kamarádství!"
msgid ""
"Unable to connect to the server. Check your internet connection or try again"
" later."
msgstr "Nelze se připojit k serveru. Zkontrolujte své připojení k internetu a případně\npřed dalším pokusem zkuste počkat."
msgstr "Nelze se připojit k serveru. Zkontrolujte své připojení k Internetu a případně\npřed dalším pokusem zkuste počkat."
#: src/race/grand_prix_data.hpp:171
msgid "Random Grand Prix"
@ -2881,7 +2881,7 @@ msgstr "Soubor s nejvyšším skóre byl příliš starý,\nvšechna nejvyšší
#. I18N: Game mode
#: src/race/race_manager.hpp:179
msgid "Follow the Leader"
msgstr "Následujte vůdce"
msgstr "Následujte vedoucího"
#. I18N: Game mode
#: src/race/race_manager.hpp:181
@ -2991,7 +2991,7 @@ msgstr "standardní"
#: src/states_screens/kart_selection.cpp:1481
#: src/states_screens/race_setup_screen.cpp:99
msgid "Locked : solve active challenges to gain access to more!"
msgstr "Zamčeno: splň aktivní výzvy k získání přístupu!"
msgstr "Zamčeno: splňte aktivní výzvy k získání přístupu!"
#: src/states_screens/arenas_screen.cpp:339
msgid "Random Arena"

View File

@ -9,7 +9,7 @@
# Flakebi, 2015
# hiker <joerg@chiu-henrichs.id.au>, 2015
# konstin <konsti.schuetze@t-online.de>, 2015
# Maximilian Wagenbach <foaly.f@web.de>, 2016
# Maximilian Wagenbach <foaly@posteo.de>, 2016
# Tobias Markus <tobbi@supertuxproject.org>, 2015-2016
# Wasilis Mandratzis-Walz, 2015
# wesen <yannick.lapp@web.de>, 2016
@ -18,7 +18,7 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"PO-Revision-Date: 2017-11-26 08:20+0000\n"
"Last-Translator: Wuzzy <almikes@aol.com>\n"
"Language-Team: German (http://www.transifex.com/supertuxkart/supertuxkart/language/de/)\n"
"MIME-Version: 1.0\n"
@ -439,7 +439,7 @@ msgstr "Anzahl der Runden:"
#. I18N: ./data/gui/edit_track.stkgui
#. I18N: In the edit track screen
msgid "Reverse:"
msgstr "Umkehren:"
msgstr "Rückwärts:"
#. I18N: ./data/gui/edit_track.stkgui
#. I18N: ./data/gui/general_text_field_dialog.stkgui
@ -3324,7 +3324,7 @@ msgstr "Runden"
#: src/states_screens/edit_gp_screen.cpp:68
msgid "Reversed"
msgstr "Umgekehrt"
msgstr "Rückwärts"
#: src/states_screens/edit_gp_screen.cpp:124
#: src/states_screens/ghost_replay_selection.cpp:177
@ -4031,7 +4031,7 @@ msgstr "Maximal unterstützte Spieler: %d"
#. I18N: In the track info screen
#: src/states_screens/track_info_screen.cpp:213
msgid "Drive in reverse"
msgstr "Spiegelverkehrte Strecke"
msgstr "Rückwärts fahren"
#. I18N: In the track info screen
#: src/states_screens/track_info_screen.cpp:218

View File

@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2017-11-21 20:34+0000\n"
"Last-Translator: Vangelis Skarmoutsos <skarmoutsosv@gmail.com>\n"
"Language-Team: Greek (http://www.transifex.com/supertuxkart/supertuxkart/language/el/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1828,7 +1828,7 @@ msgstr "Είσαι λίγο αξιολύπητος twerps δεν θα είσαι
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
msgstr ""
msgstr "Λας Ντούνας Αρένα"
#. I18N: ../stk-assets/tracks/lighthouse/track.xml
msgid "Around the lighthouse"
@ -1924,7 +1924,7 @@ msgstr "Έξλι"
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
msgstr ""
msgstr "Kiki"
#. I18N: ../stk-assets/karts/konqi/kart.xml
msgid "Konqi"

View File

@ -5,6 +5,7 @@
# Translators:
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011
# Jonas Marx <hallo@jonas-marx.com>, 2017
# Rachel Singh <rachel@moosader.com>, 2018
# Robin van der Vliet <info@robinvandervliet.nl>, 2015
# Любомир Василев, 2016
# Любомир Василев, 2016-2017
@ -13,8 +14,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-04-06 18:13+0000\n"
"Last-Translator: Rachel Singh <rachel@moosader.com>\n"
"Language-Team: Esperanto (http://www.transifex.com/supertuxkart/supertuxkart/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -3159,7 +3160,7 @@ msgstr "Enŝaltita por ĉiuj"
#: src/states_screens/dialogs/custom_video_settings.cpp:102
#: src/states_screens/options_screen_video.cpp:469
msgid "Low"
msgstr ""
msgstr "Malalta"
#. I18N: Geometry level high : everything is displayed
#. I18N: in the graphical options tooltip;
@ -3169,21 +3170,21 @@ msgstr ""
#: src/states_screens/dialogs/custom_video_settings.cpp:103
#: src/states_screens/options_screen_video.cpp:472
msgid "High"
msgstr ""
msgstr "Alta"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very low
#: src/states_screens/dialogs/custom_video_settings.cpp:94
#: src/states_screens/options_screen_video.cpp:466
msgid "Very Low"
msgstr ""
msgstr "Malaltega"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very high
#: src/states_screens/dialogs/custom_video_settings.cpp:97
#: src/states_screens/options_screen_video.cpp:475
msgid "Very High"
msgstr ""
msgstr "Altega"
#: src/states_screens/dialogs/message_dialog.cpp:129
#: src/states_screens/edit_gp_screen.cpp:257
@ -3193,11 +3194,11 @@ msgstr "Ne"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:60
msgid "Tablet"
msgstr ""
msgstr "Tabulkomputilo"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:61
msgid "Phone"
msgstr ""
msgstr "Poŝtelefono"
#: src/states_screens/dialogs/recovery_dialog.cpp:121
msgid "Username and/or email address invalid."
@ -3381,7 +3382,7 @@ msgstr "Fina tempo"
#: src/states_screens/ghost_replay_selection.cpp:83
msgid "User"
msgstr ""
msgstr "Uzanto"
#: src/states_screens/gp_info_screen.cpp:74
msgid "Default"
@ -3958,7 +3959,7 @@ msgstr "Ne sukcesis krei ludiston '%s'."
#: src/states_screens/register_screen.cpp:277
msgid "Emails don't match!"
msgstr ""
msgstr "Retpoŝtadresoj ne estas sama!"
#: src/states_screens/register_screen.cpp:281
msgid "Online username has to be between 3 and 30 characters long!"

View File

@ -3,7 +3,7 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Marc Coll Carrillo <marc.coll.carrillo@gmail.com>, 2015-2017
# Marc Coll Carrillo <marc.coll.carrillo@gmail.com>, 2015-2018
# Veronica Sanchez, 2017
# William Beltrán <wbeltranc@gmail.com>, 2016
# William Beltrán <wbeltranc@gmail.com>, 2017
@ -12,8 +12,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Veronica Sanchez\n"
"PO-Revision-Date: 2018-04-07 11:31+0000\n"
"Last-Translator: Marc Coll Carrillo <marc.coll.carrillo@gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/supertuxkart/supertuxkart/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -23,7 +23,7 @@ msgstr ""
#. I18N: ./data/achievements.xml
msgid "Christoffel Columbus"
msgstr "Cristófal Colón"
msgstr "Cristóbal Colón"
#. I18N: ./data/achievements.xml
msgid "Play every official track at least once."
@ -1208,7 +1208,7 @@ msgstr "Servidores"
#. I18N: ./data/gui/online/profile_servers.stkgui
msgid "Local Networking"
msgstr "Red Local"
msgstr "Red local"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: In the online multiplayer screen
@ -1223,7 +1223,7 @@ msgstr "Crear servidor"
#. I18N: ./data/gui/online/profile_servers.stkgui
msgid "Global Networking"
msgstr "Red Global"
msgstr "Red global"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: In the online multiplayer screen
@ -1395,7 +1395,7 @@ msgstr "Votar"
#. I18N: ./data/gui/online/waiting_for_others.stkgui
#. I18N: Networking screen
msgid "Waiting for the others..."
msgstr "Esperando a los otros..."
msgstr "Esperando a los demás..."
#. I18N: ./data/gui/options_audio.stkgui
#. I18N: ./data/gui/options_device.stkgui
@ -3376,7 +3376,7 @@ msgstr "Has desbloqueado el campeonato %0"
#: src/states_screens/ghost_replay_selection.cpp:82
msgid "Finish Time"
msgstr "Tiempo de Llegada"
msgstr "Tiempo de llegada"
#: src/states_screens/ghost_replay_selection.cpp:83
msgid "User"
@ -3895,7 +3895,7 @@ msgstr "Empatados"
#: src/states_screens/race_result_gui.cpp:1098
#: src/states_screens/race_result_gui.cpp:1154
msgid "(Own Goal)"
msgstr "(Autogol)"
msgstr "(En propia puerta)"
#: src/states_screens/race_result_gui.cpp:1220
#, c-format
@ -4020,7 +4020,7 @@ msgstr "Circuito creado por %s"
#: src/states_screens/track_info_screen.cpp:120
#, c-format
msgid "Max players supported: %d"
msgstr "Jugadores máximos soportados: %d"
msgstr "Máximos jugadores permitidos: %d"
#. I18N: In the track info screen
#: src/states_screens/track_info_screen.cpp:213

View File

@ -3,14 +3,14 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Aaron Kearns <ajkearns6@gmail.com>, 2017
# Aaron Kearns <ajkearns6@gmail.com>, 2017-2018
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-02-21 22:27+0000\n"
"Last-Translator: Aaron Kearns <ajkearns6@gmail.com>\n"
"Language-Team: Irish (http://www.transifex.com/supertuxkart/supertuxkart/language/ga/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -20,7 +20,7 @@ msgstr ""
#. I18N: ./data/achievements.xml
msgid "Christoffel Columbus"
msgstr ""
msgstr "Christoffel Columbus"
#. I18N: ./data/achievements.xml
msgid "Play every official track at least once."
@ -544,7 +544,7 @@ msgstr "Athainmnigh"
#. I18N: ./data/gui/grand_prix_lose.stkgui
#. I18N: ./data/gui/grand_prix_win.stkgui
msgid "Save Grand Prix"
msgstr ""
msgstr "Sábháil Grand Prix"
#. I18N: ./data/gui/help1.stkgui
#. I18N: ./data/gui/help2.stkgui
@ -1892,7 +1892,7 @@ msgstr "Gairdín Zen"
#. I18N: ../stk-assets/karts/adiumy/kart.xml
msgid "Adiumy"
msgstr ""
msgstr "Adiumy"
#. I18N: ../stk-assets/karts/amanda/kart.xml
msgid "Amanda"
@ -1904,7 +1904,7 @@ msgstr ""
#. I18N: ../stk-assets/karts/emule/kart.xml
msgid "Emule"
msgstr ""
msgstr "Emule"
#. I18N: ../stk-assets/karts/gavroche/kart.xml
msgid "Gavroche"
@ -1916,7 +1916,7 @@ msgstr "Gnu"
#. I18N: ../stk-assets/karts/hexley/kart.xml
msgid "Hexley"
msgstr ""
msgstr "Hexley"
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
@ -1936,7 +1936,7 @@ msgstr "Pidgin"
#. I18N: ../stk-assets/karts/puffy/kart.xml
msgid "Puffy"
msgstr ""
msgstr "Puffy"
#. I18N: ../stk-assets/karts/sara_the_racer/kart.xml
msgid "Sara the Racer"
@ -2172,13 +2172,13 @@ msgstr ""
#: src/input/binding.cpp:144
msgctxt "input_key"
msgid "Kana"
msgstr ""
msgstr "Kana"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:146
msgctxt "input_key"
msgid "Junja"
msgstr ""
msgstr "Junja"
#. I18N: input configuration screen: keyboard key
#. I18N: input configuration screen: keyboard key

View File

@ -11,7 +11,7 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"PO-Revision-Date: 2017-11-15 14:31+0000\n"
"Last-Translator: GunChleoc\n"
"Language-Team: Gaelic, Scottish (http://www.transifex.com/supertuxkart/supertuxkart/language/gd/)\n"
"MIME-Version: 1.0\n"
@ -608,7 +608,7 @@ msgstr "Modhan-\r\ngeama"
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Multi-player"
msgstr "Ioma-chluicheadair"
msgstr "Ioma-\nchluicheadair"
#. I18N: ./data/gui/help1.stkgui
#. I18N: Tab in help menu

View File

@ -8,6 +8,7 @@
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010
# GenghisKhan <genghiskhan@gmx.ca>, 2015-2016
# Liran <liranvaknin@gmail.com>, 2016-2017
# Yaroslav Serhieiev <noomorph@gmail.com>, 2018
# Yevgney Sliosarenko, 2015
# ‫רואי לוי‬‎ <roei1234567@gmail.com>, 2016
msgid ""
@ -15,8 +16,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Liran <liranvaknin@gmail.com>\n"
"PO-Revision-Date: 2018-03-25 14:36+0000\n"
"Last-Translator: Yaroslav Serhieiev <noomorph@gmail.com>\n"
"Language-Team: Hebrew (http://www.transifex.com/supertuxkart/supertuxkart/language/he/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -937,7 +938,7 @@ msgstr "מתקדם"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Deadzone"
msgstr ""
msgstr "שטח מת"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
@ -1830,7 +1831,7 @@ msgstr " אבל טיפשים קטנים ועלובים שכמותכם לעולם
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
msgstr ""
msgstr "ארנה לאס דונאס"
#. I18N: ../stk-assets/tracks/lighthouse/track.xml
msgid "Around the lighthouse"
@ -1926,7 +1927,7 @@ msgstr "הקסלי"
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
msgstr ""
msgstr "קיקי"
#. I18N: ../stk-assets/karts/konqi/kart.xml
msgid "Konqi"

View File

@ -7,14 +7,15 @@
# Christian "crse" Elbrianno, 2017
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011
# Icho Yulian Chandra <icho.yulian@gmail.com>, 2016
# Iwan Rahardi Putra <iwan.rahardi.putra@gmail.com>, 2017
# Raja Sulaiman <wormsplaycheats@gmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Christian \"crse\" Elbrianno\n"
"PO-Revision-Date: 2017-12-30 04:05+0000\n"
"Last-Translator: Iwan Rahardi Putra <iwan.rahardi.putra@gmail.com>\n"
"Language-Team: Indonesian (http://www.transifex.com/supertuxkart/supertuxkart/language/id/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -930,7 +931,7 @@ msgstr "Akselerometer"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Advanced"
msgstr ""
msgstr "Tingkat lanjut"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
@ -3412,7 +3413,7 @@ msgstr ""
#: src/states_screens/grand_prix_editor_screen.cpp:351
msgid "Name is empty."
msgstr ""
msgstr "Nama kosong."
#: src/states_screens/grand_prix_editor_screen.cpp:359
msgid "Another grand prix with this name already exists."
@ -3420,7 +3421,7 @@ msgstr ""
#: src/states_screens/grand_prix_editor_screen.cpp:365
msgid "Name is too long."
msgstr ""
msgstr "Nama terlalu panjang."
#. I18N: when failing a GP
#: src/states_screens/grand_prix_lose.cpp:155
@ -3827,11 +3828,11 @@ msgstr "Peringkat"
#: src/states_screens/race_gui_overworld.cpp:518
msgid "Press fire to start the tutorial"
msgstr ""
msgstr "Tekan tombol tembak untuk mulai latihan"
#: src/states_screens/race_gui_overworld.cpp:557
msgid "Type: Grand Prix"
msgstr ""
msgstr "Tipe: Grand Prix"
#: src/states_screens/race_gui_overworld.cpp:594
msgid "Press fire to start the challenge"
@ -3839,7 +3840,7 @@ msgstr "Tekan tembak untuk memulai tantangan"
#: src/states_screens/race_result_gui.cpp:175
msgid "Continue."
msgstr ""
msgstr "Lanjutkan."
#: src/states_screens/race_result_gui.cpp:178
msgid "Quit the server."
@ -3859,7 +3860,7 @@ msgstr "Mulai Ulang"
#: src/states_screens/race_result_gui.cpp:224
msgid "Back to challenge selection"
msgstr ""
msgstr "Kembali ke pilihan tantangan"
#: src/states_screens/race_result_gui.cpp:230
msgid "Back to the menu"
@ -3895,7 +3896,7 @@ msgstr ""
#: src/states_screens/race_result_gui.cpp:1220
#, c-format
msgid "Track %i/%i"
msgstr ""
msgstr "Putaran %i/%i"
#: src/states_screens/race_result_gui.cpp:1304
msgid "Grand Prix progress:"
@ -3908,12 +3909,12 @@ msgstr "Highscores"
#: src/states_screens/race_result_gui.cpp:1432
#, c-format
msgid "Difficulty: %s"
msgstr ""
msgstr "Tingkat kesulitan: %s"
#: src/states_screens/race_result_gui.cpp:1440
#, c-format
msgid "Best lap time: %s"
msgstr ""
msgstr "Waktu lintasan terbaik: %s"
#: src/states_screens/race_setup_screen.cpp:87
msgid "All blows allowed, so catch weapons and make clever use of them!"
@ -3930,11 +3931,11 @@ msgstr "Selalu buntuti sang pemimpin tapi jangan didahului!"
#: src/states_screens/race_setup_screen.cpp:114
msgid "Hit others with weapons until they lose all their lives."
msgstr ""
msgstr "Serang yang lain dengan senjata sampai mereka kehabisan nyawa."
#: src/states_screens/race_setup_screen.cpp:119
msgid "Push the ball into the opposite cage to score goals."
msgstr ""
msgstr "Dorong bola ke dalam gawang lawan untuk membuat gol."
#: src/states_screens/race_setup_screen.cpp:129
msgid "Explore tracks to find all hidden eggs"
@ -3942,17 +3943,17 @@ msgstr "Eksplorasi jalur untuk menemukan semua telur tersembunyi"
#: src/states_screens/race_setup_screen.cpp:137
msgid "Race against ghost karts and try to beat them!"
msgstr ""
msgstr "Berlomba dan coba kalahkan mobil hantu!"
#: src/states_screens/register_screen.cpp:218
#: src/states_screens/register_screen.cpp:225
#, c-format
msgid "Could not create player '%s'."
msgstr ""
msgstr "Tidak bisa membuat pemain '%s'."
#: src/states_screens/register_screen.cpp:277
msgid "Emails don't match!"
msgstr ""
msgstr "Email tidak sama!"
#: src/states_screens/register_screen.cpp:281
msgid "Online username has to be between 3 and 30 characters long!"
@ -3964,11 +3965,11 @@ msgstr ""
#: src/states_screens/register_screen.cpp:293
msgid "Email has to be between 5 and 254 characters long!"
msgstr ""
msgstr "Panjang email harus diantara 5 sampai 254 karakter."
#: src/states_screens/register_screen.cpp:299
msgid "Email is invalid!"
msgstr ""
msgstr "Email salah!"
#: src/states_screens/register_screen.cpp:362
msgid ""
@ -3989,7 +3990,7 @@ msgstr ""
#. I18N: track group name
#: src/states_screens/tracks_and_gp_screen.cpp:144
msgid "all"
msgstr ""
msgstr "semua"
#: src/states_screens/tracks_and_gp_screen.cpp:195
msgid "Locked!"
@ -3998,11 +3999,11 @@ msgstr "Dikunci!"
#: src/states_screens/tracks_and_gp_screen.cpp:278
#: src/states_screens/tracks_screen.cpp:227
msgid "Locked: solve active challenges to gain access to more!"
msgstr ""
msgstr "Dikunci: selesaikan tantangan yang ada untuk akses lintasan yang lain!"
#: src/states_screens/tracks_screen.cpp:194
msgid "Only official tracks are supported."
msgstr ""
msgstr "Hanya mendukung lintasan resmi."
#. I18N: when showing who is the author of track '%s'
#. I18N: (place %s where the name of the author should appear)
@ -4015,25 +4016,25 @@ msgstr "Lintasan oleh %s"
#: src/states_screens/track_info_screen.cpp:120
#, c-format
msgid "Max players supported: %d"
msgstr ""
msgstr "Maksimal pemain: %d"
#. I18N: In the track info screen
#: src/states_screens/track_info_screen.cpp:213
msgid "Drive in reverse"
msgstr ""
msgstr "Lintasan dibalik"
#. I18N: In the track info screen
#: src/states_screens/track_info_screen.cpp:218
msgid "Random item location"
msgstr ""
msgstr "Acak lokasi benda"
#: src/states_screens/user_screen.cpp:111
msgid "Exit game"
msgstr ""
msgstr "Keluar permainan"
#: src/states_screens/user_screen.cpp:484
msgid "You need to enter a password."
msgstr ""
msgstr "Kamu harus masukan password."
#: src/states_screens/user_screen.cpp:505
#, c-format
@ -4056,7 +4057,7 @@ msgstr "Apakah anda benar-benar ingin menghapus pemain '%s' ?"
#. formats.
#: src/utils/time.cpp:50
msgid "%d/%m/%Y"
msgstr ""
msgstr "%d/%m/%Y"
#. I18N: Do NOT literally translate this string!! Please enter Y as the
#. translation if your language is a RTL (right-to-left) language,
@ -4067,7 +4068,7 @@ msgstr " N"
#: ../stk-assets/tracks/overworld/scripting.as:15
msgid "Complete all challenges to unlock the big door!"
msgstr ""
msgstr "Selesaikan semua tantangan untuk membuka pintu besar!"
#: ../stk-assets/tracks/overworld/scripting.as:63
msgid ""
@ -4075,19 +4076,19 @@ msgid ""
"to enter this challenge!\n"
"Check the minimap for\n"
"available challenges."
msgstr ""
msgstr "Butuh lebih banyak angka\nuntuk mengambil tantangan ini!\nPeriksa peta kecil untuk lihat\ntantangan yang ada."
#: ../stk-assets/tracks/tutorial/scripting.as:21
#, c-format
msgid "Accelerate with <%s>, and steer with <%s> and <%s>."
msgstr ""
msgstr "Maju dengan <%s>, dan menyetir dengan <%s> dan <%s>."
#: ../stk-assets/tracks/tutorial/scripting.as:37
#: ../stk-assets/tracks/tutorial/triggers.as:38
#, c-format
msgid ""
"Collect gift boxes, and fire the weapon with <%s> to blow away these boxes!"
msgstr ""
msgstr "Ambil kotak hadiah, dan tembakan senjata dengan <%s> untuk menghancurkan peti-peti ini!"
#: ../stk-assets/tracks/tutorial/scripting.as:43
#: ../stk-assets/tracks/tutorial/triggers.as:44
@ -4095,7 +4096,7 @@ msgstr ""
msgid ""
"Press <%s> to look behind. Fire the weapon with <%s> while pressing <%s> to "
"fire behind!"
msgstr ""
msgstr "Tekan <%s> untuk lihat ke belakang. Tembakan senjata dengan <%s> saat menekan <%s> untuk menembak ke belakang!"
#: ../stk-assets/tracks/tutorial/scripting.as:53
#: ../stk-assets/tracks/tutorial/triggers.as:54
@ -4105,12 +4106,12 @@ msgstr "Gunakan nitro yang anda kumpulkan dengan menekan <%s>!"
#: ../stk-assets/tracks/tutorial/scripting.as:58
msgid "Collect nitro bottles (we will use them after the curve)."
msgstr ""
msgstr "Kumpulkan botol nitro (akan kita pakai setelah tikungan)."
#: ../stk-assets/tracks/tutorial/scripting.as:63
#, c-format
msgid "Oops! When you're in trouble, press <%s> to be rescued."
msgstr ""
msgstr "Oops! Saat dalam masalah, tekan <%s> supaya diselamatkan."
#: ../stk-assets/tracks/tutorial/scripting.as:69
#: ../stk-assets/tracks/tutorial/triggers.as:70
@ -4118,14 +4119,14 @@ msgstr ""
msgid ""
"Accelerate and press the <%s> key while turning to skid. Skidding for a "
"short while can help you turn faster to take sharp turns."
msgstr ""
msgstr "Maju dan tekan <%s> saat berbelok untuk ngesot. Ngesot beberapa saat akan membuat kamu berbelok lebih cepat pada belokan tajam."
#: ../stk-assets/tracks/tutorial/scripting.as:77
#: ../stk-assets/tracks/tutorial/triggers.as:78
msgid ""
"Note that if you manage to skid for several seconds, you will receive a "
"bonus speedup as a reward!"
msgstr ""
msgstr "Kalau kamu berhasil ngesot untuk beberapa detik, kamu akan mendapat bonus tambahan kecepatan sebagai hadiah."
#: ../stk-assets/tracks/tutorial/scripting.as:82
#: ../stk-assets/tracks/tutorial/triggers.as:83
@ -4135,7 +4136,7 @@ msgstr "Kini anda siap untuk balapan. Semoga beruntung!"
#: ../stk-assets/tracks/tutorial/triggers.as:28
#, c-format
msgid "Accelerate with <%s> and steer with <%s> and <%s>"
msgstr ""
msgstr "Maju dengan <%s> dan belok dengan <%s> dan <%s>"
#: ../stk-assets/tracks/tutorial/triggers.as:59
msgid "Collect nitro bottles (we will use them after the curve)"

View File

@ -6,7 +6,7 @@
# Davide Depau <me@davideddu.org>, 2015
# Enrico B. <enricobe@hotmail.com>, 2015
# Giuseppe Pignataro (Fasbyte01) <rogepix@gmail.com>, 2015
# Ioma Taani, 2016
# Ioma Taani, 2016,2018
# lorenzo mijorus <lorenzo.mijorus@gmail.com>, 2015
# Luca Argentieri <luca.argentieri@openmailbox.org>, 2015
# mattia_b89 <mattia.b89@gmail.com>, 2017
@ -15,8 +15,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: mattia_b89 <mattia.b89@gmail.com>\n"
"PO-Revision-Date: 2018-01-04 07:19+0000\n"
"Last-Translator: Ioma Taani\n"
"Language-Team: Italian (http://www.transifex.com/supertuxkart/supertuxkart/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -922,7 +922,7 @@ msgstr "Pulsanti invertiti"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Buttons scale"
msgstr ""
msgstr "Dimensione pulsanti"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
@ -2806,8 +2806,8 @@ msgstr "DIREZIONE ERRATA!"
#, c-format
msgid "%i spare tire kart has been spawned!"
msgid_plural "%i spare tire karts have been spawned!"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%i ruota del kart è stata creata!"
msgstr[1] "%i ruote del kart sono state create!"
#: src/modes/world.cpp:1202
msgid "You have been eliminated!"

View File

@ -3,6 +3,7 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# David Blaszyk <david@sudomail.ne.jp>, 2017
# lindwurm, 2015
# Sugahara Masayuki <brindflontia@gmail.com>, 2015
# lip_of_cygnus <Shinya1248@gmail.com>, 2015
@ -12,8 +13,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2017-11-21 21:28+0000\n"
"Last-Translator: David Blaszyk <david@sudomail.ne.jp>\n"
"Language-Team: Japanese (http://www.transifex.com/supertuxkart/supertuxkart/language/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -992,7 +993,7 @@ msgstr "閉じる"
#. I18N: ./data/gui/online/create_server.stkgui
#. I18N: In the server creation screen
msgid "Server Creation"
msgstr ""
msgstr "サーバー創造"
#. I18N: ./data/gui/online/create_server.stkgui
#. I18N: In the server creation screen
@ -1011,7 +1012,7 @@ msgstr ""
#. I18N: ./data/gui/online/create_server.stkgui
#. I18N: In the server creation screen
msgid "Password (optional)"
msgstr ""
msgstr "パスワード (任意)"
#. I18N: ./data/gui/online/create_server.stkgui
#. I18N: In the server creation screen
@ -1161,7 +1162,7 @@ msgstr "ゲームモード"
#. I18N: ./data/gui/online/networking_lobby.stkgui
#. I18N: In the networking lobby
msgid "Exit"
msgstr ""
msgstr "終了"
#. I18N: ./data/gui/online/notification_dialog.stkgui
#. I18N: User info dialog
@ -1219,7 +1220,7 @@ msgstr "サーバーを見つける"
#. I18N: In the online multiplayer screen
#: src/states_screens/create_server_screen.cpp:83
msgid "Create Server"
msgstr ""
msgstr "サーバーを創造する"
#. I18N: ./data/gui/online/profile_servers.stkgui
msgid "Global Networking"
@ -1243,7 +1244,7 @@ msgstr "パスワード:"
#. I18N: ./data/gui/online/profile_settings.stkgui
msgid "Change"
msgstr ""
msgstr "変更"
#. I18N: ./data/gui/online/recovery_info.stkgui
#. I18N: In the recovery dialog
@ -1291,12 +1292,12 @@ msgstr "ユーザーを作成"
#. I18N: ./data/gui/online/register.stkgui
#. I18N: Section in the register screen
msgid "New Online Account"
msgstr ""
msgstr "新しいオンラインアカウント"
#. I18N: ./data/gui/online/register.stkgui
#. I18N: Section in the register screen
msgid "Existing Online Account"
msgstr ""
msgstr "現存のオンラインアカウント"
#. I18N: ./data/gui/online/register.stkgui
#. I18N: Section in the register screen
@ -1345,7 +1346,7 @@ msgstr ""
#. I18N: ./data/gui/online/user_info_dialog.stkgui
#. I18N: User info dialog
msgid "Accept"
msgstr ""
msgstr "受け付ける"
#. I18N: ./data/gui/online/server_info_dialog.stkgui
#. I18N: In the server info dialog
@ -1381,7 +1382,7 @@ msgstr "フレンドを追加"
#. I18N: ./data/gui/online/user_info_dialog.stkgui
#. I18N: User info dialog
msgid "Decline"
msgstr ""
msgstr "断る"
#. I18N: ./data/gui/online/user_search.stkgui
msgid "User search"
@ -1531,7 +1532,7 @@ msgstr "FPS 表示"
#. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings
msgid "Always show login screen"
msgstr ""
msgstr "いつもログイン画面を表示"
#. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings
@ -1680,7 +1681,7 @@ msgstr "タイプ:"
#. I18N: ./data/gui/soccer_setup.stkgui
#. I18N: In soccer setup screen
msgid "Number of goals to win"
msgstr ""
msgstr "ゴールの勝ち数"
#. I18N: ./data/gui/soccer_setup.stkgui
#. I18N: In soccer setup screen
@ -1690,7 +1691,7 @@ msgstr ""
#. I18N: ./data/gui/soccer_setup.stkgui
#. I18N: In soccer setup screen
msgid "Game type (Goals limit / Time limit)"
msgstr ""
msgstr "ゲームタイプ (ゴール限定 / 時間限定)"
#. I18N: ./data/gui/soccer_setup.stkgui
#. I18N: In soccer setup screen
@ -1977,14 +1978,14 @@ msgstr ""
#: src/addons/news_manager.cpp:179
#, c-format
msgid "Error downloading news: '%s'."
msgstr ""
msgstr "ニューズをダウンロードエラー: '1%s'"
#. I18N: number of laps to race in a challenge
#: src/challenges/challenge_data.cpp:266
#: src/states_screens/race_result_gui.cpp:1424
#, c-format
msgid "Laps: %i"
msgstr ""
msgstr "ラップ: 1%i"
#: src/challenges/challenge_data.cpp:272
msgid "Follow the leader"
@ -2044,12 +2045,12 @@ msgstr "設定したコンフィグファイルが古すぎます。削除して
#: src/graphics/irr_driver.cpp:535
msgid "Video recording started."
msgstr ""
msgstr "録画を始めた"
#: src/graphics/irr_driver.cpp:541
#, c-format
msgid "Video saved in \"%s\"."
msgstr ""
msgstr "ビデオは \"%s\" に保存しました"
#: src/graphics/irr_driver.cpp:545
msgid "Encoding progress:"
@ -2121,43 +2122,43 @@ msgstr ""
#: src/input/binding.cpp:126
msgctxt "input_key"
msgid "Backspace"
msgstr ""
msgstr "バックスペース"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:128
msgctxt "input_key"
msgid "Tab"
msgstr ""
msgstr "タブ"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:130
msgctxt "input_key"
msgid "Clear"
msgstr ""
msgstr "消す"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:132
msgctxt "input_key"
msgid "Return"
msgstr ""
msgstr "リターンキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:134
msgctxt "input_key"
msgid "Shift"
msgstr ""
msgstr "シフトキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:136
msgctxt "input_key"
msgid "Control"
msgstr ""
msgstr "コントロールキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:138
msgctxt "input_key"
msgid "Alt/Menu"
msgstr ""
msgstr "Altキー/メニュー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:140
@ -2169,7 +2170,7 @@ msgstr "ポーズ"
#: src/input/binding.cpp:142
msgctxt "input_key"
msgid "Caps Lock"
msgstr ""
msgstr "キャプスロックキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:144
@ -2194,7 +2195,7 @@ msgstr ""
#: src/input/binding.cpp:151
msgctxt "input_key"
msgid "Escape"
msgstr ""
msgstr "エスケープキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:153
@ -2224,7 +2225,7 @@ msgstr ""
#: src/input/binding.cpp:161
msgctxt "input_key"
msgid "Space"
msgstr ""
msgstr "スペースキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:163
@ -2242,43 +2243,43 @@ msgstr ""
#: src/input/binding.cpp:167
msgctxt "input_key"
msgid "End"
msgstr ""
msgstr "エンドキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:169
msgctxt "input_key"
msgid "Home"
msgstr ""
msgstr "ホームキー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:171
msgctxt "input_key"
msgid "Left"
msgstr ""
msgstr "左キー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:173
msgctxt "input_key"
msgid "Up"
msgstr ""
msgstr "上キー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:175
msgctxt "input_key"
msgid "Right"
msgstr ""
msgstr "右キー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:177
msgctxt "input_key"
msgid "Down"
msgstr ""
msgstr "下キー"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:179
msgctxt "input_key"
msgid "Select"
msgstr ""
msgstr "選択"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:181
@ -2576,12 +2577,12 @@ msgstr "入力したコンフィグファイルはこのバージョンのSTKと
#. I18N: Name of the black button on xbox controller
#: src/input/gamepad_config.cpp:167
msgid "Black"
msgstr ""
msgstr "黒い"
#. I18N: Name of the white button on xbox controller
#: src/input/gamepad_config.cpp:171
msgid "White"
msgstr ""
msgstr "白い"
#. I18N: name of buttons on gamepads
#. I18N: name of stick on gamepads
@ -2652,7 +2653,7 @@ msgstr ""
#. I18N: name of buttons on gamepads
#: src/input/gamepad_config.cpp:218
msgid "Start"
msgstr ""
msgstr "スタート"
#. I18N: name of buttons on gamepads
#: src/input/gamepad_config.cpp:220
@ -3133,7 +3134,7 @@ msgstr "無効"
#: src/states_screens/dialogs/custom_video_settings.cpp:67
#: src/states_screens/options_screen_video.cpp:462
msgid "Important only"
msgstr ""
msgstr "大体だけ"
#. I18N: animations setting (only karts with human players are animated)
#: src/states_screens/dialogs/custom_video_settings.cpp:74
@ -3182,19 +3183,19 @@ msgstr ""
#: src/states_screens/edit_gp_screen.cpp:257
#: src/states_screens/ghost_replay_selection.cpp:117
msgid "No"
msgstr ""
msgstr "いいえ"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:60
msgid "Tablet"
msgstr ""
msgstr "タブレット"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:61
msgid "Phone"
msgstr ""
msgstr "スマホ"
#: src/states_screens/dialogs/recovery_dialog.cpp:121
msgid "Username and/or email address invalid."
msgstr ""
msgstr "ユーザー名またはメールアドレスは無効"
#: src/states_screens/dialogs/registration_dialog.cpp:42
#, c-format
@ -3246,7 +3247,7 @@ msgstr "リクエストを取り消す"
#: src/states_screens/dialogs/user_info_dialog.cpp:154
#: src/states_screens/dialogs/user_info_dialog.cpp:211
msgid "Today"
msgstr ""
msgstr "今日"
#: src/states_screens/dialogs/user_info_dialog.cpp:158
msgid "Friend request sent!"
@ -3308,7 +3309,7 @@ msgstr "コース"
#: src/states_screens/edit_gp_screen.cpp:67
#: src/states_screens/ghost_replay_selection.cpp:81
msgid "Laps"
msgstr ""
msgstr "ラップ"
#: src/states_screens/edit_gp_screen.cpp:68
msgid "Reversed"
@ -3374,7 +3375,7 @@ msgstr ""
#: src/states_screens/ghost_replay_selection.cpp:83
msgid "User"
msgstr ""
msgstr "ユーザー"
#: src/states_screens/gp_info_screen.cpp:74
msgid "Default"
@ -3793,7 +3794,7 @@ msgstr "スタート!"
#. I18N: Shown when a goal is scored
#: src/states_screens/race_gui_base.cpp:71
msgid "GOAL!"
msgstr ""
msgstr "ゴール!"
#. I18N: string used to show the author of the music. (e.g. "Sunny Song" by
#. "John Doe")
@ -3838,7 +3839,7 @@ msgstr "アイテムボタンを押してチャレンジを開始"
#: src/states_screens/race_result_gui.cpp:175
msgid "Continue."
msgstr ""
msgstr "続く"
#: src/states_screens/race_result_gui.cpp:178
msgid "Quit the server."
@ -3907,12 +3908,12 @@ msgstr "ハイスコア"
#: src/states_screens/race_result_gui.cpp:1432
#, c-format
msgid "Difficulty: %s"
msgstr ""
msgstr "難しさ: %s"
#: src/states_screens/race_result_gui.cpp:1440
#, c-format
msgid "Best lap time: %s"
msgstr ""
msgstr "ベストラップ時間: %s"
#: src/states_screens/race_setup_screen.cpp:87
msgid "All blows allowed, so catch weapons and make clever use of them!"

View File

@ -5,6 +5,8 @@
# Translators:
# Bruno Ramalhete <bram.512@gmail.com>, 2015
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010
# Pedro TheGamerOficialTM <pedromiguelafonso4@gmail.com>, 2017
# Pedro TheGamerOficialTM <pedromiguelafonso4@gmail.com>, 2017
# Rui <xymarior@yandex.com>, 2016-2017
# Rui <xymarior@yandex.com>, 2016
msgid ""
@ -12,8 +14,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Rui <xymarior@yandex.com>\n"
"PO-Revision-Date: 2017-11-25 11:08+0000\n"
"Last-Translator: Pedro TheGamerOficialTM <pedromiguelafonso4@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.com/supertuxkart/supertuxkart/language/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -95,11 +97,11 @@ msgstr "Apanhar um mínimo de 5 bananas por corrida."
#. I18N: ./data/achievements.xml
msgid "It's secret"
msgstr "É segredo"
msgstr "É um segredo"
#. I18N: ./data/achievements.xml
msgid "Really ... a secret."
msgstr "Realmente... um segredo."
msgstr "Realmente... é um segredo."
#. I18N: ./data/achievements.xml
msgid "Mosquito Hunter"
@ -121,7 +123,7 @@ msgstr "Fora do circuito habitual"
#. I18N: ./data/grandprix/3_tothemoonandback.grandprix
msgid "To the moon and back"
msgstr "Ira à Lua e voltar"
msgstr "Ir à Lua e voltar"
#. I18N: ./data/grandprix/4_atworldsend.grandprix
msgid "At World's End"
@ -385,7 +387,7 @@ msgstr "Todas as Pistas"
#. I18N: ./data/gui/edit_gp.stkgui
#. I18N: Title in edit grand prix screen
msgid "Edit Grand Prix"
msgstr "Editar Grande Prémio"
msgstr "Editar o grande prémio"
#. I18N: ./data/gui/edit_gp.stkgui
#. I18N: Menu item
@ -481,7 +483,7 @@ msgstr "Visualizar apenas o rever"
#. I18N: ./data/gui/track_info.stkgui
#. I18N: In the track info screen
msgid "Start Race"
msgstr "Iniciar corrida"
msgstr "Iniciar a corrida"
#. I18N: ./data/gui/ghost_replay_selection.stkgui
#. I18N: In the ghost replay selection screen
@ -491,7 +493,7 @@ msgstr "Seleção de Rever Fantasma"
#. I18N: ./data/gui/ghost_replay_selection.stkgui
#. I18N: In the ghost replay selection screen
msgid "Only show replays matching the current difficulty"
msgstr "Mostrar rever apenas na dificuldade atual"
msgstr "Mostrar apenas na dificuldade atual"
#. I18N: ./data/gui/ghost_replay_selection.stkgui
#. I18N: In the ghost replay selection screen
@ -523,7 +525,7 @@ msgstr "Continuar o Grande Prémio gravado"
#. I18N: ./data/gui/grand_prix_editor.stkgui
#. I18N: Title in grand prix editor screen
msgid "Grand Prix editor"
msgstr "Editor de Grande Prémio"
msgstr "Editor do grande prémio"
#. I18N: ./data/gui/grand_prix_editor.stkgui
#. I18N: Menu item
@ -646,19 +648,19 @@ msgid ""
"Collecting nitro allows you to get speed boosts whenever you wish by "
"pressing the appropriate key. You can see your current level of nitro in the"
" bar at the right of the game screen."
msgstr "Se apanhares garrafas de nitro podes conseguir velocidades estonteantes sempre que carregares na tecla apropriada. Podes ver o quantidade de nitro na barra à direita do ecrã de jogo."
msgstr "Se apanhares garrafas de nitro podes conseguir velocidades brutais sempre que carregares na tecla apropriada. Podes ver a quantidade de nitro na barra à direita do ecrã do jogo."
#. I18N: ./data/gui/help1.stkgui
#. I18N: In the help menu
msgid ""
"If you see a button with a lock like this one, you need to complete a "
"challenge to unlock it."
msgstr "Se vires um botão com um cadeado destes, é porque tens que completar um desafio para o desbloquear."
msgstr "Se vires um botão com um cadeado destes, é porque tens que completar uma corrida para o desbloquear."
#. I18N: ./data/gui/help1.stkgui
#. I18N: in the help menu
msgid "The 'skidding' key allows you to skid in sharp turns and get a boost."
msgstr "A tecla \"Derrapar\" permite derrapar em curvas apertadas e ganhar aceleração."
msgstr "A tecla \"Derrapar\" permite derrapar em curvas apertadas e ganhar velocidade."
#. I18N: ./data/gui/help1.stkgui
#. I18N: in the help screen
@ -679,7 +681,7 @@ msgstr "Pastilha Elástica - protege-te com um escudo ou utiliza-a quando olhare
#. I18N: ./data/gui/help2.stkgui
msgid ""
"Cake - thrown at the closest rival, best on short ranges and long straights."
msgstr "Bolo - é atirado ao rival mais próximo. Deve ser utilizado para pequenas distâncias e em reta."
msgstr "Bolo - é atirado ao rival mais próximo. Deve ser utilizado para distâncias pequenas e em reta."
#. I18N: ./data/gui/help2.stkgui
msgid ""
@ -729,7 +731,7 @@ msgstr "Corrida Normal: todas as armas são permitidas. Apanha-as e utiliza-as!"
msgid ""
"Time Trial: Contains no powerups, so only your driving skills matter! This "
"mode allows you to record the race for replaying."
msgstr "Corrida Contra o Tempo: não existem powerups por isso apenas contam as tuas capacidades de condução. Este modo permite gravar a corrida para poderes revê-la."
msgstr "Corrida Contra o Tempo: não existem powerups por isso, apenas contam as tuas capacidades de condução. Este modo permite gravar a corrida para poderes revê-la."
#. I18N: ./data/gui/help3.stkgui
#. I18N: In the help menu
@ -737,7 +739,7 @@ msgid ""
"Follow the leader: Run for second place, as the last kart will be "
"disqualified every time the counter hits zero. Beware: going in front of the"
" leader will get you eliminated too!"
msgstr "Seguir o Líder: disputa o segundo lugar, porque o último carro será desqualificado sempre que o cronómetro atinja o valor zero. Atenção: não deves ultrapassar o líder ou serás também eliminado."
msgstr "Seguir o Líder: Disputa o segundo lugar, porque o último carro será desqualificado sempre que o cronómetro atinja o valor zero. Atenção: não deves ultrapassar o líder ou serás também eliminado."
#. I18N: ./data/gui/help3.stkgui
#. I18N: In the help menu
@ -762,7 +764,7 @@ msgid ""
"instead of playing a single race, you play many in a row. The better you "
"rank, the more points you get. In the end, the player with the most points "
"wins the cup."
msgstr "* Grande parte destes modos também podem ser jogados como Grande Prémio. Em vez de fazer uma corrida, joga várias de seguida. Quanto melhor for a tua posição, mais pontos ganhas. No fim, o jogador que tiver mais pontos ganha a taça."
msgstr "* Grande parte destes modos também podem ser jogados como Grande Prémio. Em vez de fazeres uma corrida, jogas várias de seguida. Quanto melhor for a tua posição, mais pontos ganhas. No fim, o jogador que tiver mais pontos ganha a taça."
#. I18N: ./data/gui/help4.stkgui
msgid "SuperTuxKart can be played in multiplayer mode on the same computer"
@ -781,7 +783,7 @@ msgid ""
"keyboard(s), however each player will need a different set of keys, and keep"
" in mind that most keyboards are not appropriate for multiplayer gameplay "
"because they do not support large number of keypresses."
msgstr "Precisas de diversos dispositivos (ter diversos comandos ou joysticks é a melhor maneira para jogos multi-jogadores). Acede às definições e configura os comandos. Também podem jogar no teclado, mas neste caso, cada jogador terá que usar diversas teclas e esta não é a melhor forma de jogar, uma vez que a maioria dos teclados não permitem que se primam várias teclas ao mesmo tempo."
msgstr "Primeiro, precisas de diversos dispositivos (ter diversos comandos ou joysticks é a melhor maneira para jogos multi-jogadores). Acede às definições e configura os comandos. Também podes jogar no teclado, mas neste caso, cada jogador terá que usar diversas teclas e esta não é a melhor forma de jogar, uma vez que a maioria dos teclados não permitem que se primam várias teclas ao mesmo tempo."
#. I18N: ./data/gui/help4.stkgui
#. I18N: In the help menu
@ -792,7 +794,7 @@ msgid ""
" the game. Each player can use their input device to select their kart. The "
"game continues when everyone selected their kart. Note that the mouse may "
"not be used for this operation."
msgstr "Assim que configurares os dispositivos, podes jogar. Escolhe uma corrida multi-jogador no menu principal. Para escolher um veículo, cada jogador tem que pressionar a tecla de \"Disparo\" do comando, joystick ou teclado para entrar no jogo. Cada jogador pode usar o seu dispositivo para escolher o veículo. O jogo começará assim que todos os jogadores escolham o veículo. Para esta operação, não se pode utilizar o rato."
msgstr "Assim que configurares os dispositivos, podes jogar. Escolhe uma corrida multi-jogador no menu principal. Para escolher um veículo, cada jogador tem que pressionar a tecla de \"Disparo\" do comando, joystick ou teclado para entrar no jogo. Cada jogador pode usar o seu dispositivo para escolher o veículo. O jogo começará assim que todos os jogadores escolherem um veículo. Para esta operação, não podes utilizar o rato."
#. I18N: ./data/gui/help5.stkgui
msgid ""
@ -808,7 +810,7 @@ msgstr "Âncora - reduz a velocidade do kart."
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
msgid "Parachute - slows down the kart less than the anchor."
msgstr "Pára-quedas - reduz a velocidade do kart, mas menos que a âncora."
msgstr "Pára-quedas - reduz a velocidade do kart, mas reduz menos que a âncora."
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
@ -948,24 +950,24 @@ msgstr "Restaurar padrão"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
msgid "Password Change"
msgstr "Alterar Palavra-chave"
msgstr "Alterar a palavra-passe"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
msgid "Current Password"
msgstr "Palavra-chave atual"
msgstr "Palavra-passe atual"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
msgid "New Password"
msgstr "Nova Palavra-chave"
msgstr "Nova palavra-passe"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
#. I18N: ./data/gui/online/register.stkgui
#. I18N: In the registration dialog
msgid "Confirm"
msgstr "Confirmação"
msgstr "Confirmar"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
@ -992,7 +994,7 @@ msgstr "Fechar"
#. I18N: ./data/gui/online/create_server.stkgui
#. I18N: In the server creation screen
msgid "Server Creation"
msgstr "Criação de Servidor"
msgstr "Criação do Servidor"
#. I18N: ./data/gui/online/create_server.stkgui
#. I18N: In the server creation screen
@ -1073,7 +1075,7 @@ msgstr "Modo de jogo"
#. I18N: Game mode
#: src/race/race_manager.hpp:175
msgid "Normal Race"
msgstr "Corrida simples"
msgstr "Corrida normal"
#. I18N: ./data/gui/online/create_server.stkgui
#. I18N: Multiplayer game mode
@ -1188,7 +1190,7 @@ msgstr "Amigos"
#. I18N: ./data/gui/online/profile_friends.stkgui
#. I18N: In the profile screen
msgid "Look for more friends:"
msgstr "Porcurar mais amigos:"
msgstr "Procurar mais amigos:"
#. I18N: ./data/gui/online/profile_friends.stkgui
#. I18N: ./data/gui/online/user_search.stkgui
@ -1213,7 +1215,7 @@ msgstr "Rede Local"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: In the online multiplayer screen
msgid "Find Server"
msgstr "Localizar Servidor"
msgstr "Encontrar Servidor"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: In the online multiplayer screen
@ -1223,7 +1225,7 @@ msgstr "Criar Servidor"
#. I18N: ./data/gui/online/profile_servers.stkgui
msgid "Global Networking"
msgstr "Rede Mundial"
msgstr "Rede Global"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: In the online multiplayer screen
@ -1239,7 +1241,7 @@ msgstr "Definições da Conta"
#. I18N: ./data/gui/online/profile_settings.stkgui
#. I18N: In the online account settings screen
msgid "Password:"
msgstr "Palavra-chave:"
msgstr "Palavra-passe:"
#. I18N: ./data/gui/online/profile_settings.stkgui
msgid "Change"
@ -1250,20 +1252,20 @@ msgstr "Alterar"
#. I18N: ./data/gui/online/recovery_input.stkgui
#. I18N: In the recovery dialog
msgid "Account Recovery"
msgstr "Recuperação de Conta"
msgstr "Recuperação da Conta"
#. I18N: ./data/gui/online/recovery_info.stkgui
#. I18N: In the recovery dialog
msgid ""
"You will receive an email with further instructions on how to reset your "
"password. Please be patient and be sure to check your spam folder."
msgstr "Vais receber um email com informações detalhadas sobre como repôr a palavra-chave. Por favor tem paciência e lembra-te de verificar a pasta de emails indesejados ou spam."
msgstr "Vais receber um email com informações detalhadas sobre como alterar a palavra-chave. Por favor tem paciência e lembra-te de verificar a pasta de emails indesejados ou spam."
#. I18N: ./data/gui/online/recovery_input.stkgui
msgid ""
"Fill in the username and email address you supplied at registration to be "
"able to reset your password."
msgstr "Preenche o nome de utilizador e o endereço de email que introduziste ao criar a conta para poderes repôr a tua palavra-passe."
msgstr "Preenche o nome de utilizador e o endereço de email que introduziste ao criar a conta para poderes alterar a tua palavra-passe."
#. I18N: ./data/gui/online/recovery_input.stkgui
#. I18N: In the recovery dialog
@ -1526,7 +1528,7 @@ msgstr "Tema"
#. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings
msgid "Display FPS"
msgstr "Mostrar Quadros Por Segundo"
msgstr "Mostrar FPS"
#. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings
@ -1581,7 +1583,7 @@ msgstr "Resolução"
#. I18N: ./data/gui/options_video.stkgui
#. I18N: In the video settings
msgid "Fullscreen"
msgstr "Ecrã total"
msgstr "Ecrã inteiro"
#. I18N: ./data/gui/options_video.stkgui
#. I18N: In the video settings
@ -1711,7 +1713,7 @@ msgstr "Equipa Azul"
#. I18N: In the track and grand prix selection screen
#: src/states_screens/dialogs/select_challenge.cpp:147
msgid "Grand Prix"
msgstr "Grande prémio"
msgstr "Grande Prémio"
#. I18N: ./data/gui/track_info.stkgui
msgid "= Highscores ="
@ -1811,12 +1813,12 @@ msgstr "Sim, ele está no meu castelo e servir-me-á para sempre..."
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
msgid "But I'm a fair creature, so I'll make you a deal."
msgstr "Mas como sou uma criatura justa, proponho um acordo."
msgstr "Mas como sou uma criatura justa, proponho-te um acordo."
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
msgid "If you can beat me at racing, I will free the old codger."
msgstr "Se me conseguires vencer na corrida, eu liberto-o."
msgstr "Se me conseguires vencer na corrida, eu liberto o teu líder."
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
@ -1935,7 +1937,7 @@ msgstr "Nolok"
#. I18N: ../stk-assets/karts/pidgin/kart.xml
msgid "Pidgin"
msgstr "Pombo"
msgstr "Pidgin"
#. I18N: ../stk-assets/karts/puffy/kart.xml
msgid "Puffy"
@ -1943,11 +1945,11 @@ msgstr "Puffy"
#. I18N: ../stk-assets/karts/sara_the_racer/kart.xml
msgid "Sara the Racer"
msgstr "Sara a Corredora"
msgstr "Sara The Racer"
#. I18N: ../stk-assets/karts/sara_the_wizard/kart.xml
msgid "Sara the Wizard"
msgstr "Sara a Feiticeira"
msgstr "Sara The Wizard"
#. I18N: ../stk-assets/karts/suzanne/kart.xml
msgid "Suzanne"
@ -1977,7 +1979,7 @@ msgstr "Não foi possível ligar ao servidor de extras do SuperTuxKart."
#: src/addons/news_manager.cpp:179
#, c-format
msgid "Error downloading news: '%s'."
msgstr "Erro ao descarregar notícias: '%s'."
msgstr "Erro ao descarregar as notícias: '%s'."
#. I18N: number of laps to race in a challenge
#: src/challenges/challenge_data.cpp:266
@ -2139,7 +2141,7 @@ msgstr "Clear"
#: src/input/binding.cpp:132
msgctxt "input_key"
msgid "Return"
msgstr "Mudar de linha"
msgstr "Return"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:134
@ -2169,7 +2171,7 @@ msgstr "Pausa"
#: src/input/binding.cpp:142
msgctxt "input_key"
msgid "Caps Lock"
msgstr "Maiúsculas"
msgstr "Caps Lock"
#. I18N: input configuration screen: keyboard key
#: src/input/binding.cpp:144
@ -2571,7 +2573,7 @@ msgstr "Configura os atalhos de teclado."
#: src/input/device_manager.cpp:544
msgid "Your input config file is not compatible with this version of STK."
msgstr "O ficheiro de configuração não é compatível com esta versão do SuperTuxKart."
msgstr "O teu ficheiro de configuração não é compatível com esta versão do SuperTuxKart."
#. I18N: Name of the black button on xbox controller
#: src/input/gamepad_config.cpp:167

View File

@ -3,7 +3,7 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# André Marcelo Alvarenga <alvarenga@kde.org>, 2017
# André Marcelo Alvarenga <alvarenga@kde.org>, 2017-2018
# flaviozavan <flaviozavan@gmail.com>, 2015-2017
# Laete Meireles <laetemn@gmail.com>, 2015
# Pablo do Amaral Ferreira <pabloferreira1407@gmail.com>, 2015
@ -12,8 +12,8 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-01-18 01:12+0000\n"
"Last-Translator: André Marcelo Alvarenga <alvarenga@kde.org>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/supertuxkart/supertuxkart/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1827,7 +1827,7 @@ msgstr " Mas você, pequeno patético imbecil, nunca será capaz de me derrotar
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
msgstr ""
msgstr "Arena Las Dunas"
#. I18N: ../stk-assets/tracks/lighthouse/track.xml
msgid "Around the lighthouse"
@ -2941,7 +2941,7 @@ msgstr "Nome do complemento"
#: src/states_screens/addons_screen.cpp:116
msgid "Updated date"
msgstr "Atualizar data"
msgstr "Data de atualização"
#: src/states_screens/addons_screen.cpp:147
msgid ""
@ -3918,7 +3918,7 @@ msgstr "Dificuldade: %s"
#: src/states_screens/race_result_gui.cpp:1440
#, c-format
msgid "Best lap time: %s"
msgstr "Melhor tempo de volta: %s"
msgstr "Tempo da melhor volta: %s"
#: src/states_screens/race_setup_screen.cpp:87
msgid "All blows allowed, so catch weapons and make clever use of them!"
@ -4003,7 +4003,7 @@ msgstr "Bloqueado!"
#: src/states_screens/tracks_and_gp_screen.cpp:278
#: src/states_screens/tracks_screen.cpp:227
msgid "Locked: solve active challenges to gain access to more!"
msgstr "Bloqueado : ganhe os desafios ativos para ter acesso a mais!"
msgstr "Bloqueado: ganhe os desafios ativos para ter acesso a mais!"
#: src/states_screens/tracks_screen.cpp:194
msgid "Only official tracks are supported."
@ -4054,7 +4054,7 @@ msgstr "Entrando '%s'"
#: src/states_screens/user_screen.cpp:595
#, c-format
msgid "Do you really want to delete player '%s' ?"
msgstr "Você realmente quer exlcuir o jogador '%s' ?"
msgstr "Deseja realmente excluir o jogador '%s' ?"
#. I18N: Format for dates (%d = day, %m = month, %Y = year). See
#. http://www.cplusplus.com/reference/ctime/strftime/ for more info about date

View File

@ -3,14 +3,14 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Nicolae Crefelean, 2015,2017
# Nicolae Crefelean, 2015,2017-2018
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-03-02 21:38+0000\n"
"Last-Translator: Nicolae Crefelean\n"
"Language-Team: Romanian (http://www.transifex.com/supertuxkart/supertuxkart/language/ro/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -100,13 +100,13 @@ msgstr "Serios... e secret."
#. I18N: ./data/achievements.xml
msgid "Mosquito Hunter"
msgstr ""
msgstr "Vânătoarea de țânțari"
#. I18N: ./data/achievements.xml
msgid ""
"Take your opponents for mosquitos! With the swatter, squash at least 5 of "
"them in a race."
msgstr ""
msgstr "Tratează adversarii ca pe țânțari! Lovește-i cu pliciul de cel puțin 5 ori într-o cursă."
#. I18N: ./data/grandprix/1_penguinplayground.grandprix
msgid "Penguin Playground"

View File

@ -7,14 +7,15 @@
# Dmitry Dubrov <dimprogpro@hotmail.ru>, 2015
# Oleg <laol-tomsk@mail.ru>, 2015
# Val Och <v19930312@gmail.com>, 2016
# Vladislav Tananaev <vlad.tananaev@gmail.com>, 2018
# Олег Лазарев <laoltomsk@gmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Олег Лазарев <laoltomsk@gmail.com>\n"
"PO-Revision-Date: 2018-03-07 14:35+0000\n"
"Last-Translator: Andrei Stepanov\n"
"Language-Team: Russian (http://www.transifex.com/supertuxkart/supertuxkart/language/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -597,7 +598,7 @@ msgstr "Оружие"
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Game Modes"
msgstr "Режим игры"
msgstr "Режимы игры"
#. I18N: ./data/gui/help1.stkgui
#. I18N: Tab in help menu
@ -744,7 +745,7 @@ msgstr "Следуйте за лидером: будьте на втором м
#. I18N: In the help menu
msgid ""
"3 Strikes Battle: Hit others with weapons until they lose all their lives."
msgstr "Битва Трех Ударов: атакуйте других с помощью оружия до тех пор, пока они не потеряют все свои жизни."
msgstr "Битва трёх ударов: атакуйте других с помощью оружия до тех пор, пока они не потеряют все свои жизни."
#. I18N: ./data/gui/help3.stkgui
#. I18N: In the help menu
@ -1178,7 +1179,7 @@ msgstr "Вид"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: ./data/gui/online/profile_settings.stkgui
msgid "..."
msgstr "..."
msgstr ""
#. I18N: ./data/gui/online/profile_friends.stkgui
#. I18N: Section in the profile screen
@ -1334,7 +1335,7 @@ msgstr "Вы можете играть без создания сетевого
#. I18N: ./data/gui/online/registration_terms.stkgui
#. I18N: In the registration dialog
msgid "Terms and Agreement"
msgstr "Условия и Соглашение"
msgstr "Условия и соглашение"
#. I18N: ./data/gui/online/registration_terms.stkgui
#. I18N: In the registration dialog
@ -1467,7 +1468,7 @@ msgstr "Вернуться к списку устройств"
#. I18N: ./data/gui/options_input.stkgui
#. I18N: In the input configuration screen
msgid "Press enter or double-click on a device to configure it"
msgstr "Нажмите Enter или дважды кликните по устройству, чтобы настроить его"
msgstr "Нажмите «Enter» или дважды кликните по устройству, чтобы настроить его"
#. I18N: ./data/gui/options_input.stkgui
#. I18N: In the input configuration screen
@ -1479,7 +1480,7 @@ msgstr "Добавить устройство"
msgid ""
"* Which config to use will be inferred from which 'Select' key is pressed to"
" join the game."
msgstr "* Выбор конфигурации будет зависеть от того, с какого устройства нажата кнопка \"Выбрать\" при соединении к игре."
msgstr "* Выбор конфигурации будет зависеть от того, с какого устройства нажата кнопка «Выбрать» при соединении к игре."
#. I18N: ./data/gui/options_players.stkgui
#. I18N: Section in the settings menu
@ -1502,7 +1503,7 @@ msgstr "Вы играете за"
#. I18N: ./data/gui/options_players.stkgui
#. I18N: In the player configuration screen
msgid "Press enter or double-click on a player to edit their settings"
msgstr "Нажмите Enter или дважды кликните по игроку для редактирования его настроек"
msgstr "Нажмите «Enter» или дважды кликните по игроку для редактирования его настроек"
#. I18N: ./data/gui/options_players.stkgui
#. I18N: In the player configuration screen
@ -1686,7 +1687,7 @@ msgstr "Количество голов для победы"
#. I18N: ./data/gui/soccer_setup.stkgui
#. I18N: In soccer setup screen
msgid "Maximum time (min.)"
msgstr "Максимальное время (мин)"
msgstr "Максимальное время (мин.)"
#. I18N: ./data/gui/soccer_setup.stkgui
#. I18N: In soccer setup screen
@ -1824,7 +1825,7 @@ msgstr "Если ты победишь меня в гонке, то я осво
msgid ""
" But you pathetic little twerps will never be able to beat me - King of the "
"Karts!"
msgstr "Но вы, жалкие дурачки, никогда не сможете победить меня — Короля Картов !"
msgstr "Но вы, жалкие дурачки, никогда не сможете победить меня — Короля Картов!"
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
@ -1964,28 +1965,28 @@ msgstr "Вильбер"
#. I18N: ../stk-assets/karts/xue/kart.xml
msgid "Xue"
msgstr "XFCE-мышь"
msgstr "Ксю"
#: src/achievements/achievement.cpp:209
#, c-format
msgid "Completed achievement \"%s\"."
msgstr "Получено достижение \"%s\"."
msgstr "Получено достижение «%s»."
#: src/addons/addons_manager.cpp:104 src/addons/news_manager.cpp:322
msgid "Failed to connect to the SuperTuxKart add-ons server."
msgstr "Не удалось подключиться к серверу аддонов SuperTuxKart."
msgstr "Не удалось подключиться к серверу дополнений SuperTuxKart."
#: src/addons/news_manager.cpp:179
#, c-format
msgid "Error downloading news: '%s'."
msgstr "Ошибка при получении новостей: %s."
msgstr "Ошибка при получении новостей: «%s»."
#. I18N: number of laps to race in a challenge
#: src/challenges/challenge_data.cpp:266
#: src/states_screens/race_result_gui.cpp:1424
#, c-format
msgid "Laps: %i"
msgstr "Кругов: %i"
msgstr "Кол-во кругов: %i"
#: src/challenges/challenge_data.cpp:272
msgid "Follow the leader"
@ -2050,7 +2051,7 @@ msgstr "Началась запись видео."
#: src/graphics/irr_driver.cpp:541
#, c-format
msgid "Video saved in \"%s\"."
msgstr "Видео сохранено в \"%s\"."
msgstr "Видео сохранено в «%s»."
#: src/graphics/irr_driver.cpp:545
msgid "Encoding progress:"
@ -2698,13 +2699,13 @@ msgstr "Это может делать только хозяин игры!"
msgid ""
"Connect your wiimote to the Bluetooth manager, then click on Ok. Detailed "
"instructions at supertuxkart.net/Wiimote"
msgstr "Подсоедините wiimote к менеджеру Bluetooth, затем нажмите Ок. Подробную инструкцию смотрите на supertuxkart.net/Wiimote"
msgstr "Подсоедините контроллер Wii к менеджеру Bluetooth, затем нажмите ОК. Подробную инструкцию смотрите на supertuxkart.net/Wiimote"
#: 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 "Чтобы попасть в меню поиска, одновременно нажмите кнопки 1+2 на своем wiimote, затем нажмите ОК. Подробную инструкцию смотрите на supertuxkart.net/Wiimote"
msgstr "Чтобы попасть в меню поиска, одновременно нажмите кнопки 1+2 на своём контроллере Wii, затем нажмите ОК. Подробную инструкцию смотрите на supertuxkart.net/Wiimote"
#: src/input/wiimote_manager.cpp:414
#, c-format
@ -2725,7 +2726,7 @@ msgstr "Штрафное время!!!"
#: src/karts/controller/local_player_controller.cpp:243
msgid "Don't accelerate before go"
msgstr "Не жмите газ до слова \"Вперёд\"!"
msgstr "Не жмите газ до слова «Вперёд»!"
#: src/karts/controller/spare_tire_ai.cpp:147
msgid "You can have at most 3 lives!"
@ -2818,7 +2819,7 @@ msgstr "Вы дисквалифицированы!"
#: src/modes/world.cpp:1205
#, c-format
msgid "'%s' has been eliminated."
msgstr "'%s' выбыл из гонки."
msgstr "'%s' выбыл(-а) из гонки."
#: src/network/protocols/server_lobby.cpp:318
#, c-format
@ -2886,12 +2887,12 @@ msgstr "Таблица результатов устарела,\nвсе резу
#. I18N: Game mode
#: src/race/race_manager.hpp:179
msgid "Follow the Leader"
msgstr "Следуйте за Лидером"
msgstr "Следуйте за лидером"
#. I18N: Game mode
#: src/race/race_manager.hpp:181
msgid "3 Strikes Battle"
msgstr "Битва Трёх Ударов"
msgstr "Битва трёх ударов"
#. I18N: Game mode
#: src/race/race_manager.hpp:183
@ -2956,7 +2957,7 @@ msgstr "Дата обновления"
msgid ""
"Access to the Internet is disabled. (To enable it, go to options and select "
"tab 'User Interface')"
msgstr "Доступ в Интернет отсутствует. (Для включения доступа, перейдите в настройки и выберите вкладку \"Интерфейс\")"
msgstr "Доступ в Интернет отсутствует. (Для включения доступа, перейдите в настройки и выберите вкладку «Интерфейс»)"
#. I18N: as in: The Old Island by Johannes Sjolund
#: src/states_screens/addons_screen.cpp:343
@ -3052,13 +3053,13 @@ msgstr "избранное"
#: src/states_screens/dialogs/addons_loading.cpp:166
#, c-format
msgid "%s MB"
msgstr "%s Мбайт"
msgstr "%s МБ"
#: src/states_screens/dialogs/addons_loading.cpp:173
#: src/states_screens/dialogs/addons_loading.cpp:177
#, c-format
msgid "%s KB"
msgstr "%s Кбайт"
msgstr "%s КБ"
#: src/states_screens/dialogs/addons_loading.cpp:178
#, c-format
@ -3089,7 +3090,7 @@ msgid ""
"To add a new Gamepad/Joystick device, simply start SuperTuxKart with it connected and it will appear in the list.\n"
"\n"
"To add a keyboard config, you can use the button below, HOWEVER please note that most keyboards only support a limited amount of simultaneous keypresses and are thus inappropriate for multiplayer gameplay. (You can, however, connect multiple keyboards to the computer. Remember that everyone still needs different keybindings in this case.)"
msgstr "Для того, чтобы добавить Геймпад/Джойстик, просто запустите SuperTuxKart, когда он подключен. Он автоматически появится в списке устройств.\n\nЧтобы добавить настройки клавиатуры, вы можете нажать на кнопку, находящуюся ниже. Но учтите, что большинство клавиатур поддерживают только ограниченное количество одновременных нажатий клавиш и поэтому не подходят для многопользовательской игры. (Однако вы можете решить эту проблему подключением нескольких клавиатур к компьютеру. Но даже в этом случае нужно назначать различные сочетания клавиш.)"
msgstr "Для того, чтобы добавить Геймпад/Джойстик, просто запустите SuperTuxKart, когда он подключён. Он автоматически появится в списке устройств.\n\nЧтобы добавить настройки клавиатуры, вы можете нажать на кнопку, находящуюся ниже. Но учтите, что большинство клавиатур поддерживают только ограниченное количество одновременных нажатий клавиш и поэтому не подходят для многопользовательской игры. (Однако вы можете решить эту проблему подключением нескольких клавиатур к компьютеру. Но даже в этом случае нужно назначать различные сочетания клавиш.)"
#. I18N: In the 'add new input device' dialog
#: src/states_screens/dialogs/add_device_dialog.cpp:90
@ -3434,7 +3435,7 @@ msgstr "Имя не задано."
#: src/states_screens/grand_prix_editor_screen.cpp:359
msgid "Another grand prix with this name already exists."
msgstr "Уже существует Гран-при с таким же названием."
msgstr "Гран-при с таким же названием уже существует."
#: src/states_screens/grand_prix_editor_screen.cpp:365
msgid "Name is too long."
@ -3467,7 +3468,7 @@ msgstr "Заблокировано"
msgid ""
"Everyone:\n"
"Press the 'Select' button to join the game"
msgstr "Всем:\nДля присоединения к игре нажмите клавишу \"Выбрать\" "
msgstr "Всем:\nДля присоединения к игре нажмите клавишу «Выбрать»"
#: src/states_screens/main_menu_screen.cpp:510
msgid ""
@ -3512,7 +3513,7 @@ msgstr "Профиль %s"
#: src/states_screens/online_profile_friends.cpp:75
msgid "Since"
msgstr "С"
msgstr " Дата"
#: src/states_screens/online_profile_friends.cpp:76
msgid "Status"
@ -3683,7 +3684,7 @@ msgstr "Сенсорное устройство"
msgid ""
"In multiplayer mode, players can select handicapped (more difficult) "
"profiles on the kart selection screen"
msgstr "В многопользовательском режиме игроки могут выбрать профили гандикапа (сложности) на экране выбора карта."
msgstr "В многопользовательском режиме игроки могут выбрать профили гандикапа (сложности) на экране выбора карта"
#. I18N: in the language choice, to select the same language as the OS
#: src/states_screens/options_screen_ui.cpp:191
@ -3731,7 +3732,7 @@ msgstr "Динамическое освещение: %s"
#: src/states_screens/options_screen_video.cpp:498
#, c-format
msgid "Motion blur: %s"
msgstr "Размытие при движении: %s"
msgstr "Размытие в движении: %s"
#. I18N: in graphical options
#: src/states_screens/options_screen_video.cpp:501
@ -3890,7 +3891,7 @@ msgstr "Вы действительно хотите прервать Гран-
#: src/states_screens/race_result_gui.cpp:499
#: src/states_screens/race_result_gui.cpp:865
msgid "Eliminated"
msgstr "Выбыл из гонки"
msgstr "Выбыл(-а) из гонки"
#: src/states_screens/race_result_gui.cpp:1012
msgid "Red Team Wins"
@ -3939,7 +3940,7 @@ msgstr "Все возможности доступны, так что собир
#: src/states_screens/race_setup_screen.cpp:94
msgid "Contains no powerups, so only your driving skills matter!"
msgstr "Не содержит бонусов, только ваши навыки вождения имеют значение!"
msgstr "Никаких бонусов, важны только ваши навыки вождения!"
#. I18N: short definition for follow-the-leader game mode
#: src/states_screens/race_setup_screen.cpp:107
@ -3986,7 +3987,7 @@ msgstr "Электронная почта должна содержать от 4
#: src/states_screens/register_screen.cpp:299
msgid "Email is invalid!"
msgstr "Недоступная электронная почта!"
msgstr "Недействительная электронная почта!"
#: src/states_screens/register_screen.cpp:362
msgid ""
@ -4074,7 +4075,7 @@ msgstr "Вы действительно хотите удалить игрока
#. formats.
#: src/utils/time.cpp:50
msgid "%d/%m/%Y"
msgstr "%д.%м.%Г"
msgstr "%d.%m.%Y"
#. I18N: Do NOT literally translate this string!! Please enter Y as the
#. translation if your language is a RTL (right-to-left) language,

View File

@ -7,13 +7,14 @@
# Dušan Kazik <prescott66@gmail.com>, 2015
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010
# MiroslavR <miroslavr256@gmail.com>, 2015-2016
# Vladimír Záhradník <vladimir.zahradnik@gmail.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-01-05 11:47+0000\n"
"Last-Translator: Vladimír Záhradník <vladimir.zahradnik@gmail.com>\n"
"Language-Team: Slovak (http://www.transifex.com/supertuxkart/supertuxkart/language/sk/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -296,7 +297,7 @@ msgstr "Osvetlenie založené na obrázku"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Bloom"
msgstr ""
msgstr "Bloom (rozptýlené svetlo)"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
@ -306,7 +307,7 @@ msgstr "Svetelné lúče"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Ambient Occlusion"
msgstr ""
msgstr "Zatienenie okolím"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
@ -356,12 +357,12 @@ msgstr "Animácia postáv"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Rendered image quality"
msgstr ""
msgstr "Kvalita vykresľovaného obrazu"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Geometry detail"
msgstr ""
msgstr "Geometrické podrobnosti"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
@ -465,12 +466,12 @@ msgstr "Pokračovať"
#. I18N: ./data/gui/track_info.stkgui
#. I18N: In the track info screen
msgid "Record the race for ghost replay"
msgstr ""
msgstr "Nahrať pretek pre opakovačku s duchom"
#. I18N: ./data/gui/ghost_replay_info_dialog.stkgui
#. I18N: Ghost replay info action
msgid "Watch replay only"
msgstr ""
msgstr "Iba pozrieť opakovačku"
#. I18N: ./data/gui/ghost_replay_info_dialog.stkgui
#. I18N: Ghost replay info screen action
@ -486,17 +487,17 @@ msgstr "Začať preteky"
#. I18N: ./data/gui/ghost_replay_selection.stkgui
#. I18N: In the ghost replay selection screen
msgid "Ghost Replay Selection"
msgstr ""
msgstr "Výber opakovačky s duchom"
#. I18N: ./data/gui/ghost_replay_selection.stkgui
#. I18N: In the ghost replay selection screen
msgid "Only show replays matching the current difficulty"
msgstr ""
msgstr "Zobrazovať iba opakovačky odpovedajúce aktuálnej obtiažnosti"
#. I18N: ./data/gui/ghost_replay_selection.stkgui
#. I18N: In the ghost replay selection screen
msgid "Record ghost replay"
msgstr ""
msgstr "Nahrať pre opakovačku s duchom"
#. I18N: ./data/gui/gp_info.stkgui
#. I18N: In the grand prix info screen
@ -609,7 +610,7 @@ msgstr "Herné režimy"
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Multi-player"
msgstr ""
msgstr "Hra viac hráčov"
#. I18N: ./data/gui/help1.stkgui
#. I18N: Tab in help menu
@ -622,11 +623,11 @@ msgstr ""
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Bananas"
msgstr ""
msgstr "Banány"
#. I18N: ./data/gui/help1.stkgui
msgid "Start the tutorial"
msgstr ""
msgstr "Spustiť výuku"
#. I18N: ./data/gui/help1.stkgui
#. I18N: In the help menu
@ -729,7 +730,7 @@ msgstr "Obyčajné preteky: Povoľujú sa všetky údery, tak sa chopte zbraní
msgid ""
"Time Trial: Contains no powerups, so only your driving skills matter! This "
"mode allows you to record the race for replaying."
msgstr ""
msgstr "Pretek na čas: Neobsahuje žiadne bonusy, záleží iba na vašich vodičských schopnostiach! Tento režim umožňuje nahrávať pretek pre neskoršie spätné prehrávanie."
#. I18N: ./data/gui/help3.stkgui
#. I18N: In the help menu
@ -748,7 +749,7 @@ msgstr "Bitka na 3 údery: Triafajte ostatných hráčov zbraňami, kým nepríd
#. I18N: ./data/gui/help3.stkgui
#. I18N: In the help menu
msgid "Soccer: Use your kart to push the ball into the goal."
msgstr ""
msgstr "Futbal: Použite svoju motokáru na natlačenie lopty do bránky."
#. I18N: ./data/gui/help3.stkgui
#. I18N: In the help menu
@ -798,24 +799,24 @@ msgstr "Po nakonfigurovaní vstupných zariadení môžete začať hrať. V hlav
msgid ""
"Hitting a banana can result in one of the following being attached to the "
"kart:"
msgstr ""
msgstr "Náraz do banánu môže mať za následok, že sa pripojí k motokáre jedna z nasledujúcich položiek:"
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
msgid "Anchor - slows down the kart."
msgstr ""
msgstr "Kotva - spomaľuje motokáru."
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
msgid "Parachute - slows down the kart less than the anchor."
msgstr ""
msgstr "Padák - spomaľuje motokáru menej než kotva."
#. 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 ""
msgstr "Bomba - po chvíli vybuchne a vyhodí motokáru do vzduchu. Nárazom do inej motokáry prehodíte bombu inému hráčovi."
#. I18N: ./data/gui/karts.stkgui
#. I18N: In the kart selection (player setup) screen
@ -904,46 +905,46 @@ msgstr "Ukončiť"
#. I18N: ./data/gui/multitouch_settings.stkgui
msgid "Touch Device Settings"
msgstr ""
msgstr "Nastavenia dotykového zariadenia"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Device enabled"
msgstr ""
msgstr "Zariadenie je povolené"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Inverted buttons"
msgstr ""
msgstr "Prehodené tlačidlá"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Buttons scale"
msgstr ""
msgstr "Rozsah tlačidiel"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Accelerometer"
msgstr ""
msgstr "Akcelerometer"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Advanced"
msgstr ""
msgstr "Pokročilé"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Deadzone"
msgstr ""
msgstr "Zóna smrti"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Sensitivity"
msgstr ""
msgstr "Citlivosť"
#. I18N: ./data/gui/multitouch_settings.stkgui
msgid "Restore defaults"
msgstr ""
msgstr "Obnoviť predvolené nastavenia"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
@ -1208,7 +1209,7 @@ msgstr "Servery"
#. I18N: ./data/gui/online/profile_servers.stkgui
msgid "Local Networking"
msgstr ""
msgstr "Lokálna sieť"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: In the online multiplayer screen
@ -1223,7 +1224,7 @@ msgstr "Vytvoriť server"
#. I18N: ./data/gui/online/profile_servers.stkgui
msgid "Global Networking"
msgstr ""
msgstr "Globálna sieť"
#. I18N: ./data/gui/online/profile_servers.stkgui
#. I18N: In the online multiplayer screen
@ -1501,7 +1502,7 @@ msgstr "Hráte ako"
#. I18N: ./data/gui/options_players.stkgui
#. I18N: In the player configuration screen
msgid "Press enter or double-click on a player to edit their settings"
msgstr ""
msgstr "Stlačte enter alebo dvakrát rýchlo kliknite na hráča, aby ste upravili jeho nastavenia"
#. I18N: ./data/gui/options_players.stkgui
#. I18N: In the player configuration screen
@ -1756,7 +1757,7 @@ msgstr "Vymazať"
#. I18N: ../stk-assets/tracks/abyss/track.xml
msgid "Antediluvian Abyss"
msgstr ""
msgstr "Predpotopná priepasť"
#. I18N: ../stk-assets/tracks/battleisland/track.xml
msgid "Battle Island"
@ -1764,7 +1765,7 @@ msgstr "Boj na ostrove"
#. I18N: ../stk-assets/tracks/candela_city/track.xml
msgid "Candela City"
msgstr ""
msgstr "Mesto Candela"
#. I18N: ../stk-assets/tracks/cave/track.xml
msgid "Cave X"
@ -1776,7 +1777,7 @@ msgstr "Kakaový chrám"
#. I18N: ../stk-assets/tracks/cornfield_crossing/track.xml
msgid "Cornfield Crossing"
msgstr ""
msgstr "Kros kukuričným poľom"
#. I18N: ../stk-assets/tracks/fortmagma/track.xml
msgid "Fort Magma"
@ -1796,7 +1797,7 @@ msgstr "Hacienda"
#. I18N: ../stk-assets/tracks/icy_soccer_field/track.xml
msgid "Icy Soccer Field"
msgstr ""
msgstr "Ľadové futbalové ihrisko"
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
@ -1827,7 +1828,7 @@ msgstr "No poraziť mňa kráľa motokár sa vám úbohým krpcom nikdy
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
msgstr ""
msgstr "Piesočné duny"
#. I18N: ../stk-assets/tracks/lighthouse/track.xml
msgid "Around the lighthouse"
@ -1883,7 +1884,7 @@ msgstr "Chrám"
#. I18N: ../stk-assets/tracks/volcano_island/track.xml
msgid "Volcan Island"
msgstr ""
msgstr "Sopečný ostrov"
#. I18N: ../stk-assets/tracks/xr591/track.xml
msgid "XR591"
@ -1923,7 +1924,7 @@ msgstr "Hexley"
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
msgstr ""
msgstr "Kiki"
#. I18N: ../stk-assets/karts/konqi/kart.xml
msgid "Konqi"
@ -1972,7 +1973,7 @@ msgstr "Dokončili ste úspech „%s“."
#: src/addons/addons_manager.cpp:104 src/addons/news_manager.cpp:322
msgid "Failed to connect to the SuperTuxKart add-ons server."
msgstr ""
msgstr "Nepodarilo sa pripojiť k serveru doplnkov SuperTuxKart."
#: src/addons/news_manager.cpp:179
#, c-format
@ -2044,16 +2045,16 @@ msgstr "Váš konfiguračný súbor bol príliš starý, takže bol zmazaný a v
#: src/graphics/irr_driver.cpp:535
msgid "Video recording started."
msgstr ""
msgstr "Začalo nahrávanie videa."
#: src/graphics/irr_driver.cpp:541
#, c-format
msgid "Video saved in \"%s\"."
msgstr ""
msgstr "Video uložené do „%s“."
#: src/graphics/irr_driver.cpp:545
msgid "Encoding progress:"
msgstr ""
msgstr "Priebeh kódovania:"
#: src/graphics/irr_driver.cpp:1682
#, c-format
@ -2593,25 +2594,25 @@ msgstr "Ľavá spúšť"
#. I18N: name of stick on gamepads
#: src/input/gamepad_config.cpp:181 src/input/gamepad_config.cpp:244
msgid "Right thumb right"
msgstr ""
msgstr "Pravý palec doprava"
#. I18N: name of buttons on gamepads
#. I18N: name of stick on gamepads
#: src/input/gamepad_config.cpp:183 src/input/gamepad_config.cpp:246
msgid "Right thumb left"
msgstr ""
msgstr "Pravý palec doľava"
#. I18N: name of buttons on gamepads
#. I18N: name of trigger on gamepads
#: src/input/gamepad_config.cpp:185 src/input/gamepad_config.cpp:240
msgid "Right thumb down"
msgstr ""
msgstr "Pravý palec nadol"
#. I18N: name of buttons on gamepads
#. I18N: name of stick on gamepads
#: src/input/gamepad_config.cpp:187 src/input/gamepad_config.cpp:242
msgid "Right thumb up"
msgstr ""
msgstr "Pravý palec nahor"
#. I18N: name of buttons on gamepads
#: src/input/gamepad_config.cpp:189 src/input/gamepad_config.cpp:248
@ -2657,32 +2658,32 @@ msgstr "Start"
#. I18N: name of buttons on gamepads
#: src/input/gamepad_config.cpp:220
msgid "Left thumb button"
msgstr ""
msgstr "Tlačidlo ľavého palca"
#. I18N: name of buttons on gamepads
#: src/input/gamepad_config.cpp:222
msgid "Right thumb button"
msgstr ""
msgstr "Tlačidlo pravého palca"
#. I18N: name of stick on gamepads
#: src/input/gamepad_config.cpp:231
msgid "Left thumb right"
msgstr ""
msgstr "Ľavý palec doprava"
#. I18N: name of stick on gamepads
#: src/input/gamepad_config.cpp:233
msgid "Left thumb left"
msgstr ""
msgstr "Ľavý palec doľava"
#. I18N: name of stick on gamepads
#: src/input/gamepad_config.cpp:235
msgid "Left thumb down"
msgstr ""
msgstr "Ľavý palec nadol"
#. I18N: name of stick on gamepads
#: src/input/gamepad_config.cpp:237
msgid "Left thumb up"
msgstr ""
msgstr "Ľavý palec nahor"
#: src/input/input_manager.cpp:807
#, c-format
@ -2697,13 +2698,13 @@ msgstr "V tejto chvíli môže vykonávať činnosť iba vlastník hry!"
msgid ""
"Connect your wiimote to the Bluetooth manager, then click on Ok. Detailed "
"instructions at supertuxkart.net/Wiimote"
msgstr ""
msgstr "Pripojte svoj Wiimote ovládač v Správe Bluetooth zariadení a potom kliknite na tlačidlo OK. Podrobný návod je na supertuxkart.net/Wiimote"
#: 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 ""
msgstr "Súčasne na svojom Wiimote ovládači stlačte tlačidlá 1+2, čím ho prepnete do režimu vyhľadávania. Potom kliknite na tlačidlo Ok. Podrobný návod je na supertuxkart.net/Wiimote"
#: src/input/wiimote_manager.cpp:414
#, c-format
@ -2727,11 +2728,11 @@ msgstr "Nepridávajte plyn pred štartom"
#: src/karts/controller/spare_tire_ai.cpp:147
msgid "You can have at most 3 lives!"
msgstr ""
msgstr "Môžete mať najviac 3 životy!"
#: src/karts/controller/spare_tire_ai.cpp:153
msgid "+1 life."
msgstr ""
msgstr "+1 život."
#: src/karts/kart.cpp:908 src/karts/kart.cpp:913
msgid "You won the race!"
@ -2754,7 +2755,7 @@ msgstr "SuperTuxKart sa môže pripájať na server s cieľom sťahovať doplnky
#: src/main.cpp:1654
msgid "Your screen resolution is too low to run STK."
msgstr ""
msgstr "Rozlíšenie vašej obrazovky je príliš nízke na spustenie STK."
#: src/main.cpp:1668
msgid ""
@ -2766,7 +2767,7 @@ msgstr "Verzia ovládača grafickej karty je príliš stará. Prosím, nainštal
msgid ""
"Your OpenGL version appears to be too old. Please verify if an update for "
"your video driver is available. SuperTuxKart requires %s or better."
msgstr ""
msgstr "Verzia vášho OpenGL sa zdá byť príliš stará. Overte, prosím, či nie je k dispozícii aktualizácia ovládača vašej grafickej karty. SuperTuxKart vyžaduje verziu %s alebo vyššiu."
#: src/modes/easter_egg_hunt.cpp:202
#, c-format
@ -2804,9 +2805,9 @@ msgstr "ZLÁ CESTA!"
#, c-format
msgid "%i spare tire kart has been spawned!"
msgid_plural "%i spare tire karts have been spawned!"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[0] "Vznikla %i náhradná pneumatika pre motokáru!"
msgstr[1] "Vznikli %i náhradné pneumatiky pre motokáru!"
msgstr[2] "Vzniklo %i náhradných pneumatík pre motokáru!"
#: src/modes/world.cpp:1202
msgid "You have been eliminated!"
@ -2820,7 +2821,7 @@ msgstr "'%s' bol(a) vyradený(á)."
#: src/network/protocols/server_lobby.cpp:318
#, c-format
msgid "Failed to register server: %s"
msgstr ""
msgstr "Nepodarilo sa zaregistrovať server: %s"
#: src/network/servers_manager.cpp:198
msgid "No LAN server detected"
@ -2900,12 +2901,12 @@ msgstr "Futbal"
#: src/replay/replay_recorder.cpp:183
msgid "Incomplete replay file will not be saved."
msgstr ""
msgstr "Neúplný súbor s opakovačkou nebude uložený."
#: src/replay/replay_recorder.cpp:219
#, c-format
msgid "Replay saved in \"%s\"."
msgstr ""
msgstr "Opakovačka uložená do „%s\"."
#: src/states_screens/addons_screen.cpp:50
msgid "1 week"
@ -2951,7 +2952,7 @@ msgstr "Dátum aktualizácie"
msgid ""
"Access to the Internet is disabled. (To enable it, go to options and select "
"tab 'User Interface')"
msgstr ""
msgstr "Prístup k internetu je zakázaný. (Pokiaľ ho chcete povoliť, prejdite do ponuky Možnosti a vyberte kartu „Používateľské rozhranie“)"
#. I18N: as in: The Old Island by Johannes Sjolund
#: src/states_screens/addons_screen.cpp:343
@ -3001,9 +3002,9 @@ msgstr "Náhodná aréna"
#, c-format
msgid "%d arena unavailable in single player."
msgid_plural "%d arenas unavailable in single player."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[0] "%d aréna nie je k dispozícii v režime jedného hráča."
msgstr[1] "%d arény nie sú k dispozícii v režime jedného hráča."
msgstr[2] "%d arén nie je k dispozícii v režime jedného hráča."
#: src/states_screens/create_server_screen.cpp:82
msgid "Create LAN Server"
@ -3145,7 +3146,7 @@ msgstr "Zakázané"
#: src/states_screens/dialogs/custom_video_settings.cpp:67
#: src/states_screens/options_screen_video.cpp:462
msgid "Important only"
msgstr ""
msgstr "Iba dôležité"
#. I18N: animations setting (only karts with human players are animated)
#: src/states_screens/dialogs/custom_video_settings.cpp:74
@ -3164,7 +3165,7 @@ msgstr "Povolená pre všetky"
#: src/states_screens/dialogs/custom_video_settings.cpp:102
#: src/states_screens/options_screen_video.cpp:469
msgid "Low"
msgstr ""
msgstr "Nízka"
#. I18N: Geometry level high : everything is displayed
#. I18N: in the graphical options tooltip;
@ -3174,21 +3175,21 @@ msgstr ""
#: src/states_screens/dialogs/custom_video_settings.cpp:103
#: src/states_screens/options_screen_video.cpp:472
msgid "High"
msgstr ""
msgstr "Vysoká"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very low
#: src/states_screens/dialogs/custom_video_settings.cpp:94
#: src/states_screens/options_screen_video.cpp:466
msgid "Very Low"
msgstr ""
msgstr "Veľmi nízka"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very high
#: src/states_screens/dialogs/custom_video_settings.cpp:97
#: src/states_screens/options_screen_video.cpp:475
msgid "Very High"
msgstr ""
msgstr "Veľmi vysoká"
#: src/states_screens/dialogs/message_dialog.cpp:129
#: src/states_screens/edit_gp_screen.cpp:257
@ -3198,11 +3199,11 @@ msgstr "Nie"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:60
msgid "Tablet"
msgstr ""
msgstr "Tablet"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:61
msgid "Phone"
msgstr ""
msgstr "Telefón"
#: src/states_screens/dialogs/recovery_dialog.cpp:121
msgid "Username and/or email address invalid."
@ -3216,7 +3217,7 @@ msgid ""
"the box below, you are confirming that you understand these terms. If you "
"have any questions or comments regarding these terms, one of the members of "
"the development team would gladly assist you."
msgstr ""
msgstr "Prečítajte si, prosím, zmluvné podmienky pre SuperTuxKart na adrese '%s'. S týmito podmienkami musíte súhlasiť, aby ste si mohli zaregistrovať účet pre STK. Zaškrtnutím políčka nižšie potvrdzujete, že týmto podmienkam rozumiete. Pokiaľ máte akékoľvek otázky alebo pripomienky k týmto podmienkam, niektorý z členov vývojového tímu vám rád pomôže."
#: src/states_screens/dialogs/select_challenge.cpp:52
#, c-format
@ -3245,7 +3246,7 @@ msgstr "Zber nitra"
#: src/states_screens/dialogs/select_challenge.cpp:151
#: src/states_screens/race_setup_screen.cpp:136
msgid "Ghost replay race"
msgstr ""
msgstr "Opakovaný pretek s duchom"
#: src/states_screens/dialogs/server_info_dialog.cpp:75
msgid "Server successfully created. You can now join it."
@ -3382,11 +3383,11 @@ msgstr "Odomkli ste grand prix %0"
#: src/states_screens/ghost_replay_selection.cpp:82
msgid "Finish Time"
msgstr ""
msgstr "Konečný čas"
#: src/states_screens/ghost_replay_selection.cpp:83
msgid "User"
msgstr ""
msgstr "Používateľ"
#: src/states_screens/gp_info_screen.cpp:74
msgid "Default"
@ -3405,7 +3406,7 @@ msgstr "Náhodné"
#: src/states_screens/gp_info_screen.cpp:154
#: src/states_screens/gp_info_screen.cpp:179
msgid "Reload"
msgstr ""
msgstr "Znovu načítať"
#: src/states_screens/grand_prix_cutscene.cpp:75
#: src/states_screens/grand_prix_editor_screen.cpp:101
@ -3454,7 +3455,7 @@ msgstr "Náhodná motokára"
#: src/states_screens/kart_selection.cpp:859
msgid "Locked"
msgstr ""
msgstr "Uzamknuté"
#: src/states_screens/kart_selection.cpp:961
msgid ""
@ -3478,7 +3479,7 @@ msgstr "Bez prístupu k internetu nemožno sťahovať doplnky. Ak chcete sťahov
#: src/states_screens/main_menu_screen.cpp:566
msgid "The add-ons module is currently disabled in the Options screen"
msgstr ""
msgstr "Modul „Doplnky“ je momentálne vypnutý v ponuke Možnosti"
#: src/states_screens/main_menu_screen.cpp:578
msgid "Please wait while the add-ons are loading"
@ -3670,13 +3671,13 @@ msgstr "Klávesnica %i"
#: src/states_screens/options_screen_input.cpp:138
msgid "Touch Device"
msgstr ""
msgstr "Dotykové zariadenie"
#: 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 ""
msgstr "V režime viac hráčov si hráči môžu vybrať profil „hendikepovaný“ (náročnejší) na obrazovke výberu motokár"
#. I18N: in the language choice, to select the same language as the OS
#: src/states_screens/options_screen_ui.cpp:191
@ -3736,7 +3737,7 @@ msgstr "Antialiasing: %s"
#: src/states_screens/options_screen_video.cpp:504
#, c-format
msgid "Ambient occlusion: %s"
msgstr ""
msgstr "Zatienenie okolím: %s"
#: src/states_screens/options_screen_video.cpp:508
#, c-format
@ -3752,7 +3753,7 @@ msgstr "Tiene: %i"
#: src/states_screens/options_screen_video.cpp:513
#, c-format
msgid "Bloom: %s"
msgstr ""
msgstr "Bloom (rozptýlené svetlo): %s"
#. I18N: in graphical options
#: src/states_screens/options_screen_video.cpp:517
@ -3781,7 +3782,7 @@ msgstr "Globálne osvetlenie: %s"
#: src/states_screens/options_screen_video.cpp:534
#, c-format
msgid "Rendered image quality: %s"
msgstr ""
msgstr "Kvalita vykresľovaného obrazu: %s"
#: src/states_screens/race_gui.cpp:358 src/states_screens/race_gui.cpp:360
msgid "Challenge Failed"
@ -3838,7 +3839,7 @@ msgstr "Poradie"
#: src/states_screens/race_gui_overworld.cpp:518
msgid "Press fire to start the tutorial"
msgstr ""
msgstr "Stlačte tlačidlo streľby pre zahájenie výuky"
#: src/states_screens/race_gui_overworld.cpp:557
msgid "Type: Grand Prix"
@ -3850,7 +3851,7 @@ msgstr "Výzvu začnete stlačením tlačidla na útok"
#: src/states_screens/race_result_gui.cpp:175
msgid "Continue."
msgstr ""
msgstr "Pokračovať."
#: src/states_screens/race_result_gui.cpp:178
msgid "Quit the server."
@ -3945,7 +3946,7 @@ msgstr "Triafajte ostatných hráčov zbraňami, kým neprídu o všetky životy
#: src/states_screens/race_setup_screen.cpp:119
msgid "Push the ball into the opposite cage to score goals."
msgstr ""
msgstr "Dotlačte loptu do bránky protihráča."
#: src/states_screens/race_setup_screen.cpp:129
msgid "Explore tracks to find all hidden eggs"
@ -3953,7 +3954,7 @@ msgstr "Nájdite všetky vajíčka poskrývané na tratiach"
#: src/states_screens/race_setup_screen.cpp:137
msgid "Race against ghost karts and try to beat them!"
msgstr ""
msgstr "Pretekajte proti motokáram duchov a skúste ich poraziť!"
#: src/states_screens/register_screen.cpp:218
#: src/states_screens/register_screen.cpp:225
@ -4036,7 +4037,7 @@ msgstr "Jazda naopak"
#. I18N: In the track info screen
#: src/states_screens/track_info_screen.cpp:218
msgid "Random item location"
msgstr ""
msgstr "Náhodné rozmiestnenie položky"
#: src/states_screens/user_screen.cpp:111
msgid "Exit game"

View File

@ -4,13 +4,14 @@
#
# Translators:
# Andrej Znidarsic <andrej.znidarsic@gmail.com>, 2015-2016
# Sasa Batistic <sasa.batistic@gmail.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-02-28 13:25+0000\n"
"Last-Translator: Sasa Batistic <sasa.batistic@gmail.com>\n"
"Language-Team: Slovenian (http://www.transifex.com/supertuxkart/supertuxkart/language/sl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -619,11 +620,11 @@ msgstr "Več igralski način."
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Bananas"
msgstr ""
msgstr "Banane"
#. I18N: ./data/gui/help1.stkgui
msgid "Start the tutorial"
msgstr ""
msgstr "Začni z vodnikom"
#. I18N: ./data/gui/help1.stkgui
#. I18N: In the help menu
@ -800,12 +801,12 @@ msgstr ""
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
msgid "Anchor - slows down the kart."
msgstr ""
msgstr "Sidro - upočasni vozilo."
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu
msgid "Parachute - slows down the kart less than the anchor."
msgstr ""
msgstr "Padalo - manj upočasni dirkalnik kot sidro."
#. I18N: ./data/gui/help5.stkgui
#. I18N: In the help menu

View File

@ -12,7 +12,7 @@ msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"PO-Revision-Date: 2017-12-06 00:21+0000\n"
"Last-Translator: yakup <mutouk@yandex.ru>\n"
"Language-Team: Turkish (http://www.transifex.com/supertuxkart/supertuxkart/language/tr/)\n"
"MIME-Version: 1.0\n"
@ -1923,11 +1923,11 @@ msgstr ""
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
msgstr ""
msgstr "Kiki"
#. I18N: ../stk-assets/karts/konqi/kart.xml
msgid "Konqi"
msgstr ""
msgstr "Konqi"
#. I18N: ../stk-assets/karts/nolok/kart.xml
msgid "Nolok"
@ -1935,11 +1935,11 @@ msgstr "Nolok"
#. I18N: ../stk-assets/karts/pidgin/kart.xml
msgid "Pidgin"
msgstr ""
msgstr "Pidgin"
#. I18N: ../stk-assets/karts/puffy/kart.xml
msgid "Puffy"
msgstr ""
msgstr "Puffy"
#. I18N: ../stk-assets/karts/sara_the_racer/kart.xml
msgid "Sara the Racer"
@ -1959,7 +1959,7 @@ msgstr "Tux"
#. I18N: ../stk-assets/karts/wilber/kart.xml
msgid "Wilber"
msgstr ""
msgstr "Wilber"
#. I18N: ../stk-assets/karts/xue/kart.xml
msgid "Xue"

View File

@ -5,13 +5,14 @@
# Translators:
# fedik <fedikw@gmail.com>, 2015-2017
# Max Lyashuk <m_lyashuk@ukr.net>, 2015-2016
# Yaroslav Serhieiev <noomorph@gmail.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2018-03-25 14:40+0000\n"
"Last-Translator: Yaroslav Serhieiev <noomorph@gmail.com>\n"
"Language-Team: Ukrainian (http://www.transifex.com/supertuxkart/supertuxkart/language/uk/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -912,7 +913,7 @@ msgstr "Пристрій увімкнено"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Inverted buttons"
msgstr ""
msgstr "Інвертовані кнопки"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
@ -1825,7 +1826,7 @@ msgstr "Але ви, жалюгідні волоцюги, ніколи не зм
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
msgstr ""
msgstr "Арена Лас Дунас"
#. I18N: ../stk-assets/tracks/lighthouse/track.xml
msgid "Around the lighthouse"

View File

@ -7,13 +7,14 @@
# Benau, 2016
# Benau, 2015-2016
# Jin Zhang <zhangxjin@gmail.com>, 2015
# Jz Pan <acme.pjz@gmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: SuperTuxKart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-04 20:58-0400\n"
"PO-Revision-Date: 2017-11-13 00:19+0000\n"
"Last-Translator: Auria <auria.mg@gmail.com>\n"
"PO-Revision-Date: 2017-11-14 04:13+0000\n"
"Last-Translator: Jz Pan <acme.pjz@gmail.com>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/supertuxkart/supertuxkart/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -356,12 +357,12 @@ msgstr "角色动画"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Rendered image quality"
msgstr ""
msgstr "渲染图像质量"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
msgid "Geometry detail"
msgstr ""
msgstr "几何细节"
#. I18N: ./data/gui/custom_video_settings.stkgui
#. I18N: Video settings
@ -622,11 +623,11 @@ msgstr "多人游戏"
#. I18N: ./data/gui/help5.stkgui
#. I18N: Tab in help menu
msgid "Bananas"
msgstr ""
msgstr "香蕉"
#. I18N: ./data/gui/help1.stkgui
msgid "Start the tutorial"
msgstr ""
msgstr "开始教学关"
#. I18N: ./data/gui/help1.stkgui
#. I18N: In the help menu
@ -904,46 +905,46 @@ msgstr "退出"
#. I18N: ./data/gui/multitouch_settings.stkgui
msgid "Touch Device Settings"
msgstr ""
msgstr "触屏设备设置"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Device enabled"
msgstr ""
msgstr "设备启用"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Inverted buttons"
msgstr ""
msgstr "反转按键"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Buttons scale"
msgstr ""
msgstr "按键大小"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Accelerometer"
msgstr ""
msgstr "加速计"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Advanced"
msgstr ""
msgstr "高级"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Deadzone"
msgstr ""
msgstr "死区"
#. I18N: ./data/gui/multitouch_settings.stkgui
#. I18N: In the multitouch settings screen
msgid "Sensitivity"
msgstr ""
msgstr "灵敏度"
#. I18N: ./data/gui/multitouch_settings.stkgui
msgid "Restore defaults"
msgstr ""
msgstr "恢复默认"
#. I18N: ./data/gui/online/change_password.stkgui
#. I18N: In the change password dialog
@ -1764,7 +1765,7 @@ msgstr "战斗之岛"
#. I18N: ../stk-assets/tracks/candela_city/track.xml
msgid "Candela City"
msgstr ""
msgstr "坎德拉城"
#. I18N: ../stk-assets/tracks/cave/track.xml
msgid "Cave X"
@ -1776,7 +1777,7 @@ msgstr "可可寺院"
#. I18N: ../stk-assets/tracks/cornfield_crossing/track.xml
msgid "Cornfield Crossing"
msgstr ""
msgstr "玉米地穿越"
#. I18N: ../stk-assets/tracks/fortmagma/track.xml
msgid "Fort Magma"
@ -1827,7 +1828,7 @@ msgstr " 不过你们这些可怜的小蠢货是永远不可能打败我这个
#. I18N: ../stk-assets/tracks/lasdunasarena/track.xml
msgid "Las Dunas Arena"
msgstr ""
msgstr "Las Dunas 竞技场"
#. I18N: ../stk-assets/tracks/lighthouse/track.xml
msgid "Around the lighthouse"
@ -1923,7 +1924,7 @@ msgstr "Hexley"
#. I18N: ../stk-assets/karts/kiki/kart.xml
msgid "Kiki"
msgstr ""
msgstr "Kiki"
#. I18N: ../stk-assets/karts/konqi/kart.xml
msgid "Konqi"
@ -1972,7 +1973,7 @@ msgstr "完成成就 “%s”。"
#: src/addons/addons_manager.cpp:104 src/addons/news_manager.cpp:322
msgid "Failed to connect to the SuperTuxKart add-ons server."
msgstr ""
msgstr "无法连接到 SuperTuxKart 附加组件服务器。"
#: src/addons/news_manager.cpp:179
#, c-format
@ -2044,16 +2045,16 @@ msgstr "你的配置文件太旧了,新的配置文件已经创建。"
#: src/graphics/irr_driver.cpp:535
msgid "Video recording started."
msgstr ""
msgstr "视频录制开始。"
#: src/graphics/irr_driver.cpp:541
#, c-format
msgid "Video saved in \"%s\"."
msgstr ""
msgstr "视频已保存到 \"%s\"。"
#: src/graphics/irr_driver.cpp:545
msgid "Encoding progress:"
msgstr ""
msgstr "编码进度:"
#: src/graphics/irr_driver.cpp:1682
#, c-format
@ -2725,11 +2726,11 @@ msgstr "请不要在“开始”显示之前加速"
#: src/karts/controller/spare_tire_ai.cpp:147
msgid "You can have at most 3 lives!"
msgstr ""
msgstr "你最多可以有 3 条命!"
#: src/karts/controller/spare_tire_ai.cpp:153
msgid "+1 life."
msgstr ""
msgstr "+1 命"
#: src/karts/kart.cpp:908 src/karts/kart.cpp:913
msgid "You won the race!"
@ -2752,7 +2753,7 @@ msgstr "SuperTuxKart 可能會连接到服务器下载插件并通知你更新
#: src/main.cpp:1654
msgid "Your screen resolution is too low to run STK."
msgstr ""
msgstr "你的屏幕分辨率太低, 无法运行 STK。"
#: src/main.cpp:1668
msgid ""
@ -3133,7 +3134,7 @@ msgstr "已禁用"
#: src/states_screens/dialogs/custom_video_settings.cpp:67
#: src/states_screens/options_screen_video.cpp:462
msgid "Important only"
msgstr ""
msgstr "只有重要的"
#. I18N: animations setting (only karts with human players are animated)
#: src/states_screens/dialogs/custom_video_settings.cpp:74
@ -3152,7 +3153,7 @@ msgstr "启用所有"
#: src/states_screens/dialogs/custom_video_settings.cpp:102
#: src/states_screens/options_screen_video.cpp:469
msgid "Low"
msgstr ""
msgstr ""
#. I18N: Geometry level high : everything is displayed
#. I18N: in the graphical options tooltip;
@ -3162,21 +3163,21 @@ msgstr ""
#: src/states_screens/dialogs/custom_video_settings.cpp:103
#: src/states_screens/options_screen_video.cpp:472
msgid "High"
msgstr ""
msgstr ""
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very low
#: src/states_screens/dialogs/custom_video_settings.cpp:94
#: src/states_screens/options_screen_video.cpp:466
msgid "Very Low"
msgstr ""
msgstr "非常低"
#. I18N: in the graphical options tooltip;
#. indicates the rendered image quality is very high
#: src/states_screens/dialogs/custom_video_settings.cpp:97
#: src/states_screens/options_screen_video.cpp:475
msgid "Very High"
msgstr ""
msgstr "非常高"
#: src/states_screens/dialogs/message_dialog.cpp:129
#: src/states_screens/edit_gp_screen.cpp:257
@ -3186,11 +3187,11 @@ msgstr "否"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:60
msgid "Tablet"
msgstr ""
msgstr "平板电脑"
#: src/states_screens/dialogs/multitouch_settings_dialog.cpp:61
msgid "Phone"
msgstr ""
msgstr "手机"
#: src/states_screens/dialogs/recovery_dialog.cpp:121
msgid "Username and/or email address invalid."
@ -3374,7 +3375,7 @@ msgstr "完成时间"
#: src/states_screens/ghost_replay_selection.cpp:83
msgid "User"
msgstr ""
msgstr "用户"
#: src/states_screens/gp_info_screen.cpp:74
msgid "Default"
@ -3658,7 +3659,7 @@ msgstr "键盘 %i"
#: src/states_screens/options_screen_input.cpp:138
msgid "Touch Device"
msgstr ""
msgstr "触屏设备"
#: src/states_screens/options_screen_ui.cpp:159
msgid ""
@ -3769,7 +3770,7 @@ msgstr "全域照明:%s"
#: src/states_screens/options_screen_video.cpp:534
#, c-format
msgid "Rendered image quality: %s"
msgstr ""
msgstr "渲染图像质量: %s"
#: src/states_screens/race_gui.cpp:358 src/states_screens/race_gui.cpp:360
msgid "Challenge Failed"
@ -3826,7 +3827,7 @@ msgstr "排名"
#: src/states_screens/race_gui_overworld.cpp:518
msgid "Press fire to start the tutorial"
msgstr ""
msgstr "按使用道具键开始教学关"
#: src/states_screens/race_gui_overworld.cpp:557
msgid "Type: Grand Prix"

View File

@ -11,13 +11,7 @@ layout(location = 1) in vec4 i_normal;
layout(location = 2) in vec4 i_color;
layout(location = 3) in vec2 i_uv;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 12) in ivec2 i_misc_data;
@ -32,16 +26,14 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec3 test = sin(wind_direction * (i_position.y * 0.1));
test += cos(wind_direction) * 0.7;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin + test * i_color.r,
quaternion, i_scale.xyz, i_position);
vec3 world_normal = rotateVector(quaternion, i_normal.xyz);
i_rotation, i_scale.xyz, i_position);
vec3 world_normal = rotateVector(i_rotation, i_normal.xyz);
normal = (u_view_matrix * vec4(world_normal, 0.0)).xyz;
uv = i_uv;

View File

@ -5,13 +5,7 @@ layout(location = 0) in vec3 i_position;
layout(location = 2) in vec4 i_color;
layout(location = 3) in vec2 i_uv;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
#stk_include "utils/get_world_location.vert"
@ -20,17 +14,10 @@ out vec2 uv;
void main()
{
#if defined(Converts_10bit_Vector)
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec3 test = sin(wind_direction * (i_position.y * 0.1));
test += cos(wind_direction) * 0.7;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin + test * i_color.r,
quaternion, i_scale.xyz, i_position);
i_rotation, i_scale.xyz, i_position);
uv = i_uv;
gl_Position = u_shadow_projection_view_matrices[layer] * world_position;

View File

@ -17,13 +17,7 @@ layout(location = 5) in vec4 i_tangent;
layout(location = 6) in ivec4 i_joint;
layout(location = 7) in vec4 i_weight;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 12) in ivec2 i_misc_data;
@ -39,7 +33,6 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_tangent = convert10BitVector(i_tangent_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 idle_position = vec4(i_position, 1.0);
@ -104,12 +97,11 @@ void main()
skinned_position = mix(skinned_position, idle_position, step_mix);
skinned_normal = mix(skinned_normal, idle_normal, step_mix);
skinned_tangent = mix(skinned_tangent, idle_tangent, step_mix);
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
gl_Position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
gl_Position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
skinned_position.xyz);
o_normal = normalize(rotateVector(quaternion, skinned_normal.xyz));
o_tangent = normalize(rotateVector(quaternion, skinned_tangent.xyz));
o_normal = normalize(rotateVector(i_rotation, skinned_normal.xyz));
o_tangent = normalize(rotateVector(i_rotation, skinned_tangent.xyz));
o_bitangent = cross(o_normal, o_tangent) * i_tangent.w;
}

View File

@ -17,13 +17,7 @@ layout(location = 5) in vec4 i_tangent;
#endif
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 11) in vec2 i_texture_trans;
layout(location = 12) in ivec2 i_misc_data;
@ -37,6 +31,7 @@ out vec2 uv;
out vec2 uv_two;
out vec4 color;
out vec4 world_position;
out vec3 world_normal;
out float camdist;
out float hue_change;
@ -46,21 +41,19 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_tangent = convert10BitVector(i_tangent_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 v_world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 v_world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
i_position);
vec3 world_normal = rotateVector(quaternion, i_normal.xyz);
vec3 world_tangent = rotateVector(quaternion, i_tangent.xyz);
vec3 v_world_normal = rotateVector(i_rotation, i_normal.xyz);
vec3 world_tangent = rotateVector(i_rotation, i_tangent.xyz);
tangent = (u_view_matrix * vec4(world_tangent, 0.0)).xyz;
bitangent = (u_view_matrix *
// bitangent sign
vec4(cross(world_normal, world_tangent) * i_tangent.w, 0.0)
vec4(cross(v_world_normal, world_tangent) * i_tangent.w, 0.0)
).xyz;
normal = (u_view_matrix * vec4(world_normal, 0.0)).xyz;
normal = (u_view_matrix * vec4(v_world_normal, 0.0)).xyz;
uv = vec2(i_uv.x + (i_texture_trans.x * i_normal.w),
i_uv.y + (i_texture_trans.y * i_normal.w));
@ -71,4 +64,5 @@ void main()
hue_change = float(i_misc_data.y) * 0.01;
gl_Position = u_projection_view_matrix * v_world_position;
world_position = v_world_position;
world_normal = v_world_normal;
}

View File

@ -0,0 +1,90 @@
in vec3 bitangent;
in vec4 color;
in float hue_change;
in vec3 normal;
in vec3 tangent;
in vec2 uv;
in vec4 world_position;
in float camdist;
layout(location = 0) out vec4 o_diffuse_color;
layout(location = 1) out vec4 o_normal_color;
#stk_include "utils/encode_normal.frag"
#stk_include "utils/rgb_conversion.frag"
#stk_include "utils/sp_texture_sampling.frag"
void main()
{
vec2 uuv = vec2(world_position.x, world_position.z);
uuv *= 0.2;
vec4 col = multi_sampleTextureLayer0(uv, camdist);
float mask = sampleTextureLayer4(uuv * 2.0).r;
//* (1.0 - color.g)
mask = mix(1.0, mask, color.r);
mask = mix(0.0, mask, 1.0 - color.g);
if(mask < 0.5)
{
discard;
}
// Adding some skidding marks to the road
float mask_2 = sampleTextureLayer4(uuv * 0.1).r;
float mask_3 = sampleTextureLayer4(uuv * 3.5).r;
mask_2 = pow(mask_2, 1.5);
mask_2 *= pow(mask_3, 0.5);
float skidding_marks = sampleTextureLayer5(uv * 10).g;
skidding_marks *= mask_2;
col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), skidding_marks);
float skidding_marks_2 = sampleTextureLayer5(uv * 15).g;
skidding_marks_2 *= mask_2;
col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), skidding_marks_2);
// Add some cracks
float cracks_marks = sampleTextureLayer5(uv * 11).b;
float crack_mask = sampleTextureLayer4(uuv * 0.5).r;
cracks_marks *= crack_mask;
col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), cracks_marks);
if (hue_change > 0.0)
{
float mask = col.a;
vec3 old_hsv = rgbToHsv(col.rgb);
float mask_step = step(mask, 0.5);
#if !defined(Advanced_Lighting_Enabled)
// For similar color
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
#else
float saturation = mask * 2.5;
#endif
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(hue_change,
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, 1.0);
}
vec3 final_color = col.xyz; // * color.xyz;
#if defined(Advanced_Lighting_Enabled)
vec4 layer_2 = multi_sampleTextureLayer2(uv, camdist);
vec4 layer_3 = multi_sampleTextureLayer3(uv, camdist);
o_diffuse_color = vec4(final_color, layer_2.z);
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
vec3 frag_tangent = normalize(tangent);
vec3 frag_bitangent = normalize(bitangent);
vec3 frag_normal = normalize(normal);
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
vec3 world_normal = t_b_n * tangent_space_normal;
o_normal_color.xy = 0.5 * EncodeNormal(normalize(world_normal)) + 0.5;
o_normal_color.zw = layer_2.xy;
#else
o_diffuse_color = vec4(final_color, 1.0);
#endif
}

View File

@ -3,13 +3,7 @@ uniform int layer;
layout(location = 0) in vec3 i_position;
layout(location = 3) in vec2 i_uv;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
#stk_include "utils/get_world_location.vert"
@ -18,13 +12,7 @@ out vec2 uv;
void main()
{
#if defined(Converts_10bit_Vector)
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
i_position);
uv = i_uv;
gl_Position = u_shadow_projection_view_matrices[layer] * world_position;

View File

@ -24,13 +24,7 @@ layout(location = 5) in vec4 i_tangent;
layout(location = 6) in ivec4 i_joint;
layout(location = 7) in vec4 i_weight;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 11) in vec2 i_texture_trans;
layout(location = 12) in ivec2 i_misc_data;
@ -52,7 +46,6 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_tangent = convert10BitVector(i_tangent_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 idle_position = vec4(i_position, 1.0);
@ -113,11 +106,10 @@ void main()
skinned_normal = joint_matrix * idle_normal;
skinned_tangent = joint_matrix * idle_tangent;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
skinned_position.xyz);
vec3 world_normal = rotateVector(quaternion, skinned_normal.xyz);
vec3 world_tangent = rotateVector(quaternion, skinned_tangent.xyz);
vec3 world_normal = rotateVector(i_rotation, skinned_normal.xyz);
vec3 world_tangent = rotateVector(i_rotation, skinned_tangent.xyz);
tangent = (u_view_matrix * vec4(world_tangent, 0.0)).xyz;
bitangent = (u_view_matrix *

View File

@ -11,13 +11,7 @@ layout(location = 3) in vec2 i_uv;
layout(location = 6) in ivec4 i_joint;
layout(location = 7) in vec4 i_weight;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 12) in ivec2 i_misc_data;
@ -27,11 +21,6 @@ out vec2 uv;
void main()
{
#if defined(Converts_10bit_Vector)
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 idle_position = vec4(i_position, 1.0);
vec4 skinned_position = vec4(0.0);
int skinning_offset = i_misc_data.x;
@ -83,9 +72,7 @@ void main()
#endif
skinned_position = joint_matrix * idle_position;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
skinned_position.xyz);
uv = i_uv;
gl_Position = u_shadow_projection_view_matrices[layer] * world_position;

View File

@ -0,0 +1,57 @@
in vec3 bitangent;
in vec4 color;
in float hue_change;
in vec3 normal;
in vec3 tangent;
in vec2 uv;
in float camdist;
layout(location = 0) out vec4 o_diffuse_color;
layout(location = 1) out vec4 o_normal_color;
#stk_include "utils/encode_normal.frag"
#stk_include "utils/rgb_conversion.frag"
#stk_include "utils/sp_texture_sampling.frag"
void main()
{
vec4 col = multi_sampleTextureLayer0(uv, camdist);
if (hue_change > 0.0)
{
float mask = col.a;
vec3 old_hsv = rgbToHsv(col.rgb);
float mask_step = step(mask, 0.5);
#if !defined(Advanced_Lighting_Enabled)
// For similar color
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
#else
float saturation = mask * 2.5;
#endif
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(hue_change,
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, 1.0);
}
vec3 final_color = col.xyz * color.xyz;
#if defined(Advanced_Lighting_Enabled)
vec4 layer_2 = multi_sampleTextureLayer2(uv, camdist);
vec4 layer_3 = multi_sampleTextureLayer3(uv, camdist);
o_diffuse_color = vec4(final_color, layer_2.z);
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
vec3 frag_tangent = normalize(tangent);
vec3 frag_bitangent = normalize(bitangent);
vec3 frag_normal = normalize(normal);
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
vec3 world_normal = t_b_n * tangent_space_normal;
o_normal_color.xy = 0.5 * EncodeNormal(normalize(world_normal)) + 0.5;
o_normal_color.zw = layer_2.xy;
#else
o_diffuse_color = vec4(final_color, 1.0);
#endif
}

View File

@ -0,0 +1,63 @@
in vec3 bitangent;
in vec4 color;
in float hue_change;
in vec3 normal;
in vec3 world_normal;
in vec3 tangent;
in vec2 uv;
layout(location = 0) out vec4 o_diffuse_color;
layout(location = 1) out vec4 o_normal_color;
#stk_include "utils/encode_normal.frag"
#stk_include "utils/rgb_conversion.frag"
#stk_include "utils/sp_texture_sampling.frag"
void main()
{
vec4 col = sampleTextureLayer4(uv * 2.0);
//col = vec4(1.0, 0.0, 0.0, 1.0);
vec4 col_2 = sampleTextureLayer5(uv * 2.0);//vec4(0.0, 1.0, 0.0, 1.0);
float factor = dot(vec3(0.,1.,1.), world_normal);
factor = clamp(factor, 0.0, 1.0);
col = mix(col_2, col, factor);
if (hue_change > 0.0)
{
float mask = col.a;
vec3 old_hsv = rgbToHsv(col.rgb);
float mask_step = step(mask, 0.5);
#if !defined(Advanced_Lighting_Enabled)
// For similar color
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
#else
float saturation = mask * 2.5;
#endif
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(hue_change,
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, 1.0);
}
vec3 final_color = col.xyz * color.xyz;
#if defined(Advanced_Lighting_Enabled)
vec4 layer_2 = sampleTextureLayer2(uv);
vec4 layer_3 = sampleTextureLayer3(uv);
o_diffuse_color = vec4(final_color, layer_2.z);
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
vec3 frag_tangent = normalize(tangent);
vec3 frag_bitangent = normalize(bitangent);
vec3 frag_normal = normalize(normal);
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
vec3 world_normal = t_b_n * tangent_space_normal;
o_normal_color.xy = 0.5 * EncodeNormal(normalize(world_normal)) + 0.5;
o_normal_color.zw = layer_2.xy;
#else
o_diffuse_color = vec4(final_color, 1.0);
#endif
}

View File

@ -0,0 +1,13 @@
<spshader>
<shader-info name="tillingMitigation" fallback-shader="solid" use-tangents="Y"/>
<first-pass vertex-shader="sp_pass.vert"
fragment-shader="sp_tilling_mitigation.frag">
</first-pass>
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="white.frag">
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"
function="shadowCascadeUniformAssigner"/>
</uniform-assigners>
</spshader>

View File

@ -0,0 +1,13 @@
<spshader>
<shader-info name="verticalMapping" fallback-shader="solid" use-tangents="Y"/>
<first-pass vertex-shader="sp_pass.vert"
fragment-shader="sp_vertical_mapping.frag">
</first-pass>
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="white.frag">
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"
function="shadowCascadeUniformAssigner"/>
</uniform-assigners>
</spshader>

View File

@ -0,0 +1,17 @@
<spshader>
<shader-info name="roadBlending" fallback-shader="solid" use-tangents="Y"/>
<first-pass vertex-shader="sp_pass.vert"
fragment-shader="sp_road_blending.frag"
skinned-mesh-shader="sp_skinning.vert">
</first-pass>
<!--
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="white.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"
function="shadowCascadeUniformAssigner"/>
</uniform-assigners>
-->
</spshader>

View File

@ -6,11 +6,43 @@ uniform sampler2D tex_layer_3;
uniform sampler2D tex_layer_4;
uniform sampler2D tex_layer_5;
#define HIGH_SAMPLING 4.0
#define MEDIUM_SAMPLING 2.0
#define LOW_SAMPLING 1.0
vec4 sampleTextureLayer0(vec2 uv)
{
return texture(tex_layer_0, uv);
}
vec4 multi_sampleTextureLayer0(vec2 uv, float distance)
{
vec4 l_col = sampleTextureLayer0(uv * LOW_SAMPLING);
vec4 m_col = sampleTextureLayer0(uv * MEDIUM_SAMPLING);
vec4 h_col = sampleTextureLayer0(uv * HIGH_SAMPLING);
/* debug
l_col = vec4(1.0, 0.0, 0.0, 1.0);
m_col = vec4(0.0, 1.0, 0.0, 1.0);
h_col = vec4(0.0, 0.0, 1.0, 1.0);*/
// From Low to medium
float factor = distance * 0.02;
factor = pow(factor, 2.5);
factor = clamp(factor, 0.0, 1.0);
vec4 f_col = mix(m_col, l_col, factor);
// From medium to high
factor = distance * 0.1;
factor = pow(factor, 2.5);
factor = clamp(factor, 0.0, 1.0);
f_col = mix(h_col, f_col, factor);
return f_col;
}
vec4 sampleTextureLayer1(vec2 uv)
{
return texture(tex_layer_1, uv);
@ -21,11 +53,57 @@ vec4 sampleTextureLayer2(vec2 uv)
return texture(tex_layer_2, uv);
}
vec4 multi_sampleTextureLayer2(vec2 uv, float distance)
{
vec4 l_col = sampleTextureLayer2(uv * LOW_SAMPLING);
vec4 m_col = sampleTextureLayer2(uv * MEDIUM_SAMPLING);
vec4 h_col = sampleTextureLayer2(uv * HIGH_SAMPLING);
// From Low to medium
float factor = distance * 0.02;
factor = pow(factor, 2.5);
factor = clamp(factor, 0.0, 1.0);
vec4 f_col = mix(m_col, l_col, factor);
// From medium to high
factor = distance * 0.1;
factor = pow(factor, 2.5);
factor = clamp(factor, 0.0, 1.0);
f_col = mix(h_col, f_col, factor);
return f_col;
}
vec4 sampleTextureLayer3(vec2 uv)
{
return texture(tex_layer_3, uv);
}
vec4 multi_sampleTextureLayer3(vec2 uv, float distance)
{
vec4 l_col = sampleTextureLayer3(uv * LOW_SAMPLING);
vec4 m_col = sampleTextureLayer3(uv * MEDIUM_SAMPLING);
vec4 h_col = sampleTextureLayer3(uv * HIGH_SAMPLING);
// From Low to medium
float factor = distance * 0.02;
factor = pow(factor, 2.5);
factor = clamp(factor, 0.0, 1.0);
vec4 f_col = mix(m_col, l_col, factor);
// From medium to high
factor = distance * 0.1;
factor = pow(factor, 2.5);
factor = clamp(factor, 0.0, 1.0);
f_col = mix(h_col, f_col, factor);
return f_col;
}
vec4 sampleTextureLayer4(vec2 uv)
{
return texture(tex_layer_4, uv);

View File

@ -38,29 +38,29 @@
<points points="2" /> <!-- added with 5 karts -->
<points points="1" /> <!-- added with 6 karts -->
<points points="3" /> <!-- added with 7 karts -->
<points points="2" /> <!-- added with 8 karts -->
<points points="1" /> <!-- added with 8 karts -->
<points points="3" /> <!-- added with 9 karts -->
<points points="1" /> <!-- added with 10 karts -->
<points points="4" /> <!-- added with 11 karts -->
<points points="4" /> <!-- added with 10 karts -->
<points points="1" /> <!-- added with 11 karts -->
<points points="2" /> <!-- added with 12 karts -->
<points points="1" /> <!-- added with 13 karts -->
<points points="3" /> <!-- added with 14 karts -->
<points points="2" /> <!-- added with 15 karts -->
<points points="1" /> <!-- added with 16 karts -->
<points points="5" /> <!-- added with 13 karts -->
<points points="1" /> <!-- added with 14 karts -->
<points points="3" /> <!-- added with 15 karts -->
<points points="6" /> <!-- added with 16 karts -->
<points points="4" /> <!-- added with 17 karts -->
<points points="2" /> <!-- added with 18 karts -->
<points points="3" /> <!-- added with 19 karts -->
<points points="7" /> <!-- added with 19 karts -->
<points points="1" /> <!-- added with 20 karts -->
<points points="5" /> <!-- added with 21 karts -->
<points points="2" /> <!-- added with 22 karts -->
<points points="1" /> <!-- added with 23 karts -->
<points points="3" /> <!-- added with 24 karts -->
<points points="4" /> <!-- added with 25 karts -->
<points points="1" /> <!-- added with 26 karts -->
<points points="2" /> <!-- added with 27 karts -->
<points points="1" /> <!-- added with 28 karts -->
<points points="3" /> <!-- added with 29 karts -->
<points points="5" /> <!-- added with 30 karts -->
<points points="8" /> <!-- added with 21 karts -->
<points points="1" /> <!-- added with 22 karts -->
<points points="2" /> <!-- added with 23 karts -->
<points points="1" /> <!-- added with 24 karts -->
<points points="9" /> <!-- added with 25 karts -->
<points points="4" /> <!-- added with 26 karts -->
<points points="1" /> <!-- added with 27 karts -->
<points points="10" /><!-- added with 28 karts -->
<points points="2" /> <!-- added with 29 karts -->
<points points="12" /><!-- added with 30 karts -->
</grand-prix>
<!-- Time in follow-the-leader after which karts are removed.
@ -232,10 +232,12 @@
min/max-start-delay: Minimum and maximum start delay.
See http://www.humanbenchmark.com/tests/reactiontime/stats.php
Average reaction time is around 0.215 s.
nitro-usage: "none", "some", "all": if nitro should be used, and
how much the AI should try to use it good.
non-random-item-usage: If true, use items in a sophisticated way,
otherwise use items randomly.
nitro-usage: Integer determining how well the AI uses nitro, from 0 to 4
0 corresponds to no use ; while 1 to 4 corresponds to various degrees
of quality use (using it immediately for 1 to more context-aware strategies)
item-skill: Integer determining how well the AI use items, from 0 to 5
0 corresponds to no use ; 1 to use after a random time ; while 2 to 5 use
more advanced tactics
collect-avoid-items: if the AI should collect and avoid items,
or just ignore them.
handle-bomb: If the AI should actively try to pass on a bomb.
@ -294,8 +296,8 @@
shield-incoming-radius="0"
false-start-probability="0.08"
min-start-delay="0.3" max-start-delay="0.5"
nitro-usage="none"
non-random-item-usage="false"
nitro-usage="0"
item-skill="1"
collect-avoid-items="false"
handle-bomb="false"
speed-cap="-10:1.0 -5:0.9 5:0.8 20:0.7 50:0.6"
@ -312,8 +314,8 @@
shield-incoming-radius="10"
false-start-probability="0.04"
min-start-delay="0.25" max-start-delay="0.4"
nitro-usage="some"
non-random-item-usage="true"
nitro-usage="1"
item-skill="2"
collect-avoid-items="true"
handle-bomb="false"
speed-cap="10:1.0 50:0.8"
@ -327,11 +329,11 @@
straight-length-for-zipper="35"
use-slipstream="true"
disable-slipstream-usage="false"
shield-incoming-radius="10"
shield-incoming-radius="8"
false-start-probability="0.01"
min-start-delay="0.15" max-start-delay="0.28"
nitro-usage="all"
non-random-item-usage="true"
nitro-usage="2"
item-skill="3"
collect-avoid-items="true"
handle-bomb="true"
speed-cap="20:1.0 50:0.8"
@ -345,11 +347,11 @@
straight-length-for-zipper="35"
use-slipstream="true"
disable-slipstream-usage="false"
shield-incoming-radius="10"
shield-incoming-radius="6"
false-start-probability="0.0"
min-start-delay="0.15" max-start-delay="0.2"
nitro-usage="all"
non-random-item-usage="true"
nitro-usage="3"
item-skill="4"
collect-avoid-items="true"
handle-bomb="true"
speed-cap="0:1.0"

View File

@ -180,7 +180,7 @@ void STKConfig::init_defaults()
m_penalty_ticks = -100;
m_physics_fps = -100;
m_bubblegum_counter = -100;
m_shield_restrict_weapos = false;
m_shield_restrict_weapons = false;
m_max_karts = -100;
m_max_skidmarks = -100;
m_min_kart_version = -100;
@ -366,8 +366,8 @@ void STKConfig::getAllData(const XMLNode * root)
if(const XMLNode *bubblegum_node= root->getNode("bubblegum"))
{
bubblegum_node->get("disappear-counter", &m_bubblegum_counter );
bubblegum_node->get("restrict-weapons", &m_shield_restrict_weapos);
bubblegum_node->get("disappear-counter", &m_bubblegum_counter );
bubblegum_node->get("restrict-weapons", &m_shield_restrict_weapons);
}
if(const XMLNode *explosion_node= root->getNode("explosion"))

View File

@ -73,7 +73,7 @@ public:
int m_item_switch_ticks; /**< Time items will be switched. */
int m_bubblegum_counter; /**< How many times bubble gums must be
driven over before they disappear. */
bool m_shield_restrict_weapos; /**<Wether weapon usage is punished. */
bool m_shield_restrict_weapons; /**<Wether weapon usage is punished. */
float m_explosion_impulse_objects; /**<Impulse of explosion on moving
objects, e.g. road cones, ... */
int m_penalty_ticks; /**< Penalty time when starting too

View File

@ -471,6 +471,11 @@ namespace UserConfigParams
&m_multitouch_group,
"Enable screen keyboard.") );
PARAM_PREFIX BoolUserConfigParam m_hidpi_enabled
PARAM_DEFAULT( BoolUserConfigParam(false, "hidpi_enabled",
&m_multitouch_group,
"Enable high-DPI support.") );
// ---- GP start order
PARAM_PREFIX GroupUserConfigParam m_gp_start_order
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",

View File

@ -18,6 +18,7 @@
#include "font/font_with_face.hpp"
#include "config/user_config.hpp"
#include "font/face_ttf.hpp"
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
@ -332,23 +333,24 @@ void FontWithFace::setDPI()
const int screen_width = irr_driver->getFrameSize().Width;
const int screen_height = irr_driver->getFrameSize().Height;
#ifdef ANDROID
float scale = screen_height / 480.0f;
m_face_dpi = getScalingFactorTwo() * getScalingFactorOne() * scale;
if (UserConfigParams::m_hidpi_enabled)
{
float scale = screen_height / 480.0f;
m_face_dpi = getScalingFactorTwo() * getScalingFactorOne() * scale;
}
else
{
float scale = std::max(0, screen_width - 640) / 564.0f;
#else
float scale = std::max(0, screen_width - 640) / 564.0f;
// attempt to compensate for small screens
if (screen_width < 1200)
scale = std::max(0, screen_width - 640) / 750.0f;
if (screen_width < 900 || screen_height < 700)
scale = std::min(scale, 0.05f);
m_face_dpi = unsigned((getScalingFactorOne() + 0.2f * scale) *
getScalingFactorTwo());
#endif
// attempt to compensate for small screens
if (screen_width < 1200)
scale = std::max(0, screen_width - 640) / 750.0f;
if (screen_width < 900 || screen_height < 700)
scale = std::min(scale, 0.05f);
m_face_dpi = unsigned((getScalingFactorOne() + 0.2f * scale) *
getScalingFactorTwo());
}
} // setDPI
// ----------------------------------------------------------------------------

View File

@ -36,20 +36,26 @@
#include "utils/constants.hpp"
#include "utils/mini_glm.hpp"
/** Creates the slip stream object using a moving texture.
/** Creates the slip stream object
* \param kart Pointer to the kart to which the slip stream
* belongs to.
*/
SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
SlipStream::SlipStream(AbstractKart* kart)
{
m_node = NULL;
m_kart = kart;
m_moving = NULL;
m_moving_fast = NULL;
m_moving_bonus = NULL;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
m_moving = new MovingTexture(0.0f, 0.0f);
Material* material =
material_manager->getMaterialSPM("slipstream.png", "");
SP::SPMesh* mesh = createMesh(material);
SP::SPMesh* mesh = createMesh(material, false);
m_node = irr_driver->addMesh(mesh, "slipstream");
mesh->drop();
std::string debug_name = m_kart->getIdent()+" (slip-stream)";
@ -59,23 +65,65 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
m_node->setVisible(false);
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(m_node);
assert(spmn);
setSPTM(spmn->getTextureMatrix(0).data());
m_moving->setSPTM(spmn->getTextureMatrix(0).data());
m_moving_fast = new MovingTexture(0.0f, 0.0f);
material = material_manager->getMaterialSPM("slipstream2.png", "");
mesh = createMesh(material, false);
m_node_fast = irr_driver->addMesh(mesh, "slipstream2");
mesh->drop();
debug_name = m_kart->getIdent()+" (slip-stream2)";
m_node_fast->setName(debug_name.c_str());
m_node_fast->setPosition(core::vector3df(0, 0 * 0.25f + 2.5f,
m_kart->getKartLength()));
m_node_fast->setVisible(false);
spmn = dynamic_cast<SP::SPMeshNode*>(m_node_fast);
assert(spmn);
m_moving_fast->setSPTM(spmn->getTextureMatrix(0).data());
m_moving_bonus = new MovingTexture(0.0f, 0.0f);
material = material_manager->getMaterialSPM("slipstream_bonus.png", "");
mesh = createMesh(material, true);
m_bonus_node = irr_driver->addMesh(mesh, "slipstream-bonus");
mesh->drop();
debug_name = m_kart->getIdent()+" (slip-stream-bonus)";
m_bonus_node->setName(debug_name.c_str());
m_bonus_node->setPosition(core::vector3df(0, 0 * 0.25f + 2.5f,
m_kart->getKartLength()));
m_bonus_node->setVisible(true);
spmn = dynamic_cast<SP::SPMeshNode*>(m_bonus_node);
assert(spmn);
m_moving_bonus->setSPTM(spmn->getTextureMatrix(0).data());
}
#endif
m_slipstream_ticks = 0;
m_slipstream_time = 0.0f;
m_bonus_time = 0.0f;
m_bonus_active = false;
m_current_target_id = -1;//should not match a real possible kart ID
m_previous_target_id = -1;
float length = m_kart->getKartProperties()->getSlipstreamLength();
//The kart starts at 0 speed anyway
float length = 0.0f;
float kw = m_kart->getKartWidth();
float ew = m_kart->getKartProperties()->getSlipstreamWidth();
float ew = 0.0f;
float kl = m_kart->getKartLength();
//making the slipstream quad start at the kart front
//allows better results when the kart turns
Vec3 p[4];
p[0]=Vec3(-kw*0.5f, 0, -kl*0.5f );
p[0]=Vec3(-kw*0.5f, 0, kl*0.5f );
p[1]=Vec3(-ew*0.5f, 0, -kl*0.5f-length);
p[2]=Vec3( ew*0.5f, 0, -kl*0.5f-length);
p[3]=Vec3( kw*0.5f, 0, -kl*0.5f );
p[3]=Vec3( kw*0.5f, 0, kl*0.5f );
m_slipstream_quad = new Quad(p[0], p[1], p[2], p[3]);
//The position will be corrected in the update anyway
m_slipstream_inner_quad = new Quad(p[0], p[1], p[2], p[3]);
//The position will be corrected in the update anyway
m_slipstream_outer_quad = new Quad(p[0], p[1], p[2], p[3]);
#ifndef SERVER_ONLY
if (UserConfigParams::m_slipstream_debug)
{
@ -97,6 +145,22 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
m_debug_dc->recalculateBoundingBox();
m_debug_dc->setParent(m_kart->getNode());
SP::addDynamicDrawCall(m_debug_dc);
m_debug_dc2 = std::make_shared<SP::SPDynamicDrawCall>
(scene::EPT_TRIANGLE_STRIP,
SP::SPShaderManager::get()->getSPShader("additive"),
material_manager->getDefaultSPMaterial("additive"));
m_debug_dc2->getVerticesVector().resize(4);
v = m_debug_dc2->getVerticesVector().data();
for (unsigned i = 0; i < 4; i++)
{
v[i].m_position = p[idx[i]].toIrrVector();
v[i].m_normal = 0x1FF << 10;
v[i].m_color = red;
}
m_debug_dc2->recalculateBoundingBox();
m_debug_dc2->setParent(m_kart->getNode());
SP::addDynamicDrawCall(m_debug_dc2);
}
#endif
} // SlipStream
@ -110,11 +174,33 @@ SlipStream::~SlipStream()
{
irr_driver->removeNode(m_node);
}
if (m_node_fast)
{
irr_driver->removeNode(m_node_fast);
}
if (m_bonus_node)
{
irr_driver->removeNode(m_bonus_node);
}
if (m_debug_dc)
{
m_debug_dc->removeFromSP();
}
if (m_debug_dc2)
{
m_debug_dc2->removeFromSP();
}
delete m_slipstream_quad;
delete m_slipstream_inner_quad;
delete m_slipstream_outer_quad;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
delete m_moving;
delete m_moving_fast;
delete m_moving_bonus;
}
#endif
} // ~SlipStream
@ -122,8 +208,9 @@ SlipStream::~SlipStream()
/** Called at re-start of a race. */
void SlipStream::reset()
{
m_slipstream_mode = SS_NONE;
m_slipstream_ticks = 0;
m_slipstream_mode = SS_NONE;
m_slipstream_time = 0;
m_bonus_time = 0;
// Reset a potential max speed increase
m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM, 0, 0, 0, 0);
@ -136,13 +223,19 @@ void SlipStream::reset()
* texture coordniates.
* \param material The material to use.
*/
SP::SPMesh* SlipStream::createMesh(Material* material)
SP::SPMesh* SlipStream::createMesh(Material* material, bool bonus_mesh)
{
SP::SPMesh* spm = NULL;
#ifndef SERVER_ONLY
// All radius, starting with the one closest to the kart (and
// widest) to the one furthest away. A 0 indicates the end of the list
float radius[] = {1.5f, 1.0f, 0.5f, 0.0f};
std::vector<float> radius = {1.5f, 1.0f, 0.5f, 0.0f};
if (bonus_mesh)
{
radius = {0.9f,0.6f,0.3f,0.0f};
}
// The distance of each of the circle from the kart. The number of
// entries in this array must be the same as the number of non-zero
@ -160,7 +253,12 @@ SP::SPMesh* SlipStream::createMesh(Material* material)
// (radius1-radius0)/(distance1-distance0) = (radius2-radius1)/(distnace2-distance0)
// This way the line connecting the upper "+" is a straight line,
// and so the 3d cone shape will not be disturbed.
float distance[] = {2.0f, 6.0f, 10.0f };
std::vector<float> distance = {2.0f, 6.0f, 10.0f };
if (bonus_mesh)
{
distance = {0.4f, 0.8f, 1.2f };
}
// The alpha values for the rings, no 'end of list' entry required.
int alphas[] = {0, 255, 0};
@ -173,7 +271,10 @@ SP::SPMesh* SlipStream::createMesh(Material* material)
assert(num_circles > 0);
// Length is distance of last circle to distance of first circle:
m_length = distance[num_circles-1] - distance[0];
float length = distance[num_circles-1] - distance[0];
if (!bonus_mesh)
m_length = length;
// The number of points for each circle. Since part of the slip stream
// might be under the ground (esp. first and last segment), specify
@ -184,12 +285,24 @@ SP::SPMesh* SlipStream::createMesh(Material* material)
const float f = 2*M_PI/float(num_segments);
SP::SPMeshBuffer* buffer = new SP::SPMeshBuffer();
static_cast<SP::SPPerObjectUniform*>(buffer)->addAssignerFunction
("custom_alpha", [this](SP::SPUniformAssigner* ua)->void
{
// In sp shader it's assigned reverse by 1.0 - custom_alpha
ua->setValue(1.0f - stk_config->ticks2Time(m_slipstream_ticks));
});
if(!bonus_mesh)
{
static_cast<SP::SPPerObjectUniform*>(buffer)->addAssignerFunction
("custom_alpha", [this](SP::SPUniformAssigner* ua)->void
{
// In sp shader it's assigned reverse by 1.0 - custom_alpha
ua->setValue(1.0f - m_slipstream_time);
});
}
else
{
static_cast<SP::SPPerObjectUniform*>(buffer)->addAssignerFunction
("custom_alpha", [this](SP::SPUniformAssigner* ua)->void
{
// In sp shader it's assigned reverse by 1.0 - custom_alpha
ua->setValue(1.0f - m_bonus_time);
});
}
std::vector<uint16_t> indices;
std::vector<video::S3DVertexSkinnedMesh> vertices;
@ -208,7 +321,7 @@ SP::SPMesh* SlipStream::createMesh(Material* material)
// Enable texture matrix and dummy normal for visualization
v.m_normal = 0x1FF << 10 | 1 << 30;
v.m_color = video::SColor(alphas[j], 255, 255, 255);
v.m_all_uvs[0] = MiniGLM::toFloat16(curr_distance/m_length);
v.m_all_uvs[0] = MiniGLM::toFloat16(curr_distance/length);
v.m_all_uvs[1] = MiniGLM::toFloat16(
(float)(i-first_segment)/(last_segment-first_segment)
+ (j%2)*(.5f/num_segments));
@ -242,46 +355,83 @@ SP::SPMesh* SlipStream::createMesh(Material* material)
return spm;
} // createMesh
//-----------------------------------------------------------------------------
/** Sets the animation intensity (or speed).
* \param f Intensity: 0 = no slip stream,
* 1 = collecting
* 2 = using slip stream bonus
*/
void SlipStream::setIntensity(float f, const AbstractKart *kart)
//----------------------------------------------------------------------------- */
void SlipStream::updateSlipstreamingTextures(float f, const AbstractKart *kart)
{
if (!kart || !m_node)
if (!kart || !m_node || !m_node_fast)
{
if (m_node)
{
m_node->setVisible(false);
}
if (m_node_fast)
{
m_node_fast->setVisible(false);
}
return;
}
m_node->setVisible(true);
float ktf = m_kart->getKartProperties()->getSlipstreamMinCollectTime();
const float above_terrain = 0.2f;
core::vector3df my_pos = m_kart->getNode()->getPosition();
my_pos.Y = m_kart->getHoT()+above_terrain;
m_node->setPosition(my_pos);
core::vector3df other_pos = kart->getNode()->getPosition();
other_pos.Y = kart->getHoT()+above_terrain;
core::vector3df diff = other_pos - my_pos;
core::vector3df rotation = diff.getHorizontalAngle();
m_node->setRotation(rotation);
float fs = diff.getLength()/m_length;
m_node->setPosition(my_pos);
m_node->setRotation(rotation);
m_node->setScale(core::vector3df(1, 1, fs));
// For real testing in game: this needs some tuning!
m_node->setVisible(f!=0);
MovingTexture::setSpeed(f, 0);
m_node_fast->setPosition(my_pos);
m_node_fast->setRotation(rotation);
m_node_fast->setScale(core::vector3df(1, 1, fs));
m_node->setVisible(f>0.0f && f<ktf);
m_node_fast->setVisible(f>=ktf);
//specify the texture speed movement
float max_f = m_kart->getKartProperties()->getSlipstreamMaxCollectTime();
if (f > max_f) f = max_f;
f = f/2;
m_moving->setSpeed(f, 0);
m_moving_fast->setSpeed(f, 0);
return;
// For debugging: make the slip stream effect visible all the time
m_node->setVisible(true);
MovingTexture::setSpeed(1.0f, 0.0f);
} // setIntensity
m_moving->setSpeed(1.0f, 0.0f);
} // updateSlipstreamingTextures
//----------------------------------------------------------------------------- */
void SlipStream::updateBonusTexture()
{
if (!m_bonus_node)
{
return;
}
const float above_terrain = 0.2f;
core::vector3df my_pos = m_kart->getNode()->getPosition();
my_pos.Y += above_terrain;
core::vector3df previous_pos = m_kart->getRecentPreviousXYZ().toIrrVector();
core::vector3df diff = my_pos - previous_pos;
core::vector3df rotation = diff.getHorizontalAngle();
m_bonus_node->setPosition(my_pos);
m_bonus_node->setRotation(rotation);
m_bonus_node->setVisible(m_bonus_time > 0.0f && m_kart->getSpeed() > 2.0f);
float bonus_speed = 1.0f + std::max(m_bonus_time/1.5f,0.0f);
m_moving_bonus->setSpeed(bonus_speed, 0);
} //updateBonusTexture
//-----------------------------------------------------------------------------
/** Returns true if enough slipstream credits have been accumulated
@ -289,30 +439,10 @@ void SlipStream::setIntensity(float f, const AbstractKart *kart)
*/
bool SlipStream::isSlipstreamReady() const
{
return m_slipstream_ticks>
m_kart->getKartProperties()->getSlipstreamCollectTicks();
return m_slipstream_time>
m_kart->getKartProperties()->getSlipstreamMinCollectTime();
} // isSlipstreamReady
//-----------------------------------------------------------------------------
/** Returns the additional force being applied to the kart because of
* slipstreaming.
*/
void SlipStream::updateSlipstreamPower()
{
// See if we are currently using accumulated slipstream credits:
// -------------------------------------------------------------
if(m_slipstream_mode==SS_USE)
{
setIntensity(2.0f, NULL);
const KartProperties *kp = m_kart->getKartProperties();
m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM,
kp->getSlipstreamMaxSpeedIncrease(),
kp->getSlipstreamAddPower(),
kp->getSlipstreamDuration(),
kp->getSlipstreamFadeOutTicks());
}
} // upateSlipstreamPower
//-----------------------------------------------------------------------------
/** Sets the color of the debug mesh (which shows the area in which slipstream
* can be accumulated).
@ -320,23 +450,164 @@ void SlipStream::updateSlipstreamPower()
* black: kart too slow
* red: not inside of slipstream area
* green: slipstream is being accumulated.
* \param inner : bool to know if we apply the color to the inner quad or to the main one
*/
void SlipStream::setDebugColor(const video::SColor &color)
void SlipStream::setDebugColor(const video::SColor &color, bool inner)
{
if (!m_debug_dc)
if (!inner)
{
return;
}
if (!m_debug_dc)
{
return;
}
video::S3DVertexSkinnedMesh* v = m_debug_dc->getVerticesVector().data();
for (unsigned i = 0; i < 4; i++)
video::S3DVertexSkinnedMesh* v = m_debug_dc->getVerticesVector().data();
for (unsigned i = 0; i < 4; i++)
{
v[i].m_color = color;
}
m_debug_dc->setUpdateOffset(0);
}
else
{
v[i].m_color = color;
}
m_debug_dc->setUpdateOffset(0);
if (!m_debug_dc2)
{
return;
}
video::S3DVertexSkinnedMesh* v = m_debug_dc2->getVerticesVector().data();
for (unsigned i = 0; i < 4; i++)
{
v[i].m_color = color;
}
m_debug_dc2->setUpdateOffset(0);
}
} // setDebugColor
//-----------------------------------------------------------------------------
/** UpdateQuad
*/
void SlipStream::updateQuad()
{
//Change the quad form to counteract the mismatch between
//kart orientation and real direction
//Computations are contrieved by the fact we have several
//different 3D vector, one for each library.
Vec3 moving_xyz = m_kart->getPreviousXYZ() - m_kart->getXYZ();
//retrieve a vector rotated to kart direction
btScalar bx,by,bz;//a btScalar is a float or a double
bx = 1.0f;
by = bz = 0.0f;
btVector3 rotated_base;
rotated_base.setValue(bx,by,bz);
btQuaternion rotation = m_kart->getRotation();
rotated_base = quatRotate(rotation,rotated_base);
Vec3 direction_vector;
//Z and X need to be inverted and X multiplied by -1 to match moving_xyz
direction_vector = Vec3(rotated_base.getZ(), rotated_base.getY(), -rotated_base.getX());
//normalize the moving vector
float vec_length = moving_xyz.x()*moving_xyz.x()
+ moving_xyz.y()*moving_xyz.y()
+ moving_xyz.z()*moving_xyz.z();
if (vec_length != 0)
{
vec_length = core::reciprocal_squareroot(vec_length);
float x,y,z;
x = moving_xyz.x() * vec_length;
y = moving_xyz.y() * vec_length;
z = moving_xyz.z() * vec_length;
moving_xyz = Vec3(x,y,z);
}
//This vector gives us the change to apply in absolute coordinates
Vec3 noffset = moving_xyz - direction_vector;
//But the quad position is in the kart coordinate space
//So we rotate it back
rotated_base.setValue(-noffset.z(),noffset.y(),noffset.x());
rotation = rotation.inverse();
rotated_base = quatRotate(rotation,rotated_base);
noffset = Vec3(rotated_base.getZ(), rotated_base.getY(), -rotated_base.getX());
float speed_factor = m_kart->getSpeed()/m_kart->getKartProperties()->getSlipstreamBaseSpeed();
float length = m_kart->getKartProperties()->getSlipstreamLength()*speed_factor;
float kw = m_kart->getKartWidth();
float ew = m_kart->getKartProperties()->getSlipstreamWidth()*speed_factor;
float kl = m_kart->getKartLength();
float offx = (kl*0.5f+length)*noffset.x();
float offz = (kl*0.5f+length)*noffset.z();
//making the slipstream quad start at the kart front
//allows better results when the kart turns
Vec3 p[4];
p[0]=Vec3(-kw*0.5f, 0, kl*0.5f );
p[1]=Vec3(-ew*0.5f+offx, 0, -kl*0.5f-length+offz);
p[2]=Vec3( ew*0.5f+offx, 0, -kl*0.5f-length+offz);
p[3]=Vec3( kw*0.5f, 0, kl*0.5f );
//Update the slipstreaming quad
m_slipstream_quad->setQuad(p[0], p[1], p[2], p[3]);
p[1]=Vec3((-ew*0.5f+offx)*1.1f, 0, -kl*0.5f-(length+offz)*1.1f);
p[2]=Vec3((ew*0.5f+offx)*1.1f, 0, -kl*0.5f-(length+offz)*1.1f);
//Update the slipstreaming outer quad
m_slipstream_outer_quad->setQuad(p[0], p[1], p[2], p[3]);
#ifndef SERVER_ONLY
//recalculate quad position for debug drawing
if (UserConfigParams::m_slipstream_debug)
{
video::S3DVertexSkinnedMesh* v =
m_debug_dc->getVerticesVector().data();
unsigned idx[] = { 0, 3, 1, 2 };
for (unsigned i = 0; i < 4; i++)
{
v[i].m_position = p[idx[i]].toIrrVector();
}
m_debug_dc->recalculateBoundingBox();
m_debug_dc->setParent(m_kart->getNode());
SP::addDynamicDrawCall(m_debug_dc);
}
#endif
float inner_factor = m_kart->getKartProperties()->getSlipstreamInnerFactor()*sqrt(speed_factor);
length = length*inner_factor;
ew = ew*inner_factor;
if (ew > 0.5f) ew -= 0.5f;
else ew = 0;
offx = (kl*0.5f+length)*noffset.x();
offz = (kl*0.5f+length)*noffset.z();
p[1]=Vec3(-ew*0.5f+offx, 0, -kl*0.5f-length+offz);
p[2]=Vec3( ew*0.5f+offx, 0, -kl*0.5f-length+offz);
//Update the slipstreaming inner quad
m_slipstream_inner_quad->setQuad(p[0], p[1], p[2], p[3]);
#ifndef SERVER_ONLY
//recalculate inner quad position for debug drawing
if (UserConfigParams::m_slipstream_debug)
{
video::S3DVertexSkinnedMesh* v =
m_debug_dc2->getVerticesVector().data();
unsigned idx[] = { 0, 3, 1, 2 };
for (unsigned i = 0; i < 4; i++)
{
v[i].m_position = p[idx[i]].toIrrVector();
}
m_debug_dc2->recalculateBoundingBox();
m_debug_dc2->setParent(m_kart->getNode());
SP::addDynamicDrawCall(m_debug_dc2);
}
#endif
} //updateQuad
//-----------------------------------------------------------------------------
/** Update, called once per timestep.
* \param dt Time step size.
@ -350,38 +621,63 @@ void SlipStream::update(int ticks)
|| m_kart->isGhostKart())
return;
MovingTexture::update(stk_config->ticks2Time(ticks));
if(m_slipstream_mode==SS_USE)
//there is no slipstreaming at low speed
//and the quad may do weird things if going in reverse
if(m_kart->getSpeed() > 1.0f)
{
m_slipstream_ticks -= ticks;
if(m_slipstream_ticks<0) m_slipstream_mode=SS_NONE;
updateQuad();
}
updateSlipstreamPower();
float dt = stk_config->ticks2Time(ticks);
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
m_moving->update(dt);
m_moving_fast->update(dt);
m_moving_bonus->update(dt);
}
#endif
m_bonus_time -= dt;
if (m_bonus_time <= 0) m_bonus_active = false;
// If this kart is too slow for slipstreaming taking effect, do nothing
// Use a margin because what really matters is the target's speed
// If this kart is much slower than the minSpeed, then either its
// targets are slower too, or it won't stay long enough behind them
// --------------------------------------------------------------------
// Define this to get slipstream effect shown even when the karts are
// not moving. This is useful for debugging the graphics of SS-ing.
//#define DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
if(m_kart->getSpeed() < kp->getSlipstreamMinSpeed())
if(m_kart->getSpeed() < kp->getSlipstreamMinSpeed() - 2.0f)
{
setIntensity(0, NULL);
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
updateSlipstreamingTextures(0,NULL);
updateBonusTexture();
}
#endif
m_slipstream_mode = SS_NONE;
if(UserConfigParams::m_slipstream_debug)
setDebugColor(video::SColor(255, 0, 0, 0));
{
setDebugColor(video::SColor(255, 0, 0, 0),false);
setDebugColor(video::SColor(255, 0, 0, 0),true);
}
return;
}
#endif
// Then test if this kart is in the slipstream range of another kart:
// ------------------------------------------------------------------
World *world = World::getWorld();
unsigned int num_karts = world->getNumKarts();
bool is_sstreaming = false;
m_target_kart = NULL;
World *world = World::getWorld();
unsigned int num_karts = world->getNumKarts();
bool is_sstreaming = false;
bool is_inner_sstreaming = false;
bool is_outer_sstreaming = false;
m_target_kart = NULL;
std::vector<float> target_value;
// Note that this loop can not be simply replaced with a shorter loop
// using only the karts with a better position - since a kart might
@ -389,12 +685,21 @@ void SlipStream::update(int ticks)
for(unsigned int i=0; i<num_karts; i++)
{
m_target_kart= world->getKart(i);
target_value.push_back(0);
// Don't test for slipstream with itself, a kart that is being
// rescued or exploding, a ghost kart or an eliminated kart
if(m_target_kart==m_kart ||
m_target_kart->getKartAnimation() ||
m_target_kart->isGhostKart() ||
m_target_kart->isEliminated() ) continue;
m_target_kart->isEliminated() )
{
if (m_previous_target_id >= 0 && (int) i==m_previous_target_id)
m_previous_target_id = -1;
continue;
}
const KartProperties *kp_target = m_target_kart->getKartProperties();
// Transform this kart location into target kart point of view
Vec3 lc = m_target_kart->getTrans().inverse()(m_kart->getXYZ());
@ -404,93 +709,187 @@ void SlipStream::update(int ticks)
if (fabsf(lc.y()) > 6.0f) continue;
// If the kart we are testing against is too slow, no need to test
// slipstreaming. Note: We compare the speed of the other kart
// against the minimum slipstream speed kart of this kart - not
// entirely sure if this makes sense, but it makes it easier to
// give karts different slipstream properties.
// slipstreaming.
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
if (m_target_kart->getSpeed() < kp->getSlipstreamMinSpeed())
if (m_target_kart->getSpeed() < kp_target->getSlipstreamMinSpeed())
{
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
{
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 0, 0));
->setDebugColor(video::SColor(255, 0, 0, 0), false);
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 0, 0), true);
}
if (m_previous_target_id >= 0 && (int) i==m_previous_target_id)
m_previous_target_id = -1;
continue;
}
#endif
// Quick test: the kart must be not more than
// slipstream length+0.5*kart_length()+0.5*target_kart_length
// slipstream length+0.5*kart_length()+target_kart_length
// away from the other kart
// (additional target_kart_length because that kart's center
// is not the center of rotation of the slipstreaming quad)
Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ();
float l = kp->getSlipstreamLength()
+ 0.5f*( m_target_kart->getKartLength()
+m_kart->getKartLength() );
float l = kp_target->getSlipstreamLength()*1.1f;//Outer quad margin
float speed_factor = m_target_kart->getSpeed()
/kp_target->getSlipstreamBaseSpeed();
l = l*speed_factor + m_target_kart->getKartLength()
+ 0.5f*m_kart->getKartLength();
if(delta.length2() > l*l)
{
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 0, 128));
if (m_previous_target_id >= 0 && (int) i==m_previous_target_id)
m_previous_target_id = -1;
continue;
}
// Real test: if in slipstream quad of other kart
if(m_target_kart->getSlipstream()->m_slipstream_quad
// Real test 1: if in inner slipstream quad of other kart
if(m_target_kart->getSlipstream()->m_slipstream_inner_quad
->pointInside(lc))
{
is_sstreaming = true;
break;
is_inner_sstreaming = true;
is_sstreaming = true;
target_value[i] = 2000.0f - delta.length2();
continue;
}
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 0, 255));
->setDebugColor(video::SColor(255, 0, 0, 255),true);
// Real test2: if in slipstream quad of other kart
if(m_target_kart->getSlipstream()->m_slipstream_quad
->pointInside(lc))
{
is_sstreaming = true;
target_value[i] = 1000.0f - delta.length2();
continue;
}
else if (m_previous_target_id >= 0 && (int) i==m_previous_target_id)
{
m_previous_target_id = -1;
}
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 0, 255),false);
// Real test3: if in outer slipstream quad of other kart
if(m_target_kart->getSlipstream()->m_slipstream_outer_quad
->pointInside(lc))
{
is_outer_sstreaming = true;
continue;
}
} // for i < num_karts
int best_target=-1;
float best_target_value=0.0f;
//Select the best target
for(unsigned int i=0; i<num_karts; i++)
{
if (target_value[i] > best_target_value)
{
best_target_value = target_value[i];
best_target=i;
}
} // for i < num_karts
if (best_target >= 0)
{
m_target_kart = world->getKart(best_target);
}
//When changing slipstream target (including no good target)
if (best_target!=m_current_target_id)
{
m_previous_target_id = m_current_target_id;
m_current_target_id = best_target;
}
if(isSlipstreamReady() && (m_current_target_id < 0
|| (m_previous_target_id >= 0
&& target_value[m_previous_target_id] == 0.0f)))
{
// The first time slipstream is ready after collecting, and
// you are leaving the slipstream area, the bonus is activated
float additional_time = m_slipstream_time*kp->getSlipstreamDurationFactor();
if (m_bonus_time <= 0.0f)
m_bonus_time = additional_time;
else
m_bonus_time += additional_time;
m_slipstream_time = 0.0f;
m_bonus_active = true;
int fade_out = kp->getSlipstreamFadeOutTicks();
m_kart->instantSpeedIncrease(MaxSpeed::MS_INCREASE_SLIPSTREAM,
kp->getSlipstreamMaxSpeedIncrease(),
kp->getSlipstreamMaxSpeedIncrease(),
kp->getSlipstreamAddPower(),
m_bonus_time,
stk_config->ticks2Time(fade_out) );
}
if(!is_sstreaming)
{
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 255, 0, 0));
if(isSlipstreamReady())
{
// The first time slipstream is ready after collecting
// and you are leaving the slipstream area, you get a
// zipper bonus.
if(m_slipstream_mode==SS_COLLECT)
{
m_slipstream_mode = SS_USE;
m_kart->handleZipper();
m_slipstream_ticks = kp->getSlipstreamCollectTicks();
return;
}
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 255, 0, 0),false);
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 255, 0),true);
}
m_slipstream_ticks -= ticks;
if(m_slipstream_ticks<0) m_slipstream_mode = SS_NONE;
setIntensity(0, NULL);
//Reduces the easiness of reusing most of the accumulated time with another kart
if(is_outer_sstreaming)
m_slipstream_time -=dt;
else
m_slipstream_time -=3*dt;
if(m_slipstream_time<0) m_slipstream_mode = SS_NONE;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
updateSlipstreamingTextures(0,NULL);
updateBonusTexture();
}
#endif
return;
} // if !is_sstreaming
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
m_target_kart->getSlipstream()
->setDebugColor(video::SColor(255, 0, 255, 0));
// Accumulate slipstream credits now
m_target_kart->getSlipstream()->setDebugColor(video::SColor(255, 128, 255, 0),false);
if (m_slipstream_mode == SS_NONE)
m_slipstream_ticks = ticks;
// Accumulate slipstream credits now
//Twice as fast in the inner quad
if (is_inner_sstreaming)
{
m_slipstream_time = m_slipstream_mode==SS_NONE ? 2*dt : m_slipstream_time+2*dt;
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
m_target_kart->getSlipstream()->setDebugColor(video::SColor(255, 0, 255, 128),true);
}
else
m_slipstream_ticks += ticks;
{
m_slipstream_time = m_slipstream_mode==SS_NONE ? dt : m_slipstream_time+dt;
}
//Cap the possible credits
if (m_slipstream_time > m_kart->getKartProperties()->getSlipstreamMaxCollectTime())
m_slipstream_time = m_kart->getKartProperties()->getSlipstreamMaxCollectTime();
if(isSlipstreamReady())
m_kart->setSlipstreamEffect(9.0f);
setIntensity(stk_config->ticks2Time(m_slipstream_ticks), m_target_kart);
m_slipstream_mode = SS_COLLECT;
if (m_slipstream_ticks > kp->getSlipstreamCollectTicks())
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
setIntensity(1.0f, m_target_kart);
updateSlipstreamingTextures(m_slipstream_time, m_target_kart);
updateBonusTexture();
}
#endif
m_slipstream_mode = SS_COLLECT;
} // update

View File

@ -44,45 +44,86 @@ class Material;
/**
* \ingroup graphics
*/
class SlipStream : public MovingTexture
class SlipStream
{
private:
/** The kart to which this smoke belongs. */
AbstractKart *m_kart;
/** The moving texture for the normal node */
MovingTexture *m_moving;
/** The moving texture for the fast node */
MovingTexture *m_moving_fast;
/** The moving texture for the fast node */
MovingTexture *m_moving_bonus;
/** The scene node. */
scene::ISceneNode *m_node;
/** The fast scene node. */
scene::ISceneNode *m_node_fast;
/** The node used when the bonus is active. */
scene::ISceneNode *m_bonus_node;
/** For debugging: a simple quad to display where slipstream works. */
std::shared_ptr<SP::SPDynamicDrawCall> m_debug_dc;
/** For debugging: a simple quad to display where inner slipstream works. */
std::shared_ptr<SP::SPDynamicDrawCall> m_debug_dc2;
/** The length of the slipstream cylinder. This is used to scale
* the actual scene node correctly. */
float m_length;
* the actual scene node correctly. Shared between node and node_fast */
float m_length;
/** The time a kart was in slipstream. */
int m_slipstream_ticks;
float m_slipstream_time;
/** The remaining active time bonus */
float m_bonus_time;
/** This bool is used to know the first time we're going out of the slipstreaming area */
bool m_bonus_active;
/** Used to trigger automatically the slipstreaming bonus */
int m_current_target_id;
int m_previous_target_id;
/** Slipstream mode: either nothing happening, or the kart is collecting
* 'slipstream credits', or the kart is using accumulated credits. */
enum {SS_NONE, SS_COLLECT, SS_USE} m_slipstream_mode;
* 'slipstream credits'. Credits can be accumulated while the bonus is used */
enum {SS_NONE, SS_COLLECT} m_slipstream_mode;
/** This is slipstream area if the kart is at 0,0,0 without rotation. */
Quad *m_slipstream_quad;
/** This is the inner slipstream area if the kart is at 0,0,0 without rotation. */
Quad *m_slipstream_inner_quad;
/** This is the outer slipstream area if the kart is at 0,0,0 without rotation.
No slipstream time is accumulated there, but it's lost slower*/
Quad *m_slipstream_outer_quad;
/** The kart from which this kart gets slipstream. Used by the AI to
** overtake the right kart. */
AbstractKart* m_target_kart;
SP::SPMesh* createMesh(Material* material);
void setDebugColor(const video::SColor &color);
SP::SPMesh* createMesh(Material* material, bool bonus_mesh);
void setDebugColor(const video::SColor &color, bool inner);
void updateQuad();
void updateSlipstreamingTextures(float f, const AbstractKart* kart);
void updateBonusTexture();
public:
SlipStream (AbstractKart* kart);
virtual ~SlipStream ();
void reset();
virtual void update(int ticks);
void setIntensity(float f, const AbstractKart* kart);
void updateSlipstreamPower();
bool isSlipstreamReady() const;
// ------------------------------------------------------------------------
@ -94,7 +135,6 @@ public:
const AbstractKart* getSlipstreamTarget() const {return m_target_kart;}
// ------------------------------------------------------------------------
/** Returns if slipstream is being used. */
bool inUse() const {return m_slipstream_mode==SS_USE; }
bool inUse() const {return m_bonus_time>0.0f; }
}; // SlipStream
#endif

View File

@ -31,13 +31,13 @@ namespace SP
class SPInstancedData
{
private:
char m_data[32];
char m_data[44];
public:
// ------------------------------------------------------------------------
SPInstancedData()
{
memset(m_data, 0, 32);
memset(m_data, 0, 44);
}
// ------------------------------------------------------------------------
SPInstancedData(const core::matrix4& model_mat,
@ -65,21 +65,19 @@ public:
rotation.W = -rotation.W;
}
memcpy(m_data, position, 12);
uint32_t _2101010 = normalizedSignedFloatsTo1010102(
{{ rotation.X, rotation.Y, rotation.Z, 0.0f }});
memcpy(m_data + 12, &_2101010, 4);
memcpy(m_data + 12, &rotation, 16);
short s[4] = { toFloat16(scale.X), toFloat16(scale.Y),
toFloat16(scale.Z), toFloat16(rotation.W) };
memcpy(m_data + 16, s, 8);
toFloat16(scale.Z), 0 };
memcpy(m_data + 28, s, 8);
short tm[2] =
{
short(texture_trans_x * 32767.0f),
short(texture_trans_y * 32767.0f)
};
memcpy(m_data + 24, tm, 4);
memcpy(m_data + 28, &skinning_offset, 2);
memcpy(m_data + 36, tm, 4);
memcpy(m_data + 40, &skinning_offset, 2);
short hue_packed = short(core::clamp(int(hue * 100.0f), 0, 100));
memcpy(m_data + 30, &hue_packed, 2);
memcpy(m_data + 42, &hue_packed, 2);
}
// ------------------------------------------------------------------------
const void* getData() const { return m_data; }

View File

@ -247,16 +247,16 @@ void SPMeshBuffer::recreateVAO(unsigned i)
#ifndef USE_GLES2
if (CVS->isARBBufferStorageUsable())
{
glBufferStorage(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 32, NULL,
glBufferStorage(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 44, NULL,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
m_ins_dat_mapped_ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0,
m_gl_instance_size[i] * 32,
m_gl_instance_size[i] * 44,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
}
else
#endif
{
glBufferData(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 32, NULL,
glBufferData(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 44, NULL,
GL_DYNAMIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
@ -346,26 +346,23 @@ void SPMeshBuffer::recreateVAO(unsigned i)
glBindBuffer(GL_ARRAY_BUFFER, m_ins_array[i]);
// Origin
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 32, (void*)0);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 44, (void*)0);
glVertexAttribDivisorARB(8, 1);
// Rotation (quaternion .xyz)
// Rotation (quaternion in 4 32bit floats)
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 4, GL_INT_2_10_10_10_REV,
GraphicsRestrictions::isDisabled
(GraphicsRestrictions::GR_CORRECT_10BIT_NORMALIZATION) ? GL_FALSE : GL_TRUE, 32,
(void*)12);
glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, 44, (void*)12);
glVertexAttribDivisorARB(9, 1);
// Scale (3 half floats and .w for quaternion .w)
// Scale (3 half floats and .w unused)
glEnableVertexAttribArray(10);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 32, (void*)16);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 44, (void*)28);
glVertexAttribDivisorARB(10, 1);
// Texture translation
glEnableVertexAttribArray(11);
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 32, (void*)24);
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 44, (void*)36);
glVertexAttribDivisorARB(11, 1);
// Misc data (skinning offset and hue change)
glEnableVertexAttribArray(12);
glVertexAttribIPointer(12, 2, GL_SHORT, 32, (void*)28);
glVertexAttribIPointer(12, 2, GL_SHORT, 44, (void*)40);
glVertexAttribDivisorARB(12, 1);
glBindVertexArray(0);
@ -400,15 +397,15 @@ void SPMeshBuffer::uploadInstanceData()
if (CVS->isARBBufferStorageUsable())
{
memcpy(m_ins_dat_mapped_ptr[i], m_ins_dat[i].data(),
m_ins_dat[i].size() * 32);
m_ins_dat[i].size() * 44);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER, m_ins_array[i]);
void* ptr = glMapBufferRange(GL_ARRAY_BUFFER, 0,
m_ins_dat[i].size() * 32, GL_MAP_WRITE_BIT |
m_ins_dat[i].size() * 44, GL_MAP_WRITE_BIT |
GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
memcpy(ptr, m_ins_dat[i].data(), m_ins_dat[i].size() * 32);
memcpy(ptr, m_ins_dat[i].data(), m_ins_dat[i].size() * 44);
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

View File

@ -184,7 +184,7 @@ void STKTextBillboard::init(core::stringw text, FontWithFace* face)
glGenBuffers(1, &m_instanced_array);
glBindBuffer(GL_ARRAY_BUFFER, m_instanced_array);
glBufferData(GL_ARRAY_BUFFER,
12 /*position*/ + 4/*quaternion*/ + 8 /*scale*/, NULL,
12 /*position*/ + 16/*quaternion*/ + 8 /*scale*/, NULL,
GL_DYNAMIC_DRAW);
for (auto& p : m_gl_tbs)
{
@ -213,20 +213,17 @@ void STKTextBillboard::init(core::stringw text, FontWithFace* face)
glBindBuffer(GL_ARRAY_BUFFER, m_instanced_array);
// Origin
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 24, (void*)0);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 36, (void*)0);
glVertexAttribDivisorARB(8, 1);
// Rotation (quaternion .xyz)
// Rotation (quaternion in 4 32bit floats)
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 4, GL_INT_2_10_10_10_REV,
GraphicsRestrictions::isDisabled
(GraphicsRestrictions::GR_CORRECT_10BIT_NORMALIZATION) ?
GL_FALSE : GL_TRUE, 24, (void*)12);
glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, 36, (void*)12);
glVertexAttribDivisorARB(9, 1);
// Scale (3 half floats and .w for quaternion .w)
// Scale (3 half floats and .w unused)
glEnableVertexAttribArray(10);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 24, (void*)16);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 36, (void*)28);
glVertexAttribDivisorARB(10, 1);
glBindVertexArray(0);

View File

@ -143,7 +143,7 @@ public:
{
#ifndef SERVER_ONLY
glBindBuffer(GL_ARRAY_BUFFER, m_instanced_array);
glBufferSubData(GL_ARRAY_BUFFER, 0, 24, m_instanced_data.getData());
glBufferSubData(GL_ARRAY_BUFFER, 0, 36, m_instanced_data.getData());
glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
}

View File

@ -15,6 +15,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config/user_config.hpp"
#include "font/font_manager.hpp"
#include "font/regular_face.hpp"
#include "graphics/irr_driver.hpp"
@ -151,9 +152,12 @@ void DynamicRibbonWidget::add()
unsigned int screen_height = irr_driver->getActualScreenSize().Height;
m_arrows_w = (int)(screen_height / 15);
m_arrows_w = std::max(m_arrows_w, 40);
#ifdef ANDROID
m_arrows_w *= 1.5f;
#endif
if (UserConfigParams::m_hidpi_enabled)
{
m_arrows_w *= 1.5f;
}
const int button_h = m_arrows_w;
// right arrow

View File

@ -29,9 +29,13 @@
*/
void Binding::save(std::ofstream& stream) const
{
stream << "id=\"" << m_id << "\" "
<< "event=\"" << m_type << "\" "
<< "character=\"" << m_character << "\" ";
stream << "event=\"" << m_type << "\" ";
stream << "id=\"" << m_id << "\" ";
if (m_type == Input::IT_KEYBOARD)
{
stream << "character=\"" << m_character << "\" ";
}
// Only serialize the direction and the range for stick motions
if (m_type == Input::IT_STICKMOTION)

View File

@ -459,6 +459,8 @@ void DeviceManager::updateMultitouchDevice()
{
m_multitouch_device->setPlayer(NULL);
}
m_multitouch_device->updateController();
} // updateMultitouchDevice
//-----------------------------------------------------------------------------
@ -641,6 +643,18 @@ void DeviceManager::save()
configfile << "<input version=\"" << INPUT_FILE_VERSION << "\">\n\n";
configfile << "<!--\n"
<< "Event 1 : Keyboard button press\n"
<< " 'id' indicates which button, as defined by irrlicht's EKEY_CODE enum\n"
<< " 'character' contains the associated unicode character.\n"
<< " Only used as fallback when displaying special characters in the UI.\n"
<< "Event 2 : Gamepad stick motion\n"
<< " 'id' indicates which stick, starting from 0\n"
<< " 'direction' 0 means negative, 1 means positive\n"
<< "Event 3 : Gamepad button press\n"
<< " 'id' indicates which button, starting from 0\n"
<< "-->\n\n";
for(unsigned int n=0; n<m_keyboard_configs.size(); n++)
{
m_keyboard_configs[n].save(configfile);

View File

@ -1225,19 +1225,9 @@ EventPropagation InputManager::input(const SEvent& event)
{
m_device_manager->updateMultitouchDevice();
for (unsigned int i = 0; i < device->getButtonsCount(); i++)
{
MultitouchButton* button = device->getButton(i);
if (button->type != BUTTON_STEERING)
continue;
float factor = UserConfigParams::m_multitouch_tilt_factor;
factor = std::max(factor, 0.1f);
button->axis_x = (float)event.AccelerometerEvent.Y / factor;
device->handleControls(button);
}
float factor = UserConfigParams::m_multitouch_tilt_factor;
factor = std::max(factor, 0.1f);
device->updateAxisX(float(event.AccelerometerEvent.Y) / factor);
}
}

View File

@ -36,7 +36,7 @@ MultitouchDevice::MultitouchDevice()
m_type = DT_MULTITOUCH;
m_name = "Multitouch";
m_player = NULL;
m_accelerometer_active = false;
m_controller = NULL;
#ifdef ANDROID
m_android_device = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
@ -136,22 +136,6 @@ void MultitouchDevice::addButton(MultitouchButtonType type, int x, int y,
}
m_buttons.push_back(button);
#ifdef ANDROID
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
if (UserConfigParams::m_multitouch_controls == 2 &&
!m_android_device->isAccelerometerActive())
{
m_android_device->activateAccelerometer(1.0f / 30);
if (m_android_device->isAccelerometerActive())
{
m_accelerometer_active = true;
}
}
}
#endif
} // addButton
// ----------------------------------------------------------------------------
@ -159,15 +143,6 @@ void MultitouchDevice::addButton(MultitouchButtonType type, int x, int y,
*/
void MultitouchDevice::clearButtons()
{
#ifdef ANDROID
if (m_accelerometer_active == true &&
m_android_device->isAccelerometerActive())
{
m_android_device->deactivateAccelerometer();
m_accelerometer_active = false;
}
#endif
for (MultitouchButton* button : m_buttons)
{
delete button;
@ -198,6 +173,45 @@ void MultitouchDevice::reset()
}
} // reset
// ----------------------------------------------------------------------------
/** Activates accelerometer
*/
void MultitouchDevice::activateAccelerometer()
{
#ifdef ANDROID
if (!m_android_device->isAccelerometerActive())
{
m_android_device->activateAccelerometer(1.0f / 30);
}
#endif
}
// ----------------------------------------------------------------------------
/** Deativates accelerometer
*/
void MultitouchDevice::deactivateAccelerometer()
{
#ifdef ANDROID
if (m_android_device->isAccelerometerActive())
{
m_android_device->deactivateAccelerometer();
}
#endif
}
// ----------------------------------------------------------------------------
/** Get accelerometer state
* \return true if accelerometer is active
*/
bool MultitouchDevice::isAccelerometerActive()
{
#ifdef ANDROID
return m_android_device->isAccelerometerActive();
#endif
return false;
}
// ----------------------------------------------------------------------------
/** The function that is executed when touch event occurs. It updates the
* buttons state when it's needed.
@ -237,21 +251,39 @@ void MultitouchDevice::updateDeviceState(unsigned int event_id)
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
float prev_axis_x = button->axis_x;
if (button->pressed == true)
{
button->axis_x =
(float)(event.x - button->x) / (button->width/2) - 1;
}
else
{
button->axis_x = 0.0f;
}
if (prev_axis_x != button->axis_x)
{
update_controls = true;
}
}
if (button->type == MultitouchButtonType::BUTTON_STEERING ||
button->type == MultitouchButtonType::BUTTON_UP_DOWN)
{
float prev_axis_y = button->axis_y;
if (button->pressed == true)
{
updateButtonAxes(button,
(float)(event.x - button->x) / (button->width/2) - 1,
(float)(event.y - button->y) / (button->height/2) - 1);
button->axis_y =
(float)(event.y - button->y) / (button->height/2) - 1;
}
else
{
updateButtonAxes(button, 0.0f, 0.0f);
button->axis_y = 0.0f;
}
if (prev_axis_x != button->axis_x ||
prev_axis_y != button->axis_y)
if (prev_axis_y != button->axis_y)
{
update_controls = true;
}
@ -298,36 +330,94 @@ float MultitouchDevice::getSteeringFactor(float value)
m_deadzone_center), 1.0f);
}
/** Updates the button axes. It leaves X axis untouched if the accelerometer is
* used for turning left/right
* \param button A button that should be updated
* \param x A value from 0 to 1
* \param y A value from 0 to 1
*/
void MultitouchDevice::updateButtonAxes(MultitouchButton* button, float x,
float y)
{
if (m_accelerometer_active == false)
{
button->axis_x = x;
}
// ----------------------------------------------------------------------------
button->axis_y = y;
void MultitouchDevice::updateAxisX(float value)
{
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_STEER_RIGHT, int(factor * Input::MAX_VALUE));
}
else
{
m_controller->action(PA_STEER_LEFT, 0);
m_controller->action(PA_STEER_RIGHT, 0);
}
}
// ----------------------------------------------------------------------------
void MultitouchDevice::updateAxisY(float value)
{
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_ACCEL, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_BRAKE, int(factor * Input::MAX_VALUE));
}
else
{
m_controller->action(PA_BRAKE, 0);
m_controller->action(PA_ACCEL, 0);
}
}
// ----------------------------------------------------------------------------
/** Sends proper action for player controller depending on the button type
* and state.
* \param button The button that should be handled.
*/
void MultitouchDevice::handleControls(MultitouchButton* button)
{
if (m_player == NULL)
if (m_controller == NULL)
return;
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
updateAxisX(button->axis_x);
updateAxisY(button->axis_y);
}
else if (button->type == MultitouchButtonType::BUTTON_UP_DOWN)
{
updateAxisY(button->axis_y);
}
else
{
if (button->action != PA_BEFORE_FIRST)
{
int value = button->pressed ? Input::MAX_VALUE : 0;
m_controller->action(button->action, value);
}
}
}
// ----------------------------------------------------------------------------
void MultitouchDevice::updateController()
{
if (m_player == NULL)
{
m_controller = NULL;
return;
}
// Handle multitouch events only when race is running. It avoids to process
// it when pause dialog is active during the race. And there is no reason
// to use it for GUI navigation.
@ -335,60 +425,20 @@ void MultitouchDevice::handleControls(MultitouchButton* button)
GUIEngine::ModalDialog::isADialogActive() ||
GUIEngine::ScreenKeyboard::isActive() ||
race_manager->isWatchingReplay())
{
m_controller = NULL;
return;
}
AbstractKart* pk = m_player->getKart();
if (pk == NULL)
return;
Controller* controller = pk->getController();
if (controller == NULL)
return;
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
if (button->axis_y < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_y));
controller->action(PA_ACCEL, int(factor * Input::MAX_VALUE));
}
else if (button->axis_y > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_y));
controller->action(PA_BRAKE, int(factor * Input::MAX_VALUE));
}
else
{
controller->action(PA_BRAKE, 0);
controller->action(PA_ACCEL, 0);
}
m_controller = NULL;
return;
}
if (button->axis_x < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_x));
controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
}
else if (button->axis_x > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_x));
controller->action(PA_STEER_RIGHT, int(factor * Input::MAX_VALUE));
}
else
{
controller->action(PA_STEER_LEFT, 0);
controller->action(PA_STEER_RIGHT, 0);
}
}
else
{
if (button->action != PA_BEFORE_FIRST)
{
int value = button->pressed ? Input::MAX_VALUE : 0;
controller->action(button->action, value);
}
}
} // handleControls
m_controller = pk->getController();
}
// ----------------------------------------------------------------------------

View File

@ -34,6 +34,7 @@
enum MultitouchButtonType
{
BUTTON_STEERING,
BUTTON_UP_DOWN,
BUTTON_FIRE,
BUTTON_NITRO,
BUTTON_SKIDDING,
@ -68,12 +69,16 @@ struct MultitouchButton
float axis_y;
};
class Controller;
class MultitouchDevice : public InputDevice
{
private:
/** The list of pointers to all created buttons */
std::vector<MultitouchButton*> m_buttons;
Controller* m_controller;
/** The parameter that is used for steering button and determines dead area
* in a center of button */
float m_deadzone_center;
@ -82,16 +87,13 @@ private:
* at the edge of button */
float m_deadzone_edge;
/** True if accelerometer is in use */
bool m_accelerometer_active;
#ifdef ANDROID
/** Pointer to the Android irrlicht device */
CIrrDeviceAndroid* m_android_device;
#endif
float getSteeringFactor(float value);
void updateButtonAxes(MultitouchButton* button, float x, float y);
void handleControls(MultitouchButton* button);
public:
/** The array that contains data for all multitouch input events */
@ -119,12 +121,14 @@ public:
/** Returns pointer to the selected button */
MultitouchButton* getButton(unsigned int i) {return m_buttons.at(i);}
/** True if accelerometer is in use */
bool isAccelerometerActive() {return m_accelerometer_active;}
void activateAccelerometer();
void deactivateAccelerometer();
bool isAccelerometerActive();
void updateAxisX(float value);
void updateAxisY(float value);
void updateDeviceState(unsigned int event_id);
void handleControls(MultitouchButton* button);
void updateController();
void updateConfigParams();
}; // MultitouchDevice

View File

@ -89,6 +89,12 @@ void AssetsAndroid::init()
{
Log::info("AssetsAndroid", "Check data files in: %s", path.c_str());
if (!isWritable(path))
{
Log::info("AssetsAndroid", "Path doesn't have write access.");
continue;
}
if (m_file_manager->fileExists(path + "/" + app_dir_name + "/data/" + version))
{
m_stk_dir = path + "/" + app_dir_name;
@ -114,6 +120,12 @@ void AssetsAndroid::init()
Log::info("AssetsAndroid", "Check data files for different STK "
"version in: %s", path.c_str());
if (!isWritable(path))
{
Log::info("AssetsAndroid", "Path doesn't have write access.");
continue;
}
if (m_file_manager->fileExists(path + "/" + app_dir_name + "/.extracted"))
{
m_stk_dir = path + "/" + app_dir_name;
@ -498,6 +510,20 @@ void AssetsAndroid::touchFile(std::string path)
#endif
}
//-----------------------------------------------------------------------------
/** Checks if there is write access for selected path
* \param path A path that should be checked
* \return True if there is write access
*/
bool AssetsAndroid::isWritable(std::string path)
{
#ifdef ANDROID
return access(path.c_str(), R_OK) == 0 && access(path.c_str(), W_OK) == 0;
#endif
return false;
}
//-----------------------------------------------------------------------------
/** Determines best path for extracting assets, depending on available disk
* space.
@ -520,6 +546,9 @@ std::string AssetsAndroid::getPreferredPath(const std::vector<std::string>&
if (path.find("/data") == 0)
continue;
if (!isWritable(path))
continue;
struct statfs stat;
if (statfs(path.c_str(), &stat) != 0)

View File

@ -34,6 +34,7 @@ private:
bool extractDir(std::string dir_name);
void removeData();
void touchFile(std::string path);
bool isWritable(std::string path);
std::string getPreferredPath(const std::vector<std::string>& paths);
public:

View File

@ -257,7 +257,7 @@ void Powerup::use()
case PowerupManager::POWERUP_RUBBERBALL:
case PowerupManager::POWERUP_BOWLING:
case PowerupManager::POWERUP_PLUNGER:
if(stk_config->m_shield_restrict_weapos)
if(stk_config->m_shield_restrict_weapons)
m_kart->setShieldTime(0.0f); // make weapon usage destroy the shield
Powerup::adjustSound();
m_sound_use->play();

View File

@ -168,3 +168,32 @@ bool ProjectileManager::projectileIsClose(const AbstractKart * const kart,
}
return false;
} // projectileIsClose
// -----------------------------------------------------------------------------
/** Returns an int containing the numbers of a given flyable in a given radius
* around the kart
* \param kart The kart for which the test is done.
* \param radius Distance within which the projectile must be.
* \param type The type of projectile checked
*/
int ProjectileManager::getNearbyProjectileCount(const AbstractKart * const kart,
float radius, PowerupManager::PowerupType type)
{
float r2 = radius*radius;
int projectileCount = 0;
for(Projectiles::iterator i = m_active_projectiles.begin();
i != m_active_projectiles.end(); i++)
{
if ((*i)->getType() == type)
{
float dist2 = (*i)->getXYZ().distance2(kart->getXYZ());
if(dist2<r2)
{
projectileCount++;
}
}
}
return projectileCount;
} // getNearbyProjectileCount

View File

@ -66,6 +66,9 @@ public:
void removeTextures ();
bool projectileIsClose(const AbstractKart * const kart,
float radius);
int getNearbyProjectileCount(const AbstractKart * const kart,
float radius, PowerupManager::PowerupType type);
// ------------------------------------------------------------------------
/** Adds a special hit effect to be shown.
* \param hit_effect The hit effect to be added. */

View File

@ -643,8 +643,8 @@ void RubberBall::updateDistanceToTarget()
const LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
float target_distance =
world->getDistanceDownTrackForKart(m_target->getWorldKartId());
float ball_distance = getDistanceFromStart();
world->getDistanceDownTrackForKart(m_target->getWorldKartId(), true);
float ball_distance = getDistanceFromStart(true);
m_distance_to_target = target_distance - ball_distance;
if(m_distance_to_target < 0)

View File

@ -213,15 +213,19 @@ AbstractCharacteristic::ValueType AbstractCharacteristic::getType(
return TYPE_FLOAT;
case NITRO_MAX:
return TYPE_FLOAT;
case SLIPSTREAM_DURATION:
case SLIPSTREAM_DURATION_FACTOR:
return TYPE_FLOAT;
case SLIPSTREAM_BASE_SPEED:
return TYPE_FLOAT;
case SLIPSTREAM_LENGTH:
return TYPE_FLOAT;
case SLIPSTREAM_WIDTH:
return TYPE_FLOAT;
case SLIPSTREAM_COLLECT_TIME:
case SLIPSTREAM_INNER_FACTOR:
return TYPE_FLOAT;
case SLIPSTREAM_USE_TIME:
case SLIPSTREAM_MIN_COLLECT_TIME:
return TYPE_FLOAT;
case SLIPSTREAM_MAX_COLLECT_TIME:
return TYPE_FLOAT;
case SLIPSTREAM_ADD_POWER:
return TYPE_FLOAT;
@ -445,16 +449,20 @@ std::string AbstractCharacteristic::getName(CharacteristicType type)
return "NITRO_FADE_OUT_TIME";
case NITRO_MAX:
return "NITRO_MAX";
case SLIPSTREAM_DURATION:
return "SLIPSTREAM_DURATION";
case SLIPSTREAM_DURATION_FACTOR:
return "SLIPSTREAM_DURATION_FACTOR";
case SLIPSTREAM_BASE_SPEED:
return "SLIPSTREAM_BASE_SPEED";
case SLIPSTREAM_LENGTH:
return "SLIPSTREAM_LENGTH";
case SLIPSTREAM_WIDTH:
return "SLIPSTREAM_WIDTH";
case SLIPSTREAM_COLLECT_TIME:
return "SLIPSTREAM_COLLECT_TIME";
case SLIPSTREAM_USE_TIME:
return "SLIPSTREAM_USE_TIME";
case SLIPSTREAM_INNER_FACTOR:
return "SLIPSTREAM_INNER_FACTOR";
case SLIPSTREAM_MIN_COLLECT_TIME:
return "SLIPSTREAM_MIN_COLLECT_TIME";
case SLIPSTREAM_MAX_COLLECT_TIME:
return "SLIPSTREAM_MAX_COLLECT_TIME";
case SLIPSTREAM_ADD_POWER:
return "SLIPSTREAM_ADD_POWER";
case SLIPSTREAM_MIN_SPEED:
@ -1460,16 +1468,28 @@ float AbstractCharacteristic::getNitroMax() const
} // getNitroMax
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamDuration() const
float AbstractCharacteristic::getSlipstreamDurationFactor() const
{
float result;
bool is_set = false;
process(SLIPSTREAM_DURATION, &result, &is_set);
process(SLIPSTREAM_DURATION_FACTOR, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName(SLIPSTREAM_DURATION).c_str());
getName(SLIPSTREAM_DURATION_FACTOR).c_str());
return result;
} // getSlipstreamDuration
} // getSlipstreamDurationFactor
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamBaseSpeed() const
{
float result;
bool is_set = false;
process(SLIPSTREAM_BASE_SPEED, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName(SLIPSTREAM_BASE_SPEED).c_str());
return result;
} // getSlipstreamBaseSpeed
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamLength() const
@ -1496,28 +1516,40 @@ float AbstractCharacteristic::getSlipstreamWidth() const
} // getSlipstreamWidth
// ----------------------------------------------------------------------------
int AbstractCharacteristic::getSlipstreamCollectTicks() const
float AbstractCharacteristic::getSlipstreamInnerFactor() const
{
float result;
bool is_set = false;
process(SLIPSTREAM_COLLECT_TIME, &result, &is_set);
process(SLIPSTREAM_INNER_FACTOR, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName(SLIPSTREAM_COLLECT_TIME).c_str());
return stk_config->time2Ticks(result);
} // getSlipstreamCollectTicks
getName(SLIPSTREAM_INNER_FACTOR).c_str());
return result;
} // getSlipstreamInnerFactor
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamUseTime() const
float AbstractCharacteristic::getSlipstreamMinCollectTime() const
{
float result;
bool is_set = false;
process(SLIPSTREAM_USE_TIME, &result, &is_set);
process(SLIPSTREAM_MIN_COLLECT_TIME, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName(SLIPSTREAM_USE_TIME).c_str());
getName(SLIPSTREAM_MIN_COLLECT_TIME).c_str());
return result;
} // getSlipstreamUseTime
} // getSlipstreamMinCollectTime
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamMaxCollectTime() const
{
float result;
bool is_set = false;
process(SLIPSTREAM_MAX_COLLECT_TIME, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s",
getName(SLIPSTREAM_MAX_COLLECT_TIME).c_str());
return result;
} // getSlipstreamMaxCollecTime
// ----------------------------------------------------------------------------
float AbstractCharacteristic::getSlipstreamAddPower() const
@ -1785,4 +1817,3 @@ bool AbstractCharacteristic::getSkidEnabled() const
/* <characteristics-end acgetter> */

View File

@ -193,11 +193,13 @@ public:
NITRO_MAX,
// Slipstream
SLIPSTREAM_DURATION,
SLIPSTREAM_DURATION_FACTOR,
SLIPSTREAM_BASE_SPEED,
SLIPSTREAM_LENGTH,
SLIPSTREAM_WIDTH,
SLIPSTREAM_COLLECT_TIME,
SLIPSTREAM_USE_TIME,
SLIPSTREAM_INNER_FACTOR,
SLIPSTREAM_MIN_COLLECT_TIME,
SLIPSTREAM_MAX_COLLECT_TIME,
SLIPSTREAM_ADD_POWER,
SLIPSTREAM_MIN_SPEED,
SLIPSTREAM_MAX_SPEED_INCREASE,
@ -359,11 +361,13 @@ public:
float getNitroFadeOutTime() const;
float getNitroMax() const;
float getSlipstreamDuration() const;
float getSlipstreamDurationFactor() const;
float getSlipstreamBaseSpeed() const;
float getSlipstreamLength() const;
float getSlipstreamWidth() const;
int getSlipstreamCollectTicks() const;
float getSlipstreamUseTime() const;
float getSlipstreamInnerFactor() const;
float getSlipstreamMinCollectTime() const;
float getSlipstreamMaxCollectTime() const;
float getSlipstreamAddPower() const;
float getSlipstreamMinSpeed() const;
float getSlipstreamMaxSpeedIncrease() const;
@ -392,4 +396,3 @@ public:
};
#endif

View File

@ -282,11 +282,23 @@ public:
virtual float getCurrentMaxSpeed() const = 0;
// ------------------------------------------------------------------------
/** Returns how much increased speed time is left over in the given
* category. Not pure abstract, since there is no need to implement this
* e.g. in Ghost.
* category.
* \param category Which category to report on. */
virtual int getSpeedIncreaseTicksLeft(unsigned int category) const = 0;
// ------------------------------------------------------------------------
/** Sets the kart AI boost state.
* Not pure abstract, since there is no need to implement this e.g. in Ghost.
* \param boosted True if a boost should be applied. */
virtual void setBoostAI(bool boosted) = 0;
// ------------------------------------------------------------------------
/** Returns the kart AI boost state.
* Not pure abstract, since there is no need to implement this e.g. in Ghost. */
virtual bool getBoostAI() const = 0;
// ------------------------------------------------------------------------
/** Sets an increased maximum speed for a category.
* \param category The category for which to set the higher maximum speed.
* \param add_speed How much speed (in m/s) is added to the maximum speed.
@ -295,8 +307,25 @@ public:
* \param fade_out_time How long the maximum speed will fade out linearly.
*/
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
float engine_force, int duration,
int fade_out_time) = 0;
float engine_force, float duration,
float fade_out_time) = 0;
// ----------------------------------------------------------------------------
/** This adjusts the top speed using increaseMaxSpeed, but additionally
* causes an instant speed boost, which can be smaller than add-max-speed.
* (e.g. a zipper can give an instant boost of 5 m/s, but over time would
* allow the speed to go up by 10 m/s).
* \param category The category for which the speed is increased.
* \param add_max_speed Increase of the maximum allowed speed.
* \param speed_boost An instant speed increase for this kart.
* \param engine_force Additional engine force.
* \param duration Duration of the increased speed.
* \param fade_out_time How long the maximum speed will fade out linearly.
*/
virtual void instantSpeedIncrease(unsigned int category, float add_max_speed,
float speed_boost, float engine_force, float duration,
float fade_out_time) = 0;
// ------------------------------------------------------------------------
/** Defines a slowdown, which is in fraction of top speed.
* \param category The category for which the speed is increased.
@ -379,6 +408,9 @@ public:
/** Returns the current powerup. */
virtual Powerup *getPowerup() = 0;
// ------------------------------------------------------------------------
/** Returns the last used powerup type. */
virtual PowerupManager::PowerupType getLastUsedPowerup() = 0;
// ------------------------------------------------------------------------
/** Returns a points to this kart's graphical effects. */
virtual KartGFX* getKartGFX() = 0;
// ------------------------------------------------------------------------
@ -443,6 +475,12 @@ public:
* defined even if the kart is flying. */
virtual const Vec3& getNormal() const = 0;
// ------------------------------------------------------------------------
/** Returns the position 0.25s before */
virtual const Vec3& getPreviousXYZ() const = 0;
// ------------------------------------------------------------------------
/** Returns the most recent different previous position */
virtual const Vec3& getRecentPreviousXYZ() const = 0;
// ------------------------------------------------------------------------
/** Returns the height of the terrain. we're currently above */
virtual float getHoT() const = 0;
// ------------------------------------------------------------------------
@ -474,4 +512,3 @@ public:
#endif
/* EOF */

View File

@ -43,9 +43,9 @@ AIProperties::AIProperties(RaceManager::Difficulty difficulty)
m_make_use_of_slipstream = false;
m_collect_avoid_items = false;
m_handle_bomb = false;
m_item_usage_non_random = false;
m_item_usage_skill = 0;
m_disable_slipstream_usage = false;
m_nitro_usage = NITRO_NONE;
m_nitro_usage = 0;
} // AIProperties
@ -65,7 +65,7 @@ void AIProperties::load(const XMLNode *ai_node)
ai_node->get("straight-length-for-zipper",&m_straight_length_for_zipper);
ai_node->get("rb-skid-probability", &m_skid_probability );
ai_node->get("speed-cap", &m_speed_cap );
ai_node->get("non-random-item-usage", &m_item_usage_non_random );
ai_node->get("item-skill", &m_item_usage_skill );
ai_node->get("collect-avoid-items", &m_collect_avoid_items );
ai_node->get("handle-bomb", &m_handle_bomb );
ai_node->get("skidding-threshold", &m_skidding_threshold );
@ -73,21 +73,8 @@ void AIProperties::load(const XMLNode *ai_node)
ai_node->get("false-start-probability", &m_false_start_probability );
ai_node->get("min-start-delay", &m_min_start_delay );
ai_node->get("max-start-delay", &m_max_start_delay );
ai_node->get("nitro-usage", &m_nitro_usage );
std::string s;
ai_node->get("nitro-usage", &s);
if(s=="none")
m_nitro_usage = NITRO_NONE;
else if(s=="some")
m_nitro_usage = NITRO_SOME;
else if(s=="all")
m_nitro_usage = NITRO_ALL;
else
{
Log::fatal("AIProperties",
"Incorrect nitro-usage '%s' in AI '%s'.",s.c_str(),
m_ident.c_str());
}
// We actually need the square of the distance later
m_bad_item_closeness_2 *= m_bad_item_closeness_2;

View File

@ -111,11 +111,15 @@ protected:
/** If the AI should actively try to pass on a bomb. */
bool m_handle_bomb;
/** True if items should be used better (i.e. non random). */
bool m_item_usage_non_random;
/** Determines the strategies used by the AI for items. 0 is no use,
1 is random use ; 2 to 5 use varying tactics, with 2 having the worst
and 5 the best. */
int m_item_usage_skill;
/** How the AI uses nitro. */
enum {NITRO_NONE, NITRO_SOME, NITRO_ALL} m_nitro_usage;
/** How the AI uses nitro. 0 correspond to no use ; 1 to immediate use
2 to 4 to various levels of mastery (the AI tries to accumulate a reserve
and to use bursts whose size/spacing varies according to the level). */
int m_nitro_usage;
/** TODO: ONLY USE FOR OLD SKIDDING! CAN BE REMOVED once the new skidding
* works as expected.

View File

@ -319,38 +319,41 @@ void SkiddingAI::update(int ticks)
// of us.
bool commands_set = false;
if(m_ai_properties->m_handle_bomb &&
m_kart->getAttachment()->getType()==Attachment::ATTACH_BOMB &&
m_kart_ahead )
m_kart->getAttachment()->getType()==Attachment::ATTACH_BOMB)
{
// Use nitro if the kart is far ahead, or faster than this kart
m_controls->setNitro(m_distance_ahead>10.0f ||
m_kart_ahead->getSpeed() > m_kart->getSpeed());
// If we are close enough, try to hit this kart
if(m_distance_ahead<=10)
{
Vec3 target = m_kart_ahead->getXYZ();
//TODO : add logic to allow an AI kart to pass the bomb to a kart
// close behind by slowing/steering slightly
if ( m_kart_ahead != m_kart->getAttachment()->getPreviousOwner())
{
// Use nitro if the kart is far ahead, or faster than this kart
handleNitroAndZipper();
// If we are faster, try to predict the point where we will hit
// the other kart
if((m_kart_ahead->getSpeed() < m_kart->getSpeed()) &&
!m_kart_ahead->isGhostKart())
{
float time_till_hit = m_distance_ahead
/ (m_kart->getSpeed()-m_kart_ahead->getSpeed());
target += m_kart_ahead->getVelocity()*time_till_hit;
}
float steer_angle = steerToPoint(target);
setSteering(steer_angle, dt);
commands_set = true;
}
handleRescue(dt);
// If we are close enough, try to hit this kart
if(m_distance_ahead<=10)
{
Vec3 target = m_kart_ahead->getXYZ();
// If we are faster, try to predict the point where we will hit
// the other kart
if((m_kart_ahead->getSpeed() < m_kart->getSpeed()) &&
!m_kart_ahead->isGhostKart())
{
float time_till_hit = m_distance_ahead
/ (m_kart->getSpeed()-m_kart_ahead->getSpeed());
target += m_kart_ahead->getVelocity()*time_till_hit;
}
float steer_angle = steerToPoint(target);
setSteering(steer_angle, dt);
commands_set = true;
}
handleRescue(dt);
}
}
if(!commands_set)
{
/*Response handling functions*/
handleAcceleration(ticks);
handleSteering(dt);
handleItems(dt);
handleRescue(dt);
handleBraking();
// If a bomb is attached, nitro might already be set.
@ -490,6 +493,8 @@ void SkiddingAI::handleSteering(float dt)
}
//If we are going to crash against a kart, avoid it if it doesn't
//drives the kart out of the road
//TODO : adds item handling to use a cake if available to
//open the road
else if( m_crashes.m_kart != -1 && !m_crashes.m_road )
{
//-1 = left, 1 = right, 0 = no crash.
@ -551,6 +556,9 @@ void SkiddingAI::handleSteering(float dt)
m_curve[CURVE_AIM]->addPoint(aim_point);
#endif
//Manage item utilisation
handleItems(dt, &aim_point, last_node);
// Potentially adjust the point to aim for in order to either
// aim to collect item, or steer to avoid a bad item.
if(m_ai_properties->m_collect_avoid_items)
@ -1133,16 +1141,19 @@ void SkiddingAI::evaluateItems(const Item *item, Vec3 kart_aim_direction,
//-----------------------------------------------------------------------------
/** Handle all items depending on the chosen strategy.
* Either (low level AI) just use an item after 10 seconds, or do a much
* better job on higher level AI - e.g. aiming at karts ahead/behind, wait an
* appropriate time before using multiple items etc.
* Level 0 "AI" : do nothing (not used by default)
* Level 1 "AI" : use items after a random time
* Level 2 to 5 AI : strategy detailed before each item
* Each successive level is overall stronger (5 the strongest, 2 the weakest of
* non-random strategies), but two levels may share a strategy for a given item.
* (level 5 is not yet used ; meant for SuperTux GP preferred karts or boss races)
* \param dt Time step size.
* TODO: Implications of Bubble-Shield for AI's powerup-handling
* STATE: shield on -> avoid usage of offensive items (with certain tolerance)
* STATE: swatter on -> avoid usage of shield
*/
void SkiddingAI::handleItems(const float dt)
void SkiddingAI::handleItems(const float dt, const Vec3 *aim_point, int last_node)
{
m_controls->setFire(false);
if(m_kart->getKartAnimation() ||
@ -1151,6 +1162,14 @@ void SkiddingAI::handleItems(const float dt)
m_time_since_last_shot += dt;
//time since last shot is meant to avoid using the same item
//several times in rapid succession ; not to wait to use a useful
//collected item
if ( m_kart->getPowerup()->getType() != m_kart->getLastUsedPowerup() )
{
m_time_since_last_shot = 50.0f; //The AI may wait if the value is low, so set a high value
}
if (m_superpower == RaceManager::SUPERPOWER_NOLOK_BOSS)
{
m_controls->setLookBack(m_kart->getPowerup()->getType() ==
@ -1174,11 +1193,40 @@ void SkiddingAI::handleItems(const float dt)
return;
}
// Tactic 1: wait ten seconds, then use item
int ai_skill = 0;
if (m_ai_properties->m_item_usage_skill > 0)
{
if (m_ai_properties->m_item_usage_skill > 5)
{
ai_skill = 5;
}
else
{
ai_skill = m_ai_properties->m_item_usage_skill;
}
}
if (m_kart->getBoostAI() == true && ai_skill < 5)
{
ai_skill++; //possible improvement : make the boost amplitude pulled from config
}
// Tactic 0: don't use item
// -----------------------------------------
if(!m_ai_properties->m_item_usage_non_random)
if(ai_skill == 0)
{
if( m_time_since_last_shot > 10.0f )
return;
}
// Tactic 1: wait between 5 and 10 seconds, then use item
// ------------------------------------------------------
if(ai_skill == 1)
{
int random_t = 0;
random_t = m_random_skid.get(6); //Reuse the random skid generator
random_t = random_t + 5;
if( m_time_since_last_shot > random_t )
{
m_controls->setFire(true);
m_time_since_last_shot = 0.0f;
@ -1186,67 +1234,206 @@ void SkiddingAI::handleItems(const float dt)
return;
}
// Tactic 2: calculate
// -------------------
// Tactics 2 to 5: calculate
// -----------------------------------------
float min_bubble_time = 2.0f;
int projectile_types[4]; //[3] basket, [2] cakes, [1] plunger, [0] bowling
projectile_types[0] = projectile_manager->getNearbyProjectileCount(m_kart,
m_ai_properties->m_shield_incoming_radius, PowerupManager::POWERUP_BOWLING);
projectile_types[1] = projectile_manager->getNearbyProjectileCount(m_kart,
m_ai_properties->m_shield_incoming_radius, PowerupManager::POWERUP_PLUNGER);
projectile_types[2] = projectile_manager->getNearbyProjectileCount(m_kart,
m_ai_properties->m_shield_incoming_radius, PowerupManager::POWERUP_CAKE);
projectile_types[3] = projectile_manager->getNearbyProjectileCount(m_kart,
m_ai_properties->m_shield_incoming_radius, PowerupManager::POWERUP_RUBBERBALL);
bool projectile_is_close = false;
float shield_radius = m_ai_properties->m_shield_incoming_radius;
if (m_kart->getBoostAI() == true)
{
if (shield_radius == 0)
{
shield_radius = 15;
}
else if (shield_radius >= 3)
{
shield_radius = shield_radius - 2;
}
}
projectile_is_close = projectile_manager->projectileIsClose(m_kart, shield_radius);
// Preparing item list for item aware actions
// Angle to aim_point
Vec3 kart_aim_direction = *aim_point - m_kart->getXYZ();
// Make sure we have a valid last_node
if(last_node==Graph::UNKNOWN_SECTOR)
last_node = m_next_node_index[m_track_node];
int node = m_track_node;
float distance = 0;
std::vector<const Item *> items_to_collect;
std::vector<const Item *> items_to_avoid;
// 1) Filter and sort all items close by
// -------------------------------------
const float max_item_lookahead_distance = 20.0f;
while(distance < max_item_lookahead_distance)
{
int n_index= DriveGraph::get()->getNode(node)->getIndex();
const std::vector<Item *> &items_ahead =
ItemManager::get()->getItemsInQuads(n_index);
for(unsigned int i=0; i<items_ahead.size(); i++)
{
evaluateItems(items_ahead[i], kart_aim_direction,
&items_to_avoid, &items_to_collect);
} // for i<items_ahead;
distance += DriveGraph::get()->getDistanceToNext(node,
m_successor_index[node]);
node = m_next_node_index[node];
// Stop when we have reached the last quad
if(node==last_node) break;
} // while (distance < max_item_lookahead_distance)
//items_to_avoid and items_to_collect now contain the closest item information needed after
//What matters is (a) if the lists are void ; (b) if they are not, what kind of item it is
switch( m_kart->getPowerup()->getType() )
{
// Level 2 : Use the shield immediately after a wait time
// Level 3 : Use the shield against flyables except cakes. Use the shield against bad attachments.
// Use the bubble gum against an enemy close behind, except if holding a swatter.
// Level 4 : Level 3, and protect against cakes too, and use before hitting gum/banana
// Level 5 : Level 4, and use before hitting item box, and let plunger hit
// (can use the shield after)
case PowerupManager::POWERUP_BUBBLEGUM:
{
Attachment::AttachmentType type = m_kart->getAttachment()->getType();
// Don't use shield when we have a swatter.
if( type == Attachment::ATTACH_SWATTER)
break;
Attachment::AttachmentType type = m_kart->getAttachment()->getType();
// Check if a flyable (cake, ...) is close. If so, use bubblegum
// as shield
if( !m_kart->isShielded() &&
projectile_manager->projectileIsClose(m_kart,
m_ai_properties->m_shield_incoming_radius) )
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
if((ai_skill == 2) && (m_time_since_last_shot > 2.0f))
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
// Avoid dropping all bubble gums one after another
if( m_time_since_last_shot < 3.0f) break;
// Check if a flyable (cake, ...) is close. If so, use bubblegum
// as shield
if(ai_skill == 3) //don't protect against cakes
{
if( !m_kart->isShielded() && projectile_is_close
&& projectile_types[2] == 0)
{
//don't discard swatter against plunger
if( projectile_types[1] == 0
|| (projectile_types[1] >= 1 && type != Attachment::ATTACH_SWATTER))
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
}
}
else if(ai_skill == 4)
{
if( !m_kart->isShielded() && projectile_is_close)
{
//don't discard swatter against plunger
if( projectile_types[1] == 0
|| (projectile_types[1] >= 1 && type != Attachment::ATTACH_SWATTER))
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
}
}
else if (ai_skill == 5) //don't protect against plungers alone TODO : activate after plunger hit
{
if( !m_kart->isShielded() && projectile_is_close)
{
if (projectile_types[0] >=1 || projectile_types[2] >=1 || projectile_types[3] >=1 )
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
}
}
// Use bubblegum if the next kart behind is 'close' but not too close
// (too close likely means that the kart is not behind but more to the
// side of this kart and so won't be hit by the bubble gum anyway).
// Should we check the speed of the kart as well? I.e. only drop if
// the kart behind is faster? Otoh this approach helps preventing an
// overtaken kart to overtake us again.
if(m_distance_behind < 15.0f && m_distance_behind > 3.0f )
{
m_controls->setFire(true);
m_controls->setLookBack(true);
break;
}
// Use shield to remove bad attachments
if( type == Attachment::ATTACH_BOMB
|| type == Attachment::ATTACH_PARACHUTE
|| type == Attachment::ATTACH_ANVIL )
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
// If this kart is in its last lap, drop bubble gums at every
// opportunity, since this kart won't envounter them anymore.
LinearWorld *lin_world = dynamic_cast<LinearWorld*>(World::getWorld());
if(m_time_since_last_shot > 3.0f &&
lin_world &&
lin_world->getFinishedLapsOfKart(m_kart->getWorldKartId())
== race_manager->getNumLaps()-1)
{
m_controls->setFire(true);
m_controls->setLookBack(true);
break;
}
break; // POWERUP_BUBBLEGUM
}
// Use shield if kart is going to hit a bad item (banana or bubblegum)
if((ai_skill == 4) || (ai_skill == 5))
{
if( !m_kart->isShielded() && items_to_avoid.size()>0)
{
float d = (items_to_avoid[0]->getXYZ() - m_kart->getXYZ()).length2();
if ((ai_skill == 4 && d < 1.5f) || (ai_skill == 5 && d < 0.7f))
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
}
}
// Use shield if kart is going to hit an item box
if (ai_skill == 5)
{
if( !m_kart->isShielded() && items_to_collect.size()>0)
{
float d = (items_to_collect[0]->getXYZ() - m_kart->getXYZ()).length2();
if ((items_to_collect[0]->getType() == Item::ITEM_BONUS_BOX) && (d < 0.7f))
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
}
}
// Avoid dropping all bubble gums one after another
if( m_time_since_last_shot < 2.0f) break;
// Use bubblegum if the next kart behind is 'close' but not too close
// (too close likely means that the kart is not behind but more to the
// side of this kart and so won't be hit by the bubble gum anyway).
// Should we check the speed of the kart as well? I.e. only drop if
// the kart behind is faster? Otoh this approach helps preventing an
// overtaken kart to overtake us again.
if(m_distance_behind < 10.0f && m_distance_behind > 3.0f )
{
m_controls->setFire(true);
m_controls->setLookBack(true);
break;
}
break; // POWERUP_BUBBLEGUM
}
// Level 2 : Use the cake against any close enemy, with priority to those ahead
// Level 3 : Don't fire on slower karts
// Level 4 : Same as level 3 TODO : Fire if the kart has a swatter which may hit us
// Level 5 : Same as level 4 TODO : Don't fire on a shielded kart if we're just behind (gum)
case PowerupManager::POWERUP_CAKE:
{
// if the kart has a shield, do not break it by using a cake.
if(m_kart->getShieldTime() > min_bubble_time)
if((m_kart->getShieldTime() > min_bubble_time) && (stk_config->m_shield_restrict_weapons == true))
break;
// Leave some time between shots
if(m_time_since_last_shot<3.0f) break;
if(m_time_since_last_shot<2.0f) break;
// Do not fire if the kart is driving too slow
bool kart_behind_is_slow =
@ -1268,9 +1455,12 @@ void SkiddingAI::handleItems(const float dt)
// the kart anyway, or that this might force the kart ahead to
// use its nitro/zipper (and then we will shoot since then the
// kart is faster).
if ((fire_backwards && kart_behind_is_slow) ||
(!fire_backwards && kart_ahead_is_slow) )
break;
if(ai_skill >= 3)
{
if ((fire_backwards && kart_behind_is_slow) ||
(!fire_backwards && kart_ahead_is_slow) )
break;
}
// Don't fire if the kart we are aiming at is invulnerable.
if ((fire_backwards && m_kart_behind && m_kart_behind->isInvulnerable()) ||
@ -1288,15 +1478,20 @@ void SkiddingAI::handleItems(const float dt)
break;
} // POWERUP_CAKE
// Level 2 : Use the bowling ball against enemies with a 5 second delay
// Level 3 : Only 3 seconds of delay
// Level 4 : Same as level 3
// Level 5 : Same as level 4
case PowerupManager::POWERUP_BOWLING:
{
// if the kart has a shield, do not break it by using a bowling ball.
if(m_kart->getShieldTime() > min_bubble_time)
if((m_kart->getShieldTime() > min_bubble_time) && (stk_config->m_shield_restrict_weapons == true))
break;
// Leave more time between bowling balls, since they are
// slower, so it should take longer to hit something which
// can result in changing our target.
if(m_time_since_last_shot < 5.0f) break;
if(ai_skill == 2 && m_time_since_last_shot < 5.0f) break;
if(ai_skill >= 3 && m_time_since_last_shot < 3.0f) break;
// Consider angle towards karts
bool straight_behind = false;
bool straight_ahead = false;
@ -1348,7 +1543,7 @@ void SkiddingAI::handleItems(const float dt)
case PowerupManager::POWERUP_PLUNGER:
{
// if the kart has a shield, do not break it by using a plunger.
if(m_kart->getShieldTime() > min_bubble_time)
if((m_kart->getShieldTime() > min_bubble_time) && (stk_config->m_shield_restrict_weapons == true))
break;
// Leave more time after a plunger, since it will take some
@ -1369,15 +1564,131 @@ void SkiddingAI::handleItems(const float dt)
break;
} // POWERUP_PLUNGER
// Level 2 : Use the switch after a wait time
// Level 3 : Same as level 2 but don't fire if close to a good item
// Level 4 : Same as level 3 and fire if very close to a bad item
// Level 5 : Use if it makes a better item available, or if very close
// to a bad item. Don't use it if too close of a good item.
case PowerupManager::POWERUP_SWITCH:
// For now don't use a switch if this kart is first (since it's more
// likely that this kart then gets a good iteam), otherwise use it
// after a waiting an appropriate time
if(m_kart->getPosition()>1 &&
m_time_since_last_shot >
stk_config->ticks2Time(stk_config->m_item_switch_ticks)+2.0f)
m_controls->setFire(true);
break; // POWERUP_SWITCH
{
// It's extremely unlikely two switches are used close one after another
if(ai_skill == 2)
{
if (m_time_since_last_shot > 2.0f)
{
m_controls->setFire(true);
break;
}
}
else if((ai_skill == 3) || (ai_skill == 4))
{
if( (ai_skill == 4) && items_to_avoid.size() > 0)
{
float d = (items_to_avoid[0]->getXYZ() - m_kart->getXYZ()).length2();
if (d < 2.0f)
{
m_controls->setFire(true);
break;
}
}
else if (items_to_collect.size() > 0)
{
float d = (items_to_collect[0]->getXYZ() - m_kart->getXYZ()).length2();
if (d > 10.0f)
{
m_controls->setFire(true);
break;
}
}
else if (m_time_since_last_shot > 2.0f)
{
m_controls->setFire(true);
break;
}
}
//TODO : retrieve ranking powerup class and use it to evaluate the best item
// available depending of if the switch is used or not
// In the mean time big nitro > item box > small nitro
//TODO : make steering switch-aware so that the kart goes towards a bad item
// and use the switch at the last moment
//It would also be possible but complicated to check if using the switch will
//cause another kart not far from taking a bad item instead of a good one
//It should also be possible but complicated to discard items when a good
//and a bad one are two close from one another
else if(ai_skill == 5)
{
//First step : identify the best available item
int i;
int bad = 0;
int good = 0;
//Good will store 1 for nitro, big or small, 2 for item box
//Big nitro are usually hard to take for the AI
for(i=items_to_collect.size()-1; i>=0; i--)
{
if (items_to_collect[i]->getType() == Item::ITEM_BONUS_BOX)
{
good = 2;
i = -1;
}
else if ( (items_to_collect[i]->getType() == Item::ITEM_NITRO_BIG) ||
(items_to_collect[i]->getType() == Item::ITEM_NITRO_SMALL) )
{
good = 1;
}
}
//Bad will store 2 for bananas, 3 for bubble gum
for(i=items_to_avoid.size()-1; i>=0; i--)
{
if (items_to_avoid[i]->getType() == Item::ITEM_BUBBLEGUM)
{
bad = 3;
i = -1;
}
else if ( items_to_avoid[i]->getType() == Item::ITEM_BANANA )
{
bad = 2;
}
}
//Second step : make sure a close item don't make the choice pointless
if( items_to_avoid.size()>0)
{
float d = (items_to_avoid[0]->getXYZ() - m_kart->getXYZ()).length2();
//fire if very close to a bad item
if (d < 2.0f)
{
m_controls->setFire(true);
break;
}
}
if( items_to_collect.size()>0)
{
float d = (items_to_collect[0]->getXYZ() - m_kart->getXYZ()).length2();
//don't fire if close to a good item
if (d < 5.0f)
{
break;
}
}
//Third step : Use or don't use to get the best available item
if( bad > good)
{
m_controls->setFire(true);
break;
}
} //ai_skill == 5
break;
} // POWERUP_SWITCH
case PowerupManager::POWERUP_PARACHUTE:
// Wait one second more than a previous parachute
@ -1401,8 +1712,33 @@ void SkiddingAI::handleItems(const float dt)
}
break; // POWERUP_ANVIL
// Level 2 : Use the swatter immediately after a wait time
// Level 3 : Use the swatter when enemies are close
// Level 4 : Level 3 and use the swatter to remove bad attachments
// Level 5 : Same as level 4.
case PowerupManager::POWERUP_SWATTER:
{
Attachment::AttachmentType type = m_kart->getAttachment()->getType();
if((ai_skill == 2) && (m_time_since_last_shot > 2.0f))
{
m_controls->setFire(true);
break;
}
// Use swatter to remove bad attachments
if((ai_skill == 4) || (ai_skill == 5))
{
if( type == Attachment::ATTACH_BOMB
|| type == Attachment::ATTACH_PARACHUTE
|| type == Attachment::ATTACH_ANVIL )
{
m_controls->setFire(true);
m_controls->setLookBack(false);
break;
}
}
// Squared distance for which the swatter works
float d2 = m_kart->getKartProperties()->getSwatterDistance();
// if the kart has a shield, do not break it by using a swatter.
@ -1423,7 +1759,7 @@ void SkiddingAI::handleItems(const float dt)
}
case PowerupManager::POWERUP_RUBBERBALL:
// if the kart has a shield, do not break it by using a swatter.
if(m_kart->getShieldTime() > min_bubble_time)
if((m_kart->getShieldTime() > min_bubble_time) && (stk_config->m_shield_restrict_weapons == true))
break;
// Perhaps some more sophisticated algorithm might be useful.
// For now: fire if there is a kart ahead (which means that
@ -1585,107 +1921,236 @@ void SkiddingAI::handleRescue(const float dt)
} // handleRescue
//-----------------------------------------------------------------------------
/** Decides wether to use nitro or not.
/** Decides wether to use nitro and zipper or not.
*/
void SkiddingAI::handleNitroAndZipper()
{
m_controls->setNitro(false);
// If we are already very fast, save nitro.
if(m_kart->getSpeed() > 0.95f*m_kart->getCurrentMaxSpeed())
return;
// Don't use nitro when the AI has a plunger in the face!
if(m_kart->getBlockedByPlungerTicks()>0) return;
//Calculated here and not passed as parameter to not redo all the calls to the function
//May be better to change it
// Don't use nitro if we are braking
int ai_skill = 0;
if (m_ai_properties->m_item_usage_skill > 0)
{
if (m_ai_properties->m_item_usage_skill > 5)
{
ai_skill = 5;
}
else
{
ai_skill = m_ai_properties->m_item_usage_skill;
}
}
int nitro_skill = 0;
if (m_ai_properties->m_nitro_usage > 0)
{
if (m_ai_properties->m_nitro_usage > 4)
{
nitro_skill = 4;
}
else
{
nitro_skill = m_ai_properties->m_nitro_usage;
}
}
if (m_kart->getBoostAI() == true)
{
if (ai_skill < 5)
{
ai_skill = ai_skill + 1; //possible improvement : make the boost amplitude pulled from config
}
if (nitro_skill < 4)
{
nitro_skill = nitro_skill + 1; //possible improvement : make the boost amplitude pulled from config
}
}
if (m_kart->getPowerup()->getType()!=PowerupManager::POWERUP_ZIPPER)
{
ai_skill = 0; //don't try to use the zipper if there is none
}
//Nitro continue to be advantageous during the fadeout
int nitro_ticks = m_kart->getSpeedIncreaseTicksLeft(MaxSpeed::MS_INCREASE_NITRO);
float nitro_time = ( stk_config->ticks2Time(nitro_ticks)
+ m_kart->getKartProperties()->getNitroFadeOutTime() );
float nitro_max_time = m_kart->getKartProperties()->getNitroDuration()
+ m_kart->getKartProperties()->getNitroFadeOutTime();
//Nitro skill 0 : don't use
//Nitro skill 1 : don't use if the kart is braking, on the ground, has finished the race, has no nitro,
// has a parachute or an anvil attached, or has a plunger in the face.
// Otherwise, use it immediately
//Nitro skill 2 : Don't use nitro if there is more than 1,2 seconds of effect/fadeout left. Use it when at
// max speed or under 5 of speed (after rescue, etc.). Use it to pass bombs.
// Tries to builds a reserve of 4 energy to use towards the end
//Nitro skill 3 : Same as level 2, but don't use until 0.5 seconds of effect/fadeout left, and don't use close
// to bad items, and has a target reserve of 8 energy
//Nitro skill 4 : Same as level 3, but don't use until 0.05 seconds of effect/fadeout left and ignore the plunger
// and has a target reserve of 12 energy
m_controls->setNitro(false);
float energy_reserve = 0;
if (nitro_skill == 2)
{
energy_reserve = 4;
}
if (nitro_skill == 3)
{
energy_reserve = 8;
}
if (nitro_skill == 4)
{
energy_reserve = 12;
}
// Don't use nitro or zipper if we are braking
if(m_controls->getBrake()) return;
// Don't use nitro if the kart is not on ground or has finished the race
// Don't use nitro or zipper if the kart is not on ground or has finished the race
if(!m_kart->isOnGround() || m_kart->hasFinishedRace()) return;
// Don't compute nitro usage if we don't have nitro or are not supposed
// to use it, and we don't have a zipper or are not supposed to use
// it (calculated).
if( (m_kart->getEnergy()==0 ||
m_ai_properties->m_nitro_usage==AIProperties::NITRO_NONE) &&
(m_kart->getPowerup()->getType()!=PowerupManager::POWERUP_ZIPPER ||
!m_ai_properties->m_item_usage_non_random ) )
return;
// Don't use nitro or zipper when the AI has a plunger in the face!
if(m_kart->getBlockedByPlungerTicks()>0)
{
if ((nitro_skill < 4) && (ai_skill < 5))
{
return;
}
else if (nitro_skill < 4)
{
nitro_skill = 0;
}
else if (ai_skill < 5)
{
ai_skill = 0;
}
}
// If there are items to avoid close, and we only have zippers, don't
// use them (since this make it harder to avoid items).
if(m_avoid_item_close &&
(m_kart->getEnergy()==0 ||
m_ai_properties->m_nitro_usage==AIProperties::NITRO_NONE) )
return;
// If a parachute or anvil is attached, the nitro doesn't give much
// If a parachute or anvil is attached, the nitro and zipper don't give much
// benefit. Better wait till later.
const bool has_slowdown_attachment =
m_kart->getAttachment()->getType()==Attachment::ATTACH_PARACHUTE ||
m_kart->getAttachment()->getType()==Attachment::ATTACH_ANVIL;
if(has_slowdown_attachment) return;
// If the kart is very slow (e.g. after rescue), use nitro
if(m_kart->getSpeed()<5)
// Don't compute nitro usage if we don't have nitro
if( m_kart->getEnergy()==0 )
{
nitro_skill = 0;
}
// Don't use nitro if there is already a nitro boost active
// Nitro effect and fadeout varies between karts type from 2 to 4 seconds
// So vary time according to kart properties
if ((nitro_skill == 4) && nitro_time >= (nitro_max_time*0.01f) )
{
nitro_skill = 0;
}
else if ((nitro_skill == 3) && nitro_time >= (nitro_max_time*0.35f) )
{
nitro_skill = 0;
}
else if ((nitro_skill == 2) && nitro_time >= (nitro_max_time*0.5f) )
{
nitro_skill = 0;
}
// If there are items to avoid close
// Don't use zippers
// Dont use nitro if nitro_skill is 3 or 4
// (since going faster makes it harder to avoid items).
if(m_avoid_item_close && (m_kart->getEnergy()==0 || nitro_skill == 0 || nitro_skill >= 3) )
return;
// If basic AI, use nitro immediately
if (nitro_skill == 1)
{
m_controls->setNitro(true);
return;
}
// If this kart is the last kart, and we have enough
// (i.e. more than 2) nitro, use it.
// -------------------------------------------------
const unsigned int num_karts = m_world->getCurrentNumKarts();
if(m_kart->getPosition()== (int)num_karts &&
num_karts>1 && m_kart->getEnergy()>2.0f)
// Estimate time towards the end of the race.
// Decreases the reserve size when there is an estimate of time remaining
// to the end of less than 2,5 times the maximum nitro effect duration.
// This vary depending on kart characteristic.
// There is a margin because the kart will go a bit faster than predicted
// by the estimate, because the kart may collect more nitro and because
// there may be moments when it's not useful to use nitro (parachutes, etc).
if(nitro_skill >= 2 && energy_reserve > 0.0f)
{
m_controls->setNitro(true);
return;
}
float finish = m_world->getEstimatedFinishTime(m_kart->getWorldKartId()) - m_world->getTime();
float max_time_effect = nitro_max_time / m_kart->getKartProperties()->getNitroConsumption()
* m_kart->getEnergy()*2; //the minimum burst consumes around 0.5 energy
// On the last track shortly before the finishing line, use nitro
// anyway. Since the kart is faster with nitro, estimate a 50% time
// decrease (additionally some nitro will be saved when top speed
// is reached).
if(m_world->getLapForKart(m_kart->getWorldKartId())
==race_manager->getNumLaps()-1 &&
m_ai_properties->m_nitro_usage == AIProperties::NITRO_ALL)
{
float finish =
m_world->getEstimatedFinishTime(m_kart->getWorldKartId());
if( 1.5f*m_kart->getEnergy() >= finish - m_world->getTime() )
// The burster forces the AI to consume its reserve by series of 2 bursts
// Otherwise the bursting differences of the various nitro skill wouldn't matter here
// In short races, most AI nitro usage may be at the end with the reserve
float burster;
if ( nitro_time > 0)
{
m_controls->setNitro(true);
return;
burster = 2*nitro_max_time;
}
else
{
burster = 0;
}
if( (2.5f*max_time_effect) >= (finish - burster) )
{
// Absolute reduction to avoid small amount of unburned nitro at the end
energy_reserve = (finish - burster)/(2.5f*max_time_effect/m_kart->getEnergy()) - 0.5f ;
}
}
// A kart within this distance is considered to be overtaking (or to be
// overtaken).
const float overtake_distance = 10.0f;
// Try to overtake a kart that is close ahead, except
// when we are already much faster than that kart
// --------------------------------------------------
if(m_kart_ahead &&
m_distance_ahead < overtake_distance &&
m_kart_ahead->getSpeed()+5.0f > m_kart->getSpeed() )
// If trying to pass a bomb to a kart faster or far ahead, use nitro reserve
if(m_kart->getAttachment()->getType() == Attachment::ATTACH_BOMB
&& nitro_skill >= 2 && energy_reserve > 0.0f)
{
m_controls->setNitro(true);
return;
if (m_distance_ahead>10.0f || m_kart_ahead->getSpeed() > m_kart->getSpeed() )
{
energy_reserve = 0 ;
}
}
if(m_kart_behind &&
m_distance_behind < overtake_distance &&
m_kart_behind->getSpeed() > m_kart->getSpeed() )
// Don't use nitro if building an energy reserve
if (m_kart->getEnergy() <= energy_reserve)
{
// Only prevent overtaking on highest level
m_controls->setNitro(m_ai_properties->m_nitro_usage
== AIProperties::NITRO_ALL);
nitro_skill = 0;
}
// If the kart is very slow (e.g. after rescue), use nitro
if(nitro_skill > 0 && m_kart->getSpeed()<5 && m_kart->getSpeed()>2)
{
m_controls->setNitro(true);
return;
}
if(m_kart->getPowerup()->getType()==PowerupManager::POWERUP_ZIPPER &&
m_kart->getSpeed()>1.0f &&
// If kart is at max speed, use nitro
// This is to profit from the max speed increase
// And because it means there should be no slowing down from, e.g. plungers
if (nitro_skill > 0 && m_kart->getSpeed() > 0.99f*m_kart->getCurrentMaxSpeed() )
{
m_controls->setNitro(true);
return;
}
// If this kart is the last kart, and we have nitro, use it.
// -------------------------------------------------
const unsigned int num_karts = m_world->getCurrentNumKarts();
if(nitro_skill > 0 && m_kart->getPosition()== (int)num_karts &&
num_karts > 1 )
{
m_controls->setNitro(true);
return;
}
// Use zipper
if(ai_skill >= 2 && m_kart->getSpeed()>1.0f &&
m_kart->getSpeedIncreaseTicksLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0)
{
DriveNode::DirectionType dir;

View File

@ -242,7 +242,8 @@ private:
void handleRaceStart();
void handleAcceleration(int ticks);
void handleSteering(float dt);
void handleItems(const float dt);
void handleItems(const float dt, const Vec3 *aim_point,
int last_node);
void handleRescue(const float dt);
void handleBraking();
void handleNitroAndZipper();

View File

@ -1182,7 +1182,7 @@ void SkiddingAI::handleItems(const float dt)
// Tactic 1: wait ten seconds, then use item
// -----------------------------------------
if(!m_ai_properties->m_item_usage_non_random)
if(m_ai_properties->m_item_usage_skill <= 1)
{
if( m_time_since_last_shot > 10.0f )
{
@ -1655,16 +1655,16 @@ void SkiddingAI::handleNitroAndZipper()
// to use it, and we don't have a zipper or are not supposed to use
// it (calculated).
if( (m_kart->getEnergy()==0 ||
m_ai_properties->m_nitro_usage==AIProperties::NITRO_NONE) &&
m_ai_properties->m_nitro_usage == 0) &&
(m_kart->getPowerup()->getType()!=PowerupManager::POWERUP_ZIPPER ||
!m_ai_properties->m_item_usage_non_random ) )
m_ai_properties->m_item_usage_skill <= 1 ) )
return;
// If there are items to avoid close, and we only have zippers, don't
// use them (since this make it harder to avoid items).
if(m_avoid_item_close &&
(m_kart->getEnergy()==0 ||
m_ai_properties->m_nitro_usage==AIProperties::NITRO_NONE) )
m_ai_properties->m_nitro_usage == 0) )
return;
// If a parachute or anvil is attached, the nitro doesn't give much
// benefit. Better wait till later.
@ -1697,7 +1697,7 @@ void SkiddingAI::handleNitroAndZipper()
// is reached).
if(m_world->getLapForKart(m_kart->getWorldKartId())
==race_manager->getNumLaps()-1 &&
m_ai_properties->m_nitro_usage == AIProperties::NITRO_ALL)
m_ai_properties->m_nitro_usage >= 2)
{
float finish =
m_world->getEstimatedFinishTime(m_kart->getWorldKartId());
@ -1728,8 +1728,7 @@ void SkiddingAI::handleNitroAndZipper()
m_kart_behind->getSpeed() > m_kart->getSpeed() )
{
// Only prevent overtaking on highest level
m_controls->setNitro(m_ai_properties->m_nitro_usage
== AIProperties::NITRO_ALL);
m_controls->setNitro(m_ai_properties->m_nitro_usage >= 2 );
return;
}

View File

@ -117,6 +117,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_max_speed = new MaxSpeed(this);
m_terrain_info = new TerrainInfo();
m_powerup = new Powerup(this);
m_last_used_powerup = PowerupManager::POWERUP_NOTHING;
m_vehicle = NULL;
m_initial_position = position;
m_race_position = position;
@ -141,8 +142,18 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_is_jumping = false;
m_min_nitro_ticks = 0;
m_fire_clicked = 0;
m_boosted_ai = false;
m_type = RaceManager::KT_AI;
m_xyz_history_size = stk_config->time2Ticks(XYZ_HISTORY_TIME);
Vec3 initial_position = getXYZ();
for (int i=0;i<m_xyz_history_size;i++)
{
m_previous_xyz.push_back(initial_position);
}
m_time_previous_counter = 0.0f;
m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false;
@ -365,6 +376,12 @@ void Kart::reset()
m_has_caught_nolok_bubblegum = false;
m_is_jumping = false;
for (int i=0;i<m_xyz_history_size;i++)
{
m_previous_xyz[i] = getXYZ();
}
m_time_previous_counter = 0.0f;
// In case that the kart was in the air, in which case its
// linear damping is 0
if(m_body)
@ -442,18 +459,30 @@ void Kart::setXYZ(const Vec3& a)
// -----------------------------------------------------------------------------
void Kart::increaseMaxSpeed(unsigned int category, float add_speed,
float engine_force, int duration,
int fade_out_time)
float engine_force, float duration,
float fade_out_time)
{
m_max_speed->increaseMaxSpeed(category, add_speed, engine_force, duration,
fade_out_time);
m_max_speed->increaseMaxSpeed(category, add_speed, engine_force,
stk_config->time2Ticks(duration),
stk_config->time2Ticks(fade_out_time));
} // increaseMaxSpeed
// -----------------------------------------------------------------------------
void Kart::instantSpeedIncrease(unsigned int category, float add_max_speed,
float speed_boost, float engine_force, float duration,
float fade_out_time)
{
m_max_speed->instantSpeedIncrease(category, add_max_speed, speed_boost,
engine_force,
stk_config->time2Ticks(duration),
stk_config->time2Ticks(fade_out_time) );
} // instantSpeedIncrease
// -----------------------------------------------------------------------------
void Kart::setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time)
{
m_max_speed->setSlowdown(category, max_speed_fraction, fade_in_time);
m_max_speed->setSlowdown(category, max_speed_fraction, fade_in_time);
} // setSlowdown
// -----------------------------------------------------------------------------
@ -467,6 +496,17 @@ int Kart::getSpeedIncreaseTicksLeft(unsigned int category) const
return m_max_speed->getSpeedIncreaseTicksLeft(category);
} // getSpeedIncreaseTimeLeft
// -----------------------------------------------------------------------------
void Kart::setBoostAI(bool boosted)
{
m_boosted_ai = boosted;
} // setBoostAI
// -----------------------------------------------------------------------------
bool Kart::getBoostAI() const
{
return m_boosted_ai;
} // getBoostAI
// -----------------------------------------------------------------------------
/** Returns the current material the kart is on. */
const Material *Kart::getMaterial() const
@ -505,6 +545,15 @@ void Kart::setPowerup(PowerupManager::PowerupType t, int n)
m_powerup->set(t, n);
} // setPowerup
// ----------------------------------------------------------------------------
/** Sets the powerup this kart has last used. Number is always 1.
* \param t Type of the powerup.
*/
void Kart::setLastUsedPowerup(PowerupManager::PowerupType t)
{
m_last_used_powerup = t;
} // setLastUsedPowerup
// -----------------------------------------------------------------------------
int Kart::getNumPowerup() const
{
@ -1185,6 +1234,11 @@ void Kart::eliminate()
m_stars_effect->update(1);
}
if (m_attachment)
{
m_attachment->clear();
}
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_TERRAIN, 0);
m_kart_gfx->setGFXInvisible();
if (m_engine_sound)
@ -1256,6 +1310,18 @@ void Kart::update(int ticks)
{
m_kart_animation->update(dt);
}
m_time_previous_counter += dt;
while (m_time_previous_counter > stk_config->ticks2Time(1))
{
m_previous_xyz[0] = getXYZ();
for (int i=m_xyz_history_size-1;i>0;i--)
{
m_previous_xyz[i] = m_previous_xyz[i-1];
}
m_time_previous_counter -= stk_config->ticks2Time(1);
}
// Update the position and other data taken from the physics (or
// an animation which calls setXYZ(), which also updates the kart
// physical position).
@ -1356,6 +1422,10 @@ void Kart::update(int ticks)
if(m_controls.getFire() && !m_fire_clicked && !m_kart_animation)
{
if (m_powerup->getType() != PowerupManager::POWERUP_NOTHING)
{
setLastUsedPowerup(m_powerup->getType());
}
// use() needs to be called even if there currently is no collecteable
// since use() can test if something needs to be switched on/off.
m_powerup->use() ;
@ -1984,14 +2054,16 @@ void Kart::updateNitro(int ticks)
// when pressing the key, don't allow the min time to go under zero.
// If it went under zero, it would be reset
// As the time deduction happens before, it can be an arbitrarily
// small number > 0. Smaller means more responsive controls.
if (m_controls.getNitro() && m_min_nitro_ticks <= 0)
m_min_nitro_ticks = 1;
}
bool increase_speed = (m_controls.getNitro() && isOnGround());
bool increase_speed = (m_min_nitro_ticks > 0 && isOnGround());
if (!increase_speed && m_min_nitro_ticks <= 0)
{
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
if (m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
m_nitro_sound->stop();
return;
}
@ -2867,7 +2939,7 @@ void Kart::updateGraphics(float dt)
// --------------------------------------------------------
float nitro_frac = 0;
if ( (m_controls.getNitro() || m_min_nitro_ticks > 0) &&
isOnGround() && m_collected_energy > 0 )
m_collected_energy > 0 )
{
// fabs(speed) is important, otherwise the negative number will
// become a huge unsigned number in the particle scene node!
@ -3055,6 +3127,22 @@ const Vec3& Kart::getNormal() const
return m_terrain_info->getNormal();
} // getNormal
// ------------------------------------------------------------------------
/** Returns the position 0.25s before */
const Vec3& Kart::getPreviousXYZ() const
{
return m_previous_xyz[m_xyz_history_size-1];
} // getPreviousXYZ
// ------------------------------------------------------------------------
/** Returns a more recent different previous position */
const Vec3& Kart::getRecentPreviousXYZ() const
{
//Not the most recent, because the angle variations would be too
//irregular on some tracks whose roads are not smooth enough
return m_previous_xyz[m_xyz_history_size/5];
} // getRecentPreviousXYZ
// ------------------------------------------------------------------------
void Kart::playSound(SFXBuffer* buffer)
{

View File

@ -74,6 +74,18 @@ protected:
* new lap is triggered. */
Vec3 m_xyz_front;
/* Determines the time covered by the history size, in seconds */
const float XYZ_HISTORY_TIME = 0.25f;
/* Determines the number of previous XYZ positions of the kart to remember
Initialized in the constructor and unchanged from then on */
int m_xyz_history_size;
/** The coordinates of the XYZ_HISTORY_SIZE previous positions */
std::vector<Vec3> m_previous_xyz;
float m_time_previous_counter;
/** Is time flying activated */
bool m_is_jumping;
@ -87,6 +99,9 @@ protected:
/** Handles the powerup of a kart. */
Powerup *m_powerup;
/** Remember the last **used** powerup type of a kart for AI purposes. */
PowerupManager::PowerupType m_last_used_powerup;
/** True if kart is flying (for debug purposes only). */
bool m_flying;
@ -158,6 +173,9 @@ protected:
/** True if fire button was pushed and not released */
bool m_fire_clicked;
/** True if the kart has been selected to have a boosted ai */
bool m_boosted_ai;
// Bullet physics parameters
// -------------------------
btCompoundShape m_kart_chassis;
@ -260,11 +278,16 @@ public:
virtual void startEngineSFX ();
virtual void adjustSpeed (float f);
virtual void increaseMaxSpeed(unsigned int category, float add_speed,
float engine_force, int duration,
int fade_out_time);
float engine_force, float duration,
float fade_out_time);
virtual void instantSpeedIncrease(unsigned int category, float add_max_speed,
float speed_boost, float engine_force, float duration,
float fade_out_time);
virtual void setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time);
virtual int getSpeedIncreaseTicksLeft(unsigned int category) const OVERRIDE;
virtual int getSpeedIncreaseTicksLeft(unsigned int category) const;
virtual void setBoostAI (bool boosted);
virtual bool getBoostAI () const;
virtual void collectedItem(Item *item, int random_attachment);
virtual float getStartupBoost() const;
@ -298,12 +321,18 @@ public:
/** Sets a new powerup. */
virtual void setPowerup (PowerupManager::PowerupType t, int n);
// ------------------------------------------------------------------------
/** Sets the last used powerup. */
virtual void setLastUsedPowerup (PowerupManager::PowerupType t);
// ------------------------------------------------------------------------
/** Returns the current powerup. */
virtual const Powerup* getPowerup() const { return m_powerup; }
// ------------------------------------------------------------------------
/** Returns the current powerup. */
virtual Powerup* getPowerup() { return m_powerup; }
// ------------------------------------------------------------------------
/** Returns the last used powerup. */
virtual PowerupManager::PowerupType getLastUsedPowerup() { return m_last_used_powerup; }
// ------------------------------------------------------------------------
/** Returns the number of powerups. */
virtual int getNumPowerup() const;
// ------------------------------------------------------------------------
@ -454,6 +483,14 @@ public:
/** Returns the normal of the terrain the kart is over atm. This is
* defined even if the kart is flying. */
virtual const Vec3& getNormal() const;
// ------------------------------------------------------------------------
/** Returns the position 0.25s before */
virtual const Vec3& getPreviousXYZ() const;
// ------------------------------------------------------------------------
/** Returns a more recent different previous position */
virtual const Vec3& getRecentPreviousXYZ() const;
// ------------------------------------------------------------------------
/** For debugging only: check if a kart is flying. */
bool isFlying() const { return m_flying; }
@ -479,4 +516,3 @@ public:
#endif
/* EOF */

Some files were not shown because too many files have changed in this diff Show More