Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7a2988273 | ||
|
|
8691dfb2d4 | ||
|
|
edde451551 | ||
|
|
851bd36ce1 | ||
|
|
27bcdb341e | ||
|
|
17649cc502 | ||
|
|
f4c8c72e16 | ||
|
|
b6027e0f18 | ||
|
|
9d94473c05 | ||
|
|
85c05098b1 | ||
|
|
0e9e2af89e | ||
|
|
08f407c55c | ||
|
|
fe8dcdf478 | ||
|
|
6281b479ac | ||
|
|
489182749b | ||
|
|
d3ce304d28 | ||
|
|
d5c403dfe3 | ||
|
|
9f0d22c013 | ||
|
|
bf3b88e458 | ||
|
|
2ab2953879 | ||
|
|
c1ebcf8165 | ||
|
|
92b37d6de4 | ||
|
|
5ad6be3d5b | ||
|
|
c7b01b8e23 | ||
|
|
b45a5cec2e | ||
|
|
745df386e4 | ||
|
|
b9cb30bbd7 | ||
|
|
8b4cd23329 | ||
|
|
19f107d23f | ||
|
|
d7684d7cea | ||
|
|
2dbffbe7fd | ||
|
|
e841ae4526 | ||
|
|
17867219a0 | ||
|
|
45b750c01b | ||
|
|
cb58631b5a | ||
|
|
0333054ca6 | ||
|
|
a65d4b0829 | ||
|
|
21793191c4 | ||
|
|
99d1c48e0a | ||
|
|
001c7b30ee | ||
|
|
3d95cdc76f | ||
|
|
0b162984a5 | ||
|
|
a48b88d890 | ||
|
|
2b075e7f0f | ||
|
|
4df5a269e8 | ||
|
|
4049067c50 | ||
|
|
2b8e5c09d0 | ||
|
|
d88bebae1e | ||
|
|
5b42b43dee | ||
|
|
7b707a3546 | ||
|
|
5c2286f556 | ||
|
|
7f2f62be11 | ||
|
|
6b7bc2c67e | ||
|
|
80c8e2ace3 | ||
|
|
60dc171700 | ||
|
|
cc77d63f5b | ||
|
|
822fa73b07 | ||
|
|
b0251cf0b1 | ||
|
|
43152ff3ed | ||
|
|
e31ea79602 | ||
|
|
5a72ef711c | ||
|
|
b2447f114f | ||
|
|
c22da37992 | ||
|
|
7ac674aebd | ||
|
|
12ea4bc76f |
@@ -2,12 +2,15 @@
|
|||||||
* Ghost replay races by Benau
|
* Ghost replay races by Benau
|
||||||
* Battle mode AI by Benau
|
* Battle mode AI by Benau
|
||||||
* Soccer mode AI by Benau
|
* Soccer mode AI by Benau
|
||||||
|
* New icy soccer field by samuncle and Benau
|
||||||
* New subsea track by samuncle
|
* New subsea track by samuncle
|
||||||
|
* New volcano track by Ponzino
|
||||||
* TTF font rendering by Benau
|
* TTF font rendering by Benau
|
||||||
* Kart properties refactor by Flakebi
|
* Kart properties refactor by Flakebi
|
||||||
* Scripting work under the hood
|
* Scripting work under the hood
|
||||||
* Work on the track editor by mhp
|
* Work on the track editor by mhp
|
||||||
* Tweak to challenges
|
* Tweak to challenges
|
||||||
|
* New farm track song by 0zone0ne and Krobonil
|
||||||
* Bugfixes
|
* Bugfixes
|
||||||
|
|
||||||
## SuperTuxKart 0.9.1
|
## SuperTuxKart 0.9.1
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# root CMakeLists for the SuperTuxKart project
|
# root CMakeLists for the SuperTuxKart project
|
||||||
project(SuperTuxKart)
|
project(SuperTuxKart)
|
||||||
set(PROJECT_VERSION "0.9.1")
|
set(PROJECT_VERSION "0.9.2")
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8.4)
|
cmake_minimum_required(VERSION 2.8.4)
|
||||||
if(NOT (CMAKE_MAJOR_VERSION VERSION_LESS 3))
|
if(NOT (CMAKE_MAJOR_VERSION VERSION_LESS 3))
|
||||||
@@ -68,6 +68,7 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/lib/enet")
|
|||||||
include_directories("${PROJECT_SOURCE_DIR}/lib/enet/include")
|
include_directories("${PROJECT_SOURCE_DIR}/lib/enet/include")
|
||||||
|
|
||||||
# Build glew library
|
# Build glew library
|
||||||
|
add_definitions(-DGLEW_NO_GLU)
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/glew")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/glew")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/lib/glew/include")
|
include_directories("${PROJECT_SOURCE_DIR}/lib/glew/include")
|
||||||
|
|
||||||
@@ -365,6 +366,11 @@ if(UNIX AND NOT APPLE)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# FreeBSD does not search in /usr/local/lib, but at least Freetype is installed there :(
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
# In theory it would be cleaner to let CMake detect the right dependencies. In practice, this means that if a OSX user has
|
# In theory it would be cleaner to let CMake detect the right dependencies. In practice, this means that if a OSX user has
|
||||||
# unix-style installs of Vorbis/Ogg/OpenAL/etc. they will be picked up over our frameworks. This is blocking when I make releases :
|
# unix-style installs of Vorbis/Ogg/OpenAL/etc. they will be picked up over our frameworks. This is blocking when I make releases :
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# SuperTuxKart Installation Instructions
|
# SuperTuxKart Installation Instructions
|
||||||
|
|
||||||
Note: If you obtained this source code from Github, you also need to download the game assets from Sourceforge using SVN.
|
Note: If you obtained this source code from Github, you also need to download
|
||||||
|
the game assets from Sourceforge using SVN.
|
||||||
|
|
||||||
`svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets`
|
`svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets`
|
||||||
|
|
||||||
@@ -26,8 +27,10 @@ First, make sure that you have the following packages installed:
|
|||||||
Ubuntu command:
|
Ubuntu command:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev \
|
sudo apt-get install build-essential cmake libbluetooth-dev \
|
||||||
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev libxrandr-dev libfreetype6-dev
|
libcurl4-gnutls-dev libfreetype6-dev libfribidi-dev libgl1-mesa-dev \
|
||||||
|
libjpeg-dev libogg-dev libopenal-dev libpng-dev libvorbis-dev libxrandr-dev \
|
||||||
|
mesa-common-dev pkg-config zlib1g-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Unpack the files from the tarball like this:
|
Unpack the files from the tarball like this:
|
||||||
|
|||||||
BIN
data/CREDITS
BIN
data/CREDITS
Binary file not shown.
@@ -17,11 +17,11 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.8.1</string>
|
<string>0.9.2-rc1</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>SPTK</string>
|
<string>SPTK</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.8.1</string>
|
<string>0.9.2-rc1</string>
|
||||||
<key>CSResourcesFileMapped</key>
|
<key>CSResourcesFileMapped</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<challenge version="2">
|
<challenge version="2">
|
||||||
<track id="cocoa_temple" laps="3"/>
|
<track id="cocoa_temple" laps="3"/>
|
||||||
<mode major="single" minor="quickrace"/>
|
<mode major="single" minor="quickrace"/>
|
||||||
<requirements trophies="15"/>
|
<requirements trophies="5"/>
|
||||||
|
|
||||||
<hard>
|
<hard>
|
||||||
<karts number="5"/>
|
<karts number="5"/>
|
||||||
|
|||||||
19
data/challenges/volcano_island.challenge
Normal file
19
data/challenges/volcano_island.challenge
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<challenge version="2">
|
||||||
|
<track id="volcano_island" laps="2"/>
|
||||||
|
<mode major="single" minor="quickrace"/>
|
||||||
|
<requirements trophies="15"/>
|
||||||
|
|
||||||
|
<hard>
|
||||||
|
<karts number="5"/>
|
||||||
|
<requirements position="1"/>
|
||||||
|
</hard>
|
||||||
|
<medium>
|
||||||
|
<karts number="4"/>
|
||||||
|
<requirements position="1"/>
|
||||||
|
</medium>
|
||||||
|
<easy>
|
||||||
|
<karts number="4"/>
|
||||||
|
<requirements position="1"/>
|
||||||
|
</easy>
|
||||||
|
</challenge>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<track id="greenvalley" laps="2" reverse="false" />
|
<track id="greenvalley" laps="2" reverse="false" />
|
||||||
<track id="mansion" laps="3" reverse="false" />
|
<track id="mansion" laps="3" reverse="false" />
|
||||||
<track id="stk_enterprise" laps="3" reverse="false" />
|
<track id="stk_enterprise" laps="3" reverse="false" />
|
||||||
<track id="city" laps="2" reverse="false" />
|
<track id="volcano_island" laps="2" reverse="false" />
|
||||||
|
|
||||||
</supertuxkart_grand_prix>
|
</supertuxkart_grand_prix>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<card is="Intel(R) HD Graphics 3000" os="windows" disable="FramebufferSRGBWorking"/>
|
<card is="Intel(R) HD Graphics 3000" os="windows" disable="FramebufferSRGBWorking"/>
|
||||||
<card contains="Intel" os="osx" disable="GI"/>
|
<card contains="Intel" os="osx" disable="GI"/>
|
||||||
<card contains="Intel" os="linux" version="<11.2" disable="ComputeShader"/>
|
<card contains="Intel" os="linux" version="<11.2" disable="ComputeShader"/>
|
||||||
|
<card contains="Intel" os="linux" version="<11.2" disable="GeometryShader"/>
|
||||||
<card contains="Intel" os="linux" version="<16.0" disable="FramebufferSRGBCapable"/>
|
<card contains="Intel" os="linux" version="<16.0" disable="FramebufferSRGBCapable"/>
|
||||||
<card contains="Intel" os="linux" version="<11.2" disable="TextureCompressionS3TC"/>
|
<card contains="Intel" os="linux" version="<11.2" disable="TextureCompressionS3TC"/>
|
||||||
<card contains="Intel" os="windows" disable="TextureCompressionS3TC"/>
|
<card contains="Intel" os="windows" disable="TextureCompressionS3TC"/>
|
||||||
@@ -15,11 +16,11 @@
|
|||||||
<card contains="NVIDIA" disable="ShaderAtomicCounters"/>
|
<card contains="NVIDIA" disable="ShaderAtomicCounters"/>
|
||||||
<card contains="Mesa" os="linux" version="<10.3" disable="BufferStorage"/>
|
<card contains="Mesa" os="linux" version="<10.3" disable="BufferStorage"/>
|
||||||
<card contains="Mesa" os="linux" version="<10.3" disable="DriverRecentEnough"/>
|
<card contains="Mesa" os="linux" version="<10.3" disable="DriverRecentEnough"/>
|
||||||
<card contains="Mesa" os="linux" version="<10.6" disable="GeometryShader4"/>
|
<card contains="Mesa" os="linux" version="<11.2" disable="GeometryShader"/>
|
||||||
<card contains="Mesa" os="linux" version="<11.2" disable="TextureCompressionS3TC"/>
|
<card contains="Mesa" os="linux" version="<11.2" disable="TextureCompressionS3TC"/>
|
||||||
<card contains="Gallium" os="linux" version="<10.3" disable="BufferStorage"/>
|
<card contains="Gallium" os="linux" version="<10.3" disable="BufferStorage"/>
|
||||||
<card contains="Gallium" os="linux" version="<10.3" disable="DriverRecentEnough"/>
|
<card contains="Gallium" os="linux" version="<10.3" disable="DriverRecentEnough"/>
|
||||||
<card contains="Gallium" os="linux" version="<10.6" disable="GeometryShader4"/>
|
<card contains="Gallium" os="linux" version="<11.2" disable="GeometryShader"/>
|
||||||
<card contains="Gallium" os="linux" version="<11.2" disable="TextureCompressionS3TC"/>
|
<card contains="Gallium" os="linux" version="<11.2" disable="TextureCompressionS3TC"/>
|
||||||
<!-- On osx radeon appears to have different version numbers, e.g.
|
<!-- On osx radeon appears to have different version numbers, e.g.
|
||||||
1.32.20 -->
|
1.32.20 -->
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
<spacer height="25" width="10"/>
|
<spacer height="25" width="10"/>
|
||||||
|
|
||||||
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||||
|
<!--
|
||||||
<icon-button id="tab_servers" width="128" height="128" icon="gui/main_network.png"/>
|
<icon-button id="tab_servers" width="128" height="128" icon="gui/main_network.png"/>
|
||||||
|
-->
|
||||||
<icon-button id="tab_achievements" width="128" height="128" icon="gui/gp_copy.png"
|
<icon-button id="tab_achievements" width="128" height="128" icon="gui/gp_copy.png"
|
||||||
I18N="Section in the profile screen" text="Achievements"/>
|
I18N="Section in the profile screen" text="Achievements"/>
|
||||||
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png"/>
|
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png"/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<spacer height="25" width="10"/>
|
<spacer height="25" width="10"/>
|
||||||
|
|
||||||
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||||
<icon-button id="tab_servers" width="128" height="128" icon="gui/main_network.png"/>
|
<!--<icon-button id="tab_servers" width="128" height="128" icon="gui/main_network.png"/>-->
|
||||||
<icon-button id="tab_achievements" width="128" height="128" icon="gui/gp_copy.png"/>
|
<icon-button id="tab_achievements" width="128" height="128" icon="gui/gp_copy.png"/>
|
||||||
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png"
|
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png"
|
||||||
I18N="Section in the profile screen" text="Friends"/>
|
I18N="Section in the profile screen" text="Friends"/>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<spacer height="25" width="10"/>
|
<spacer height="25" width="10"/>
|
||||||
|
|
||||||
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||||
<icon-button id="tab_servers" width="128" height="128" icon="gui/main_network.png"/>
|
<!--<icon-button id="tab_servers" width="128" height="128" icon="gui/main_network.png"/>-->
|
||||||
<icon-button id="tab_achievements" width="128" height="128" icon="gui/gp_copy.png"/>
|
<icon-button id="tab_achievements" width="128" height="128" icon="gui/gp_copy.png"/>
|
||||||
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png" />
|
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png" />
|
||||||
<icon-button id="tab_settings" width="128" height="128" icon="gui/main_options.png"
|
<icon-button id="tab_settings" width="128" height="128" icon="gui/main_options.png"
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 23 KiB |
1190
data/po/ar.po
1190
data/po/ar.po
File diff suppressed because it is too large
Load Diff
3801
data/po/be.po
3801
data/po/be.po
File diff suppressed because it is too large
Load Diff
2502
data/po/bg.po
2502
data/po/bg.po
File diff suppressed because it is too large
Load Diff
3793
data/po/bn.po
3793
data/po/bn.po
File diff suppressed because it is too large
Load Diff
1429
data/po/br.po
1429
data/po/br.po
File diff suppressed because it is too large
Load Diff
3797
data/po/bs.po
3797
data/po/bs.po
File diff suppressed because it is too large
Load Diff
1146
data/po/ca.po
1146
data/po/ca.po
File diff suppressed because it is too large
Load Diff
1155
data/po/cs.po
1155
data/po/cs.po
File diff suppressed because it is too large
Load Diff
1538
data/po/da.po
1538
data/po/da.po
File diff suppressed because it is too large
Load Diff
1178
data/po/de.po
1178
data/po/de.po
File diff suppressed because it is too large
Load Diff
1565
data/po/el.po
1565
data/po/el.po
File diff suppressed because it is too large
Load Diff
1100
data/po/en_AU.po
1100
data/po/en_AU.po
File diff suppressed because it is too large
Load Diff
1100
data/po/en_GB.po
1100
data/po/en_GB.po
File diff suppressed because it is too large
Load Diff
3793
data/po/eo.po
3793
data/po/eo.po
File diff suppressed because it is too large
Load Diff
1147
data/po/es.po
1147
data/po/es.po
File diff suppressed because it is too large
Load Diff
1202
data/po/eu.po
1202
data/po/eu.po
File diff suppressed because it is too large
Load Diff
3789
data/po/fa.po
3789
data/po/fa.po
File diff suppressed because it is too large
Load Diff
1148
data/po/fi.po
1148
data/po/fi.po
File diff suppressed because it is too large
Load Diff
1321
data/po/fr.po
1321
data/po/fr.po
File diff suppressed because it is too large
Load Diff
1102
data/po/fr_CA.po
1102
data/po/fr_CA.po
File diff suppressed because it is too large
Load Diff
3804
data/po/ga.po
3804
data/po/ga.po
File diff suppressed because it is too large
Load Diff
1154
data/po/gd.po
1154
data/po/gd.po
File diff suppressed because it is too large
Load Diff
2051
data/po/gl.po
2051
data/po/gl.po
File diff suppressed because it is too large
Load Diff
1144
data/po/he.po
1144
data/po/he.po
File diff suppressed because it is too large
Load Diff
3793
data/po/hi.po
3793
data/po/hi.po
File diff suppressed because it is too large
Load Diff
3797
data/po/hr.po
3797
data/po/hr.po
File diff suppressed because it is too large
Load Diff
2132
data/po/hu.po
2132
data/po/hu.po
File diff suppressed because it is too large
Load Diff
3793
data/po/hy.po
3793
data/po/hy.po
File diff suppressed because it is too large
Load Diff
3789
data/po/id.po
3789
data/po/id.po
File diff suppressed because it is too large
Load Diff
3793
data/po/is.po
3793
data/po/is.po
File diff suppressed because it is too large
Load Diff
1535
data/po/it.po
1535
data/po/it.po
File diff suppressed because it is too large
Load Diff
1154
data/po/ja.po
1154
data/po/ja.po
File diff suppressed because it is too large
Load Diff
3794
data/po/jbo.po
3794
data/po/jbo.po
File diff suppressed because it is too large
Load Diff
1125
data/po/ko.po
1125
data/po/ko.po
File diff suppressed because it is too large
Load Diff
1350
data/po/kw.po
1350
data/po/kw.po
File diff suppressed because it is too large
Load Diff
3789
data/po/ky.po
3789
data/po/ky.po
File diff suppressed because it is too large
Load Diff
2391
data/po/la.po
2391
data/po/la.po
File diff suppressed because it is too large
Load Diff
1221
data/po/lt.po
1221
data/po/lt.po
File diff suppressed because it is too large
Load Diff
1151
data/po/lv.po
1151
data/po/lv.po
File diff suppressed because it is too large
Load Diff
3792
data/po/mn_MN.po
3792
data/po/mn_MN.po
File diff suppressed because it is too large
Load Diff
1273
data/po/nb.po
1273
data/po/nb.po
File diff suppressed because it is too large
Load Diff
3792
data/po/nb_NO.po
3792
data/po/nb_NO.po
File diff suppressed because it is too large
Load Diff
1160
data/po/nl.po
1160
data/po/nl.po
File diff suppressed because it is too large
Load Diff
1150
data/po/nn.po
1150
data/po/nn.po
File diff suppressed because it is too large
Load Diff
3792
data/po/no.po
3792
data/po/no.po
File diff suppressed because it is too large
Load Diff
3792
data/po/no_NO.po
3792
data/po/no_NO.po
File diff suppressed because it is too large
Load Diff
3792
data/po/oc.po
3792
data/po/oc.po
File diff suppressed because it is too large
Load Diff
3793
data/po/os.po
3793
data/po/os.po
File diff suppressed because it is too large
Load Diff
1163
data/po/pl.po
1163
data/po/pl.po
File diff suppressed because it is too large
Load Diff
1136
data/po/pt.po
1136
data/po/pt.po
File diff suppressed because it is too large
Load Diff
1146
data/po/pt_BR.po
1146
data/po/pt_BR.po
File diff suppressed because it is too large
Load Diff
3796
data/po/ro.po
3796
data/po/ro.po
File diff suppressed because it is too large
Load Diff
1161
data/po/ru.po
1161
data/po/ru.po
File diff suppressed because it is too large
Load Diff
3792
data/po/sc.po
3792
data/po/sc.po
File diff suppressed because it is too large
Load Diff
3793
data/po/sco.po
3793
data/po/sco.po
File diff suppressed because it is too large
Load Diff
1380
data/po/sk.po
1380
data/po/sk.po
File diff suppressed because it is too large
Load Diff
1156
data/po/sl.po
1156
data/po/sl.po
File diff suppressed because it is too large
Load Diff
3793
data/po/sq.po
3793
data/po/sq.po
File diff suppressed because it is too large
Load Diff
1748
data/po/sr.po
1748
data/po/sr.po
File diff suppressed because it is too large
Load Diff
1385
data/po/sv.po
1385
data/po/sv.po
File diff suppressed because it is too large
Load Diff
1192
data/po/tr.po
1192
data/po/tr.po
File diff suppressed because it is too large
Load Diff
2432
data/po/tt.po
2432
data/po/tt.po
File diff suppressed because it is too large
Load Diff
1453
data/po/uk.po
1453
data/po/uk.po
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# A simple script that adds all authors from transifex, which are
|
# A simple script that adds all authors from transifex, which are
|
||||||
# listed in comments at the beginning of the file, to the
|
# listed in comments at the beginning of the file, to the
|
||||||
# 'translator-credits' translations - where launchpad added them
|
# 'translator-credits' translations - where launchpad added them
|
||||||
@@ -19,75 +19,79 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv)!=2:
|
if len(sys.argv) < 2:
|
||||||
print "Usage: getpo_authors.py PATH_TO_PO_FILE"
|
print "Usage: getpo_authors.py PATH_TO_PO_FILE"
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
f = open(sys.argv[1], "r")
|
for filename in sys.argv[1:]:
|
||||||
if not f:
|
print("Processing file ", filename)
|
||||||
print "Can not find", sys.argv[1]
|
f = open(filename, "r")
|
||||||
exit
|
if not f:
|
||||||
lines = f.readlines()
|
print "Can not find", filename
|
||||||
|
exit
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
new_authors = []
|
new_authors = []
|
||||||
found = 0
|
found = 0
|
||||||
|
|
||||||
# Find all authors with a simple finite state machine:
|
# Find all authors with a simple finite state machine:
|
||||||
contributions = -1
|
contributions = -1
|
||||||
line_count = 0
|
line_count = 0
|
||||||
for i in lines:
|
for i in lines:
|
||||||
line = i[:-1] # remove \n
|
line = i[:-1] # remove \n
|
||||||
if line=="# Translators:":
|
if line=="# Translators:":
|
||||||
found = 1
|
found = 1
|
||||||
elif found and line[:2]=="# " and line [:14]!="# FIRST AUTHOR":
|
elif found and line[:2]=="# " and line [:14]!="# FIRST AUTHOR":
|
||||||
new_authors.append(line[2:])
|
new_authors.append(line[2:])
|
||||||
elif line[:5]=="msgid":
|
elif line[:5]=="msgid":
|
||||||
found = 0
|
found = 0
|
||||||
elif line[:31]== "msgstr \"Launchpad Contributions":
|
elif line[:31]== "msgstr \"Launchpad Contributions":
|
||||||
contributions = line_count
|
contributions = line_count
|
||||||
line_count = line_count + 1
|
line_count = line_count + 1
|
||||||
|
|
||||||
|
|
||||||
# Delete all email addresses - not sure if the authors
|
# Delete all email addresses - not sure if the authors
|
||||||
# would want them to be published
|
# would want them to be published
|
||||||
email=re.compile(" *<.*@.*\..*> *") # one @ and one dot at least
|
email=re.compile(" *<.*@.*\..*> *") # one @ and one dot at least
|
||||||
for i in range(len(new_authors)):
|
for i in range(len(new_authors)):
|
||||||
g = email.search(new_authors[i])
|
g = email.search(new_authors[i])
|
||||||
if g:
|
if g:
|
||||||
new_authors[i] = new_authors[i][:g.start()] \
|
new_authors[i] = new_authors[i][:g.start()] \
|
||||||
+ new_authors[i][g.end():]
|
+ new_authors[i][g.end():]
|
||||||
|
|
||||||
# Get the old authors from the translator-credits string:
|
# Get the old authors from the translator-credits string:
|
||||||
if contributions>0:
|
if contributions>0:
|
||||||
# Ignore the first entry, which is "msgstr ...", and the
|
# Ignore the first entry, which is "msgstr ...", and the
|
||||||
# last two characters, which are the '"\n'.
|
# last two characters, which are the '"\n'.
|
||||||
old_authors = lines[contributions][:-2].split("\\n")[1:]
|
old_authors = lines[contributions][:-2].split("\\n")[1:]
|
||||||
for i in range(len(old_authors)):
|
for i in range(len(old_authors)):
|
||||||
old_authors[i] = old_authors[i].strip()
|
old_authors[i] = old_authors[i].strip()
|
||||||
else:
|
else:
|
||||||
old_authors=[]
|
old_authors=[]
|
||||||
|
|
||||||
all_authors = old_authors + new_authors;
|
all_authors = old_authors + new_authors;
|
||||||
all_authors = sorted(all_authors, key=lambda x: x.lower())
|
all_authors = sorted(all_authors, key=lambda x: x.lower())
|
||||||
all_authors_string = reduce(lambda x,y: x+"\\n"+y, all_authors, "")
|
all_authors_string = reduce(lambda x,y: x+"\\n"+y, all_authors, "")
|
||||||
|
|
||||||
credits_line = "msgstr \"Launchpad Contributions:%s\"\n"%all_authors_string
|
credits_line = "msgstr \"Launchpad Contributions:%s\"\n"%all_authors_string
|
||||||
# If no old authors exists, write a new entry:
|
# If no old authors exists, write a new entry:
|
||||||
if contributions==-1:
|
if contributions==-1:
|
||||||
lines.append("\n")
|
lines.append("\n")
|
||||||
lines.append("#: src/states_screens/credits.cpp:209\n")
|
lines.append("#: src/states_screens/credits.cpp:209\n")
|
||||||
lines.append("msgid \"translator-credits\"\n")
|
lines.append("msgid \"translator-credits\"\n")
|
||||||
lines.append(credits_line)
|
lines.append(credits_line)
|
||||||
else:
|
else:
|
||||||
# Otherwise just replace the old contribution string
|
# Otherwise just replace the old contribution string
|
||||||
lines[contributions] = credits_line
|
lines[contributions] = credits_line
|
||||||
|
|
||||||
|
|
||||||
# Overwrite old file
|
# Overwrite old file
|
||||||
f = open(sys.argv[1], "w")
|
f = open(filename, "w")
|
||||||
for i in lines:
|
for i in lines:
|
||||||
f.write(i)
|
f.write(i)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
print("Done with ", filename)
|
||||||
|
|
||||||
|
|||||||
3789
data/po/uz.po
3789
data/po/uz.po
File diff suppressed because it is too large
Load Diff
3789
data/po/vi.po
3789
data/po/vi.po
File diff suppressed because it is too large
Load Diff
3788
data/po/zh.po
3788
data/po/zh.po
File diff suppressed because it is too large
Load Diff
1144
data/po/zh_CN.po
1144
data/po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1148
data/po/zh_TW.po
1148
data/po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ out vec4 FragColor;
|
|||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec3 eyedir = vec3(gl_FragCoord.xy / screen, 1.);
|
vec3 eyedir = vec3(mod(gl_FragCoord.xy, screen) / screen, 1.);
|
||||||
eyedir = 2.0 * eyedir - 1.0;
|
eyedir = 2.0 * eyedir - 1.0;
|
||||||
vec4 tmp = (InverseProjectionMatrix * vec4(eyedir, 1.));
|
vec4 tmp = (InverseProjectionMatrix * vec4(eyedir, 1.));
|
||||||
tmp /= tmp.w;
|
tmp /= tmp.w;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ void main(void)
|
|||||||
float bl = 0.0;
|
float bl = 0.0;
|
||||||
float m = log2(r) + 6 + log2(invSamples);
|
float m = log2(r) + 6 + log2(invSamples);
|
||||||
|
|
||||||
float theta = 2. * 3.14 * tau * .5 * invSamples + phi;
|
float theta = mod(2. * 3.14 * tau * .5 * invSamples + phi, 6.283185307179586);
|
||||||
vec2 rotations = vec2(cos(theta), sin(theta)) * screen;
|
vec2 rotations = vec2(cos(theta), sin(theta)) * screen;
|
||||||
vec2 offset = vec2(cos(invSamples), sin(invSamples));
|
vec2 offset = vec2(cos(invSamples), sin(invSamples));
|
||||||
|
|
||||||
|
|||||||
1
data/supertuxkart.0.9.2
Normal file
1
data/supertuxkart.0.9.2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
supertuxkart.0.9.2
|
||||||
@@ -8,28 +8,28 @@
|
|||||||
<summary>A racing game</summary>
|
<summary>A racing game</summary>
|
||||||
<description>
|
<description>
|
||||||
<p>
|
<p>
|
||||||
SuperTuxKart is a fun 3D kart racing game.
|
Supertuxkart is a free 3D kart racing game, with a focus on having fun over
|
||||||
You can play with up to 4 friends on one PC, racing against each other or
|
realism. You can play with up to 4 friends on one PC, racing against each
|
||||||
just try to beat the computer.
|
other, or try to beat the computer in single-player mode.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
See the great lighthouse or drive through the sand and visit the pyramids.
|
See the great lighthouse or drive through the sand and visit the pyramids.
|
||||||
Race underground or in space, watching the stars passing by.
|
Race underground or in space, watching the stars pass by. Or rest under the
|
||||||
Have some rest under the palms on the beach (watching the other karts
|
palm trees on the beach, watching the other karts overtake you. But don't eat
|
||||||
overtaking you :) ).
|
the bananas! Watch for bowling balls, plungers, bubble gum and cakes thrown by
|
||||||
But don't eat the bananas! Watch for bowling balls, plungers, bubble gum
|
your opponents.
|
||||||
and cakes thrown by opponents.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
You can do a single race against other karts, compete in one of several
|
You can do a single race against other karts, compete in one of several Grand
|
||||||
Grand Prix, try to beat the high score in time trials on your own, play
|
Prix, try to beat the high score in time trials on your own, play battle mode
|
||||||
battle mode against your friends, and more!
|
against the computer or your friends, and more!
|
||||||
</p>
|
</p>
|
||||||
</description>
|
</description>
|
||||||
<url type="homepage">http://supertuxkart.sourceforge.net/</url>
|
<url type="homepage">http://supertuxkart.sourceforge.net/</url>
|
||||||
<screenshots>
|
<screenshots>
|
||||||
<screenshot type="default">http://supertuxkart.sourceforge.net/persistent/images/4/4d/SuperTuxKart_0.8_screenshot.jpg</screenshot>
|
<screenshot type="default">http://supertuxkart.sourceforge.net/persistent/images/4/4e/Supertuxkart-0.9-screenshot-2.jpg</screenshot>
|
||||||
<screenshot>http://supertuxkart.sourceforge.net/persistent/images/1/1f/SuperTuxKart_0.8_screenshot4.jpg</screenshot>
|
<screenshot>http://supertuxkart.sourceforge.net/persistent/images/a/a9/Supertuxkart-0.9-screenshot-1.jpg</screenshot>
|
||||||
|
<screenshot>http://supertuxkart.sourceforge.net/persistent/images/6/63/Supertuxkart-0.9-screenshot-3.jpg</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
<updatecontact>supertuxkart-devel@lists.sourceforge.net</updatecontact>
|
<updatecontact>supertuxkart-devel@lists.sourceforge.net</updatecontact>
|
||||||
</application>
|
</application>
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ endif()
|
|||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
include_directories(${OPENGL_INCLUDE_DIR})
|
include_directories(${OPENGL_INCLUDE_DIR})
|
||||||
|
|
||||||
|
add_definitions(-DGLEW_STATIC)
|
||||||
|
|
||||||
add_library(glew STATIC
|
add_library(glew STATIC
|
||||||
include/GL/glew.h include/GL/glxew.h include/GL/wglew.h
|
include/GL/glew.h include/GL/glxew.h include/GL/wglew.h
|
||||||
src/glew.c src/glewinfo.c
|
src/glew.c src/glewinfo.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions(-DGLEW_STATIC)
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ void CentralVideoSettings::init()
|
|||||||
hasMultiDrawIndirect = false;
|
hasMultiDrawIndirect = false;
|
||||||
hasTextureCompression = false;
|
hasTextureCompression = false;
|
||||||
hasUBO = false;
|
hasUBO = false;
|
||||||
|
hasExplicitAttribLocation = false;
|
||||||
hasGS = false;
|
hasGS = false;
|
||||||
|
|
||||||
m_GI_has_artifact = false;
|
m_GI_has_artifact = false;
|
||||||
@@ -154,11 +155,24 @@ void CentralVideoSettings::init()
|
|||||||
hasUBO = true;
|
hasUBO = true;
|
||||||
Log::info("GLDriver", "ARB Uniform Buffer Object Present");
|
Log::info("GLDriver", "ARB Uniform Buffer Object Present");
|
||||||
}
|
}
|
||||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_GEOMETRY_SHADER4) &&
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXPLICIT_ATTRIB_LOCATION) &&
|
||||||
|
hasGLExtension("GL_ARB_explicit_attrib_location")) {
|
||||||
|
hasExplicitAttribLocation = true;
|
||||||
|
Log::info("GLDriver", "ARB Explicit Attrib Location Present");
|
||||||
|
}
|
||||||
|
#if defined(__linux__)
|
||||||
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_GEOMETRY_SHADER) &&
|
||||||
|
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 2))) {
|
||||||
|
hasGS = true;
|
||||||
|
Log::info("GLDriver", "Geometry Shaders Present");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_GEOMETRY_SHADER) &&
|
||||||
hasGLExtension("GL_ARB_geometry_shader4")) {
|
hasGLExtension("GL_ARB_geometry_shader4")) {
|
||||||
hasGS = true;
|
hasGS = true;
|
||||||
Log::info("GLDriver", "ARB Geometry Shader 4 Present");
|
Log::info("GLDriver", "ARB Geometry Shader 4 Present");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Only unset the high def textures if they are set as default. If the
|
// Only unset the high def textures if they are set as default. If the
|
||||||
// user has enabled them (bit 1 set), then leave them enabled.
|
// user has enabled them (bit 1 set), then leave them enabled.
|
||||||
@@ -229,7 +243,7 @@ bool CentralVideoSettings::needsSRGBCapableVisualWorkaround() const
|
|||||||
return m_need_srgb_visual_workaround;
|
return m_need_srgb_visual_workaround;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CentralVideoSettings::isARBGeometryShader4Usable() const
|
bool CentralVideoSettings::isARBGeometryShadersUsable() const
|
||||||
{
|
{
|
||||||
return hasGS;
|
return hasGS;
|
||||||
}
|
}
|
||||||
@@ -239,6 +253,11 @@ bool CentralVideoSettings::isARBUniformBufferObjectUsable() const
|
|||||||
return hasUBO;
|
return hasUBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CentralVideoSettings::isARBExplicitAttribLocationUsable() const
|
||||||
|
{
|
||||||
|
return hasExplicitAttribLocation;
|
||||||
|
}
|
||||||
|
|
||||||
bool CentralVideoSettings::isEXTTextureCompressionS3TCUsable() const
|
bool CentralVideoSettings::isEXTTextureCompressionS3TCUsable() const
|
||||||
{
|
{
|
||||||
return hasTextureCompression;
|
return hasTextureCompression;
|
||||||
@@ -311,12 +330,12 @@ bool CentralVideoSettings::isARBMultiDrawIndirectUsable() const
|
|||||||
|
|
||||||
bool CentralVideoSettings::supportsShadows() const
|
bool CentralVideoSettings::supportsShadows() const
|
||||||
{
|
{
|
||||||
return isARBGeometryShader4Usable() && isARBUniformBufferObjectUsable();
|
return isARBGeometryShadersUsable() && isARBUniformBufferObjectUsable() && isARBExplicitAttribLocationUsable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CentralVideoSettings::supportsGlobalIllumination() const
|
bool CentralVideoSettings::supportsGlobalIllumination() const
|
||||||
{
|
{
|
||||||
return isARBGeometryShader4Usable() && isARBUniformBufferObjectUsable() && !m_GI_has_artifact;
|
return isARBGeometryShadersUsable() && isARBUniformBufferObjectUsable() && isARBExplicitAttribLocationUsable() && !m_GI_has_artifact;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CentralVideoSettings::supportsIndirectInstancingRendering() const
|
bool CentralVideoSettings::supportsIndirectInstancingRendering() const
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ private:
|
|||||||
bool hasTextureView;
|
bool hasTextureView;
|
||||||
bool hasBindlessTexture;
|
bool hasBindlessTexture;
|
||||||
bool hasUBO;
|
bool hasUBO;
|
||||||
|
bool hasExplicitAttribLocation;
|
||||||
bool hasGS;
|
bool hasGS;
|
||||||
bool hasTextureCompression;
|
bool hasTextureCompression;
|
||||||
bool hasAtomics;
|
bool hasAtomics;
|
||||||
@@ -60,7 +61,7 @@ public:
|
|||||||
bool isARBUniformBufferObjectUsable() const;
|
bool isARBUniformBufferObjectUsable() const;
|
||||||
bool isEXTTextureCompressionS3TCUsable() const;
|
bool isEXTTextureCompressionS3TCUsable() const;
|
||||||
bool isARBTextureViewUsable() const;
|
bool isARBTextureViewUsable() const;
|
||||||
bool isARBGeometryShader4Usable() const;
|
bool isARBGeometryShadersUsable() const;
|
||||||
bool isARBTextureStorageUsable() const;
|
bool isARBTextureStorageUsable() const;
|
||||||
bool isAMDVertexShaderLayerUsable() const;
|
bool isAMDVertexShaderLayerUsable() const;
|
||||||
bool isARBComputeShaderUsable() const;
|
bool isARBComputeShaderUsable() const;
|
||||||
@@ -73,6 +74,7 @@ public:
|
|||||||
bool isARBShaderStorageBufferObjectUsable() const;
|
bool isARBShaderStorageBufferObjectUsable() const;
|
||||||
bool isARBImageLoadStoreUsable() const;
|
bool isARBImageLoadStoreUsable() const;
|
||||||
bool isARBMultiDrawIndirectUsable() const;
|
bool isARBMultiDrawIndirectUsable() const;
|
||||||
|
bool isARBExplicitAttribLocationUsable() const;
|
||||||
|
|
||||||
|
|
||||||
// Are all required extensions available for feature support
|
// Are all required extensions available for feature support
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace GraphicsRestrictions
|
|||||||
|
|
||||||
const char *m_names_of_restrictions[] = {
|
const char *m_names_of_restrictions[] = {
|
||||||
"UniformBufferObject",
|
"UniformBufferObject",
|
||||||
"GeometryShader4",
|
"GeometryShader",
|
||||||
"DrawIndirect",
|
"DrawIndirect",
|
||||||
"TextureView",
|
"TextureView",
|
||||||
"TextureStorage",
|
"TextureStorage",
|
||||||
@@ -56,6 +56,7 @@ namespace GraphicsRestrictions
|
|||||||
"BindlessTexture",
|
"BindlessTexture",
|
||||||
"TextureCompressionS3TC",
|
"TextureCompressionS3TC",
|
||||||
"AMDVertexShaderLayer",
|
"AMDVertexShaderLayer",
|
||||||
|
"ExplicitAttribLocation",
|
||||||
"DriverRecentEnough",
|
"DriverRecentEnough",
|
||||||
"HighDefinitionTextures",
|
"HighDefinitionTextures",
|
||||||
"AdvancedPipeline",
|
"AdvancedPipeline",
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace GraphicsRestrictions
|
|||||||
enum GraphicsRestrictionsType
|
enum GraphicsRestrictionsType
|
||||||
{
|
{
|
||||||
GR_UNIFORM_BUFFER_OBJECT,
|
GR_UNIFORM_BUFFER_OBJECT,
|
||||||
GR_GEOMETRY_SHADER4,
|
GR_GEOMETRY_SHADER,
|
||||||
GR_DRAW_INDIRECT,
|
GR_DRAW_INDIRECT,
|
||||||
GR_TEXTURE_VIEW,
|
GR_TEXTURE_VIEW,
|
||||||
GR_TEXTURE_STORAGE,
|
GR_TEXTURE_STORAGE,
|
||||||
@@ -50,6 +50,7 @@ namespace GraphicsRestrictions
|
|||||||
GR_BINDLESS_TEXTURE,
|
GR_BINDLESS_TEXTURE,
|
||||||
GR_EXT_TEXTURE_COMPRESSION_S3TC,
|
GR_EXT_TEXTURE_COMPRESSION_S3TC,
|
||||||
GR_AMD_VERTEX_SHADER_LAYER,
|
GR_AMD_VERTEX_SHADER_LAYER,
|
||||||
|
GR_EXPLICIT_ATTRIB_LOCATION,
|
||||||
GR_DRIVER_RECENT_ENOUGH,
|
GR_DRIVER_RECENT_ENOUGH,
|
||||||
GR_HIGHDEFINITION_TEXTURES,
|
GR_HIGHDEFINITION_TEXTURES,
|
||||||
GR_ADVANCED_PIPELINE,
|
GR_ADVANCED_PIPELINE,
|
||||||
|
|||||||
@@ -674,7 +674,7 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
|||||||
node->render();
|
node->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CVS->supportsIndirectInstancingRendering())
|
if (CVS->supportsIndirectInstancingRendering() && CVS->isARBExplicitAttribLocationUsable())
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
|
||||||
InstancedColorizeShader::getInstance()->use();
|
InstancedColorizeShader::getInstance()->use();
|
||||||
|
|||||||
@@ -84,6 +84,9 @@ GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
|
|||||||
if (CVS->isAMDVertexShaderLayerUsable())
|
if (CVS->isAMDVertexShaderLayerUsable())
|
||||||
code << "#extension GL_AMD_vertex_shader_layer : enable\n";
|
code << "#extension GL_AMD_vertex_shader_layer : enable\n";
|
||||||
|
|
||||||
|
if (CVS->isARBExplicitAttribLocationUsable())
|
||||||
|
code << "#extension GL_ARB_explicit_attrib_location : enable\n";
|
||||||
|
|
||||||
if (CVS->isAZDOEnabled())
|
if (CVS->isAZDOEnabled())
|
||||||
{
|
{
|
||||||
code << "#extension GL_ARB_bindless_texture : enable\n";
|
code << "#extension GL_ARB_bindless_texture : enable\n";
|
||||||
|
|||||||
@@ -299,6 +299,7 @@ void Skybox::generateSpecularCubemap()
|
|||||||
}
|
}
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glDeleteFramebuffers(1, &fbo);
|
glDeleteFramebuffers(1, &fbo);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
} // generateSpecularCubemap
|
} // generateSpecularCubemap
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -419,8 +419,7 @@ void initTexturesTransparent(GLMesh &mesh)
|
|||||||
{
|
{
|
||||||
if (!mesh.textures[0])
|
if (!mesh.textures[0])
|
||||||
{
|
{
|
||||||
Log::fatal("STKMesh", "Missing texture for material transparent");
|
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
compressTexture(mesh.textures[0], true);
|
compressTexture(mesh.textures[0], true);
|
||||||
if (CVS->isAZDOEnabled())
|
if (CVS->isAZDOEnabled())
|
||||||
|
|||||||
@@ -532,10 +532,9 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
|
|||||||
for (unsigned int j = 0; j < used_location.size(); j++)
|
for (unsigned int j = 0; j < used_location.size(); j++)
|
||||||
{
|
{
|
||||||
if (!found) continue;
|
if (!found) continue;
|
||||||
Vec3 d = BattleGraph::get()
|
float test_distance = BattleGraph::get()
|
||||||
->getPolyOfNode(used_location[j]).getCenter() -
|
->getDistance(used_location[j], node);
|
||||||
BattleGraph::get()->getPolyOfNode(node).getCenter();
|
found = test_distance > MIN_DIST;
|
||||||
found = d.length_2d() > MIN_DIST;
|
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -283,23 +283,24 @@ void AIBaseController::crashed(const Material *m)
|
|||||||
} // crashed(Material)
|
} // crashed(Material)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void AIBaseController::checkPosition(const Vec3 &point,
|
void AIBaseController::checkPosition(const Vec3 &point, posData *pos_data,
|
||||||
posData *pos_data,
|
Vec3 *lc, bool use_front_xyz) const
|
||||||
Vec3 *lc) const
|
|
||||||
{
|
{
|
||||||
// Convert to local coordinates from the point of view of current kart
|
// Convert to local coordinates from the point of view of current kart
|
||||||
btQuaternion q(btVector3(0, 1, 0), -m_kart->getHeading());
|
btQuaternion q(btVector3(0, 1, 0), -m_kart->getHeading());
|
||||||
Vec3 p = point - m_kart->getXYZ();
|
Vec3 p = point -
|
||||||
|
(use_front_xyz ? m_kart->getFrontXYZ() : m_kart->getXYZ());
|
||||||
Vec3 local_coordinates = quatRotate(q, p);
|
Vec3 local_coordinates = quatRotate(q, p);
|
||||||
|
|
||||||
// Save local coordinates for later use if needed
|
// Save local coordinates for later use if needed
|
||||||
if (lc) *lc = local_coordinates;
|
if (lc) *lc = local_coordinates;
|
||||||
|
|
||||||
// on_side: tell whether it's left or right hand side
|
if (pos_data == NULL) return;
|
||||||
|
// lhs: tell whether it's left or right hand side
|
||||||
if (local_coordinates.getX() < 0)
|
if (local_coordinates.getX() < 0)
|
||||||
pos_data->on_side = true;
|
pos_data->lhs = true;
|
||||||
else
|
else
|
||||||
pos_data->on_side = false;
|
pos_data->lhs = false;
|
||||||
|
|
||||||
// behind: tell whether it's behind or not
|
// behind: tell whether it's behind or not
|
||||||
if (local_coordinates.getZ() < 0)
|
if (local_coordinates.getZ() < 0)
|
||||||
@@ -309,6 +310,6 @@ void AIBaseController::checkPosition(const Vec3 &point,
|
|||||||
|
|
||||||
pos_data->angle = atan2(fabsf(local_coordinates.getX()),
|
pos_data->angle = atan2(fabsf(local_coordinates.getX()),
|
||||||
fabsf(local_coordinates.getZ()));
|
fabsf(local_coordinates.getZ()));
|
||||||
pos_data->distance = p.length_2d();
|
pos_data->distance = p.length();
|
||||||
|
|
||||||
} // checkPosition
|
} // checkPosition
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ protected:
|
|||||||
static int m_test_ai;
|
static int m_test_ai;
|
||||||
|
|
||||||
/** Position info structure of targets. */
|
/** Position info structure of targets. */
|
||||||
struct posData {bool behind; bool on_side; float angle; float distance;};
|
struct posData {bool behind; bool lhs; float angle; float distance;};
|
||||||
|
|
||||||
void setControllerName(const std::string &name);
|
void setControllerName(const std::string &name);
|
||||||
float steerToPoint(const Vec3 &point);
|
float steerToPoint(const Vec3 &point);
|
||||||
@@ -77,7 +77,9 @@ protected:
|
|||||||
/** This can be called to detect if the kart is stuck (i.e. repeatedly
|
/** This can be called to detect if the kart is stuck (i.e. repeatedly
|
||||||
* hitting part of the track). */
|
* hitting part of the track). */
|
||||||
bool isStuck() const { return m_stuck; }
|
bool isStuck() const { return m_stuck; }
|
||||||
void checkPosition(const Vec3&, posData*, Vec3* lc = NULL) const;
|
void checkPosition(const Vec3&, posData*,
|
||||||
|
Vec3* lc = NULL,
|
||||||
|
bool use_front_xyz = false) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AIBaseController(AbstractKart *kart);
|
AIBaseController(AbstractKart *kart);
|
||||||
|
|||||||
@@ -29,10 +29,20 @@
|
|||||||
#include "tracks/battle_graph.hpp"
|
#include "tracks/battle_graph.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
|
|
||||||
|
int ArenaAI::m_test_node_for_banana = BattleGraph::UNKNOWN_POLY;
|
||||||
|
|
||||||
|
bool isNodeWithBanana(const std::pair<const Item*, int>& item_pair)
|
||||||
|
{
|
||||||
|
return item_pair.second == ArenaAI::m_test_node_for_banana &&
|
||||||
|
item_pair.first->getType() == Item::ITEM_BANANA &&
|
||||||
|
!item_pair.first->wasCollected();
|
||||||
|
}
|
||||||
|
|
||||||
ArenaAI::ArenaAI(AbstractKart *kart)
|
ArenaAI::ArenaAI(AbstractKart *kart)
|
||||||
: AIBaseController(kart)
|
: AIBaseController(kart)
|
||||||
{
|
{
|
||||||
m_debug_sphere = NULL;
|
m_debug_sphere = NULL;
|
||||||
|
m_debug_sphere_next = NULL;
|
||||||
} // ArenaAI
|
} // ArenaAI
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -41,6 +51,8 @@ ArenaAI::ArenaAI(AbstractKart *kart)
|
|||||||
void ArenaAI::reset()
|
void ArenaAI::reset()
|
||||||
{
|
{
|
||||||
m_target_node = BattleGraph::UNKNOWN_POLY;
|
m_target_node = BattleGraph::UNKNOWN_POLY;
|
||||||
|
m_current_forward_node = BattleGraph::UNKNOWN_POLY;
|
||||||
|
m_current_forward_point = Vec3(0, 0, 0);
|
||||||
m_adjusting_side = false;
|
m_adjusting_side = false;
|
||||||
m_closest_kart = NULL;
|
m_closest_kart = NULL;
|
||||||
m_closest_kart_node = BattleGraph::UNKNOWN_POLY;
|
m_closest_kart_node = BattleGraph::UNKNOWN_POLY;
|
||||||
@@ -49,14 +61,17 @@ void ArenaAI::reset()
|
|||||||
m_cur_kart_pos_data = {0};
|
m_cur_kart_pos_data = {0};
|
||||||
m_is_stuck = false;
|
m_is_stuck = false;
|
||||||
m_is_uturn = false;
|
m_is_uturn = false;
|
||||||
|
m_avoiding_banana = false;
|
||||||
m_target_point = Vec3(0, 0, 0);
|
m_target_point = Vec3(0, 0, 0);
|
||||||
m_time_since_last_shot = 0.0f;
|
m_time_since_last_shot = 0.0f;
|
||||||
m_time_since_driving = 0.0f;
|
m_time_since_driving = 0.0f;
|
||||||
m_time_since_reversing = 0.0f;
|
m_time_since_reversing = 0.0f;
|
||||||
m_time_since_uturn = 0.0f;
|
m_time_since_uturn = 0.0f;
|
||||||
|
m_turn_radius = 0.0f;
|
||||||
|
m_turn_angle = 0.0f;
|
||||||
m_on_node.clear();
|
m_on_node.clear();
|
||||||
m_path_corners.clear();
|
m_aiming_points.clear();
|
||||||
m_portals.clear();
|
m_aiming_nodes.clear();
|
||||||
|
|
||||||
m_cur_difficulty = race_manager->getDifficulty();
|
m_cur_difficulty = race_manager->getDifficulty();
|
||||||
AIBaseController::reset();
|
AIBaseController::reset();
|
||||||
@@ -72,10 +87,14 @@ void ArenaAI::update(float dt)
|
|||||||
// This is used to enable firing an item backwards.
|
// This is used to enable firing an item backwards.
|
||||||
m_controls->m_look_back = false;
|
m_controls->m_look_back = false;
|
||||||
m_controls->m_nitro = false;
|
m_controls->m_nitro = false;
|
||||||
|
m_avoiding_banana = false;
|
||||||
|
|
||||||
// Don't do anything if there is currently a kart animations shown.
|
// Don't do anything if there is currently a kart animations shown.
|
||||||
if (m_kart->getKartAnimation())
|
if (m_kart->getKartAnimation())
|
||||||
|
{
|
||||||
|
resetAfterStop();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isWaiting())
|
if (isWaiting())
|
||||||
{
|
{
|
||||||
@@ -90,16 +109,16 @@ void ArenaAI::update(float dt)
|
|||||||
findClosestKart(true);
|
findClosestKart(true);
|
||||||
findTarget();
|
findTarget();
|
||||||
handleArenaItems(dt);
|
handleArenaItems(dt);
|
||||||
handleArenaBanana();
|
|
||||||
|
|
||||||
if (m_kart->getSpeed() > 15.0f && m_cur_kart_pos_data.angle < 0.2f)
|
if (m_kart->getSpeed() > 15.0f && m_turn_angle < 20)
|
||||||
{
|
{
|
||||||
// Only use nitro when target is straight
|
// Only use nitro when turn angle is big (180 - angle)
|
||||||
m_controls->m_nitro = true;
|
m_controls->m_nitro = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_is_uturn)
|
if (m_is_uturn)
|
||||||
{
|
{
|
||||||
|
resetAfterStop();
|
||||||
handleArenaUTurn(dt);
|
handleArenaUTurn(dt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -113,6 +132,129 @@ void ArenaAI::update(float dt)
|
|||||||
|
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool ArenaAI::updateAimingPosition()
|
||||||
|
{
|
||||||
|
// Notice: we use the point ahead of kart to determine next node,
|
||||||
|
// to compensate the time difference between steering
|
||||||
|
m_current_forward_point =
|
||||||
|
m_kart->getTrans()(Vec3(0, 0, m_kart->getKartLength()));
|
||||||
|
m_current_forward_node = BattleGraph::get()->pointToNode
|
||||||
|
(m_current_forward_node, m_current_forward_point,
|
||||||
|
false/*ignore_vertical*/);
|
||||||
|
|
||||||
|
// Use current node if forward node is unknown, or near the target
|
||||||
|
const int forward = (m_current_forward_node == BattleGraph::UNKNOWN_POLY ||
|
||||||
|
m_current_forward_node == m_target_node ||
|
||||||
|
getCurrentNode() == m_target_node ? getCurrentNode() :
|
||||||
|
m_current_forward_node);
|
||||||
|
|
||||||
|
if (forward == BattleGraph::UNKNOWN_POLY ||
|
||||||
|
m_target_node == BattleGraph::UNKNOWN_POLY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (forward == m_target_node)
|
||||||
|
{
|
||||||
|
m_aiming_points.push_back(BattleGraph::get()
|
||||||
|
->getPolyOfNode(forward).getCenter());
|
||||||
|
m_aiming_points.push_back(m_target_point);
|
||||||
|
|
||||||
|
m_aiming_nodes.insert(forward);
|
||||||
|
m_aiming_nodes.insert(getCurrentNode());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int next_node = BattleGraph::get()
|
||||||
|
->getNextShortestPathPoly(forward, m_target_node);
|
||||||
|
if (next_node == BattleGraph::UNKNOWN_POLY)
|
||||||
|
{
|
||||||
|
Log::error("ArenaAI", "Next node is unknown, did you forget to link"
|
||||||
|
"adjacent face in navmesh?");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_aiming_points.push_back(BattleGraph::get()
|
||||||
|
->getPolyOfNode(forward).getCenter());
|
||||||
|
m_aiming_points.push_back(BattleGraph::get()
|
||||||
|
->getPolyOfNode(next_node).getCenter());
|
||||||
|
|
||||||
|
m_aiming_nodes.insert(forward);
|
||||||
|
m_aiming_nodes.insert(next_node);
|
||||||
|
m_aiming_nodes.insert(getCurrentNode());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // updateAimingPosition
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** This function sets the steering.
|
||||||
|
* \param dt Time step size.
|
||||||
|
*/
|
||||||
|
void ArenaAI::handleArenaSteering(const float dt)
|
||||||
|
{
|
||||||
|
const int current_node = getCurrentNode();
|
||||||
|
|
||||||
|
if (current_node == BattleGraph::UNKNOWN_POLY ||
|
||||||
|
m_target_node == BattleGraph::UNKNOWN_POLY)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_aiming_points.clear();
|
||||||
|
m_aiming_nodes.clear();
|
||||||
|
const bool found_position = updateAimingPosition();
|
||||||
|
if (ignorePathFinding())
|
||||||
|
{
|
||||||
|
// Steer directly
|
||||||
|
checkPosition(m_target_point, &m_cur_kart_pos_data);
|
||||||
|
#ifdef AI_DEBUG
|
||||||
|
m_debug_sphere->setPosition(m_target_point.toIrrVector());
|
||||||
|
#endif
|
||||||
|
if (m_cur_kart_pos_data.behind)
|
||||||
|
{
|
||||||
|
m_adjusting_side = m_cur_kart_pos_data.lhs;
|
||||||
|
m_is_uturn = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float target_angle = steerToPoint(m_target_point);
|
||||||
|
setSteering(target_angle, dt);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (found_position)
|
||||||
|
{
|
||||||
|
updateBananaLocation();
|
||||||
|
assert(m_aiming_points.size() == 2);
|
||||||
|
updateTurnRadius(m_kart->getXYZ(), m_aiming_points[0],
|
||||||
|
m_aiming_points[1]);
|
||||||
|
m_target_point = m_aiming_points[1];
|
||||||
|
checkPosition(m_target_point, &m_cur_kart_pos_data);
|
||||||
|
#ifdef AI_DEBUG
|
||||||
|
m_debug_sphere->setVisible(true);
|
||||||
|
m_debug_sphere_next->setVisible(true);
|
||||||
|
m_debug_sphere->setPosition(m_aiming_points[0].toIrrVector());
|
||||||
|
m_debug_sphere_next->setPosition(m_aiming_points[1].toIrrVector());
|
||||||
|
#endif
|
||||||
|
if (m_cur_kart_pos_data.behind)
|
||||||
|
{
|
||||||
|
m_adjusting_side = m_cur_kart_pos_data.lhs;
|
||||||
|
m_is_uturn = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float target_angle = steerToPoint(m_target_point);
|
||||||
|
setSteering(target_angle, dt);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Do nothing (go straight) if no targets found
|
||||||
|
setSteering(0.0f, dt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} // handleSteering
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void ArenaAI::checkIfStuck(const float dt)
|
void ArenaAI::checkIfStuck(const float dt)
|
||||||
{
|
{
|
||||||
@@ -154,6 +296,7 @@ void ArenaAI::checkIfStuck(const float dt)
|
|||||||
*/
|
*/
|
||||||
void ArenaAI::handleArenaAcceleration(const float dt)
|
void ArenaAI::handleArenaAcceleration(const float dt)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_controls->m_brake)
|
if (m_controls->m_brake)
|
||||||
{
|
{
|
||||||
m_controls->m_accel = 0.0f;
|
m_controls->m_accel = 0.0f;
|
||||||
@@ -173,7 +316,7 @@ void ArenaAI::handleArenaUTurn(const float dt)
|
|||||||
|
|
||||||
if (fabsf(m_kart->getSpeed()) >
|
if (fabsf(m_kart->getSpeed()) >
|
||||||
(m_kart->getKartProperties()->getEngineMaxSpeed() / 5)
|
(m_kart->getKartProperties()->getEngineMaxSpeed() / 5)
|
||||||
&& m_kart->getSpeed() < 0) // Try to emulate reverse like human players
|
&& m_kart->getSpeed() < 0) // Try to emulate reverse like human players
|
||||||
m_controls->m_accel = -0.06f;
|
m_controls->m_accel = -0.06f;
|
||||||
else
|
else
|
||||||
m_controls->m_accel = -5.0f;
|
m_controls->m_accel = -5.0f;
|
||||||
@@ -201,6 +344,7 @@ bool ArenaAI::handleArenaUnstuck(const float dt)
|
|||||||
{
|
{
|
||||||
if (!m_is_stuck || m_is_uturn) return false;
|
if (!m_is_stuck || m_is_uturn) return false;
|
||||||
|
|
||||||
|
resetAfterStop();
|
||||||
setSteering(0.0f, dt);
|
setSteering(0.0f, dt);
|
||||||
|
|
||||||
if (fabsf(m_kart->getSpeed()) >
|
if (fabsf(m_kart->getSpeed()) >
|
||||||
@@ -223,287 +367,76 @@ bool ArenaAI::handleArenaUnstuck(const float dt)
|
|||||||
} // handleArenaUnstuck
|
} // handleArenaUnstuck
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** This function sets the steering.
|
void ArenaAI::updateBananaLocation()
|
||||||
* \param dt Time step size.
|
|
||||||
*/
|
|
||||||
void ArenaAI::handleArenaSteering(const float dt)
|
|
||||||
{
|
{
|
||||||
const int current_node = getCurrentNode();
|
std::vector<std::pair<const Item*, int>>& item_list =
|
||||||
|
|
||||||
if (current_node == BattleGraph::UNKNOWN_POLY ||
|
|
||||||
m_target_node == BattleGraph::UNKNOWN_POLY) return;
|
|
||||||
|
|
||||||
if (m_target_node == current_node)
|
|
||||||
{
|
|
||||||
// Very close to the item, steer directly
|
|
||||||
checkPosition(m_target_point, &m_cur_kart_pos_data);
|
|
||||||
#ifdef AI_DEBUG
|
|
||||||
m_debug_sphere->setPosition(m_target_point.toIrrVector());
|
|
||||||
#endif
|
|
||||||
if (m_cur_kart_pos_data.behind)
|
|
||||||
{
|
|
||||||
m_adjusting_side = m_cur_kart_pos_data.on_side;
|
|
||||||
m_is_uturn = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float target_angle = steerToPoint(m_target_point);
|
|
||||||
setSteering(target_angle, dt);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (m_target_node != current_node)
|
|
||||||
{
|
|
||||||
findPortals(current_node, m_target_node);
|
|
||||||
stringPull(m_kart->getXYZ(), m_target_point);
|
|
||||||
if (m_path_corners.size() > 0)
|
|
||||||
m_target_point = m_path_corners[0];
|
|
||||||
|
|
||||||
checkPosition(m_target_point, &m_cur_kart_pos_data);
|
|
||||||
#ifdef AI_DEBUG
|
|
||||||
m_debug_sphere->setPosition(m_target_point.toIrrVector());
|
|
||||||
#endif
|
|
||||||
if (m_cur_kart_pos_data.behind)
|
|
||||||
{
|
|
||||||
m_adjusting_side = m_cur_kart_pos_data.on_side;
|
|
||||||
m_is_uturn = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float target_angle = steerToPoint(m_target_point);
|
|
||||||
setSteering(target_angle, dt);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Do nothing (go straight) if no targets found
|
|
||||||
setSteering(0.0f, dt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} // handleSteering
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ArenaAI::handleArenaBanana()
|
|
||||||
{
|
|
||||||
if (m_is_uturn) return;
|
|
||||||
|
|
||||||
const std::vector< std::pair<const Item*, int> >& item_list =
|
|
||||||
BattleGraph::get()->getItemList();
|
BattleGraph::get()->getItemList();
|
||||||
const unsigned int items_count = item_list.size();
|
|
||||||
for (unsigned int i = 0; i < items_count; ++i)
|
std::set<int>::iterator node = m_aiming_nodes.begin();
|
||||||
|
while (node != m_aiming_nodes.end())
|
||||||
{
|
{
|
||||||
const Item* item = item_list[i].first;
|
m_test_node_for_banana = *node;
|
||||||
if (item->getType() == Item::ITEM_BANANA && !item->wasCollected())
|
std::vector<std::pair<const Item*, int>>::iterator it =
|
||||||
|
std::find_if(item_list.begin(), item_list.end(), isNodeWithBanana);
|
||||||
|
|
||||||
|
if (it != item_list.end())
|
||||||
{
|
{
|
||||||
posData banana_pos = {0};
|
Vec3 banana_lc;
|
||||||
Vec3 banana_lc(0, 0, 0);
|
checkPosition(it->first->getXYZ(), NULL, &banana_lc,
|
||||||
checkPosition(item->getXYZ(), &banana_pos, &banana_lc);
|
true/*use_front_xyz*/);
|
||||||
if (banana_pos.angle < 0.2f && banana_pos.distance < 7.5f &&
|
|
||||||
!banana_pos.behind)
|
// If satisfy the below condition, AI should not eat banana:
|
||||||
|
// banana_lc.z() < 0.0f, behind the kart
|
||||||
|
if (banana_lc.z() < 0.0f)
|
||||||
{
|
{
|
||||||
// Check whether it's straight ahead towards a banana
|
node++;
|
||||||
// If so, adjust target point
|
|
||||||
banana_lc = (banana_pos.on_side ? banana_lc + Vec3 (2, 0, 0) :
|
|
||||||
banana_lc - Vec3 (2, 0, 0));
|
|
||||||
m_target_point = m_kart->getTrans()(banana_lc);
|
|
||||||
m_target_node = BattleGraph::get()
|
|
||||||
->pointToNode(getCurrentNode(), m_target_point,
|
|
||||||
false/*ignore_vertical*/);
|
|
||||||
|
|
||||||
// Handle one banana only
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // handleArenaBanana
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** This function finds the polyon edges(portals) that the AI will cross before
|
|
||||||
* reaching its destination. We start from the current polygon and call
|
|
||||||
* BattleGraph::getNextShortestPathPoly() to find the next polygon on the shortest
|
|
||||||
* path to the destination. Then find the common edge between the current
|
|
||||||
* poly and the next poly, store it and step through the channel.
|
|
||||||
*
|
|
||||||
* 1----2----3 In this case, the portals are:
|
|
||||||
* |strt| | (2,5) (4,5) (10,7) (10,9) (11,12)
|
|
||||||
* 6----5----4
|
|
||||||
* | |
|
|
||||||
* 7----10----11----14
|
|
||||||
* | | | end |
|
|
||||||
* 8----9-----12----13
|
|
||||||
*
|
|
||||||
* \param start The start node(polygon) of the channel.
|
|
||||||
* \param end The end node(polygon) of the channel.
|
|
||||||
*/
|
|
||||||
void ArenaAI::findPortals(int start, int end)
|
|
||||||
{
|
|
||||||
int this_node = start;
|
|
||||||
|
|
||||||
// We can't use NULL because NULL==0 which is a valid node, so we initialize
|
|
||||||
// with a value that is always invalid.
|
|
||||||
int next_node = -999;
|
|
||||||
|
|
||||||
m_portals.clear();
|
|
||||||
|
|
||||||
while (next_node != end && this_node != -1 && next_node != -1 && this_node != end)
|
|
||||||
{
|
|
||||||
next_node = BattleGraph::get()->getNextShortestPathPoly(this_node, end);
|
|
||||||
if (next_node == BattleGraph::UNKNOWN_POLY || next_node == -999) return;
|
|
||||||
|
|
||||||
std::vector<int> this_node_verts =
|
|
||||||
NavMesh::get()->getNavPoly(this_node).getVerticesIndex();
|
|
||||||
std::vector<int> next_node_verts=
|
|
||||||
NavMesh::get()->getNavPoly(next_node).getVerticesIndex();
|
|
||||||
|
|
||||||
// this_node_verts and next_node_verts hold vertices of polygons in CCW order
|
|
||||||
// We reverse next_node_verts so it becomes easy to compare edges in the next step
|
|
||||||
std::reverse(next_node_verts.begin(),next_node_verts.end());
|
|
||||||
|
|
||||||
Vec3 portalLeft, portalRight;
|
|
||||||
//bool flag = 0;
|
|
||||||
for (unsigned int n_i = 0; n_i < next_node_verts.size(); n_i++)
|
|
||||||
{
|
|
||||||
for (unsigned int t_i = 0; t_i < this_node_verts.size(); t_i++)
|
|
||||||
{
|
|
||||||
if ((next_node_verts[n_i] == this_node_verts[t_i]) &&
|
|
||||||
(next_node_verts[(n_i+1)%next_node_verts.size()] ==
|
|
||||||
this_node_verts[(t_i+1)%this_node_verts.size()]))
|
|
||||||
{
|
|
||||||
portalLeft = NavMesh::get()->
|
|
||||||
getVertex(this_node_verts[(t_i+1)%this_node_verts.size()]);
|
|
||||||
|
|
||||||
portalRight = NavMesh::get()->getVertex(this_node_verts[t_i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_portals.push_back(std::make_pair(portalLeft, portalRight));
|
|
||||||
// for debugging:
|
|
||||||
//m_debug_sphere->setPosition((portalLeft).toIrrVector());
|
|
||||||
this_node = next_node;
|
|
||||||
}
|
|
||||||
} // findPortals
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** This function implements the funnel algorithm for finding shortest paths
|
|
||||||
* through a polygon channel. This means that we should move from corner to
|
|
||||||
* corner to move on the most straight and shortest path to the destination.
|
|
||||||
* This can be visualized as pulling a string from the end point to the start.
|
|
||||||
* The string will bend at the corners, and this algorithm will find those
|
|
||||||
* corners using portals from findPortals(). The AI will aim at the first
|
|
||||||
* corner and the rest can be used for estimating the curve (braking).
|
|
||||||
*
|
|
||||||
* 1----2----3 In this case, the corners are:
|
|
||||||
* |strt| | <5,10,end>
|
|
||||||
* 6----5----4
|
|
||||||
* | |
|
|
||||||
* 7----10----11----14
|
|
||||||
* | | | end |
|
|
||||||
* 8----9-----12----13
|
|
||||||
*
|
|
||||||
* \param start_pos The start position (usually the AI's current position).
|
|
||||||
* \param end_pos The end position (m_target_point).
|
|
||||||
*/
|
|
||||||
void ArenaAI::stringPull(const Vec3& start_pos, const Vec3& end_pos)
|
|
||||||
{
|
|
||||||
Vec3 funnel_apex = start_pos;
|
|
||||||
Vec3 funnel_left = m_portals[0].first;
|
|
||||||
Vec3 funnel_right = m_portals[0].second;
|
|
||||||
unsigned int apex_index=0, fun_left_index=0, fun_right_index=0;
|
|
||||||
m_portals.push_back(std::make_pair(end_pos, end_pos));
|
|
||||||
m_path_corners.clear();
|
|
||||||
const float eps=0.0001f;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < m_portals.size(); i++)
|
|
||||||
{
|
|
||||||
Vec3 portal_left = m_portals[i].first;
|
|
||||||
Vec3 portal_right = m_portals[i].second;
|
|
||||||
|
|
||||||
//Compute for left edge
|
|
||||||
if ((funnel_left == funnel_apex) ||
|
|
||||||
portal_left.sideOfLine2D(funnel_apex, funnel_left) <= -eps)
|
|
||||||
{
|
|
||||||
funnel_left = 0.98f*portal_left + 0.02f*portal_right;
|
|
||||||
//funnel_left = portal_left;
|
|
||||||
fun_left_index = i;
|
|
||||||
|
|
||||||
if (portal_left.sideOfLine2D(funnel_apex, funnel_right) < -eps)
|
|
||||||
{
|
|
||||||
funnel_apex = funnel_right;
|
|
||||||
apex_index = fun_right_index;
|
|
||||||
m_path_corners.push_back(funnel_apex);
|
|
||||||
|
|
||||||
funnel_left = funnel_apex;
|
|
||||||
funnel_right = funnel_apex;
|
|
||||||
i = apex_index;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the node AI will pass has a banana, adjust the aim position
|
||||||
|
banana_lc = (banana_lc.x() < 0 ? banana_lc + Vec3(5, 0, 0) :
|
||||||
|
banana_lc - Vec3(5, 0, 0));
|
||||||
|
m_aiming_points[1] = m_kart->getTrans()(banana_lc);
|
||||||
|
m_avoiding_banana = true;
|
||||||
|
// Handle one banana only
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
node++;
|
||||||
//Compute for right edge
|
|
||||||
if ((funnel_right == funnel_apex) ||
|
|
||||||
portal_right.sideOfLine2D(funnel_apex, funnel_right) >= eps)
|
|
||||||
{
|
|
||||||
funnel_right = 0.98f*portal_right + 0.02f*portal_left;
|
|
||||||
//funnel_right = portal_right;
|
|
||||||
fun_right_index = i;
|
|
||||||
|
|
||||||
if (portal_right.sideOfLine2D(funnel_apex, funnel_left) > eps)
|
|
||||||
{
|
|
||||||
funnel_apex = funnel_left;
|
|
||||||
apex_index = fun_left_index;
|
|
||||||
m_path_corners.push_back(funnel_apex);
|
|
||||||
|
|
||||||
funnel_left = funnel_apex;
|
|
||||||
funnel_right = funnel_apex;
|
|
||||||
i = apex_index;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Push end_pos to m_path_corners so if no corners, we aim at target
|
} // updateBananaLocation
|
||||||
m_path_corners.push_back(end_pos);
|
|
||||||
} // stringPull
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** This function handles braking. It calls determineTurnRadius() to find out
|
/** This function handles braking. It used the turn radius found by
|
||||||
* the curve radius. Depending on the turn radius, it finds out the maximum
|
* updateTurnRadius(). Depending on the turn radius, it finds out the maximum
|
||||||
* speed. If the current speed is greater than the max speed and a set minimum
|
* speed. If the current speed is greater than the max speed and a set minimum
|
||||||
* speed, brakes are applied.
|
* speed, brakes are applied.
|
||||||
*/
|
*/
|
||||||
void ArenaAI::handleArenaBraking()
|
void ArenaAI::handleArenaBraking()
|
||||||
{
|
{
|
||||||
m_controls->m_brake = false;
|
|
||||||
|
|
||||||
if (getCurrentNode() == BattleGraph::UNKNOWN_POLY ||
|
|
||||||
m_target_node == BattleGraph::UNKNOWN_POLY) return;
|
|
||||||
|
|
||||||
// A kart will not brake when the speed is already slower than this
|
// A kart will not brake when the speed is already slower than this
|
||||||
// value. This prevents a kart from going too slow (or even backwards)
|
// value. This prevents a kart from going too slow (or even backwards)
|
||||||
// in tight curves.
|
// in tight curves.
|
||||||
const float MIN_SPEED = 5.0f;
|
const float MIN_SPEED = 5.0f;
|
||||||
|
|
||||||
std::vector<Vec3> points;
|
if (forceBraking() && m_kart->getSpeed() > MIN_SPEED)
|
||||||
|
{
|
||||||
|
// Brake now
|
||||||
|
m_controls->m_brake = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
points.push_back(m_kart->getXYZ());
|
m_controls->m_brake = false;
|
||||||
points.push_back(m_path_corners[0]);
|
|
||||||
points.push_back((m_path_corners.size()>=2) ? m_path_corners[1] : m_path_corners[0]);
|
|
||||||
|
|
||||||
float current_curve_radius = determineTurnRadius(points);
|
if (getCurrentNode() == BattleGraph::UNKNOWN_POLY ||
|
||||||
|
m_target_node == BattleGraph::UNKNOWN_POLY) return;
|
||||||
|
|
||||||
Vec3 d1 = m_kart->getXYZ() - m_target_point;
|
if (m_aiming_points.empty()) return;
|
||||||
Vec3 d2 = m_kart->getXYZ() - m_path_corners[0];
|
|
||||||
if (d1.length2_2d() < d2.length2_2d())
|
|
||||||
current_curve_radius = d1.length_2d();
|
|
||||||
|
|
||||||
float max_turn_speed = m_kart->getSpeedForTurnRadius(current_curve_radius);
|
const float max_turn_speed = m_kart->getSpeedForTurnRadius(m_turn_radius);
|
||||||
|
|
||||||
if (m_kart->getSpeed() > max_turn_speed &&
|
if (m_kart->getSpeed() > 1.25f * max_turn_speed &&
|
||||||
|
fabsf(m_controls->m_steer) > 0.95f &&
|
||||||
m_kart->getSpeed() > MIN_SPEED)
|
m_kart->getSpeed() > MIN_SPEED)
|
||||||
{
|
{
|
||||||
m_controls->m_brake = true;
|
m_controls->m_brake = true;
|
||||||
@@ -512,60 +445,58 @@ void ArenaAI::handleArenaBraking()
|
|||||||
} // handleArenaBraking
|
} // handleArenaBraking
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** The turn radius is determined by fitting a parabola to 3 points: current
|
void ArenaAI::updateTurnRadius(const Vec3& p1, const Vec3& p2,
|
||||||
* location of AI, first corner and the second corner. Once the constants are
|
const Vec3& p3)
|
||||||
* computed, a formula is used to find the radius of curvature at the kart's
|
|
||||||
* current location.
|
|
||||||
* NOTE: This method does not apply enough braking, should think of something
|
|
||||||
* else.
|
|
||||||
*/
|
|
||||||
float ArenaAI::determineTurnRadius( std::vector<Vec3>& points )
|
|
||||||
{
|
{
|
||||||
// Declaring variables
|
// First use cosine formula to find out the angle made by the distance
|
||||||
float a, b;
|
// between kart (point one) to point two and point two between point three
|
||||||
irr::core::CMatrix4<float> A;
|
const float a = (p1 - p2).length();
|
||||||
irr::core::CMatrix4<float> X;
|
const float b = (p2 - p3).length();
|
||||||
irr::core::CMatrix4<float> B;
|
const float c = (p1 - p3).length();
|
||||||
|
const float angle = 180 - findAngleFrom3Edges(a, b, c);
|
||||||
|
|
||||||
//Populating matrices
|
// Only calculate radius if not almost straight line
|
||||||
for (unsigned int i = 0; i < 3; i++)
|
if (angle > 1 && angle < 179)
|
||||||
{
|
{
|
||||||
A(i, 0) = points[i].x()*points[i].x();
|
// angle
|
||||||
A(i, 1) = points[i].x();
|
// ^
|
||||||
A(i, 2) = 1.0f;
|
// a / \ b
|
||||||
A(i, 3) = 0.0f;
|
// 90/\ /\90
|
||||||
|
// \ / \ /
|
||||||
|
// \ /
|
||||||
|
// \ /
|
||||||
|
// \ /
|
||||||
|
// |
|
||||||
|
// Try to estimate the turn radius with the help of a kite-like
|
||||||
|
// polygon as shown, find out the lowest angle which is
|
||||||
|
// (4 - 2) * 180 - 90 - 90 - angle (180 - angle from above)
|
||||||
|
// Then we use this value as the angle of a sector of circle,
|
||||||
|
// a + b as the arc length, then the radius can be calculated easily
|
||||||
|
m_turn_radius = ((a + b) / (angle / 360)) / M_PI / 2;
|
||||||
}
|
}
|
||||||
A(3, 0) = A(3, 1) = A(3, 2) = 0.0f;
|
else
|
||||||
A(3, 3) = 1.0f;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 3; i++)
|
|
||||||
{
|
{
|
||||||
B(i, 0) = points[i].z();
|
// Return large radius so no braking is needed otherwise
|
||||||
B(i, 1) = 0.0f;
|
m_turn_radius = 45.0f;
|
||||||
B(i, 2) = 0.0f;
|
|
||||||
B(i, 3) = 0.0f;
|
|
||||||
}
|
}
|
||||||
B(3, 0) = B(3, 1) = B(3, 2) = B(3, 3) = 0.0f;
|
m_turn_angle = angle;
|
||||||
|
|
||||||
//Computing inverse : X = inv(A)*B
|
} // updateTurnRadius
|
||||||
irr::core::CMatrix4<float> invA;
|
|
||||||
if (!A.getInverse(invA))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
X = invA*B;
|
//-----------------------------------------------------------------------------
|
||||||
a = X(0, 0);
|
float ArenaAI::findAngleFrom3Edges(float a, float b, float c)
|
||||||
b = X(0, 1);
|
{
|
||||||
//c = X(0, 2);
|
// Cosine forumla : c2 = a2 + b2 - 2ab cos C
|
||||||
|
float test_value = ((c * c) - (a * a) - (b * b)) / (-(2 * a * b));
|
||||||
|
// Prevent error
|
||||||
|
if (test_value < -1)
|
||||||
|
test_value = -1;
|
||||||
|
else if (test_value > 1)
|
||||||
|
test_value = 1;
|
||||||
|
|
||||||
float x = points.front().x();
|
return acosf(test_value) * RAD_TO_DEGREE;
|
||||||
//float z = a*pow(x, 2) + b*x + c;
|
|
||||||
float dx_by_dz = 2*a*x + b;
|
|
||||||
float d2x_by_dz = 2*a;
|
|
||||||
|
|
||||||
float radius = pow(abs(1 + pow(dx_by_dz, 2)), 1.5f)/ abs(d2x_by_dz);
|
} // findAngleFrom3Edges
|
||||||
|
|
||||||
return radius;
|
|
||||||
} // determineTurnRadius
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void ArenaAI::handleArenaItems(const float dt)
|
void ArenaAI::handleArenaItems(const float dt)
|
||||||
@@ -663,7 +594,8 @@ void ArenaAI::handleArenaItems(const float dt)
|
|||||||
if (m_time_since_last_shot < 1.0f) break;
|
if (m_time_since_last_shot < 1.0f) break;
|
||||||
|
|
||||||
if (m_closest_kart_pos_data.distance < 6.0f &&
|
if (m_closest_kart_pos_data.distance < 6.0f &&
|
||||||
(difficulty || perfect_aim))
|
(difficulty || perfect_aim) &&
|
||||||
|
!m_closest_kart->isInvulnerable())
|
||||||
{
|
{
|
||||||
m_controls->m_fire = true;
|
m_controls->m_fire = true;
|
||||||
m_controls->m_look_back = fire_behind;
|
m_controls->m_look_back = fire_behind;
|
||||||
@@ -755,14 +687,15 @@ void ArenaAI::collectItemInArena(Vec3* aim_point, int* target_node) const
|
|||||||
m_kart->getKartProperties()->getNitroSmallContainer()))
|
m_kart->getKartProperties()->getNitroSmallContainer()))
|
||||||
continue; // Ignore nitro when already has some
|
continue; // Ignore nitro when already has some
|
||||||
|
|
||||||
Vec3 d = item->getXYZ() - m_kart->getXYZ();
|
float test_distance = BattleGraph::get()
|
||||||
if (d.length_2d() <= distance &&
|
->getDistance(item_list[i].second, getCurrentNode());
|
||||||
|
if (test_distance <= distance &&
|
||||||
(item->getType() == Item::ITEM_BONUS_BOX ||
|
(item->getType() == Item::ITEM_BONUS_BOX ||
|
||||||
item->getType() == Item::ITEM_NITRO_BIG ||
|
item->getType() == Item::ITEM_NITRO_BIG ||
|
||||||
item->getType() == Item::ITEM_NITRO_SMALL))
|
item->getType() == Item::ITEM_NITRO_SMALL))
|
||||||
{
|
{
|
||||||
closest_item_num = i;
|
closest_item_num = i;
|
||||||
distance = d.length_2d();
|
distance = test_distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ protected:
|
|||||||
/** For debugging purpose: a sphere indicating where the AI
|
/** For debugging purpose: a sphere indicating where the AI
|
||||||
* is targeting at. */
|
* is targeting at. */
|
||||||
irr::scene::ISceneNode *m_debug_sphere;
|
irr::scene::ISceneNode *m_debug_sphere;
|
||||||
|
irr::scene::ISceneNode *m_debug_sphere_next;
|
||||||
|
|
||||||
/** The node(poly) at which the target point lies in. */
|
/** The node(poly) at which the target point lies in. */
|
||||||
int m_target_node;
|
int m_target_node;
|
||||||
@@ -63,7 +64,10 @@ protected:
|
|||||||
/** The target point. */
|
/** The target point. */
|
||||||
Vec3 m_target_point;
|
Vec3 m_target_point;
|
||||||
|
|
||||||
void collectItemInArena(Vec3*, int*) const;
|
bool m_avoiding_banana;
|
||||||
|
|
||||||
|
void collectItemInArena(Vec3*, int*) const;
|
||||||
|
float findAngleFrom3Edges(float a, float b, float c);
|
||||||
private:
|
private:
|
||||||
/** Used by handleArenaUTurn, it tells whether to do left or right
|
/** Used by handleArenaUTurn, it tells whether to do left or right
|
||||||
* turning when steering is overridden. */
|
* turning when steering is overridden. */
|
||||||
@@ -81,15 +85,7 @@ private:
|
|||||||
|
|
||||||
/** Holds the unique node ai has driven through, useful to tell if AI is
|
/** Holds the unique node ai has driven through, useful to tell if AI is
|
||||||
* stuck by determine the size of this set. */
|
* stuck by determine the size of this set. */
|
||||||
std::set <int> m_on_node;
|
std::set<int> m_on_node;
|
||||||
|
|
||||||
/** Holds the corner points computed using the funnel algorithm that the AI
|
|
||||||
* will eventaully move through. See stringPull(). */
|
|
||||||
std::vector<Vec3> m_path_corners;
|
|
||||||
|
|
||||||
/** Holds the set of portals that the kart will cross when moving through
|
|
||||||
* polygon channel. See findPortals(). */
|
|
||||||
std::vector<std::pair<Vec3,Vec3> > m_portals;
|
|
||||||
|
|
||||||
/** Time an item has been collected and not used. */
|
/** Time an item has been collected and not used. */
|
||||||
float m_time_since_last_shot;
|
float m_time_since_last_shot;
|
||||||
@@ -103,22 +99,35 @@ private:
|
|||||||
/** This is a timer that counts down when the kart is doing u-turn. */
|
/** This is a timer that counts down when the kart is doing u-turn. */
|
||||||
float m_time_since_uturn;
|
float m_time_since_uturn;
|
||||||
|
|
||||||
|
float m_turn_radius;
|
||||||
|
float m_turn_angle;
|
||||||
|
|
||||||
|
Vec3 m_current_forward_point;
|
||||||
|
int m_current_forward_node;
|
||||||
|
|
||||||
|
std::set<int> m_aiming_nodes;
|
||||||
|
std::vector<Vec3> m_aiming_points;
|
||||||
|
|
||||||
void checkIfStuck(const float dt);
|
void checkIfStuck(const float dt);
|
||||||
float determineTurnRadius(std::vector<Vec3>& points);
|
|
||||||
void findPortals(int start, int end);
|
|
||||||
void handleArenaAcceleration(const float dt);
|
void handleArenaAcceleration(const float dt);
|
||||||
void handleArenaBanana();
|
|
||||||
void handleArenaBraking();
|
void handleArenaBraking();
|
||||||
void handleArenaItems(const float dt);
|
void handleArenaItems(const float dt);
|
||||||
void handleArenaSteering(const float dt);
|
void handleArenaSteering(const float dt);
|
||||||
void handleArenaUTurn(const float dt);
|
void handleArenaUTurn(const float dt);
|
||||||
bool handleArenaUnstuck(const float dt);
|
bool handleArenaUnstuck(const float dt);
|
||||||
void stringPull(const Vec3&, const Vec3&);
|
bool updateAimingPosition();
|
||||||
|
void updateBananaLocation();
|
||||||
|
void updateTurnRadius(const Vec3& p1, const Vec3& p2,
|
||||||
|
const Vec3& p3);
|
||||||
virtual int getCurrentNode() const = 0;
|
virtual int getCurrentNode() const = 0;
|
||||||
virtual bool isWaiting() const = 0;
|
virtual bool isWaiting() const = 0;
|
||||||
|
virtual void resetAfterStop() {};
|
||||||
virtual void findClosestKart(bool use_difficulty) = 0;
|
virtual void findClosestKart(bool use_difficulty) = 0;
|
||||||
virtual void findTarget() = 0;
|
virtual void findTarget() = 0;
|
||||||
|
virtual bool forceBraking() { return m_avoiding_banana; }
|
||||||
|
virtual bool ignorePathFinding() { return false; }
|
||||||
public:
|
public:
|
||||||
|
static int m_test_node_for_banana;
|
||||||
ArenaAI(AbstractKart *kart);
|
ArenaAI(AbstractKart *kart);
|
||||||
virtual ~ArenaAI() {};
|
virtual ~ArenaAI() {};
|
||||||
virtual void update (float delta);
|
virtual void update (float delta);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user