mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-19 09:12:19 +00:00
Compare commits
147 commits
56b9240594
...
c89509bc4b
Author | SHA1 | Date | |
---|---|---|---|
c89509bc4b | |||
fc058fa432 | |||
3b22a3e02f | |||
ed1ef4e694 | |||
9103332e36 | |||
0948a53648 | |||
bbd34c9452 | |||
e4282f100a | |||
eb9e73f68b | |||
e0a95d14a6 | |||
fa28ed77a6 | |||
5335813629 | |||
796fa4275f | |||
5b0163d069 | |||
c9e7e0f01b | |||
cf107a81a1 | |||
4e2d7e2104 | |||
ChillerDragon | 74bb327799 | ||
22d699fbc0 | |||
51c0b4dafc | |||
5f57ba9130 | |||
69fa7ea18f | |||
41c40fb27f | |||
0664f12265 | |||
8b5da71e89 | |||
ChillerDragon | d0eebee44d | ||
1cbdb9d2f0 | |||
8f79d4252c | |||
7abad2b8a4 | |||
c64b744ad3 | |||
f599449f31 | |||
226d948acc | |||
58f14edb95 | |||
a3fc627285 | |||
f79784bec7 | |||
ccaddd2016 | |||
7a60f4a5e7 | |||
ChillerDragon | e9187cc352 | ||
ChillerDragon | 2cf6622cd7 | ||
ChillerDragon | 19a888734c | ||
ChillerDragon | 44fc871463 | ||
157498799e | |||
a017190753 | |||
e17da385dd | |||
bfc6a15df9 | |||
ChillerDragon | 2a26c1c5d6 | ||
624ac85e8c | |||
d9b031c887 | |||
403c4a40da | |||
0e2960206a | |||
a8616ef2ab | |||
ChillerDragon | 8b304cab23 | ||
9e88ca5846 | |||
ChillerDragon | 1b8e402a65 | ||
30acedaac5 | |||
bb3c76a290 | |||
341e3f6ec7 | |||
d4f72803be | |||
f2d5b83f84 | |||
fcf810cae1 | |||
50b0af1614 | |||
b5c11bc860 | |||
7951136fab | |||
ChillerDragon | 82ca4bc335 | ||
ChillerDragon | 5986ee03b9 | ||
ChillerDragon | e1cb617c42 | ||
ChillerDragon | daad41fbd7 | ||
ChillerDragon | ed49fef917 | ||
ChillerDragon | e20250cd65 | ||
36f0bcc509 | |||
dd82cf83a2 | |||
8ca93d451b | |||
871f97a283 | |||
ChillerDragon | 2c77aeef2b | ||
ChillerDragon | f053a29463 | ||
ChillerDragon | f8a4e7dbab | ||
ChillerDragon | f44def1cdd | ||
bb45db8ad3 | |||
468900acfe | |||
6ab597a465 | |||
a83248b9ec | |||
383bef93b9 | |||
f0449befa5 | |||
ChillerDragon | c02a2ed1d6 | ||
d452bcda8f | |||
60688bf80e | |||
29a205a6d9 | |||
c10b466a40 | |||
914867d980 | |||
d40cc86bfa | |||
f754054874 | |||
05970178b2 | |||
3d5b533816 | |||
cdc5b9922a | |||
528a38265e | |||
099ec44eac | |||
b641fdb8fd | |||
e54fb30e72 | |||
325f908f09 | |||
870cff3da2 | |||
4ea9ed9b2b | |||
98b0f50111 | |||
fe35322bb0 | |||
41cd82c2d3 | |||
21375f0e1d | |||
55891afc50 | |||
1d65fff3ff | |||
edcc3245f4 | |||
88739c5345 | |||
da4bc09429 | |||
ChillerDragon | 43dee5d4c5 | ||
ba4f0368a4 | |||
5cf0e5e997 | |||
218ce1f53f | |||
91ae4ca120 | |||
41fee0bb3f | |||
cc1dc405fe | |||
1dd56f1a90 | |||
ecec1ff2a7 | |||
5a66dc05f4 | |||
7df1b24491 | |||
31ee6abe82 | |||
d78032e9a6 | |||
3d6820ab68 | |||
8b7e5dee4d | |||
76c44cfb40 | |||
f407adc61c | |||
9fbbf5cde7 | |||
dc0d4b3b76 | |||
9a7bc70f76 | |||
0e016f9732 | |||
cb57aa82bf | |||
14f1b36dd1 | |||
906f75c13a | |||
7c8f9b43ac | |||
c4ff37d9d9 | |||
3a2cecb8b4 | |||
358cd20183 | |||
9d920b3575 | |||
5fb059ad92 | |||
4b8dcc3315 | |||
b30b493ab8 | |||
29f3323735 | |||
7c62b457b7 | |||
8b27a6e852 | |||
8f6d5d453e | |||
a013372be4 |
|
@ -2462,6 +2462,7 @@ if(CLIENT)
|
|||
editor_trackers.cpp
|
||||
editor_trackers.h
|
||||
editor_ui.h
|
||||
enums.h
|
||||
explanations.cpp
|
||||
layer_selector.cpp
|
||||
layer_selector.h
|
||||
|
@ -2500,8 +2501,13 @@ if(CLIENT)
|
|||
mapitems/sound.cpp
|
||||
mapitems/sound.h
|
||||
popups.cpp
|
||||
prompt.cpp
|
||||
prompt.h
|
||||
proof_mode.cpp
|
||||
proof_mode.h
|
||||
quick_action.h
|
||||
quick_actions.cpp
|
||||
quick_actions.h
|
||||
smooth_value.cpp
|
||||
smooth_value.h
|
||||
tileart.cpp
|
||||
|
@ -2924,6 +2930,7 @@ if(GTEST_FOUND OR DOWNLOAD_GTEST)
|
|||
compression.cpp
|
||||
csv.cpp
|
||||
datafile.cpp
|
||||
editor.cpp
|
||||
fs.cpp
|
||||
git_revision.cpp
|
||||
hash.cpp
|
||||
|
|
|
@ -275,9 +275,6 @@ Player
|
|||
Player country:
|
||||
== ﺐﻋﻼﻟﺍ ﺪﻠﺑ:
|
||||
|
||||
Player options
|
||||
== ﺐﻋﻼﻟﺍ ﺕﺍﺩﺍﺪﻋﺍ
|
||||
|
||||
Players
|
||||
== ﻦﻴﺒﻋﻻ
|
||||
|
||||
|
@ -773,9 +770,6 @@ Skin prefix
|
|||
Show HUD
|
||||
== ﻞﻜﺸﻟﺍ ﺭﺎﻬﻇﺍ
|
||||
|
||||
Reload
|
||||
== ﻞﻴﻤﺤﺘﻟﺍ ﺓﺩﺎﻋﺍ
|
||||
|
||||
9+ new mentions
|
||||
== 9+ ﺓﺪﻳﺪﺟ ﺕﺍﺭﺎﻌﺷﺍ
|
||||
|
||||
|
@ -1026,9 +1020,6 @@ Debug mode enabled. Press Ctrl+Shift+D to disable debug mode.
|
|||
Existing Player
|
||||
== ﺩﻮﺟﻮﻣ ﺐﻋﻼﻟﺍ
|
||||
|
||||
Your nickname '%s' is already used (%d points). Do you still want to use it?
|
||||
==
|
||||
|
||||
Checking for existing player with your name
|
||||
== ﻚﻤﺳﺎﺑ ﺐﻋﻻ ﺩﻮﺟﻭ ﻦﻣ ﻖﻘﺤﺘﻟﺍ
|
||||
|
||||
|
@ -1092,9 +1083,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1225,6 +1225,9 @@ Render complete
|
|||
Are you sure that you want to restart?
|
||||
==
|
||||
|
||||
Your nickname '%s' is already used (%d points). Do you still want to use it?
|
||||
==
|
||||
|
||||
There's an unsaved map in the editor, you might want to save it.
|
||||
==
|
||||
|
||||
|
@ -1478,6 +1481,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1645,7 +1654,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1819,6 +1828,39 @@ Unregister protocol and file extensions
|
|||
DDNet %s is available:
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Extras
|
||||
==
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#modified by:
|
||||
# Gokturk 2024-06-09 12:00:50
|
||||
# Gokturk 2024-07-17 02:24:00
|
||||
# Gokturk 2024-08-29 23:39:00
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -274,9 +275,6 @@ Play background music
|
|||
Player
|
||||
== Oyunçu
|
||||
|
||||
Player options
|
||||
== Oyunçu parametrlər
|
||||
|
||||
Players
|
||||
== Oyunçular
|
||||
|
||||
|
@ -652,9 +650,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Dummy daxil ol
|
||||
|
||||
Reload
|
||||
== Yenilə
|
||||
|
||||
Deactivate
|
||||
== Qeyri-aktiv etmək
|
||||
|
||||
|
@ -1450,9 +1445,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace interfeysi
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Xal lövhəsində klient ID-lərini göstərin
|
||||
|
||||
Show DDRace HUD
|
||||
== DDRace interfeysi göstər
|
||||
|
||||
|
@ -1870,3 +1862,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/wiki/Mapping
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== '%s' Link ünvanını həll etmək mümkün olmadı. Ətraflı məlumat üçün yerli konsola baxın
|
||||
|
||||
Connect address error
|
||||
== Link ünvanı xətası
|
||||
|
||||
Could not connect dummy
|
||||
== Dummy qoşula bilmədi
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Bu serverdə dummy icazə verilmir
|
||||
|
||||
Please wait…
|
||||
== Zəhmət olmasa gözləyin…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Klient ID'sini göstərin (aparıcı lövhə, söhbət, izləyici)
|
||||
|
||||
Normal:
|
||||
== Normal:
|
||||
|
||||
Team:
|
||||
== Komanda:
|
||||
|
||||
Dummy settings
|
||||
== Dummy parametrlər
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Dummy parametrlərini redaktə etmək üçün açın
|
||||
|
||||
Randomize
|
||||
== Təsadüfi
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== '%s' Bunu silmək istədiyinizə əminsiniz?
|
||||
|
||||
Delete skin
|
||||
== Skini silin
|
||||
|
||||
Basic
|
||||
== Sadə
|
||||
|
||||
Custom
|
||||
== Xüsusi
|
||||
|
||||
Unable to delete skin
|
||||
== Skin silinə bilməz
|
||||
|
||||
Customize
|
||||
== Fərdiləşdirmək
|
||||
|
|
|
@ -282,9 +282,6 @@ Player
|
|||
Player country:
|
||||
== Краіна гульца:
|
||||
|
||||
Player options
|
||||
== Опцыі гульца
|
||||
|
||||
Players
|
||||
== Гульцы
|
||||
|
||||
|
@ -868,9 +865,6 @@ Loading ghost files
|
|||
Time
|
||||
== Час
|
||||
|
||||
Reload
|
||||
== Перазагрузіць
|
||||
|
||||
Deactivate
|
||||
== Выключыць
|
||||
|
||||
|
@ -1167,9 +1161,6 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Паказваць ID кліента ў табло ачкоў
|
||||
|
||||
Show DDRace HUD
|
||||
== Паказваць DDRace HUD
|
||||
|
||||
|
@ -1706,6 +1697,7 @@ Regular background color
|
|||
Entities background color
|
||||
== Колер фону энтыты
|
||||
|
||||
[Graphics error]
|
||||
An error during command recording occurred. Try to update your GPU drivers.
|
||||
== Адбылася памылка падчас выканання каманды запісу. Паспрабуйце абнавіць драйверы відэакарты.
|
||||
|
||||
|
@ -1874,3 +1866,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/wiki/Mapping
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
|
|
@ -280,9 +280,6 @@ Player
|
|||
Player country:
|
||||
== Država
|
||||
|
||||
Player options
|
||||
== Postavke igrača
|
||||
|
||||
Players
|
||||
== Igrači
|
||||
|
||||
|
@ -651,9 +648,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Konektuj dummy-a
|
||||
|
||||
Reload
|
||||
== Reload
|
||||
|
||||
Deactivate
|
||||
== Deaktiviraj
|
||||
|
||||
|
@ -951,9 +945,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1385,6 +1388,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1591,7 +1600,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1777,6 +1786,39 @@ Chat command (e.g. showall 1)
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
# Rafael Fontenelle 2024-04-30 14:52:00
|
||||
# Rafael Fontenelle 2024-06-11 22:43:00
|
||||
# Rafael Fontenelle 2024-07-17 12:04:00
|
||||
# Rafael Fontenelle 2024-09-02 16:02:00
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -311,9 +312,6 @@ Player
|
|||
Player country:
|
||||
== País do jogador:
|
||||
|
||||
Player options
|
||||
== Opções do jogador
|
||||
|
||||
Players
|
||||
== Jogadores
|
||||
|
||||
|
@ -818,9 +816,6 @@ Show DDNet map finishes in server browser
|
|||
transmits your player name to info.ddnet.org
|
||||
== transmite seu nome de jogador para info.ddnet.org
|
||||
|
||||
Reload
|
||||
== Recarregar
|
||||
|
||||
Time
|
||||
== Tempo
|
||||
|
||||
|
@ -1376,9 +1371,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== HUD do DDRace
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Mostrar IDs de cliente no placar
|
||||
|
||||
Show DDRace HUD
|
||||
== Mostrar HUD do DDRace
|
||||
|
||||
|
@ -1901,3 +1893,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/wiki/Mapping
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== Não foi possível resolver o endereço de conexão '%s'. Veja o console local para detalhes.
|
||||
|
||||
Connect address error
|
||||
== Erro no endereço de conexão
|
||||
|
||||
Could not connect dummy
|
||||
== Não foi possível conectar o dummy
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Dummy não é permitido neste servidor
|
||||
|
||||
Please wait…
|
||||
== Por favor, aguarde…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Mostrar IDs de clientes (placar, chat, observador)
|
||||
|
||||
Normal:
|
||||
== Normal:
|
||||
|
||||
Team:
|
||||
== Time:
|
||||
|
||||
Dummy settings
|
||||
== Configurações do dummy
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Alterne para editar suas configurações do dummy
|
||||
|
||||
Randomize
|
||||
== Aleatorizar
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== Tem certeza que deseja excluir '%s'?
|
||||
|
||||
Delete skin
|
||||
== Excluir skin
|
||||
|
||||
Basic
|
||||
== Básico
|
||||
|
||||
Custom
|
||||
== Personalizado
|
||||
|
||||
Unable to delete skin
|
||||
== Não foi possível excluir skin
|
||||
|
||||
Customize
|
||||
== Personalizar
|
||||
|
|
|
@ -277,9 +277,6 @@ Player
|
|||
Player country:
|
||||
== Страна на играча:
|
||||
|
||||
Player options
|
||||
== Настройки на Играча
|
||||
|
||||
Players
|
||||
== Играчи
|
||||
|
||||
|
@ -546,9 +543,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1094,6 +1100,12 @@ Are you sure that you want to disconnect?
|
|||
Connect Dummy
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Connecting dummy
|
||||
==
|
||||
|
||||
|
@ -1441,7 +1453,7 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1693,9 +1705,6 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Reload
|
||||
==
|
||||
|
||||
Use current map as background
|
||||
==
|
||||
|
||||
|
@ -1732,6 +1741,39 @@ No updates available
|
|||
Check now
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -275,9 +275,6 @@ Player
|
|||
Player country:
|
||||
== País del jugador
|
||||
|
||||
Player options
|
||||
== Opcions del jugador
|
||||
|
||||
Players
|
||||
== Jugadors
|
||||
|
||||
|
@ -782,9 +779,6 @@ Show DDNet map finishes in server browser
|
|||
transmits your player name to info.ddnet.org
|
||||
== retransmet el teu nom de jugar a info.ddnet.org
|
||||
|
||||
Reload
|
||||
== Recarga
|
||||
|
||||
Successfully saved the replay!
|
||||
== S'ha guardat la repetició correctament!
|
||||
|
||||
|
@ -1197,9 +1191,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1541,6 +1544,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1672,7 +1681,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1828,6 +1837,39 @@ Entities background color
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Extras
|
||||
==
|
||||
|
||||
|
|
|
@ -277,9 +277,6 @@ Player
|
|||
Player country:
|
||||
== Çĕршыв:
|
||||
|
||||
Player options
|
||||
== Опцисем
|
||||
|
||||
Players
|
||||
== Çынсем
|
||||
|
||||
|
@ -549,9 +546,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1097,6 +1103,12 @@ Are you sure that you want to disconnect?
|
|||
Connect Dummy
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Connecting dummy
|
||||
==
|
||||
|
||||
|
@ -1441,7 +1453,7 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1693,9 +1705,6 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Reload
|
||||
==
|
||||
|
||||
Use current map as background
|
||||
==
|
||||
|
||||
|
@ -1732,6 +1741,39 @@ No updates available
|
|||
Check now
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# Petr 2011-04-02 23:02:33
|
||||
# Medik & Petr 2011-07-02 19:37:05
|
||||
# TeeWorlds-org 2011-07-15 00:34:19
|
||||
# dobrykafe 2024-06-09 00:00:00
|
||||
# dobrykafe 2024-08-30 00:00:00
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -281,9 +281,6 @@ Player
|
|||
Player country:
|
||||
== Země hráčů:
|
||||
|
||||
Player options
|
||||
== Možnosti hráčů
|
||||
|
||||
Players
|
||||
== Hráči
|
||||
|
||||
|
@ -646,9 +643,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Připojit dummyho
|
||||
|
||||
Reload
|
||||
== Znovu načíst
|
||||
|
||||
Deactivate
|
||||
== Deaktivovat
|
||||
|
||||
|
@ -1634,9 +1628,6 @@ Show local time always
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Zobrazit ID klientů ve výsledkové tabulce
|
||||
|
||||
Show DDRace HUD
|
||||
== Zobrazit DDRace HUD
|
||||
|
||||
|
@ -1853,26 +1844,77 @@ Tee
|
|||
Show only chat messages from team members
|
||||
== Zobrazit pouze zprávy od členů týmu
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== Nelze získat adresu k připojení '%s'. Podrobnosti najdete v místní konzoli.
|
||||
|
||||
Connect address error
|
||||
== Chyba v adrese k připojení
|
||||
|
||||
Could not connect dummy
|
||||
== Nepodařilo se připojit dummyho
|
||||
|
||||
[Spectating]
|
||||
Following %s
|
||||
==
|
||||
== Sledujete %s
|
||||
|
||||
Example of usage
|
||||
==
|
||||
== Příklad použití
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Dummy není na tomto serveru povolen
|
||||
|
||||
Please wait…
|
||||
== Čekejte prosím…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Zobrazit ID klientů (výsledková tabulka, chat, divák)
|
||||
|
||||
Normal:
|
||||
== Normální:
|
||||
|
||||
Team:
|
||||
== Tým:
|
||||
|
||||
Dummy settings
|
||||
== Nastavení dummyho
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Přepnutím upravíte nastavení dummyho
|
||||
|
||||
Randomize
|
||||
== Randomizovat
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== Jste si jisti, že chcete smazat '%s'?
|
||||
|
||||
Delete skin
|
||||
== Odstranit skin
|
||||
|
||||
Basic
|
||||
== Základní
|
||||
|
||||
Custom
|
||||
== Vlastní
|
||||
|
||||
Unable to delete skin
|
||||
== Nelze odstranit skin
|
||||
|
||||
Customize
|
||||
== Přizpůsobit
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
== Kolo %d/%d
|
||||
|
||||
[Spectators]
|
||||
%d others…
|
||||
==
|
||||
== %d dalších…
|
||||
|
||||
[Team and size]
|
||||
%d\n(%d/%d)
|
||||
==
|
||||
== %d\n(%d/%d)
|
||||
|
||||
Team %d (%d/%d)
|
||||
==
|
||||
== Tým %d (%d/%d)
|
||||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
==
|
||||
== https://wiki.ddnet.org/wiki/Mapping
|
||||
|
|
|
@ -278,9 +278,6 @@ Player
|
|||
Player country:
|
||||
== Spillernes land:
|
||||
|
||||
Player options
|
||||
== Spillermuligheder
|
||||
|
||||
Players
|
||||
== Spillere
|
||||
|
||||
|
@ -676,9 +673,6 @@ Kill
|
|||
Pause
|
||||
== Pause
|
||||
|
||||
Reload
|
||||
== Genindlæs
|
||||
|
||||
Deactivate
|
||||
== Deaktiver
|
||||
|
||||
|
@ -1100,9 +1094,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1486,6 +1489,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1653,7 +1662,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1824,6 +1833,39 @@ Chat command (e.g. showall 1)
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Extras
|
||||
==
|
||||
|
||||
|
|
|
@ -290,9 +290,6 @@ Player
|
|||
Player country:
|
||||
== Speler land:
|
||||
|
||||
Player options
|
||||
== Speler opties
|
||||
|
||||
Players
|
||||
== Spelers
|
||||
|
||||
|
@ -663,9 +660,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Verbind Dummy
|
||||
|
||||
Reload
|
||||
== Herladen
|
||||
|
||||
Deactivate
|
||||
== Deactiveren
|
||||
|
||||
|
@ -1243,9 +1237,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1584,6 +1587,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1709,7 +1718,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1850,6 +1859,39 @@ Entities background color
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Extras
|
||||
==
|
||||
|
||||
|
|
|
@ -300,9 +300,6 @@ Kill
|
|||
Pause
|
||||
== Paŭzi
|
||||
|
||||
Player options
|
||||
== Ludantaj agordoj
|
||||
|
||||
Player
|
||||
== Ludanto
|
||||
|
||||
|
@ -565,9 +562,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1053,6 +1059,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Stop record
|
||||
==
|
||||
|
||||
|
@ -1481,7 +1493,7 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1724,9 +1736,6 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Reload
|
||||
==
|
||||
|
||||
Use current map as background
|
||||
==
|
||||
|
||||
|
@ -1751,6 +1760,39 @@ DDNet Client updated!
|
|||
No updates available
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -281,9 +281,6 @@ Player
|
|||
Player country:
|
||||
== Mängija maa:
|
||||
|
||||
Player options
|
||||
== Mängija sätted
|
||||
|
||||
Players
|
||||
== Mängijad
|
||||
|
||||
|
@ -710,9 +707,6 @@ Kill
|
|||
Pause
|
||||
== Paus
|
||||
|
||||
Reload
|
||||
== Lae uuesti
|
||||
|
||||
Deactivate
|
||||
== Deaktiveeri
|
||||
|
||||
|
@ -1605,9 +1599,6 @@ Show local time always
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Näita kliendi ID-eid tulemustabelis
|
||||
|
||||
Show DDRace HUD
|
||||
== Näita DDRace HUD-i
|
||||
|
||||
|
@ -1872,5 +1863,56 @@ Round %d/%d
|
|||
Team %d (%d/%d)
|
||||
== Tiim %d (%d/%d)
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
==
|
||||
|
|
|
@ -280,9 +280,6 @@ Player
|
|||
Player country:
|
||||
== Pelaajan maa:
|
||||
|
||||
Player options
|
||||
== Pelaajavalinnat
|
||||
|
||||
Players
|
||||
== Pelaajat
|
||||
|
||||
|
@ -709,9 +706,6 @@ Kill
|
|||
Pause
|
||||
== Pysäytä
|
||||
|
||||
Reload
|
||||
== Päivitä
|
||||
|
||||
Deactivate
|
||||
== Deaktivoi
|
||||
|
||||
|
@ -1634,9 +1628,6 @@ Show local time always
|
|||
DDRace HUD
|
||||
== DDrace-HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Näytä asiakas-ID:t pistetaulukossa
|
||||
|
||||
Show DDRace HUD
|
||||
== Näytä DDRace-HUD
|
||||
|
||||
|
@ -1832,6 +1823,15 @@ Loading sound files
|
|||
Moved ingame
|
||||
== Liikui pelissä
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
[Spectating]
|
||||
Following %s
|
||||
==
|
||||
|
@ -1842,15 +1842,57 @@ Following %s
|
|||
Example of usage
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Converse
|
||||
==
|
||||
|
||||
Tee
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show only chat messages from team members
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -302,9 +302,6 @@ Player
|
|||
Player country:
|
||||
== Origine des Tees:
|
||||
|
||||
Player options
|
||||
== Options des joueurs
|
||||
|
||||
Players
|
||||
== Joueurs
|
||||
|
||||
|
@ -610,9 +607,6 @@ AntiPing: predict other players
|
|||
Are you sure that you want to disconnect your dummy?
|
||||
== Êtes vous sûrs de vouloir déconnecter votre dummy ?
|
||||
|
||||
Reload
|
||||
== Recharger
|
||||
|
||||
Server best:
|
||||
== Meilleur score du serveur
|
||||
|
||||
|
@ -1390,9 +1384,6 @@ Name Plate
|
|||
Hook Collisions
|
||||
== Collisions du grappin
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Afficher les IDs des clients dans le tableau des scores
|
||||
|
||||
Hook collision line width
|
||||
== Largeur de la ligne de collision du grappin
|
||||
|
||||
|
@ -1874,6 +1865,15 @@ Entities background color
|
|||
Moved ingame
|
||||
== Déplacé en jeu
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
[Spectating]
|
||||
Following %s
|
||||
==
|
||||
|
@ -1881,6 +1881,48 @@ Following %s
|
|||
Example of usage
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -280,9 +280,6 @@ Player
|
|||
Player country:
|
||||
== País do xogador
|
||||
|
||||
Player options
|
||||
== Opcións de xogador
|
||||
|
||||
Players
|
||||
== Xogadores
|
||||
|
||||
|
@ -652,9 +649,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Conectar Dummy
|
||||
|
||||
Reload
|
||||
== Recargar
|
||||
|
||||
Deactivate
|
||||
== Desactivar
|
||||
|
||||
|
@ -1358,9 +1352,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== HUD DDRace
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Mostrar IDs de cliente na táboa de puntuación
|
||||
|
||||
Show DDRace HUD
|
||||
== Mostrar o HUD DDRace
|
||||
|
||||
|
@ -1571,6 +1562,15 @@ Relative
|
|||
Absolute
|
||||
== Absoluto
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1767,6 +1767,12 @@ Delete folder
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1797,6 +1803,9 @@ Info Messages
|
|||
Show local time always
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Always show chat
|
||||
==
|
||||
|
||||
|
@ -1851,6 +1860,39 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -299,9 +299,6 @@ Player
|
|||
Player country:
|
||||
== Spielerland:
|
||||
|
||||
Player options
|
||||
== Spieleroptionen
|
||||
|
||||
Players
|
||||
== Spieler
|
||||
|
||||
|
@ -365,9 +362,6 @@ Shotgun
|
|||
Show chat
|
||||
== Chat anzeigen
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Client-IDs in der Punktetafel anzeigen
|
||||
|
||||
Show DDRace HUD
|
||||
== DDRace-HUD anzeigen
|
||||
|
||||
|
@ -815,9 +809,6 @@ Skin prefix
|
|||
Show HUD
|
||||
== HUD zeigen
|
||||
|
||||
Reload
|
||||
== Neu laden
|
||||
|
||||
9+ new mentions
|
||||
== 9+ Erwähnungen
|
||||
|
||||
|
@ -1887,5 +1878,56 @@ Round %d/%d
|
|||
Team %d (%d/%d)
|
||||
== Team %d (%d/%d)
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== Konnte Verbindungsadresse '%s' nicht auflösen, siehe lokale Konsole für Details.
|
||||
|
||||
Connect address error
|
||||
== Fehler in Verbindungsadresse
|
||||
|
||||
Could not connect dummy
|
||||
== Konnte Dummy nicht verbinden
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Dummy ist auf diesem Server nicht erlaubt
|
||||
|
||||
Please wait…
|
||||
== Bitte warten…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Client-IDs anzeigen (Punktetafel, Chat, Beobachter)
|
||||
|
||||
Normal:
|
||||
== Normal:
|
||||
|
||||
Team:
|
||||
== Team:
|
||||
|
||||
Dummy settings
|
||||
== Dummy-Einstellungen
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Zu Dummy-Einstellungen wechseln
|
||||
|
||||
Randomize
|
||||
== Randomisieren
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== Bist du sicher dass du '%s' löschen willst?
|
||||
|
||||
Delete skin
|
||||
== Skin löschen
|
||||
|
||||
Basic
|
||||
== Einfach
|
||||
|
||||
Custom
|
||||
== Individuell
|
||||
|
||||
Unable to delete skin
|
||||
== Kann Skin nicht löschen
|
||||
|
||||
Customize
|
||||
== Anpassen
|
||||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
==
|
||||
|
|
|
@ -280,9 +280,6 @@ Player
|
|||
Player country:
|
||||
== Χώρα παίκτη:
|
||||
|
||||
Player options
|
||||
== Επιλογές παίκτη
|
||||
|
||||
Players
|
||||
== Παίκτες
|
||||
|
||||
|
@ -555,9 +552,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1100,6 +1106,12 @@ Are you sure that you want to disconnect?
|
|||
Connect Dummy
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Connecting dummy
|
||||
==
|
||||
|
||||
|
@ -1444,7 +1456,7 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1693,9 +1705,6 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Reload
|
||||
==
|
||||
|
||||
Use current map as background
|
||||
==
|
||||
|
||||
|
@ -1732,6 +1741,39 @@ No updates available
|
|||
Check now
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -270,9 +270,6 @@ Pistol
|
|||
Player
|
||||
== Játékos
|
||||
|
||||
Player options
|
||||
== Játékosok kezelése
|
||||
|
||||
Players
|
||||
== Játékosok
|
||||
|
||||
|
@ -789,9 +786,6 @@ Show DDNet map finishes in server browser
|
|||
transmits your player name to info.ddnet.org
|
||||
== továbbítja a játékosnevedet az info.ddnet.org oldalra
|
||||
|
||||
Reload
|
||||
== Újratöltés
|
||||
|
||||
Hammerfly dummy
|
||||
== Másolat kalapácsolás
|
||||
|
||||
|
@ -1060,9 +1054,6 @@ Auto
|
|||
Replay
|
||||
== Visszajátszás
|
||||
|
||||
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
|
||||
==
|
||||
|
||||
Getting server list from master server
|
||||
== Szerverlista lekérése a fő szerverekről
|
||||
|
||||
|
@ -1338,9 +1329,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Mutassa a kliensek ID-ét a pontszámtáblán
|
||||
|
||||
Show DDRace HUD
|
||||
== Mutassa a DDRace HUD-ot (Speciális HUD)
|
||||
|
||||
|
@ -1551,6 +1539,15 @@ Unregister protocol and file extensions
|
|||
Open the directory to add custom assets
|
||||
== Megnyitni az egyedi Képek helyét
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1563,6 +1560,9 @@ Saving settings to '%s' failed
|
|||
Error saving settings
|
||||
==
|
||||
|
||||
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
|
||||
==
|
||||
|
||||
Loading demo file from storage
|
||||
==
|
||||
|
||||
|
@ -1772,6 +1772,12 @@ Delete folder
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1802,6 +1808,9 @@ Info Messages
|
|||
Show local time always
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Always show chat
|
||||
==
|
||||
|
||||
|
@ -1853,6 +1862,39 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -284,9 +284,6 @@ Player
|
|||
Player country:
|
||||
== Filtra per paese:
|
||||
|
||||
Player options
|
||||
== Opzioni giocatore
|
||||
|
||||
Players
|
||||
== Giocatori
|
||||
|
||||
|
@ -709,9 +706,6 @@ Kill
|
|||
Pause
|
||||
== Pausa
|
||||
|
||||
Reload
|
||||
== Ricarica
|
||||
|
||||
Deactivate
|
||||
== Disattiva
|
||||
|
||||
|
@ -1273,9 +1267,6 @@ Hook Collisions
|
|||
Show health, shields and ammo
|
||||
== Mostra vita, scudi e munizioni
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Mostra gli ID clienti nella scoreboard
|
||||
|
||||
Show DDRace HUD
|
||||
== Mostra l'HUD DDRace
|
||||
|
||||
|
@ -1411,9 +1402,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1680,6 +1680,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1783,6 +1789,9 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Always show chat
|
||||
==
|
||||
|
||||
|
@ -1873,6 +1882,39 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Extras
|
||||
==
|
||||
|
||||
|
|
|
@ -274,9 +274,6 @@ Player
|
|||
Player country:
|
||||
== 所在地:
|
||||
|
||||
Player options
|
||||
== プレイヤー設定
|
||||
|
||||
Players
|
||||
== プレーヤー
|
||||
|
||||
|
@ -684,9 +681,6 @@ Kill
|
|||
Pause
|
||||
== 観察
|
||||
|
||||
Reload
|
||||
== 更新
|
||||
|
||||
Deactivate
|
||||
== 無効にする
|
||||
|
||||
|
@ -1135,9 +1129,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1512,6 +1515,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1664,7 +1673,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1829,6 +1838,39 @@ Chat command (e.g. showall 1)
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Extras
|
||||
==
|
||||
|
||||
|
|
|
@ -280,9 +280,6 @@ Pistol
|
|||
Player
|
||||
== 플레이어
|
||||
|
||||
Player options
|
||||
== 플레이어 옵션
|
||||
|
||||
Players
|
||||
== 플레이어
|
||||
|
||||
|
@ -534,9 +531,6 @@ Successfully saved the replay!
|
|||
Replay feature is disabled!
|
||||
== 리플레이 기능을 비활성화했습니다!
|
||||
|
||||
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
|
||||
==
|
||||
|
||||
Warning
|
||||
== 주의
|
||||
|
||||
|
@ -702,9 +696,6 @@ Pause
|
|||
Time
|
||||
== 시간
|
||||
|
||||
Reload
|
||||
== 새로고침
|
||||
|
||||
Deactivate
|
||||
== 비활성화
|
||||
|
||||
|
@ -1359,9 +1350,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== 점수판에 클라이언트 ID 표시
|
||||
|
||||
Show DDRace HUD
|
||||
== DDRace HUD 표시
|
||||
|
||||
|
@ -1563,6 +1551,15 @@ Copy info
|
|||
Create a random skin
|
||||
== 무작위 스킨 생성
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1575,6 +1572,9 @@ Saving settings to '%s' failed
|
|||
Error saving settings
|
||||
==
|
||||
|
||||
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
|
||||
==
|
||||
|
||||
Loading demo file from storage
|
||||
==
|
||||
|
||||
|
@ -1784,6 +1784,12 @@ Delete folder
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1814,6 +1820,9 @@ Info Messages
|
|||
Show local time always
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Always show chat
|
||||
==
|
||||
|
||||
|
@ -1865,6 +1874,39 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -309,9 +309,6 @@ Player
|
|||
Player country:
|
||||
== Өлкөсү:
|
||||
|
||||
Player options
|
||||
== Оюнчу опциялары
|
||||
|
||||
Players
|
||||
== Оюнчулар
|
||||
|
||||
|
@ -546,9 +543,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1091,6 +1097,12 @@ Are you sure that you want to disconnect?
|
|||
Connect Dummy
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Connecting dummy
|
||||
==
|
||||
|
||||
|
@ -1435,7 +1447,7 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1684,9 +1696,6 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Reload
|
||||
==
|
||||
|
||||
Use current map as background
|
||||
==
|
||||
|
||||
|
@ -1723,6 +1732,39 @@ No updates available
|
|||
Check now
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -279,9 +279,6 @@ Player
|
|||
Player country:
|
||||
== Spillerland:
|
||||
|
||||
Player options
|
||||
== Spillerinstillinger
|
||||
|
||||
Players
|
||||
== Spillere
|
||||
|
||||
|
@ -653,9 +650,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Koble til dummy
|
||||
|
||||
Reload
|
||||
== Last på nytt
|
||||
|
||||
Deactivate
|
||||
== Deaktiver
|
||||
|
||||
|
@ -1101,9 +1095,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1487,6 +1490,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1654,7 +1663,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1825,6 +1834,39 @@ Chat command (e.g. showall 1)
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Extras
|
||||
==
|
||||
|
||||
|
|
|
@ -519,9 +519,6 @@ Kill
|
|||
Pause
|
||||
== ﺚﮑﻣ ﺖﻟﺎﺣ
|
||||
|
||||
Player options
|
||||
== ﻦﮑﯾﺯﺎﺑ ﺕﺎﻤﯿﻈﻨﺗ
|
||||
|
||||
Player
|
||||
== ﻦﮑﯾﺯﺎﺑ
|
||||
|
||||
|
@ -543,9 +540,6 @@ Vote command:
|
|||
Time
|
||||
== ﻥﺎﻣﺯ
|
||||
|
||||
Reload
|
||||
== ﻩﺭﺎﺑﻭﺩ ﯼﺮﯿﮔﺭﺎﺑ
|
||||
|
||||
Deactivate
|
||||
== ﻥﺩﺮﮐ ﻝﺎﻌﻓﺮﯿﻏ
|
||||
|
||||
|
@ -1225,9 +1219,6 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== ﺯﺎﯿﺘﻣﺍ ﯼﻮﻠﺑﺎﺗ ﺭﺩ ﺖﻨﯾﻼﮐ ID ﺶﯾﺎﻤﻧ
|
||||
|
||||
Show DDRace HUD
|
||||
== DDRace HUD ﺶﯾﺎﻤﻧ
|
||||
|
||||
|
@ -1518,9 +1509,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1754,6 +1754,12 @@ Delete folder
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1787,6 +1793,9 @@ Info Messages
|
|||
Show local time always
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Always show chat
|
||||
==
|
||||
|
||||
|
@ -1841,6 +1850,39 @@ Entities background color
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -282,9 +282,6 @@ Player
|
|||
Player country:
|
||||
== Narodowość:
|
||||
|
||||
Player options
|
||||
== Opcje gracza
|
||||
|
||||
Players
|
||||
== Gracze
|
||||
|
||||
|
@ -683,9 +680,6 @@ Enable replays
|
|||
Automatically create statboard csv
|
||||
== Automatycznie stwórz plik csv z tabelą wyników
|
||||
|
||||
Reload
|
||||
== Przeładuj
|
||||
|
||||
Replay feature is disabled!
|
||||
== Funkcja odtwarzania jest wyłączona!
|
||||
|
||||
|
@ -1639,9 +1633,6 @@ Show health, shields and ammo
|
|||
Show local time always
|
||||
== Pokazuj czas lokalny
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Pokazuj ID klienta w tabeli wyników
|
||||
|
||||
Show DDRace HUD
|
||||
== Pokazuj HUD DDRace
|
||||
|
||||
|
@ -1808,6 +1799,15 @@ Submitting the render commands failed. Try to update your GPU drivers.
|
|||
Failed to swap framebuffers. Try to update your GPU drivers.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Match %d of %d
|
||||
==
|
||||
|
||||
|
@ -1840,6 +1840,12 @@ Folder Link
|
|||
map not included
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Aim bind
|
||||
==
|
||||
|
||||
|
@ -1855,9 +1861,45 @@ Tee
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show only chat messages from team members
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -290,9 +290,6 @@ Player
|
|||
Player country:
|
||||
== País do jogador
|
||||
|
||||
Player options
|
||||
== Opções do jogador
|
||||
|
||||
Players
|
||||
== Jogadores
|
||||
|
||||
|
@ -773,9 +770,6 @@ Connect Dummy
|
|||
Time
|
||||
== Tempo
|
||||
|
||||
Reload
|
||||
== Recarregar
|
||||
|
||||
Deactivate
|
||||
== Desativar
|
||||
|
||||
|
@ -890,9 +884,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1330,6 +1333,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Kill
|
||||
==
|
||||
|
||||
|
@ -1563,7 +1572,7 @@ Show local time always
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1767,6 +1776,39 @@ Chat command (e.g. showall 1)
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -286,9 +286,6 @@ Player
|
|||
Player country:
|
||||
== Țara jucătorului:
|
||||
|
||||
Player options
|
||||
== Opțiuni jucător
|
||||
|
||||
Players
|
||||
== Jucători
|
||||
|
||||
|
@ -561,9 +558,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1106,6 +1112,12 @@ Are you sure that you want to disconnect?
|
|||
Connect Dummy
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Connecting dummy
|
||||
==
|
||||
|
||||
|
@ -1450,7 +1462,7 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
==
|
||||
|
||||
Show client IDs in scoreboard
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Show DDRace HUD
|
||||
|
@ -1699,9 +1711,6 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Reload
|
||||
==
|
||||
|
||||
Use current map as background
|
||||
==
|
||||
|
||||
|
@ -1738,6 +1747,39 @@ No updates available
|
|||
Check now
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Emoticons
|
||||
==
|
||||
|
||||
|
|
|
@ -294,9 +294,6 @@ Player
|
|||
Player country:
|
||||
== Страна игрока:
|
||||
|
||||
Player options
|
||||
== Опции игрока
|
||||
|
||||
Players
|
||||
== Игроки
|
||||
|
||||
|
@ -634,7 +631,7 @@ Loading DDNet Client
|
|||
== Загрузка DDNet Client
|
||||
|
||||
Normal message
|
||||
== Обычное с.
|
||||
== Обычное
|
||||
|
||||
Connecting dummy
|
||||
== Подключение дамми
|
||||
|
@ -646,10 +643,10 @@ Save ghost
|
|||
== Сохранять тень
|
||||
|
||||
DDNet Client updated!
|
||||
== DDNet Client обновлён!
|
||||
== DDNet клиент обновлён!
|
||||
|
||||
Highlighted message
|
||||
== Выделенное с.
|
||||
== Выделенное
|
||||
|
||||
Demo
|
||||
== Демо
|
||||
|
@ -727,7 +724,7 @@ Downloading %s:
|
|||
== Скачивание %s:
|
||||
|
||||
Update failed! Check log…
|
||||
== Ошибка. Проверьте логи…
|
||||
== Не удалось обновиться! Подробности в логах…
|
||||
|
||||
Restart
|
||||
== Рестарт
|
||||
|
@ -750,9 +747,6 @@ Fetch Info
|
|||
Connect Dummy
|
||||
== Подключить дамми
|
||||
|
||||
Reload
|
||||
== Перезагрузить
|
||||
|
||||
Deactivate
|
||||
== Выключить
|
||||
|
||||
|
@ -850,7 +844,7 @@ DDNet
|
|||
== DDNet
|
||||
|
||||
Friend message
|
||||
== Дружеское с.
|
||||
== Дружеское
|
||||
|
||||
Save the best demo of each race
|
||||
== Сохранять лучшее демо каждой карты
|
||||
|
@ -922,10 +916,10 @@ Ratio
|
|||
== Соотношение
|
||||
|
||||
Net
|
||||
== Сеть
|
||||
== Сальдо
|
||||
|
||||
FPM
|
||||
== FPM
|
||||
== У/мин
|
||||
|
||||
Spree
|
||||
== Серия
|
||||
|
@ -946,7 +940,7 @@ Grabs
|
|||
== 9+ упоминаний
|
||||
|
||||
Client message
|
||||
== Клиентское с.
|
||||
== Клиентское
|
||||
|
||||
Warning
|
||||
== Предупреждение
|
||||
|
@ -979,7 +973,7 @@ Run server
|
|||
== Запустить сервер
|
||||
|
||||
Server executable not found, can't run server
|
||||
== Файл сервера не найден, невозможно запустить
|
||||
== Файл сервера не найден, не удалось запустить сервер
|
||||
|
||||
Editor
|
||||
== Редактор
|
||||
|
@ -1362,9 +1356,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Показывать ид. игроков
|
||||
|
||||
Show DDRace HUD
|
||||
== Показывать DDRace HUD
|
||||
|
||||
|
@ -1887,3 +1878,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/wiki/Mapping/ru
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== Не удалось определить адрес подключения '%s'. Подробности в локальной консоли.
|
||||
|
||||
Connect address error
|
||||
== Ошибка адреса подключения
|
||||
|
||||
Could not connect dummy
|
||||
== Невозможно подключить дамми
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Дамми не разрешен на этом сервере
|
||||
|
||||
Please wait…
|
||||
== Пожалуйста, подождите…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Показывать ID клиента (табло, чат, наблюдатель)
|
||||
|
||||
Normal:
|
||||
== Обычный:
|
||||
|
||||
Team:
|
||||
== В команде:
|
||||
|
||||
Dummy settings
|
||||
== Настройки дамми
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Нажмите, чтобы изменить настройки дамми
|
||||
|
||||
Randomize
|
||||
== Случайный
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== Вы уверены, что хотите удалить '%s'?
|
||||
|
||||
Delete skin
|
||||
== Удалить скин
|
||||
|
||||
Basic
|
||||
== Пресеты
|
||||
|
||||
Custom
|
||||
== Кастомизация
|
||||
|
||||
Unable to delete skin
|
||||
== Невозможно удалить скин
|
||||
|
||||
Customize
|
||||
== Кастомизировать
|
||||
|
|
|
@ -281,9 +281,6 @@ Player
|
|||
Player country:
|
||||
== Država igrača
|
||||
|
||||
Player options
|
||||
== Podešavanja igrača
|
||||
|
||||
Players
|
||||
== Igrači
|
||||
|
||||
|
@ -685,9 +682,6 @@ Kill
|
|||
Pause
|
||||
== Pauza
|
||||
|
||||
Reload
|
||||
== Osveži
|
||||
|
||||
Deactivate
|
||||
== Deaktiviraj
|
||||
|
||||
|
@ -1264,9 +1258,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace Prikaz
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Prikaži identitete na tabli rezultata
|
||||
|
||||
Show DDRace HUD
|
||||
== Prikaži DDRace Prikaz
|
||||
|
||||
|
@ -1649,6 +1640,15 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1785,6 +1785,12 @@ Netversion
|
|||
map not included
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1809,6 +1815,9 @@ Info Messages
|
|||
Show local time always
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Always show chat
|
||||
==
|
||||
|
||||
|
@ -1860,6 +1869,39 @@ Regular background color
|
|||
Entities background color
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
|
||||
|
|
|
@ -277,9 +277,6 @@ Player
|
|||
Player country:
|
||||
== Држава играча
|
||||
|
||||
Player options
|
||||
== Подешавања играча
|
||||
|
||||
Players
|
||||
== Играчи
|
||||
|
||||
|
@ -684,9 +681,6 @@ Kill
|
|||
Pause
|
||||
== Пауза
|
||||
|
||||
Reload
|
||||
== Освежи
|
||||
|
||||
Deactivate
|
||||
== Деактивирај
|
||||
|
||||
|
@ -1263,9 +1257,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace Приказ
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Прикажи идентитете на табли резултата
|
||||
|
||||
Show DDRace HUD
|
||||
== Прикажи DDRace Приказ
|
||||
|
||||
|
@ -1422,9 +1413,18 @@ Could not initialize the given graphics backend, reverting to the default backen
|
|||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
==
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
==
|
||||
|
||||
Connect address error
|
||||
==
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
==
|
||||
|
||||
Could not connect dummy
|
||||
==
|
||||
|
||||
Error playing demo
|
||||
==
|
||||
|
||||
|
@ -1703,6 +1703,12 @@ Unable to delete the demo '%s'
|
|||
Unable to delete the folder '%s'. Make sure it's empty first.
|
||||
==
|
||||
|
||||
Dummy is not allowed on this server
|
||||
==
|
||||
|
||||
Please wait…
|
||||
==
|
||||
|
||||
Loading…
|
||||
==
|
||||
|
||||
|
@ -1766,6 +1772,9 @@ Info Messages
|
|||
Show local time always
|
||||
==
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
==
|
||||
|
||||
Always show chat
|
||||
==
|
||||
|
||||
|
@ -1850,6 +1859,39 @@ Entities background color
|
|||
Unregister protocol and file extensions
|
||||
==
|
||||
|
||||
Normal:
|
||||
==
|
||||
|
||||
Team:
|
||||
==
|
||||
|
||||
Dummy settings
|
||||
==
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
==
|
||||
|
||||
Randomize
|
||||
==
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
==
|
||||
|
||||
Delete skin
|
||||
==
|
||||
|
||||
Basic
|
||||
==
|
||||
|
||||
Custom
|
||||
==
|
||||
|
||||
Unable to delete skin
|
||||
==
|
||||
|
||||
Customize
|
||||
==
|
||||
|
||||
Open the directory to add custom assets
|
||||
==
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
# 2024-04-21 By
|
||||
# 2024-06-10 By
|
||||
# 2024-07-21 By
|
||||
# 2024-08-29 Pioooooo
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -342,9 +343,6 @@ HUD
|
|||
Player country:
|
||||
== 玩家国家 / 地区:
|
||||
|
||||
Player options
|
||||
== 玩家选项
|
||||
|
||||
Players
|
||||
== 玩家
|
||||
|
||||
|
@ -831,9 +829,6 @@ Show DDNet map finishes in server browser
|
|||
transmits your player name to info.ddnet.org
|
||||
== 将会发送你的玩家昵称到 info.ddnet.org
|
||||
|
||||
Reload
|
||||
== 刷新
|
||||
|
||||
Enable replays
|
||||
== 启用短时回放
|
||||
|
||||
|
@ -1389,9 +1384,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== 显示客户端 IDs (计分板中)
|
||||
|
||||
Show DDRace HUD
|
||||
== 显示 DDRace HUD
|
||||
|
||||
|
@ -1523,7 +1515,7 @@ Are you sure that you want to reset the controls to their defaults?
|
|||
|
||||
[Graphics error]
|
||||
Failed during initialization. Try to change gfx_backend to OpenGL or Vulkan in settings_ddnet.cfg in the config directory and try again.
|
||||
== 初始化失败。请尝试打开配置目录中的设置文件(settings_ddnet.cfg)并将“gfx_backend OpenGL”修改为“gfx_backend Vulkan”(若没有前者则可直接输入后者)再重试。
|
||||
== 初始化失败。请尝试打开配置目录中的设置文件(settings_ddnet.cfg)并将 “gfx_backend” 设置为 “gfx_backend OpenGL” 或 “gfx_backend Vulkan” 再重试。
|
||||
|
||||
[Graphics error]
|
||||
Out of VRAM. Try removing custom assets (skins, entities, etc.), especially those with high resolution.
|
||||
|
@ -1547,7 +1539,7 @@ Failed to swap framebuffers. Try to update your GPU drivers.
|
|||
|
||||
[Graphics error]
|
||||
Unknown error. Try to change gfx_backend to OpenGL or Vulkan in settings_ddnet.cfg in the config directory and try again.
|
||||
== 未知错误。请尝试打开配置目录中的设置文件(settings_ddnet.cfg)并将“gfx_backend OpenGL”修改为“gfx_backend Vulkan”(若没有前者则可直接输入后者)再重试。
|
||||
== 未知错误。请尝试打开配置目录中的设置文件(settings_ddnet.cfg)并将 “gfx_backend” 设置为 “gfx_backend OpenGL” 或 “gfx_backend Vulkan” 再重试。
|
||||
|
||||
[Graphics error]
|
||||
Could not initialize the given graphics backend, reverting to the default backend now.
|
||||
|
@ -1575,7 +1567,7 @@ No controller found. Plug in a controller.
|
|||
== 未检测到任何控制器。请尝试重新连接控制器。
|
||||
|
||||
Unregister protocol and file extensions
|
||||
== 未注册的协议与扩充文件
|
||||
== 清除协议与文件类型关联
|
||||
|
||||
Open the directory to add custom assets
|
||||
== 打开用以添加自定义资源的文件夹路径
|
||||
|
@ -1914,3 +1906,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/index.php?title=Mapping/zh&variant=zh-hans
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== 无法解析连接地址 '%s'。检查本地控制台以获取详情。
|
||||
|
||||
Connect address error
|
||||
== 连接地址错误
|
||||
|
||||
Could not connect dummy
|
||||
== 无法连接分身
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== 此服务器禁止使用分身
|
||||
|
||||
Please wait…
|
||||
== 请稍等…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== 显示客户端 ID(计分板、聊天、观战者)
|
||||
|
||||
Normal:
|
||||
== 正常:
|
||||
|
||||
Team:
|
||||
== 队伍:
|
||||
|
||||
Dummy settings
|
||||
== 分身设置
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== 切换以编辑分身设置
|
||||
|
||||
Randomize
|
||||
== 随机
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== 你确定要删除'%s'吗?
|
||||
|
||||
Delete skin
|
||||
== 删除皮肤
|
||||
|
||||
Basic
|
||||
== 基本
|
||||
|
||||
Custom
|
||||
== 自定义
|
||||
|
||||
Unable to delete skin
|
||||
== 无法删除皮肤
|
||||
|
||||
Customize
|
||||
== 自定义
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Limit and Petr
|
||||
#modified by:
|
||||
# LimiT 2011-07-02 20:24:44
|
||||
# dobrykafe 2024-06-09 00:00:00
|
||||
# dobrykafe 2024-08-30 00:00:00
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -278,9 +278,6 @@ Player
|
|||
Player country:
|
||||
== Filter krajín:
|
||||
|
||||
Player options
|
||||
== Nastavenia hráča
|
||||
|
||||
Players
|
||||
== Hráči
|
||||
|
||||
|
@ -1420,9 +1417,6 @@ Show votes window after voting
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Zobraziť ID klientov vo výsledkovej tabuľke
|
||||
|
||||
Show DDRace HUD
|
||||
== Zobraziť DDRace HUD
|
||||
|
||||
|
@ -1648,9 +1642,6 @@ Regular background color
|
|||
Entities background color
|
||||
== Farba pozadia entít
|
||||
|
||||
Reload
|
||||
== Znovu načítať
|
||||
|
||||
Use current map as background
|
||||
== Použiť aktuálnu mapu ako pozadie
|
||||
|
||||
|
@ -1850,26 +1841,77 @@ Tee
|
|||
Show only chat messages from team members
|
||||
== Zobraziť iba správy od členov tímu
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== Nie je možné získať adresu na pripojenie '%s'. Podrobnosti nájdete v miestnej konzole.
|
||||
|
||||
Connect address error
|
||||
== Chyba v adrese na pripojenie
|
||||
|
||||
Could not connect dummy
|
||||
== Nepodarilo sa pripojiť dummyho
|
||||
|
||||
[Spectating]
|
||||
Following %s
|
||||
==
|
||||
== Sledujete %s
|
||||
|
||||
Example of usage
|
||||
==
|
||||
== Príklad použitia
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Dummy nie je na tomto serveri povolený
|
||||
|
||||
Please wait…
|
||||
== Čakajte prosím…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Zobraziť ID klientov (výsledková tabuľka, chat, divák)
|
||||
|
||||
Normal:
|
||||
== Normálny:
|
||||
|
||||
Team:
|
||||
== Tím:
|
||||
|
||||
Dummy settings
|
||||
== Nastavenie dummyho
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Prepnutím upravíte nastavenie dummyho
|
||||
|
||||
Randomize
|
||||
== Randomizovať
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== Ste si istí, že chcete zmazať '%s'?
|
||||
|
||||
Delete skin
|
||||
== Odstrániť skin
|
||||
|
||||
Basic
|
||||
== Základné
|
||||
|
||||
Custom
|
||||
== Vlastné
|
||||
|
||||
Unable to delete skin
|
||||
== Nedá sa odstrániť skin
|
||||
|
||||
Customize
|
||||
== Prispôsobiť
|
||||
|
||||
Round %d/%d
|
||||
==
|
||||
== Kolo %d/%d
|
||||
|
||||
[Spectators]
|
||||
%d others…
|
||||
==
|
||||
== %d ďalších…
|
||||
|
||||
[Team and size]
|
||||
%d\n(%d/%d)
|
||||
==
|
||||
== %d\n(%d/%d)
|
||||
|
||||
Team %d (%d/%d)
|
||||
==
|
||||
== Tím %d (%d/%d)
|
||||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
==
|
||||
== https://wiki.ddnet.org/wiki/Mapping
|
||||
|
|
|
@ -299,9 +299,6 @@ Player
|
|||
Player country:
|
||||
== País del jugador
|
||||
|
||||
Player options
|
||||
== Opciones de jugador
|
||||
|
||||
Players
|
||||
== Jugadores
|
||||
|
||||
|
@ -626,7 +623,7 @@ Types
|
|||
== Tipos
|
||||
|
||||
DDNet %s is out!
|
||||
== ¡DDNet %s ya esta disponible!
|
||||
== ¡DDNet %s ya está disponible!
|
||||
|
||||
Downloading %s:
|
||||
== Descargando %s:
|
||||
|
@ -673,9 +670,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Conectar Dummy
|
||||
|
||||
Reload
|
||||
== Recargar
|
||||
|
||||
Deactivate
|
||||
== Desactivar
|
||||
|
||||
|
@ -1390,9 +1384,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== HUD DDRace
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Mostrar IDs de cliente en la tabla de puntuación
|
||||
|
||||
Show DDRace HUD
|
||||
== Mostrar el HUD DDRace
|
||||
|
||||
|
@ -1891,3 +1882,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/wiki/Mapping/es
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== No se pudo resolver la dirección de conexión '%s'. Ver la consola local para más detalles.
|
||||
|
||||
Connect address error
|
||||
== Error de dirección de conexión
|
||||
|
||||
Could not connect dummy
|
||||
== No se pudo conectar tu dummy
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== No se permiten dummys en este servidor
|
||||
|
||||
Please wait…
|
||||
== Espera por favor…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Mostrar IDs de cliente (scoreboard, chat, espectador)
|
||||
|
||||
Normal:
|
||||
== Normal:
|
||||
|
||||
Team:
|
||||
== Equipo:
|
||||
|
||||
Dummy settings
|
||||
== Configuración del dummy
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Actívalo para configurar tu dummy
|
||||
|
||||
Randomize
|
||||
== Aleatorizar
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== ¿Estás seguro de que quieres eliminar '%s'?
|
||||
|
||||
Delete skin
|
||||
== Eliminar skin
|
||||
|
||||
Basic
|
||||
== Básico
|
||||
|
||||
Custom
|
||||
== Personalizado
|
||||
|
||||
Unable to delete skin
|
||||
== No se pudo borrar la skin
|
||||
|
||||
Customize
|
||||
== Personalizar
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# 3edcxzaq1 2020-06-25 00:00:00
|
||||
# cur.ie 2020-09-28 00:00:00
|
||||
# simpygirl 2022-02-20 00:00:00
|
||||
# furo 2024-07-17 00:00:00
|
||||
# furo 2024-08-29 00:00:00
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -282,9 +282,6 @@ Player
|
|||
Player country:
|
||||
== Land
|
||||
|
||||
Player options
|
||||
== Spelaralternativ
|
||||
|
||||
Players
|
||||
== Spelare
|
||||
|
||||
|
@ -900,9 +897,6 @@ Show HUD
|
|||
Pause
|
||||
== Pausa
|
||||
|
||||
Reload
|
||||
== Ladda om
|
||||
|
||||
Spree
|
||||
== Spree
|
||||
|
||||
|
@ -1516,9 +1510,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Visa klient ID i poänglista
|
||||
|
||||
Show DDRace HUD
|
||||
== Visa DDRace HUD
|
||||
|
||||
|
@ -1875,3 +1866,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/wiki/Mapping
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== Kunde inte förstå anslutnings adress '%s'. Se den lokala konsolen för detaljer.
|
||||
|
||||
Connect address error
|
||||
== Anslutnings problem
|
||||
|
||||
Could not connect dummy
|
||||
== Kunde inte ansluta dummy
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Dummy är inte tillåten på denna server
|
||||
|
||||
Please wait…
|
||||
== Vänligen vänta…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Visa klient IDen (poänglistan, chatt, åskadarmeny)
|
||||
|
||||
Normal:
|
||||
== Normal:
|
||||
|
||||
Team:
|
||||
== Lag:
|
||||
|
||||
Dummy settings
|
||||
== Dummy inställningar
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Växla för att ändra dina dummy inställningar
|
||||
|
||||
Randomize
|
||||
== Slumpa
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== Är du säker att du vill ta bort '%s'?
|
||||
|
||||
Delete skin
|
||||
== Ta bort skin
|
||||
|
||||
Basic
|
||||
== Enkel
|
||||
|
||||
Custom
|
||||
== Anpassa
|
||||
|
||||
Unable to delete skin
|
||||
== Kunde inte ta bort skin
|
||||
|
||||
Customize
|
||||
== Ändra
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
# 2024-04-21 By
|
||||
# 2024-06-10 By
|
||||
# 2024-07-21 By
|
||||
# 2024-08-29 Pioooooo
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -331,9 +332,6 @@ HUD
|
|||
Player country:
|
||||
== 玩家國家/地區:
|
||||
|
||||
Player options
|
||||
== 玩家選項
|
||||
|
||||
Players
|
||||
== 玩家
|
||||
|
||||
|
@ -820,9 +818,6 @@ Show DDNet map finishes in server browser
|
|||
transmits your player name to info.ddnet.org
|
||||
== 將會發送你的玩家名稱到 info.ddnet.org
|
||||
|
||||
Reload
|
||||
== 重新整理
|
||||
|
||||
Enable replays
|
||||
== 啟用短時回放
|
||||
|
||||
|
@ -1227,7 +1222,7 @@ Team %d
|
|||
== 隊伍 %d
|
||||
|
||||
Position:
|
||||
== 坐標
|
||||
== 坐標
|
||||
|
||||
Speed:
|
||||
== 速度
|
||||
|
@ -1378,9 +1373,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace HUD
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== 顯示客戶端 IDs (計分板中)
|
||||
|
||||
Show DDRace HUD
|
||||
== 顯示 DDRace HUD
|
||||
|
||||
|
@ -1512,7 +1504,7 @@ Are you sure that you want to reset the controls to their defaults?
|
|||
|
||||
[Graphics error]
|
||||
Failed during initialization. Try to change gfx_backend to OpenGL or Vulkan in settings_ddnet.cfg in the config directory and try again.
|
||||
== 初始化失敗。請嘗試打開配置目錄中的設定檔案 (settings_ddnet.cfg) 并將“gfx_backend OpenGL”修改為“gfx_backend Vulkan” (若沒有前者則可直接輸入後者) 再重試。
|
||||
== 初始化失敗。請嘗試打開配置目錄中的設定檔案 (settings_ddnet.cfg) 并將 “gfx_backend” 設定為 “gfx_backend OpenGL” 或 “gfx_backend Vulkan” 再重試。
|
||||
|
||||
[Graphics error]
|
||||
Out of VRAM. Try removing custom assets (skins, entities, etc.), especially those with high resolution.
|
||||
|
@ -1536,7 +1528,7 @@ Failed to swap framebuffers. Try to update your GPU drivers.
|
|||
|
||||
[Graphics error]
|
||||
Unknown error. Try to change gfx_backend to OpenGL or Vulkan in settings_ddnet.cfg in the config directory and try again.
|
||||
== 未知錯誤。請嘗試打開配置目錄中的設定檔案 (settings_ddnet.cfg) 并將“gfx_backend OpenGL”修改為“gfx_backend Vulkan” (若沒有前者則可直接輸入後者) 再重試。
|
||||
== 未知錯誤。請嘗試打開配置目錄中的設定檔案 (settings_ddnet.cfg) 并將 “gfx_backend” 設定為 “gfx_backend OpenGL” 或 “gfx_backend Vulkan” 再重試。
|
||||
|
||||
[Graphics error]
|
||||
Could not initialize the given graphics backend, reverting to the default backend now.
|
||||
|
@ -1564,7 +1556,7 @@ No controller found. Plug in a controller.
|
|||
== 未檢測到任何控制器。請嘗試重新連接控制器。
|
||||
|
||||
Unregister protocol and file extensions
|
||||
== 未注冊的協議與擴充檔案
|
||||
== 清除連結與檔案類型關聯
|
||||
|
||||
Open the directory to add custom assets
|
||||
== 打開用以新增自定義材質的資料夾路徑
|
||||
|
@ -1903,3 +1895,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/index.php?title=Mapping/zh&variant=zh-hant
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== 無法解析連線地址 '%s'。檢查本機控制台以取得詳情。
|
||||
|
||||
Connect address error
|
||||
== 連線地址錯誤
|
||||
|
||||
Could not connect dummy
|
||||
== 無法連線分身
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== 此服務器禁止使用分身
|
||||
|
||||
Please wait…
|
||||
== 請稍等…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== 顯示客戶端 ID(計分板、聊天、旁觀者)
|
||||
|
||||
Normal:
|
||||
== 正常:
|
||||
|
||||
Team:
|
||||
== 隊伍:
|
||||
|
||||
Dummy settings
|
||||
== 分身設定
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== 切換以編輯分身設定
|
||||
|
||||
Randomize
|
||||
== 隨機
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== 你確定要刪除'%s'嗎?
|
||||
|
||||
Delete skin
|
||||
== 刪除外觀
|
||||
|
||||
Basic
|
||||
== 基本
|
||||
|
||||
Custom
|
||||
== 自定義
|
||||
|
||||
Unable to delete skin
|
||||
== 無法刪除外觀
|
||||
|
||||
Customize
|
||||
== 自定義
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# Gokturk 2024-04-24 03:01:50
|
||||
# Gokturk 2024-06-09 12:00:50
|
||||
# Gokturk 2024-07-17 02:24:00
|
||||
# Gokturk 2024-08-29 23:31:00
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -287,9 +288,6 @@ Play background music
|
|||
Player
|
||||
== Oyuncu
|
||||
|
||||
Player options
|
||||
== Oyuncu ayarları
|
||||
|
||||
Players
|
||||
== Oyuncular
|
||||
|
||||
|
@ -665,9 +663,6 @@ Connecting dummy
|
|||
Connect Dummy
|
||||
== Dummy Katıl
|
||||
|
||||
Reload
|
||||
== Yenile
|
||||
|
||||
Deactivate
|
||||
== Devre dışı bırak
|
||||
|
||||
|
@ -1463,9 +1458,6 @@ Show health, shields and ammo
|
|||
DDRace HUD
|
||||
== DDRace arayüzü
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Skor tablosunda ki istemci ID'lerini göster
|
||||
|
||||
Show DDRace HUD
|
||||
== DDRace arayüzünü göster
|
||||
|
||||
|
@ -1883,3 +1875,54 @@ Team %d (%d/%d)
|
|||
|
||||
https://wiki.ddnet.org/wiki/Mapping
|
||||
== https://wiki.ddnet.org/wiki/Mapping/tr
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== '%s' Bağlantı adresi çözümlenemedi. Detaylar için yerel konsola bakın
|
||||
|
||||
Connect address error
|
||||
== Bağlantı adresi hatası
|
||||
|
||||
Could not connect dummy
|
||||
== Dummy bağlanamadı
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Bu sunucuda dummy izin verilmiyor
|
||||
|
||||
Please wait…
|
||||
== Lütfen bekleyin…
|
||||
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== İstemci ID'sini göster (skor tablosu, sohbet, izleyici)
|
||||
|
||||
Normal:
|
||||
== Normal:
|
||||
|
||||
Team:
|
||||
== Takım:
|
||||
|
||||
Dummy settings
|
||||
== Dummy ayarları
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Dummy ayarlarını düzenlemek için açın
|
||||
|
||||
Randomize
|
||||
== Rastgele
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== '%s' bunu silmek istediğine emin misin?
|
||||
|
||||
Delete skin
|
||||
== Skini sil
|
||||
|
||||
Basic
|
||||
== Basit
|
||||
|
||||
Custom
|
||||
== Özel
|
||||
|
||||
Unable to delete skin
|
||||
== Skin silinemiyor
|
||||
|
||||
Customize
|
||||
== Özelleştir
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#modified by:
|
||||
# 404_not_found 2011-07-30 19:50:58
|
||||
# EGYT5453 (15.05.2024-04.06.2024)
|
||||
# veydzh3r (31.08.2024-01.09.2024)
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -32,10 +33,10 @@
|
|||
== ще %d…
|
||||
|
||||
%d player
|
||||
== Гравців: %d
|
||||
== Гравці: %d
|
||||
|
||||
%d players
|
||||
== Гравців: %d
|
||||
== Гравці: %d
|
||||
|
||||
[Demo player duration]
|
||||
%d sec.
|
||||
|
@ -76,10 +77,10 @@
|
|||
== Нових згадок: 9+
|
||||
|
||||
A demo with this name already exists
|
||||
== Демо з цією назвою вже існує
|
||||
== Демо з цією назвою уже існує
|
||||
|
||||
A folder with this name already exists
|
||||
== Тека з цією назвою вже існує
|
||||
== Тека з цією назвою уже існує
|
||||
|
||||
[Graphics error]
|
||||
A render command failed. Try to update your GPU drivers.
|
||||
|
@ -120,7 +121,7 @@ AFR
|
|||
== АФР
|
||||
|
||||
Aim bind
|
||||
== Прив'язка
|
||||
== Прив’язка
|
||||
|
||||
All
|
||||
== Усі
|
||||
|
@ -165,6 +166,9 @@ AntiPing: predict weapons
|
|||
Appearance
|
||||
== Вигляд
|
||||
|
||||
Are you sure that you want to delete '%s'?
|
||||
== Ви дійсно хочете видалити '%s'?
|
||||
|
||||
Are you sure that you want to delete the demo '%s'?
|
||||
== Ви дійсно хочете видалити демо '%s'?
|
||||
|
||||
|
@ -172,13 +176,13 @@ Are you sure that you want to delete the folder '%s'?
|
|||
== Ви дійсно хочете видалити теку '%s'?
|
||||
|
||||
Are you sure that you want to disconnect?
|
||||
== Ви дійсно хочете від'єднатися?
|
||||
== Ви дійсно хочете від’єднатися?
|
||||
|
||||
Are you sure that you want to disconnect and switch to a different server?
|
||||
== Ви дійсно хочете від'єднатися й приєднатися до іншого сервера?
|
||||
== Ви дійсно хочете від’єднатися й приєднатися до іншого сервера?
|
||||
|
||||
Are you sure that you want to disconnect your dummy?
|
||||
== Ви дійсно хочете від'єднати свого даммі?
|
||||
== Ви дійсно хочете від’єднати свого даммі?
|
||||
|
||||
Are you sure that you want to quit?
|
||||
== Ви дійсно хочете вийти?
|
||||
|
@ -190,7 +194,7 @@ Are you sure that you want to remove the player '%s' from your friends list?
|
|||
== Ви дійсно хочете прибрати гравця '%s' зі списку друзів?
|
||||
|
||||
Are you sure that you want to reset the controls to their defaults?
|
||||
== Ви дійсно хочете скинути налаштування керування до значень за замовчуванням?
|
||||
== Ви дійсно хочете скинути налаштування керувань до початкових значень?
|
||||
|
||||
Are you sure that you want to restart?
|
||||
== Ви дійсно хочете перезапустити?
|
||||
|
@ -208,7 +212,7 @@ AUS
|
|||
== АВС
|
||||
|
||||
Authed name color in scoreboard
|
||||
== Колір авторизованих у таблі
|
||||
== Колір авторизованих у таблиці
|
||||
|
||||
Auto
|
||||
== Авто
|
||||
|
@ -217,7 +221,7 @@ auto
|
|||
== автоматично
|
||||
|
||||
Automatically create statboard csv
|
||||
== Автоматично зберігати статистику у CSV-файл
|
||||
== Автоматично зберігати статистику у файл CSV
|
||||
|
||||
Automatically record demos
|
||||
== Автоматично записувати демо
|
||||
|
@ -232,11 +236,14 @@ Axis
|
|||
== Осі
|
||||
|
||||
Background
|
||||
== Фон
|
||||
== Тло
|
||||
|
||||
Background music volume
|
||||
== Гучність фонової музики
|
||||
|
||||
Basic
|
||||
== Базовий
|
||||
|
||||
Best
|
||||
== НКом
|
||||
|
||||
|
@ -256,7 +263,7 @@ Call vote
|
|||
== Голосувати
|
||||
|
||||
Can't find a Tutorial server
|
||||
== Не вдалося знайти сервер-посібник
|
||||
== Не вдається знайти навчальний сервер
|
||||
|
||||
Cancel
|
||||
== Скасувати
|
||||
|
@ -289,13 +296,13 @@ Check now
|
|||
== Перевірити
|
||||
|
||||
Checking for existing player with your name
|
||||
== Перевіряємо Ваш нікнейм на доступність
|
||||
== Перевірка на наявність гравця з вашим ім’ям
|
||||
|
||||
CHN
|
||||
== КИТ
|
||||
|
||||
Choose default eyes when joining a server
|
||||
== Очі, які відображатимуться за замовчуванням
|
||||
== Типові очі під час приєднання до сервера
|
||||
|
||||
Clan
|
||||
== Клан
|
||||
|
@ -322,7 +329,7 @@ Close the demo player
|
|||
== Закрити програвач демо
|
||||
|
||||
Colors of the hook collision line, in case of a possible collision with:
|
||||
== Кольори лінії зіткнення гака, якщо він може зіштовхнутися з:
|
||||
== Кольори лінії зіткнення гака, в разі можливого зіткнення з:
|
||||
|
||||
Communities
|
||||
== Спільноти
|
||||
|
@ -330,26 +337,29 @@ Communities
|
|||
Config directory
|
||||
== Тека налаштувань
|
||||
|
||||
Connect address error
|
||||
== Помилка адреси з’єднання
|
||||
|
||||
Connect Dummy
|
||||
== Приєднати даммі
|
||||
== Під’єднати даммі
|
||||
|
||||
Connected
|
||||
== Приєднано
|
||||
== Під’єднано
|
||||
|
||||
Connecting dummy
|
||||
== Приєднуємо даммі
|
||||
== Під’єднання даммі
|
||||
|
||||
Connecting to
|
||||
== Приєднуємося до
|
||||
== Під’єднання до
|
||||
|
||||
Connection Problems…
|
||||
== Проблеми зі з'єднанням…
|
||||
== Проблеми зі з’єднанням…
|
||||
|
||||
Console
|
||||
== Консоль
|
||||
|
||||
Continue anyway?
|
||||
== Все одно продовжити?
|
||||
== Усе одно продовжити?
|
||||
|
||||
Controller
|
||||
== Контролер
|
||||
|
@ -366,19 +376,25 @@ Converse
|
|||
Copy info
|
||||
== Скопіювати
|
||||
|
||||
Could not connect dummy
|
||||
== Не вдалося під’єднати даммі
|
||||
|
||||
[Graphics error]
|
||||
Could not initialize the given graphics backend, reverting to the default backend now.
|
||||
== Не вдалося ініціалізувати заданий графічний рушій, повертаємося до рушія за замовчуванням.
|
||||
== Не вдалося ініціалізувати заданий графічний рушій, повернення до тпового рушія.
|
||||
|
||||
[Graphics error]
|
||||
Could not initialize the given graphics backend, this is probably because you didn't install the driver of the integrated graphics card.
|
||||
== Не вдалося ініціалізувати заданий графічний рушій, можливо тому що ви не встановили драйвери на вбудовану відеокарту.
|
||||
== Не вдалося ініціалізувати заданий графічний рушій, імовірно, ви не встановили драйвери на вбудовану відеокарту.
|
||||
|
||||
Could not resolve connect address '%s'. See local console for details.
|
||||
== Не вдалося визначити адресу з’єднання '%s'. Див. локальну консоль для подробиць.
|
||||
|
||||
Could not save downloaded map. Try manually deleting this file: %s
|
||||
== Не вдалося зберегти завантажену мапу. Спробуйте самостійно видалити цей файл: %s
|
||||
|
||||
Count players only
|
||||
== Рахувати тільки гравців
|
||||
== Рахувати лише гравців
|
||||
|
||||
Countries
|
||||
== Країни
|
||||
|
@ -395,9 +411,15 @@ Current
|
|||
custom
|
||||
== власний
|
||||
|
||||
Custom
|
||||
== Власний
|
||||
|
||||
Custom colors
|
||||
== Власні кольори
|
||||
|
||||
Customize
|
||||
== Налаштувати
|
||||
|
||||
Cut interval
|
||||
== Інтервал
|
||||
|
||||
|
@ -417,7 +439,7 @@ DDNet %s is out!
|
|||
== Вийшов DDNet %s!
|
||||
|
||||
DDNet Client needs to be restarted to complete update!
|
||||
== Потрібно перезапустити клієнт DDNet, щоб завершити оновлення!
|
||||
== Потрібно перезапустити клієнт DDNet для завершення оновлення!
|
||||
|
||||
DDNet Client updated!
|
||||
== Клієнт DDNet оновлено!
|
||||
|
@ -426,22 +448,22 @@ DDRace HUD
|
|||
== HUD DDRace
|
||||
|
||||
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
|
||||
== DDraceNetwork — кооперативна мережева гра, ціль якої — дістатися разом зі своєю групою тії до фінішної прямої. Новачкам варто почати із серверів "Для новачків" (Novice), на яких є найпростіші мапи. Зважайте на затримку, коли вибираєте сервер.
|
||||
== DDraceNetwork — кооперативна мережева гра, ціль якої — дістатися разом зі своєю групою тії до фінішної прямої. Новачкам варто почати із серверів «Для новачків» (Novice), на яких є найпростіші мапи. Зважайте на затримку, коли вибираєте сервер.
|
||||
|
||||
Deactivate
|
||||
== Деактивувати
|
||||
|
||||
Deactivate all
|
||||
== Деактивувати усіх
|
||||
== Деактивувати всіх
|
||||
|
||||
Deaths
|
||||
== С
|
||||
== Смерті
|
||||
|
||||
Debug mode enabled. Press Ctrl+Shift+D to disable debug mode.
|
||||
== Увімкнено режим налагодження. Натисніть Ctrl+Shift+D, щоб його вимкнути.
|
||||
|
||||
default
|
||||
== за замовчуванням
|
||||
== типово
|
||||
|
||||
Default length
|
||||
== Звичайна тривалість
|
||||
|
@ -458,6 +480,9 @@ Delete demo
|
|||
Delete folder
|
||||
== Видалити теку
|
||||
|
||||
Delete skin
|
||||
== Видалити скін
|
||||
|
||||
Demo
|
||||
== Демо
|
||||
|
||||
|
@ -471,16 +496,16 @@ Demos directory
|
|||
== Тека демо
|
||||
|
||||
Desktop fullscreen
|
||||
== Стільничний повноекранний
|
||||
== Робочий стіл на весь екран
|
||||
|
||||
Disconnect
|
||||
== Від'єднатися
|
||||
== Від’єднатися
|
||||
|
||||
Disconnect Dummy
|
||||
== Від'єднати даммі
|
||||
== Від’єднати даммі
|
||||
|
||||
Disconnected
|
||||
== Від'єднано
|
||||
== Від’єднано
|
||||
|
||||
Discord
|
||||
== Discord
|
||||
|
@ -498,10 +523,10 @@ Download skins
|
|||
== Завантажувати скіни
|
||||
|
||||
Downloading %s:
|
||||
== Завантажуємо %s:
|
||||
== Завантаження %s:
|
||||
|
||||
Downloading map
|
||||
== Завантажуємо мапу
|
||||
== Завантаження мапи
|
||||
|
||||
Draw!
|
||||
== Нічия!
|
||||
|
@ -512,8 +537,14 @@ Dummy
|
|||
Dummy copy
|
||||
== Повторювати рухи
|
||||
|
||||
Dummy is not allowed on this server
|
||||
== Використання даммі заборонене на цьому сервері
|
||||
|
||||
Dummy settings
|
||||
== Налаштування даммі
|
||||
|
||||
Dynamic Camera
|
||||
== Рухома камера
|
||||
== Динамічна камера
|
||||
|
||||
Editor
|
||||
== Редактор
|
||||
|
@ -546,7 +577,7 @@ Enable regular chat sound
|
|||
== Звук звичайного повідомлення
|
||||
|
||||
Enable replays
|
||||
== Повтори
|
||||
== Увімкнути повтори
|
||||
|
||||
Enable server message sound
|
||||
== Звук повідомлення сервера
|
||||
|
@ -558,13 +589,13 @@ Enter Password
|
|||
== Введіть пароль
|
||||
|
||||
Enter Username
|
||||
== Введіть логін
|
||||
== Введіть ім’я користувача
|
||||
|
||||
Entities
|
||||
== Сутності
|
||||
|
||||
Entities background color
|
||||
== Колір фону сутностей
|
||||
== Колір тла сутностей
|
||||
|
||||
Error
|
||||
== Помилка
|
||||
|
@ -582,13 +613,13 @@ EUR
|
|||
== ЄВР
|
||||
|
||||
Example of usage
|
||||
== Наприклад
|
||||
== Приклад використання
|
||||
|
||||
Exclude
|
||||
== Виключити
|
||||
|
||||
Existing Player
|
||||
== Гравець вже існує
|
||||
== Гравець уже існує
|
||||
|
||||
Export cut as a separate demo
|
||||
== Експортувати фрагмент як окреме демо
|
||||
|
@ -651,7 +682,7 @@ Following
|
|||
|
||||
[Spectating]
|
||||
Following %s
|
||||
== Слідуємо за %s
|
||||
== Cпостерігання за %s
|
||||
|
||||
Force vote
|
||||
== Форсувати
|
||||
|
@ -681,7 +712,7 @@ FSAA samples
|
|||
== Вибірка FSAA
|
||||
|
||||
Fullscreen
|
||||
== Повноекранний
|
||||
== На весь екран
|
||||
|
||||
Game
|
||||
== Гра
|
||||
|
@ -708,13 +739,13 @@ Gameplay
|
|||
== Ігролад
|
||||
|
||||
General
|
||||
== Загальне
|
||||
== Загальні
|
||||
|
||||
Getting game info
|
||||
== Отримуємо інформацію про гру
|
||||
== Отримання інформації про гру
|
||||
|
||||
Getting server list from master server
|
||||
== Отримуємо список серверів з головного сервера
|
||||
== Отримання списку серверів з головного сервера
|
||||
|
||||
Ghost
|
||||
== Привид
|
||||
|
@ -726,7 +757,7 @@ Go back one marker
|
|||
== Перемотати до попередньої мітки
|
||||
|
||||
Go back one tick
|
||||
== Перемотати вперед на один тік
|
||||
== Перемотати вперед на один такт
|
||||
|
||||
Go back the specified duration
|
||||
== Перемотати назад
|
||||
|
@ -735,7 +766,7 @@ Go forward one marker
|
|||
== Перемотати до наступної мітки
|
||||
|
||||
Go forward one tick
|
||||
== Перемотати назад на один тік
|
||||
== Перемотати вперед на один такт
|
||||
|
||||
Go forward the specified duration
|
||||
== Перемотати вперед
|
||||
|
@ -801,31 +832,31 @@ HUD
|
|||
== HUD
|
||||
|
||||
Hue
|
||||
== Тон
|
||||
== Відтінок
|
||||
|
||||
Indicate map finish
|
||||
== Позначати пройдені мапи
|
||||
|
||||
Info Messages
|
||||
== Інфо-повідомлення
|
||||
== Інфо. повідомлення
|
||||
|
||||
Ingame controller mode
|
||||
== Режим контролера у грі
|
||||
|
||||
Ingame controller sens.
|
||||
== Чутл. у грі
|
||||
== Чутливість у грі
|
||||
|
||||
Ingame mouse sens.
|
||||
== Чутл. у грі
|
||||
== Чутливість у грі
|
||||
|
||||
Initializing assets
|
||||
== Ініціалізуємо текстури
|
||||
== Ініціалізація текстур
|
||||
|
||||
Initializing components
|
||||
== Ініціалізуємо компоненти
|
||||
== Ініціалізація компонентів
|
||||
|
||||
Initializing map logic
|
||||
== Ініціалізуємо логіку мапи
|
||||
== Ініціалізація логіки мапи
|
||||
|
||||
Internet
|
||||
== Інтернет
|
||||
|
@ -834,7 +865,7 @@ Invalid Demo
|
|||
== Недійсне демо
|
||||
|
||||
It's recommended that you check the settings to adjust them to your liking before joining a server.
|
||||
== Перед тим як приєднатися до сервера, рекомендуємо змінити налаштування до ваших уподобань.
|
||||
== Перед тим, як приєднатися до сервера, рекомендуємо змінити налаштування до ваших уподобань.
|
||||
|
||||
Join blue
|
||||
== До синіх
|
||||
|
@ -846,7 +877,7 @@ Join red
|
|||
== До червоних
|
||||
|
||||
Join Tutorial Server
|
||||
== Приєднатися до сервера-посібника
|
||||
== Приєднатися до навчального сервера
|
||||
|
||||
Jump
|
||||
== Стрибок
|
||||
|
@ -885,52 +916,52 @@ Loading…
|
|||
== Завантаження…
|
||||
|
||||
Loading assets
|
||||
== Завантажуємо текстури
|
||||
== Завантаження текстур
|
||||
|
||||
Loading commands…
|
||||
== Завантажуємо команди…
|
||||
== Завантаження команд…
|
||||
|
||||
Loading DDNet Client
|
||||
== Завантажуємо клієнт DDNet
|
||||
== Завантаження клієнта DDNet
|
||||
|
||||
Loading demo file from storage
|
||||
== Завантажуємо демо-файл зі сховища
|
||||
== Завантаження демо-файлу зі сховища
|
||||
|
||||
Loading demo files
|
||||
== Завантажуємо демо-файли
|
||||
== Завантаження демо-файлів
|
||||
|
||||
Loading ghost files
|
||||
== Завантажуємо файли привида
|
||||
== Завантаження файлів привида
|
||||
|
||||
Loading map file from storage
|
||||
== Завантажуємо файл мапи зі сховища
|
||||
== Завантаження файлу мапи зі сховища
|
||||
|
||||
Loading menu images
|
||||
== Завантажуємо зображення меню
|
||||
== Завантаження зображень меню
|
||||
|
||||
Loading menu themes
|
||||
== Завантажуємо теми меню
|
||||
== Завантаження тем меню
|
||||
|
||||
Loading race demo files
|
||||
== Завантажуємо демо-файли забігів
|
||||
== Завантаження демо-файлів забігів
|
||||
|
||||
Loading skin files
|
||||
== Завантажуємо файли скінів
|
||||
== Завантаження файлів скінів
|
||||
|
||||
Loading sound files
|
||||
== Завантажуємо звукові файли
|
||||
== Завантаження звукових файлів
|
||||
|
||||
Lock team
|
||||
== Замкнути команду
|
||||
|
||||
Locked
|
||||
== Заблоковано
|
||||
== Замкнено
|
||||
|
||||
Main menu
|
||||
== Головне меню
|
||||
|
||||
Manual
|
||||
== Вручну
|
||||
== Уручну
|
||||
|
||||
Map
|
||||
== Мапа
|
||||
|
@ -940,7 +971,7 @@ map not included
|
|||
== мапу не включено
|
||||
|
||||
Map sound volume
|
||||
== Гучність мапи
|
||||
== Гучність звуків мапи
|
||||
|
||||
Mark the beginning of a cut (right click to reset)
|
||||
== Позначити початок фрагмента (права кнопка миші, щоб скинути)
|
||||
|
@ -955,13 +986,13 @@ Match %d of %d
|
|||
== Збіг %d з %d
|
||||
|
||||
Max CSVs
|
||||
== Найбільше CSV-файлів
|
||||
== Макс. кількість файлів CSV
|
||||
|
||||
Max demos
|
||||
== Найбільше демо-файлів
|
||||
== Макс. кількість демо-файлів
|
||||
|
||||
Max Screenshots
|
||||
== Найбільше знімків екрана
|
||||
== Макс. кількість знімків екрана
|
||||
|
||||
may cause delay
|
||||
== може спричинити затримку
|
||||
|
@ -985,7 +1016,7 @@ Move left
|
|||
== Вліво
|
||||
|
||||
Move player to spectators
|
||||
== Зробити гравця спостерігачем
|
||||
== Зробити гравця глядачем
|
||||
|
||||
Move right
|
||||
== Вправо
|
||||
|
@ -1000,7 +1031,7 @@ Multi-View
|
|||
== Мульти-камера
|
||||
|
||||
Mute when not active
|
||||
== Приглушувати, якщо вікно неактивне
|
||||
== Приглушувати звук поза грою
|
||||
|
||||
NA
|
||||
== ПНА
|
||||
|
@ -1021,7 +1052,7 @@ Netversion
|
|||
== Версія
|
||||
|
||||
New name:
|
||||
== Нова назва
|
||||
== Нова назва:
|
||||
|
||||
New random timeout code
|
||||
== Новий випадковий код тайм-ауту
|
||||
|
@ -1033,16 +1064,16 @@ Next weapon
|
|||
== Наст. зброя
|
||||
|
||||
Nickname
|
||||
== Нікнейм
|
||||
== Псевдонім
|
||||
|
||||
No
|
||||
== Ні
|
||||
|
||||
No answer from server yet.
|
||||
== Сервер ще не відповів.
|
||||
== Поки що немає відповіді від сервера.
|
||||
|
||||
No controller found. Plug in a controller.
|
||||
== Жодного контролера не знайдено. Підключіть контролер.
|
||||
== Жодного контролера не знайдено. Під’єднайте контролер.
|
||||
|
||||
No demo selected
|
||||
== Жодного демо не вибрано
|
||||
|
@ -1071,6 +1102,9 @@ No updates available
|
|||
None
|
||||
== Немає
|
||||
|
||||
Normal:
|
||||
== Звичайний:
|
||||
|
||||
Normal Color
|
||||
== Колір звичайних повідомлень
|
||||
|
||||
|
@ -1078,23 +1112,23 @@ Normal message
|
|||
== Звичайні повідомлення
|
||||
|
||||
NOT CONNECTED
|
||||
== НЕ ПРИЄДНАНО
|
||||
== НЕ ПІД’ЄДНАНО
|
||||
|
||||
Nothing hookable
|
||||
== нічим, за що можна зачепитися
|
||||
|
||||
[friends (server browser)]
|
||||
Offline (%d)
|
||||
== Офлайн (%d)
|
||||
== Не в мережі (%d)
|
||||
|
||||
Ok
|
||||
== Гаразд
|
||||
|
||||
Online clanmates (%d)
|
||||
== Онлайн клановці (%d)
|
||||
== Співклановці в мережі (%d)
|
||||
|
||||
Online players (%d)
|
||||
== Онлайн гравці (%d)
|
||||
== Гравці в мережі (%d)
|
||||
|
||||
Only save improvements
|
||||
== Зберігати лише покращення
|
||||
|
@ -1125,7 +1159,7 @@ Open the settings file
|
|||
|
||||
[Graphics error]
|
||||
Out of VRAM. Try removing custom assets (skins, entities, etc.), especially those with high resolution.
|
||||
== Недостатньо відеопам'яті. Спробуйте видалити власні текстури (скіни, сутності і т.п.), особливо ті, що мають високу роздільну здатність.
|
||||
== Недостатньо відеопам’яті. Спробуйте видалити власні текстури (скіни, сутності і т.д.), особливо ті, що мають високу роздільність.
|
||||
|
||||
Overlay entities
|
||||
== Накладати сутності
|
||||
|
@ -1134,7 +1168,7 @@ Parent Folder
|
|||
== Батьківська тека
|
||||
|
||||
Particles
|
||||
== Часточки
|
||||
== Частинки
|
||||
|
||||
Pause
|
||||
== Пауза
|
||||
|
@ -1176,9 +1210,6 @@ Player country:
|
|||
Player info change cooldown
|
||||
== Затримка зміни інформації про гравця
|
||||
|
||||
Player options
|
||||
== Налаштування гравців
|
||||
|
||||
Players
|
||||
== Гравці
|
||||
|
||||
|
@ -1191,11 +1222,14 @@ Please enter your nickname below.
|
|||
Please use a different filename
|
||||
== Будь ласка, назвіть файл по-іншому
|
||||
|
||||
Please wait…
|
||||
== Будь ласка, зачекайте…
|
||||
|
||||
Position:
|
||||
== Позиція:
|
||||
|
||||
Preparing demo playback
|
||||
== Підготовлюємо відтворення демо
|
||||
== Підготовлення відтворення демо
|
||||
|
||||
Press a key…
|
||||
== Натисніть клавішу…
|
||||
|
@ -1210,7 +1244,7 @@ Quads are used for background decoration
|
|||
== Квади використовуються для декорацій
|
||||
|
||||
Quit
|
||||
== Вихід
|
||||
== Вийти
|
||||
|
||||
Quitting. Please wait…
|
||||
== Вихід. Будь ласка, зачекайте…
|
||||
|
@ -1218,6 +1252,9 @@ Quitting. Please wait…
|
|||
Race
|
||||
== Забіг
|
||||
|
||||
Randomize
|
||||
== Навмання
|
||||
|
||||
Ratio
|
||||
== У/С
|
||||
|
||||
|
@ -1225,7 +1262,7 @@ Reason:
|
|||
== Причина:
|
||||
|
||||
Reconnect in %d sec
|
||||
== Переприєднання через %dс
|
||||
== Повторне під’єднання за %dс
|
||||
|
||||
Record demo
|
||||
== Запис демо
|
||||
|
@ -1240,15 +1277,12 @@ Refresh Rate
|
|||
== Частота кадрів
|
||||
|
||||
Regular background color
|
||||
== Колір звичайного фону
|
||||
== Колір звичайного тла
|
||||
|
||||
[Ingame controller mode]
|
||||
Relative
|
||||
== Відносний
|
||||
|
||||
Reload
|
||||
== Оновити
|
||||
|
||||
Remote console
|
||||
== Віддалена консоль
|
||||
|
||||
|
@ -1286,10 +1320,10 @@ Replay
|
|||
== Повтор
|
||||
|
||||
Replay feature is disabled!
|
||||
== Повтори відключено!
|
||||
== Повтори вимкнено!
|
||||
|
||||
Requesting to join the game
|
||||
== Запитуємо приєднання до гри
|
||||
== Запит на приєднання до гри
|
||||
|
||||
Reset
|
||||
== Скинути
|
||||
|
@ -1301,7 +1335,7 @@ Reset filter
|
|||
== Скинути фільтр
|
||||
|
||||
Reset to defaults
|
||||
== Скинути
|
||||
== Скинути до типових
|
||||
|
||||
Restart
|
||||
== Перезапустити
|
||||
|
@ -1328,7 +1362,7 @@ SA
|
|||
== ПДА
|
||||
|
||||
Same clan color in scoreboard
|
||||
== Колір співклановців у таблі
|
||||
== Колір співклановців у таблиці
|
||||
|
||||
Sat.
|
||||
== Насич.
|
||||
|
@ -1340,7 +1374,7 @@ Save ghost
|
|||
== Зберігати привида
|
||||
|
||||
Save power by lowering refresh rate (higher input latency)
|
||||
== Зберігати енергію зниженням частоти кадрів (вища затримка вводу)
|
||||
== Економити енергію шляхом зниження частоти кадрів (вища затримка введення)
|
||||
|
||||
Save the best demo of each race
|
||||
== Зберігати найкраще демо кожного забігу
|
||||
|
@ -1355,7 +1389,7 @@ Score limit
|
|||
== Гра до
|
||||
|
||||
Scoreboard
|
||||
== Табло
|
||||
== Таблиця
|
||||
|
||||
Screen
|
||||
== Екран
|
||||
|
@ -1367,10 +1401,10 @@ Search
|
|||
== Пошук
|
||||
|
||||
Searching
|
||||
== Шукаємо
|
||||
== Пошук
|
||||
|
||||
Sending initial client info
|
||||
== Надсилаємо початкові дані клієнта
|
||||
== Надсилання початкових даних клієнта
|
||||
|
||||
Server address:
|
||||
== Адреса сервера:
|
||||
|
@ -1391,7 +1425,7 @@ Server not full
|
|||
== Неповний сервер
|
||||
|
||||
Set all to Rifle
|
||||
== Встановити так, як у гвинтівки
|
||||
== Установити так, як у гвинтівки
|
||||
|
||||
Settings
|
||||
== Налаштування
|
||||
|
@ -1417,8 +1451,8 @@ Show chat
|
|||
Show clan above name plates
|
||||
== Показувати клан над ніками
|
||||
|
||||
Show client IDs in scoreboard
|
||||
== Показувати ID клієнта в таблі
|
||||
Show client IDs (scoreboard, chat, spectator)
|
||||
== Показувати ID клієнта (таблиця, чат, глядачі)
|
||||
|
||||
Show DDNet map finishes in server browser
|
||||
== Показувати пройдені мапи DDNet у браузері серверів
|
||||
|
@ -1430,7 +1464,7 @@ Show dummy actions
|
|||
== Показувати дії з даммі
|
||||
|
||||
Show entities
|
||||
== Сутності
|
||||
== Показ сутностей
|
||||
|
||||
Show finish messages
|
||||
== Показувати повідомлення про фініші
|
||||
|
@ -1439,7 +1473,7 @@ Show freeze bars
|
|||
== Показувати смугу заморозки
|
||||
|
||||
Show friend mark (♥) in name plates
|
||||
== Показувати позначку друга (♥) біля ніків
|
||||
== Показувати позначку друга (♥) біля псевдонімів
|
||||
|
||||
Show friends only
|
||||
== Показувати лише з друзями
|
||||
|
@ -1448,10 +1482,10 @@ Show ghost
|
|||
== Показувати привида
|
||||
|
||||
Show health, shields and ammo
|
||||
== Показувати здоров'я, щити й набої
|
||||
== Показувати здоров’я, захист і набої
|
||||
|
||||
Show hook strength icon indicator
|
||||
== Показувати графічний індикатор сили гака
|
||||
== Показувати іконку індикатора сили гака
|
||||
|
||||
Show hook strength number indicator
|
||||
== Показувати числовий індикатор сили гака
|
||||
|
@ -1475,10 +1509,10 @@ Show local time always
|
|||
== Завжди показувати місцевий час
|
||||
|
||||
Show name plates
|
||||
== Показувати ніки
|
||||
== Показувати псевдоніми
|
||||
|
||||
Show names in chat in team colors
|
||||
== Фарбувати ніки в чаті в кольори команд
|
||||
== Показувати імена в чаті в кольорах команди
|
||||
|
||||
Show only chat messages from friends
|
||||
== Показувати лише повідомлення від друзів
|
||||
|
@ -1517,7 +1551,7 @@ Show text entities
|
|||
== Текстові сутності
|
||||
|
||||
Show tiles layers from BG map
|
||||
== Показувати тайли з мапи фону
|
||||
== Показувати плитки з мапи фону
|
||||
|
||||
Show quads
|
||||
== Показувати квади
|
||||
|
@ -1547,13 +1581,13 @@ Slow down the demo
|
|||
== Сповільнити
|
||||
|
||||
Smooth Dynamic Camera
|
||||
== Гладка рухома камера
|
||||
== Гладка динамічна камера
|
||||
|
||||
Some map images could not be loaded. Check the local console for details.
|
||||
== Деякі зображення мапи не завантажилися. Деталі у локальній консолі.
|
||||
== Деякі зображення мапи не завантажилися. Див. локальну консоль для подробиць.
|
||||
|
||||
Some map sounds could not be loaded. Check the local console for details.
|
||||
== Деякі звуки мапи не завантажилися. Деталі у локальній консолі.
|
||||
== Деякі звуки мапи не завантажилися. Див. локальну консоль для подробиць.
|
||||
|
||||
Something hookable
|
||||
== чимось, за що можна зачепитися
|
||||
|
@ -1577,10 +1611,10 @@ Spectate previous
|
|||
== Попер. гравець
|
||||
|
||||
Spectator mode
|
||||
== Режим спостерігача
|
||||
== Режим глядача
|
||||
|
||||
Spectators
|
||||
== Спостерігачі
|
||||
== Глядачі
|
||||
|
||||
Speed
|
||||
== Швидкість
|
||||
|
@ -1632,7 +1666,7 @@ Switch weapon on pickup
|
|||
== Змінювати зброю при підхопленні
|
||||
|
||||
Switch weapon when out of ammo
|
||||
== Змінювати зброю коли закінчуються набої
|
||||
== Змінювати зброю при закінченні набоїв
|
||||
|
||||
System message
|
||||
== Повідомлення системи
|
||||
|
@ -1640,6 +1674,9 @@ System message
|
|||
Team
|
||||
== Команда
|
||||
|
||||
Team:
|
||||
== Командний:
|
||||
|
||||
Team %d
|
||||
== Команда %d
|
||||
|
||||
|
@ -1695,7 +1732,10 @@ Toggle ghost
|
|||
== Привид
|
||||
|
||||
Toggle keyboard shortcuts
|
||||
== Перемкнути скорочення
|
||||
== Перемкнути сполучення
|
||||
|
||||
Toggle to edit your dummy settings
|
||||
== Перемкніть, щоб змінити налаштування даммі
|
||||
|
||||
transmits your player name to info.ddnet.org
|
||||
== передає ваш нікнейм до info.ddnet.org
|
||||
|
@ -1707,7 +1747,7 @@ Try again
|
|||
== Спробувати ще раз
|
||||
|
||||
Trying to determine UDP connectivity…
|
||||
== Намагаємося визначити UDP-з'єднання…
|
||||
== Спроба визначити UDP-з’єднання…
|
||||
|
||||
Tutorial
|
||||
== Посібник
|
||||
|
@ -1728,10 +1768,13 @@ UI Color
|
|||
== Колір інтерфейсу
|
||||
|
||||
UI controller sens.
|
||||
== Чутл. у інтерфейсі
|
||||
== Чутл. в інтерфейсі
|
||||
|
||||
UI mouse sens.
|
||||
== Чутл. у інтерфейсі
|
||||
== Чутл. в інтерфейсі
|
||||
|
||||
Unable to delete skin
|
||||
== Не вдалося видалити скін
|
||||
|
||||
Unable to delete the demo '%s'
|
||||
== Не вдалося видалити демо '%s'
|
||||
|
@ -1756,25 +1799,25 @@ Unregister protocol and file extensions
|
|||
== Розреєструвати протокол і розширення файлів
|
||||
|
||||
Update failed! Check log…
|
||||
== Оновлення не вдалося! Перевірте журнал…
|
||||
== Помилка оновлення! Перевірте журнал…
|
||||
|
||||
Update now
|
||||
== Оновити
|
||||
|
||||
Updating…
|
||||
== Оновлюємо…
|
||||
== Оновлення…
|
||||
|
||||
Uploading map data to GPU
|
||||
== Вивантажуємо дані мапи до відеокарти
|
||||
== Вивантаження даних мапи до відеокарти
|
||||
|
||||
Use current map as background
|
||||
== Використовувати поточну мапу як фон
|
||||
== Використовувати поточну мапу як тло
|
||||
|
||||
Use high DPI
|
||||
== Високий DPI
|
||||
|
||||
Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
|
||||
== Натисніть "k", щоб умерти (почати спочатку), "q", щоб спостерігати за іншими гравцями. Інші скорочення дивіться у налаштуваннях.
|
||||
== Натисніть «k», щоб умерти (почати спочатку), «q», щоб спостерігати за іншими гравцями. Інші призначення клавіш дивіться у налаштуваннях.
|
||||
|
||||
Use old chat style
|
||||
== Старий стиль чату
|
||||
|
@ -1798,7 +1841,7 @@ Video name:
|
|||
== Назва відео:
|
||||
|
||||
Video was saved to '%s'
|
||||
== Відео було збережено до '%s'
|
||||
== Відео збережено до '%s'
|
||||
|
||||
Videos directory
|
||||
== Тека відео
|
||||
|
@ -1843,13 +1886,13 @@ Why are you slowmo replaying to read this?
|
|||
== Чому ви переглядаєте це у повторі?
|
||||
|
||||
Windowed
|
||||
== Віконний
|
||||
== У вікні
|
||||
|
||||
Windowed borderless
|
||||
== Віконний без рамок
|
||||
== Вікно без рамок
|
||||
|
||||
Windowed fullscreen
|
||||
== Віконний повноекранний
|
||||
== Вікно на весь екран
|
||||
|
||||
Yes
|
||||
== Так
|
||||
|
@ -1858,10 +1901,10 @@ Your movements are not taken into account when calculating the line colors
|
|||
== Ваші рухи не враховуються при розранку кольору лінії
|
||||
|
||||
You must restart the game for all settings to take effect.
|
||||
== Щоб налаштування набрали чинності, перезапустіть гру.
|
||||
== Щоб налаштування набули чинності, перезапустіть гру.
|
||||
|
||||
Your nickname '%s' is already used (%d points). Do you still want to use it?
|
||||
== Нікнейм '%s' вже зайнято (%d балів). Все ще хочете використовувати його?
|
||||
== Ваш псевдонім «%s» вже зайнято (%d балів). Усе ще хочете використовувати його?
|
||||
|
||||
Your skin
|
||||
== Ваш скін
|
||||
|
|
|
@ -7,8 +7,6 @@ export MAKEFLAGS
|
|||
|
||||
ANDROID_NDK_VERSION="$(cd "$ANDROID_HOME/ndk" && find . -maxdepth 1 | sort -n | tail -1)"
|
||||
ANDROID_NDK_VERSION="${ANDROID_NDK_VERSION:2}"
|
||||
# ANDROID_NDK_VERSION must be exported for build.sh step
|
||||
export ANDROID_NDK_VERSION
|
||||
# ANDROID_NDK_HOME must be exported for cargo-ndk
|
||||
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION"
|
||||
|
||||
|
@ -197,6 +195,7 @@ cd "${BUILD_FOLDER}" || exit 1
|
|||
|
||||
mkdir -p src/main
|
||||
mkdir -p src/main/res/values
|
||||
mkdir -p src/main/res/xml
|
||||
mkdir -p src/main/res/mipmap
|
||||
|
||||
function copy_dummy_files() {
|
||||
|
@ -213,6 +212,7 @@ copy_dummy_files scripts/android/files/proguard-rules.pro proguard-rules.pro
|
|||
copy_dummy_files scripts/android/files/settings.gradle settings.gradle
|
||||
copy_dummy_files scripts/android/files/AndroidManifest.xml src/main/AndroidManifest.xml
|
||||
copy_dummy_files scripts/android/files/res/values/strings.xml src/main/res/values/strings.xml
|
||||
copy_dummy_files scripts/android/files/res/xml/shortcuts.xml src/main/res/xml/shortcuts.xml
|
||||
copy_dummy_files other/icons/DDNet_256x256x32.png src/main/res/mipmap/ic_launcher.png
|
||||
copy_dummy_files other/icons/DDNet_256x256x32.png src/main/res/mipmap/ic_launcher_round.png
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
android:name="org.ddnet.client.NativeMain"
|
||||
android:exported="true"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
|
||||
android:screenOrientation="landscape">
|
||||
android:screenOrientation="landscape"
|
||||
android:launchMode="singleInstance">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
@ -38,6 +39,9 @@
|
|||
<meta-data
|
||||
android:name="android.app.lib_name"
|
||||
android:value="DDNet" />
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -18,7 +18,6 @@ java {
|
|||
|
||||
android {
|
||||
compileSdkVersion 34
|
||||
ndkVersion "TW_NDK_VERSION"
|
||||
defaultConfig {
|
||||
applicationId "org.ddnet.client"
|
||||
namespace("org.ddnet.client")
|
||||
|
|
|
@ -45,12 +45,13 @@ sed -i "s/TW_KEY_NAME/${TW_KEY_NAME_ESCAPED}/g" build.gradle
|
|||
sed -i "s/TW_KEY_PW/${TW_KEY_PW_ESCAPED}/g" build.gradle
|
||||
sed -i "s/TW_KEY_ALIAS/${TW_KEY_ALIAS_ESCAPED}/g" build.gradle
|
||||
|
||||
sed -i "s/TW_NDK_VERSION/${ANDROID_NDK_VERSION}/g" build.gradle
|
||||
sed -i "s/TW_VERSION_CODE/${TW_VERSION_CODE}/g" build.gradle
|
||||
sed -i "s/TW_VERSION_NAME/${TW_VERSION_NAME}/g" build.gradle
|
||||
|
||||
sed -i "s/DDNet/${APK_BASENAME}/g" src/main/res/values/strings.xml
|
||||
|
||||
sed -i "s/org.ddnet.client/${APK_PACKAGE_NAME}/g" src/main/res/xml/shortcuts.xml
|
||||
|
||||
sed -i "s/\"DDNet\"/\"${APK_BASENAME}\"/g" src/main/AndroidManifest.xml
|
||||
sed -i "s/org.ddnet.client/${APK_PACKAGE_NAME}/g" src/main/AndroidManifest.xml
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ public class NativeMain extends SDLActivity {
|
|||
|
||||
private static final int COMMAND_RESTART_APP = SDLActivity.COMMAND_USER + 1;
|
||||
|
||||
private String[] launchArguments = new String[0];
|
||||
|
||||
@Override
|
||||
protected String[] getLibraries() {
|
||||
return new String[] {
|
||||
|
@ -20,17 +22,35 @@ public class NativeMain extends SDLActivity {
|
|||
@Override
|
||||
public void onCreate(Bundle SavedInstanceState) {
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
|
||||
Intent intent = getIntent();
|
||||
if(intent != null) {
|
||||
String gfxBackend = intent.getStringExtra("gfx-backend");
|
||||
if(gfxBackend != null) {
|
||||
if(gfxBackend.equals("Vulkan")) {
|
||||
launchArguments = new String[] {"gfx_backend Vulkan"};
|
||||
} else if(gfxBackend.equals("OpenGL")) {
|
||||
launchArguments = new String[] {"gfx_backend OpenGL"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.onCreate(SavedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getArguments() {
|
||||
return launchArguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUnhandledMessage(int command, Object param) {
|
||||
if(command == COMMAND_RESTART_APP) {
|
||||
restartApp();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void restartApp() {
|
||||
Intent restartIntent =
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">DDNet</string>
|
||||
<string name="app_name">DDNet</string>
|
||||
<string name="shortcut_play_vulkan_short">Play (Vulkan)</string>
|
||||
<string name="shortcut_play_opengl_short">Play (OpenGL)</string>
|
||||
</resources>
|
||||
|
|
30
scripts/android/files/res/xml/shortcuts.xml
Normal file
30
scripts/android/files/res/xml/shortcuts.xml
Normal file
|
@ -0,0 +1,30 @@
|
|||
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<shortcut
|
||||
android:shortcutId="play-vulkan"
|
||||
android:enabled="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:shortcutShortLabel="@string/shortcut_play_vulkan_short">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:targetPackage="org.ddnet.client"
|
||||
android:targetClass="org.ddnet.client.NativeMain">
|
||||
<extra
|
||||
android:name="gfx-backend"
|
||||
android:value="Vulkan" />
|
||||
</intent>
|
||||
</shortcut>
|
||||
<shortcut
|
||||
android:shortcutId="play-opengl"
|
||||
android:enabled="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:shortcutShortLabel="@string/shortcut_play_opengl_short">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:targetPackage="org.ddnet.client"
|
||||
android:targetClass="org.ddnet.client.NativeMain">
|
||||
<extra
|
||||
android:name="gfx-backend"
|
||||
android:value="OpenGL" />
|
||||
</intent>
|
||||
</shortcut>
|
||||
</shortcuts>
|
|
@ -37,7 +37,7 @@ def decode(fileobj, elements_per_key):
|
|||
if current_key:
|
||||
if len(data[current_key]) != 1+elements_per_key:
|
||||
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
|
||||
data[current_key].append(index)
|
||||
data[current_key].append(index - 1 if current_context else index)
|
||||
if line in data:
|
||||
raise LanguageDecodeError("Key defined multiple times: " + line, fileobj.name, index)
|
||||
data[(line, current_context)] = [index - 1 if current_context else index]
|
||||
|
|
|
@ -1236,6 +1236,7 @@ int str_format_int(char *buffer, size_t buffer_size, int value);
|
|||
template<typename... Args>
|
||||
int str_format_opt(char *buffer, int buffer_size, const char *format, Args... args)
|
||||
{
|
||||
static_assert(sizeof...(args) > 0, "Use str_copy instead of str_format without format arguments");
|
||||
return str_format(buffer, buffer_size, format, args...);
|
||||
}
|
||||
|
||||
|
|
|
@ -443,7 +443,9 @@ static bool BackendInitGlew(EBackendType BackendType, int &GlewMajor, int &GlewM
|
|||
#ifdef CONF_GLEW_HAS_CONTEXT_INIT
|
||||
if(GLEW_OK != glewContextInit())
|
||||
#else
|
||||
if(GLEW_OK != glewInit())
|
||||
GLenum InitResult = glewInit();
|
||||
const char *pVideoDriver = SDL_GetCurrentVideoDriver();
|
||||
if(GLEW_OK != InitResult && pVideoDriver && !str_comp(pVideoDriver, "wayland") && GLEW_ERROR_NO_GLX_DISPLAY != InitResult)
|
||||
#endif
|
||||
return false;
|
||||
|
||||
|
@ -1019,6 +1021,13 @@ int CGraphicsBackend_SDL_GL::Init(const char *pName, int *pScreen, int *pWidth,
|
|||
SDL_GetVersion(&Linked);
|
||||
dbg_msg("sdl", "SDL version %d.%d.%d (compiled = %d.%d.%d)", Linked.major, Linked.minor, Linked.patch,
|
||||
Compiled.major, Compiled.minor, Compiled.patch);
|
||||
|
||||
#if CONF_PLATFORM_LINUX && SDL_VERSION_ATLEAST(2, 0, 22)
|
||||
// needed to workaround SDL from forcing exclusively X11 if linking against the GLX flavour of GLEW instead of the EGL one
|
||||
// w/o this on Wayland systems (no XWayland support) SDL's Video subsystem will fail to load (starting from SDL2.30+)
|
||||
if(Linked.major == 2 && Linked.minor >= 30)
|
||||
SDL_SetHint(SDL_HINT_VIDEODRIVER, "x11,wayland");
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!SDL_WasInit(SDL_INIT_VIDEO))
|
||||
|
|
|
@ -247,11 +247,7 @@ void CClient::SendReady(int Conn)
|
|||
|
||||
void CClient::SendMapRequest()
|
||||
{
|
||||
if(m_MapdownloadFileTemp)
|
||||
{
|
||||
io_close(m_MapdownloadFileTemp);
|
||||
Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE);
|
||||
}
|
||||
dbg_assert(!m_MapdownloadFileTemp, "Map download already in progress");
|
||||
m_MapdownloadFileTemp = Storage()->OpenFile(m_aMapdownloadFilenameTemp, IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||
if(IsSixup())
|
||||
{
|
||||
|
@ -656,6 +652,7 @@ void CClient::DisconnectWithReason(const char *pReason)
|
|||
m_aRconAuthed[0] = 0;
|
||||
mem_zero(m_aRconUsername, sizeof(m_aRconUsername));
|
||||
mem_zero(m_aRconPassword, sizeof(m_aRconPassword));
|
||||
m_MapDetailsPresent = false;
|
||||
m_ServerSentCapabilities = false;
|
||||
m_UseTempRconCommands = 0;
|
||||
m_ExpectedRconCommands = -1;
|
||||
|
@ -671,22 +668,7 @@ void CClient::DisconnectWithReason(const char *pReason)
|
|||
m_CurrentServerCurrentPingTime = -1;
|
||||
m_CurrentServerNextPingTime = -1;
|
||||
|
||||
// disable all downloads
|
||||
m_MapdownloadChunk = 0;
|
||||
if(m_pMapdownloadTask)
|
||||
m_pMapdownloadTask->Abort();
|
||||
if(m_MapdownloadFileTemp)
|
||||
{
|
||||
io_close(m_MapdownloadFileTemp);
|
||||
Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE);
|
||||
}
|
||||
m_MapdownloadFileTemp = 0;
|
||||
m_MapdownloadSha256Present = false;
|
||||
m_MapdownloadSha256 = SHA256_ZEROED;
|
||||
m_MapdownloadCrc = 0;
|
||||
m_MapdownloadTotalsize = -1;
|
||||
m_MapdownloadAmount = 0;
|
||||
m_MapDetailsPresent = false;
|
||||
ResetMapDownload(true);
|
||||
|
||||
// clear the current server info
|
||||
mem_zero(&m_CurrentServerInfo, sizeof(m_CurrentServerInfo));
|
||||
|
@ -1543,6 +1525,8 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
DummyDisconnect(0);
|
||||
}
|
||||
|
||||
ResetMapDownload(true);
|
||||
|
||||
SHA256_DIGEST *pMapSha256 = nullptr;
|
||||
const char *pMapUrl = nullptr;
|
||||
if(MapDetailsWerePresent && str_comp(m_aMapDetailsName, pMap) == 0 && m_MapDetailsCrc == MapCrc)
|
||||
|
@ -1559,12 +1543,6 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(m_MapdownloadFileTemp)
|
||||
{
|
||||
io_close(m_MapdownloadFileTemp);
|
||||
Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE);
|
||||
}
|
||||
|
||||
// start map download
|
||||
FormatMapDownloadFilename(pMap, pMapSha256, MapCrc, false, m_aMapdownloadFilename, sizeof(m_aMapdownloadFilename));
|
||||
FormatMapDownloadFilename(pMap, pMapSha256, MapCrc, true, m_aMapdownloadFilenameTemp, sizeof(m_aMapdownloadFilenameTemp));
|
||||
|
@ -1573,16 +1551,11 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
str_format(aBuf, sizeof(aBuf), "starting to download map to '%s'", m_aMapdownloadFilenameTemp);
|
||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", aBuf);
|
||||
|
||||
m_MapdownloadChunk = 0;
|
||||
str_copy(m_aMapdownloadName, pMap);
|
||||
|
||||
m_MapdownloadSha256Present = (bool)pMapSha256;
|
||||
m_MapdownloadSha256 = pMapSha256 ? *pMapSha256 : SHA256_ZEROED;
|
||||
m_MapdownloadCrc = MapCrc;
|
||||
m_MapdownloadTotalsize = MapSize;
|
||||
m_MapdownloadAmount = 0;
|
||||
|
||||
ResetMapDownload();
|
||||
|
||||
if(pMapSha256)
|
||||
{
|
||||
|
@ -2220,24 +2193,44 @@ int CClient::UnpackAndValidateSnapshot(CSnapshot *pFrom, CSnapshot *pTo)
|
|||
return Builder.Finish(pTo);
|
||||
}
|
||||
|
||||
void CClient::ResetMapDownload()
|
||||
void CClient::ResetMapDownload(bool ResetActive)
|
||||
{
|
||||
if(m_pMapdownloadTask)
|
||||
{
|
||||
m_pMapdownloadTask->Abort();
|
||||
m_pMapdownloadTask = NULL;
|
||||
m_pMapdownloadTask = nullptr;
|
||||
}
|
||||
|
||||
if(m_MapdownloadFileTemp)
|
||||
{
|
||||
io_close(m_MapdownloadFileTemp);
|
||||
m_MapdownloadFileTemp = 0;
|
||||
}
|
||||
|
||||
if(Storage()->FileExists(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE))
|
||||
{
|
||||
Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE);
|
||||
}
|
||||
|
||||
if(ResetActive)
|
||||
{
|
||||
m_MapdownloadChunk = 0;
|
||||
m_MapdownloadSha256Present = false;
|
||||
m_MapdownloadSha256 = SHA256_ZEROED;
|
||||
m_MapdownloadCrc = 0;
|
||||
m_MapdownloadTotalsize = -1;
|
||||
m_MapdownloadAmount = 0;
|
||||
m_aMapdownloadFilename[0] = '\0';
|
||||
m_aMapdownloadFilenameTemp[0] = '\0';
|
||||
m_aMapdownloadName[0] = '\0';
|
||||
}
|
||||
m_MapdownloadFileTemp = 0;
|
||||
m_MapdownloadAmount = 0;
|
||||
}
|
||||
|
||||
void CClient::FinishMapDownload()
|
||||
{
|
||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "download complete, loading map");
|
||||
|
||||
int Prev = m_MapdownloadTotalsize;
|
||||
m_MapdownloadTotalsize = -1;
|
||||
SHA256_DIGEST *pSha256 = m_MapdownloadSha256Present ? &m_MapdownloadSha256 : 0;
|
||||
SHA256_DIGEST *pSha256 = m_MapdownloadSha256Present ? &m_MapdownloadSha256 : nullptr;
|
||||
|
||||
bool FileSuccess = true;
|
||||
if(Storage()->FileExists(m_aMapdownloadFilename, IStorage::TYPE_SAVE))
|
||||
|
@ -2245,36 +2238,26 @@ void CClient::FinishMapDownload()
|
|||
FileSuccess &= Storage()->RenameFile(m_aMapdownloadFilenameTemp, m_aMapdownloadFilename, IStorage::TYPE_SAVE);
|
||||
if(!FileSuccess)
|
||||
{
|
||||
ResetMapDownload();
|
||||
char aError[128 + IO_MAX_PATH_LENGTH];
|
||||
str_format(aError, sizeof(aError), Localize("Could not save downloaded map. Try manually deleting this file: %s"), m_aMapdownloadFilename);
|
||||
DisconnectWithReason(aError);
|
||||
return;
|
||||
}
|
||||
|
||||
// load map
|
||||
const char *pError = LoadMap(m_aMapdownloadName, m_aMapdownloadFilename, pSha256, m_MapdownloadCrc);
|
||||
if(!pError)
|
||||
{
|
||||
ResetMapDownload();
|
||||
ResetMapDownload(true);
|
||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "loading done");
|
||||
SendReady(CONN_MAIN);
|
||||
}
|
||||
else if(m_pMapdownloadTask) // fallback
|
||||
{
|
||||
ResetMapDownload();
|
||||
m_MapdownloadTotalsize = Prev;
|
||||
ResetMapDownload(false);
|
||||
SendMapRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_MapdownloadFileTemp)
|
||||
{
|
||||
io_close(m_MapdownloadFileTemp);
|
||||
m_MapdownloadFileTemp = 0;
|
||||
Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE);
|
||||
}
|
||||
ResetMapDownload();
|
||||
DisconnectWithReason(pError);
|
||||
}
|
||||
}
|
||||
|
@ -2800,7 +2783,7 @@ void CClient::Update()
|
|||
else if(m_pMapdownloadTask->State() == EHttpState::ERROR || m_pMapdownloadTask->State() == EHttpState::ABORTED)
|
||||
{
|
||||
dbg_msg("webdl", "http failed, falling back to gameserver");
|
||||
ResetMapDownload();
|
||||
ResetMapDownload(false);
|
||||
SendMapRequest();
|
||||
}
|
||||
}
|
||||
|
@ -3333,7 +3316,7 @@ bool CClient::InitNetworkClient(char *pError, size_t ErrorSize)
|
|||
if(g_Config.m_Bindaddr[0])
|
||||
str_format(pError, ErrorSize, "Could not open the network client, try changing or unsetting the bindaddr '%s'.", g_Config.m_Bindaddr);
|
||||
else
|
||||
str_format(pError, ErrorSize, "Could not open the network client.");
|
||||
str_copy(pError, "Could not open the network client.", ErrorSize);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -4374,8 +4357,20 @@ void CClient::RegisterCommands()
|
|||
|
||||
// used for server browser update
|
||||
m_pConsole->Chain("br_filter_string", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_exclude_string", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_full", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_empty", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_spectators", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_friends", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_country", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_country_index", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_pw", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_gametype", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_gametype_strict", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_connecting_players", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_serveraddress", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_unfinished_map", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("br_filter_login", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("add_favorite", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("remove_favorite", ConchainServerBrowserUpdate, this);
|
||||
m_pConsole->Chain("end_favorite_group", ConchainServerBrowserUpdate, this);
|
||||
|
|
|
@ -360,7 +360,7 @@ public:
|
|||
|
||||
int UnpackAndValidateSnapshot(CSnapshot *pFrom, CSnapshot *pTo);
|
||||
|
||||
void ResetMapDownload();
|
||||
void ResetMapDownload(bool ResetActive);
|
||||
void FinishMapDownload();
|
||||
|
||||
void RequestDDNetInfo() override;
|
||||
|
|
|
@ -27,9 +27,6 @@
|
|||
#include <engine/http.h>
|
||||
#include <engine/storage.h>
|
||||
|
||||
static constexpr const char *COMMUNITY_COUNTRY_NONE = "none";
|
||||
static constexpr const char *COMMUNITY_TYPE_NONE = "None";
|
||||
|
||||
class CSortWrap
|
||||
{
|
||||
typedef bool (CServerBrowser::*SortFunc)(int, int) const;
|
||||
|
|
|
@ -228,10 +228,8 @@ int CSound::Init()
|
|||
return -1;
|
||||
}
|
||||
|
||||
m_MixingRate = g_Config.m_SndRate;
|
||||
|
||||
SDL_AudioSpec Format, FormatOut;
|
||||
Format.freq = m_MixingRate;
|
||||
Format.freq = g_Config.m_SndRate;
|
||||
Format.format = AUDIO_S16;
|
||||
Format.channels = 2;
|
||||
Format.samples = g_Config.m_SndBufferSize;
|
||||
|
@ -239,7 +237,7 @@ int CSound::Init()
|
|||
Format.userdata = this;
|
||||
|
||||
// Open the audio device and start playing sound!
|
||||
m_Device = SDL_OpenAudioDevice(nullptr, 0, &Format, &FormatOut, 0);
|
||||
m_Device = SDL_OpenAudioDevice(nullptr, 0, &Format, &FormatOut, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
if(m_Device == 0)
|
||||
{
|
||||
dbg_msg("sound", "unable to open audio: %s", SDL_GetError());
|
||||
|
@ -248,6 +246,7 @@ int CSound::Init()
|
|||
else
|
||||
dbg_msg("sound", "sound init successful using audio driver '%s'", SDL_GetCurrentAudioDriver());
|
||||
|
||||
m_MixingRate = FormatOut.freq;
|
||||
m_MaxFrames = FormatOut.samples * 2;
|
||||
#if defined(CONF_VIDEORECORDER)
|
||||
m_MaxFrames = maximum<uint32_t>(m_MaxFrames, 1024 * 2); // make the buffer bigger just in case
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
virtual int GetInteger(unsigned Index) const = 0;
|
||||
virtual float GetFloat(unsigned Index) const = 0;
|
||||
virtual const char *GetString(unsigned Index) const = 0;
|
||||
virtual ColorHSLA GetColor(unsigned Index, bool Light) const = 0;
|
||||
virtual std::optional<ColorHSLA> GetColor(unsigned Index, bool Light) const = 0;
|
||||
|
||||
virtual void RemoveArgument(unsigned Index) = 0;
|
||||
|
||||
|
|
|
@ -254,6 +254,7 @@ public:
|
|||
virtual void Ban(int ClientId, int Seconds, const char *pReason, bool VerbatimReason) = 0;
|
||||
virtual void RedirectClient(int ClientId, int Port, bool Verbose = false) = 0;
|
||||
virtual void ChangeMap(const char *pMap) = 0;
|
||||
virtual void ReloadMap() = 0;
|
||||
|
||||
virtual void DemoRecorder_HandleAutoStart() = 0;
|
||||
|
||||
|
|
|
@ -2341,7 +2341,7 @@ void CServer::UpdateRegisterServerInfo()
|
|||
JsonWriter.WriteAttribute("map");
|
||||
JsonWriter.BeginObject();
|
||||
JsonWriter.WriteAttribute("name");
|
||||
JsonWriter.WriteStrValue(m_aCurrentMap);
|
||||
JsonWriter.WriteStrValue(GetMapName());
|
||||
JsonWriter.WriteAttribute("sha256");
|
||||
JsonWriter.WriteStrValue(aMapSha256);
|
||||
JsonWriter.WriteAttribute("size");
|
||||
|
@ -2551,6 +2551,11 @@ void CServer::ChangeMap(const char *pMap)
|
|||
m_MapReload = str_comp(Config()->m_SvMap, m_aCurrentMap) != 0;
|
||||
}
|
||||
|
||||
void CServer::ReloadMap()
|
||||
{
|
||||
m_MapReload = true;
|
||||
}
|
||||
|
||||
int CServer::LoadMap(const char *pMapName)
|
||||
{
|
||||
m_MapReload = false;
|
||||
|
|
|
@ -379,6 +379,7 @@ public:
|
|||
|
||||
void ChangeMap(const char *pMap) override;
|
||||
const char *GetMapName() const override;
|
||||
void ReloadMap() override;
|
||||
int LoadMap(const char *pMapName);
|
||||
|
||||
void SaveDemo(int ClientId, float Time) override;
|
||||
|
|
|
@ -309,6 +309,9 @@ public:
|
|||
|
||||
static constexpr const char *COMMUNITY_DDNET = "ddnet";
|
||||
static constexpr const char *COMMUNITY_NONE = "none";
|
||||
|
||||
static constexpr const char *COMMUNITY_COUNTRY_NONE = "none";
|
||||
static constexpr const char *COMMUNITY_TYPE_NONE = "None";
|
||||
/**
|
||||
* Special community value for country/type filters that
|
||||
* affect all communities.
|
||||
|
|
|
@ -111,22 +111,29 @@ void SIntConfigVariable::ResetToOld()
|
|||
void SColorConfigVariable::CommandCallback(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
SColorConfigVariable *pData = static_cast<SColorConfigVariable *>(pUserData);
|
||||
|
||||
char aBuf[IConsole::CMDLINE_LENGTH + 64];
|
||||
if(pResult->NumArguments())
|
||||
{
|
||||
if(pData->CheckReadOnly())
|
||||
return;
|
||||
|
||||
const ColorHSLA Color = pResult->GetColor(0, pData->m_Light);
|
||||
const unsigned Value = Color.Pack(pData->m_Light ? 0.5f : 0.0f, pData->m_Alpha);
|
||||
const auto Color = pResult->GetColor(0, pData->m_Light);
|
||||
if(Color)
|
||||
{
|
||||
const unsigned Value = Color->Pack(pData->m_Light ? 0.5f : 0.0f, pData->m_Alpha);
|
||||
|
||||
*pData->m_pVariable = Value;
|
||||
if(pResult->m_ClientId != IConsole::CLIENT_ID_GAME)
|
||||
pData->m_OldValue = Value;
|
||||
*pData->m_pVariable = Value;
|
||||
if(pResult->m_ClientId != IConsole::CLIENT_ID_GAME)
|
||||
pData->m_OldValue = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "%s is not a valid color.", pResult->GetString(0));
|
||||
pData->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "config", aBuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "Value: %u", *pData->m_pVariable);
|
||||
pData->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "config", aBuf);
|
||||
|
||||
|
@ -493,8 +500,8 @@ void CConfigManager::Con_Toggle(IConsole::IResult *pResult, void *pUserData)
|
|||
{
|
||||
SColorConfigVariable *pColorVariable = static_cast<SColorConfigVariable *>(pVariable);
|
||||
const float Darkest = pColorVariable->m_Light ? 0.5f : 0.0f;
|
||||
const ColorHSLA Value = *pColorVariable->m_pVariable == pResult->GetColor(1, pColorVariable->m_Light).Pack(Darkest, pColorVariable->m_Alpha) ? pResult->GetColor(2, pColorVariable->m_Light) : pResult->GetColor(1, pColorVariable->m_Light);
|
||||
pColorVariable->SetValue(Value.Pack(Darkest, pColorVariable->m_Alpha));
|
||||
const std::optional<ColorHSLA> Value = *pColorVariable->m_pVariable == pResult->GetColor(1, pColorVariable->m_Light).value_or(ColorHSLA(0, 0, 0)).Pack(Darkest, pColorVariable->m_Alpha) ? pResult->GetColor(2, pColorVariable->m_Light) : pResult->GetColor(1, pColorVariable->m_Light);
|
||||
pColorVariable->SetValue(Value.value_or(ColorHSLA(0, 0, 0)).Pack(Darkest, pColorVariable->m_Alpha));
|
||||
}
|
||||
else if(pVariable->m_Type == SConfigVariable::VAR_STRING)
|
||||
{
|
||||
|
|
|
@ -105,6 +105,7 @@ MACRO_CONFIG_INT(EdZoomTarget, ed_zoom_target, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG
|
|||
MACRO_CONFIG_INT(EdShowkeys, ed_showkeys, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show pressed keys")
|
||||
MACRO_CONFIG_INT(EdAlignQuads, ed_align_quads, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable/disable quad alignment. When enabled, red lines appear to show how quad/points are aligned and snapped to other quads/points when moving them")
|
||||
MACRO_CONFIG_INT(EdShowQuadsRect, ed_show_quads_rect, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show the bounds of the selected quad. In case of multiple quads, it shows the bounds of the englobing rect. Can be helpful when aligning a group of quads")
|
||||
MACRO_CONFIG_INT(EdAutoMapReload, ed_auto_map_reload, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Run 'hot_reload' on the local server while rcon authed on map save")
|
||||
|
||||
MACRO_CONFIG_INT(ClShowWelcome, cl_show_welcome, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show welcome message indicating the first launch of the client")
|
||||
MACRO_CONFIG_INT(ClMotdTime, cl_motd_time, 10, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "How long to show the server message of the day")
|
||||
|
@ -343,6 +344,9 @@ MACRO_CONFIG_INT(BrDemoSort, br_demo_sort, 0, 0, 2, CFGFLAG_SAVE | CFGFLAG_CLIEN
|
|||
MACRO_CONFIG_INT(BrDemoSortOrder, br_demo_sort_order, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Sorting order in demo browser")
|
||||
MACRO_CONFIG_INT(BrDemoFetchInfo, br_demo_fetch_info, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Whether to auto fetch demo infos on refresh")
|
||||
|
||||
MACRO_CONFIG_INT(GhSort, gh_sort, 1, 0, 2, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Sorting column in ghost list")
|
||||
MACRO_CONFIG_INT(GhSortOrder, gh_sort_order, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Sorting order in ghost list")
|
||||
|
||||
MACRO_CONFIG_INT(SndBufferSize, snd_buffer_size, 512, 128, 32768, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Sound buffer size (may cause delay if large)")
|
||||
MACRO_CONFIG_INT(SndRate, snd_rate, 48000, 5512, 384000, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Sound mixing rate")
|
||||
MACRO_CONFIG_INT(SndEnable, snd_enable, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Sound enable")
|
||||
|
|
|
@ -40,22 +40,29 @@ float CConsole::CResult::GetFloat(unsigned Index) const
|
|||
return str_tofloat(m_apArgs[Index]);
|
||||
}
|
||||
|
||||
ColorHSLA CConsole::CResult::GetColor(unsigned Index, bool Light) const
|
||||
std::optional<ColorHSLA> CConsole::CResult::GetColor(unsigned Index, bool Light) const
|
||||
{
|
||||
if(Index >= m_NumArgs)
|
||||
return ColorHSLA(0, 0, 0);
|
||||
return std::nullopt;
|
||||
|
||||
const char *pStr = m_apArgs[Index];
|
||||
if(str_isallnum(pStr) || ((pStr[0] == '-' || pStr[0] == '+') && str_isallnum(pStr + 1))) // Teeworlds Color (Packed HSL)
|
||||
{
|
||||
const ColorHSLA Hsla = ColorHSLA(str_toulong_base(pStr, 10), true);
|
||||
unsigned long Value = str_toulong_base(pStr, 10);
|
||||
if(Value == std::numeric_limits<unsigned long>::max())
|
||||
return std::nullopt;
|
||||
const ColorHSLA Hsla = ColorHSLA(Value, true);
|
||||
if(Light)
|
||||
return Hsla.UnclampLighting();
|
||||
return Hsla;
|
||||
}
|
||||
else if(*pStr == '$') // Hex RGB/RGBA
|
||||
{
|
||||
return color_cast<ColorHSLA>(color_parse<ColorRGBA>(pStr + 1).value_or(ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
auto ParsedColor = color_parse<ColorRGBA>(pStr + 1);
|
||||
if(ParsedColor)
|
||||
return color_cast<ColorHSLA>(ParsedColor.value());
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
else if(!str_comp_nocase(pStr, "red"))
|
||||
return ColorHSLA(0.0f / 6.0f, 1, .5f);
|
||||
|
@ -76,7 +83,7 @@ ColorHSLA CConsole::CResult::GetColor(unsigned Index, bool Light) const
|
|||
else if(!str_comp_nocase(pStr, "black"))
|
||||
return ColorHSLA(0, 0, 0);
|
||||
|
||||
return ColorHSLA(0, 0, 0);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const IConsole::CCommandInfo *CConsole::CCommand::NextCommandInfo(int AccessLevel, int FlagMask) const
|
||||
|
@ -129,12 +136,12 @@ int CConsole::ParseStart(CResult *pResult, const char *pString, int Length)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CConsole::ParseArgs(CResult *pResult, const char *pFormat)
|
||||
int CConsole::ParseArgs(CResult *pResult, const char *pFormat, bool IsColor)
|
||||
{
|
||||
char Command = *pFormat;
|
||||
char *pStr;
|
||||
int Optional = 0;
|
||||
int Error = 0;
|
||||
int Error = PARSEARGS_OK;
|
||||
|
||||
pResult->ResetVictim();
|
||||
|
||||
|
@ -155,7 +162,7 @@ int CConsole::ParseArgs(CResult *pResult, const char *pFormat)
|
|||
{
|
||||
if(!Optional)
|
||||
{
|
||||
Error = 1;
|
||||
Error = PARSEARGS_MISSING_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -191,7 +198,7 @@ int CConsole::ParseArgs(CResult *pResult, const char *pFormat)
|
|||
pStr++; // skip due to escape
|
||||
}
|
||||
else if(pStr[0] == 0)
|
||||
return 1; // return error
|
||||
return PARSEARGS_MISSING_VALUE; // return error
|
||||
|
||||
*pDst = *pStr;
|
||||
pDst++;
|
||||
|
@ -215,13 +222,7 @@ int CConsole::ParseArgs(CResult *pResult, const char *pFormat)
|
|||
|
||||
if(Command == 'r') // rest of the string
|
||||
break;
|
||||
else if(Command == 'v') // validate victim
|
||||
pStr = str_skip_to_whitespace(pStr);
|
||||
else if(Command == 'i') // validate int
|
||||
pStr = str_skip_to_whitespace(pStr);
|
||||
else if(Command == 'f') // validate float
|
||||
pStr = str_skip_to_whitespace(pStr);
|
||||
else if(Command == 's') // validate string
|
||||
else if(Command == 'v' || Command == 'i' || Command == 'f' || Command == 's')
|
||||
pStr = str_skip_to_whitespace(pStr);
|
||||
|
||||
if(pStr[0] != 0) // check for end of string
|
||||
|
@ -230,6 +231,32 @@ int CConsole::ParseArgs(CResult *pResult, const char *pFormat)
|
|||
pStr++;
|
||||
}
|
||||
|
||||
// validate args
|
||||
if(Command == 'i')
|
||||
{
|
||||
// don't validate colors here
|
||||
if(!IsColor)
|
||||
{
|
||||
int Value;
|
||||
if(!str_toint(pResult->GetString(pResult->NumArguments() - 1), &Value) ||
|
||||
Value == std::numeric_limits<int>::max() || Value == std::numeric_limits<int>::min())
|
||||
{
|
||||
Error = PARSEARGS_INVALID_INTEGER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(Command == 'f')
|
||||
{
|
||||
float Value;
|
||||
if(!str_tofloat(pResult->GetString(pResult->NumArguments() - 1), &Value) ||
|
||||
Value == std::numeric_limits<float>::max() || Value == std::numeric_limits<float>::min())
|
||||
{
|
||||
Error = PARSEARGS_INVALID_FLOAT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(pVictim)
|
||||
{
|
||||
pResult->SetVictim(pVictim);
|
||||
|
@ -487,10 +514,15 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, int ClientId, bo
|
|||
|
||||
if(Stroke || IsStrokeCommand)
|
||||
{
|
||||
if(ParseArgs(&Result, pCommand->m_pParams))
|
||||
if(int Error = ParseArgs(&Result, pCommand->m_pParams, pCommand->m_pfnCallback == &SColorConfigVariable::CommandCallback))
|
||||
{
|
||||
char aBuf[TEMPCMD_NAME_LENGTH + TEMPCMD_PARAMS_LENGTH + 32];
|
||||
str_format(aBuf, sizeof(aBuf), "Invalid arguments. Usage: %s %s", pCommand->m_pName, pCommand->m_pParams);
|
||||
char aBuf[CMDLINE_LENGTH + 64];
|
||||
if(Error == PARSEARGS_INVALID_INTEGER)
|
||||
str_format(aBuf, sizeof(aBuf), "%s is not a valid integer.", Result.GetString(Result.NumArguments() - 1));
|
||||
else if(Error == PARSEARGS_INVALID_FLOAT)
|
||||
str_format(aBuf, sizeof(aBuf), "%s is not a valid decimal number.", Result.GetString(Result.NumArguments() - 1));
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), "Invalid arguments. Usage: %s %s", pCommand->m_pName, pCommand->m_pParams);
|
||||
Print(OUTPUT_LEVEL_STANDARD, "chatresp", aBuf);
|
||||
}
|
||||
else if(m_StoreCommands && pCommand->m_Flags & CFGFLAG_STORE)
|
||||
|
|
|
@ -115,7 +115,7 @@ class CConsole : public IConsole
|
|||
const char *GetString(unsigned Index) const override;
|
||||
int GetInteger(unsigned Index) const override;
|
||||
float GetFloat(unsigned Index) const override;
|
||||
ColorHSLA GetColor(unsigned Index, bool Light) const override;
|
||||
std::optional<ColorHSLA> GetColor(unsigned Index, bool Light) const override;
|
||||
|
||||
void RemoveArgument(unsigned Index) override
|
||||
{
|
||||
|
@ -144,7 +144,16 @@ class CConsole : public IConsole
|
|||
};
|
||||
|
||||
int ParseStart(CResult *pResult, const char *pString, int Length);
|
||||
int ParseArgs(CResult *pResult, const char *pFormat);
|
||||
|
||||
enum
|
||||
{
|
||||
PARSEARGS_OK = 0,
|
||||
PARSEARGS_MISSING_VALUE,
|
||||
PARSEARGS_INVALID_INTEGER,
|
||||
PARSEARGS_INVALID_FLOAT,
|
||||
};
|
||||
|
||||
int ParseArgs(CResult *pResult, const char *pFormat, bool IsColor = false);
|
||||
|
||||
/*
|
||||
this function will set pFormat to the next parameter (i,s,r,v,?) it contains and
|
||||
|
|
|
@ -490,8 +490,7 @@ void CNetBan::ConBans(IConsole::IResult *pResult, void *pUser)
|
|||
|
||||
if(NumBans == 0)
|
||||
{
|
||||
str_format(aMsg, sizeof(aMsg), "The ban list is empty.");
|
||||
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aMsg);
|
||||
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "The ban list is empty.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,16 @@
|
|||
|
||||
#include "protocolglue.h"
|
||||
|
||||
int GameFlags_ClampToSix(int Flags)
|
||||
{
|
||||
int Six = 0;
|
||||
if(Flags & GAMEFLAG_TEAMS)
|
||||
Six |= GAMEFLAG_TEAMS;
|
||||
if(Flags & GAMEFLAG_FLAGS)
|
||||
Six |= GAMEFLAG_FLAGS;
|
||||
return Six;
|
||||
}
|
||||
|
||||
int PlayerFlags_SevenToSix(int Flags)
|
||||
{
|
||||
int Six = 0;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef ENGINE_SHARED_PROTOCOLGLUE_H
|
||||
#define ENGINE_SHARED_PROTOCOLGLUE_H
|
||||
|
||||
int GameFlags_ClampToSix(int Flags);
|
||||
int PlayerFlags_SevenToSix(int Flags);
|
||||
int PlayerFlags_SixToSeven(int Flags);
|
||||
void PickupType_SevenToSix(int Type7, int &Type6, int &SubType6);
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
CreateFolder("mapres", TYPE_SAVE);
|
||||
CreateFolder("downloadedmaps", TYPE_SAVE);
|
||||
CreateFolder("skins", TYPE_SAVE);
|
||||
CreateFolder("skins7", TYPE_SAVE);
|
||||
CreateFolder("downloadedskins", TYPE_SAVE);
|
||||
CreateFolder("themes", TYPE_SAVE);
|
||||
CreateFolder("communityicons", TYPE_SAVE);
|
||||
|
|
|
@ -93,6 +93,7 @@ MAYBE_UNUSED static const char *FONT_ICON_EARTH_AMERICAS = "\xEF\x95\xBD";
|
|||
MAYBE_UNUSED static const char *FONT_ICON_NETWORK_WIRED = "\xEF\x9B\xBF";
|
||||
MAYBE_UNUSED static const char *FONT_ICON_LIST_UL = "\xEF\x83\x8A";
|
||||
MAYBE_UNUSED static const char *FONT_ICON_INFO = "\xEF\x84\xA9";
|
||||
MAYBE_UNUSED static const char *FONT_ICON_TERMINAL = "\xEF\x84\xA0";
|
||||
|
||||
MAYBE_UNUSED static const char *FONT_ICON_SLASH = "\xEF\x9C\x95";
|
||||
MAYBE_UNUSED static const char *FONT_ICON_PLAY = "\xEF\x81\x8B";
|
||||
|
|
|
@ -1693,8 +1693,7 @@ void CHud::RenderRecord()
|
|||
if(m_ServerRecord > 0.0f)
|
||||
{
|
||||
char aBuf[64];
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Server best:"));
|
||||
TextRender()->Text(5, 75, 6, aBuf, -1.0f);
|
||||
TextRender()->Text(5, 75, 6, Localize("Server best:"), -1.0f);
|
||||
char aTime[32];
|
||||
str_time_float(m_ServerRecord, TIME_HOURS_CENTISECS, aTime, sizeof(aTime));
|
||||
str_format(aBuf, sizeof(aBuf), "%s%s", m_ServerRecord > 3600 ? "" : " ", aTime);
|
||||
|
@ -1705,8 +1704,7 @@ void CHud::RenderRecord()
|
|||
if(PlayerRecord > 0.0f)
|
||||
{
|
||||
char aBuf[64];
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Personal best:"));
|
||||
TextRender()->Text(5, 82, 6, aBuf, -1.0f);
|
||||
TextRender()->Text(5, 82, 6, Localize("Personal best:"), -1.0f);
|
||||
char aTime[32];
|
||||
str_time_float(PlayerRecord, TIME_HOURS_CENTISECS, aTime, sizeof(aTime));
|
||||
str_format(aBuf, sizeof(aBuf), "%s%s", PlayerRecord > 3600 ? "" : " ", aTime);
|
||||
|
|
|
@ -1208,7 +1208,7 @@ void CMenus::RenderPopupFullscreen(CUIRect Screen)
|
|||
pButtonText = Localize("Ok");
|
||||
if(Client()->ReconnectTime() > 0)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Reconnect in %d sec"), (int)((Client()->ReconnectTime() - time_get()) / time_freq()));
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Reconnect in %d sec"), (int)((Client()->ReconnectTime() - time_get()) / time_freq()) + 1);
|
||||
pTitle = Client()->ErrorString();
|
||||
pExtraText = aBuf;
|
||||
pButtonText = Localize("Abort");
|
||||
|
@ -1282,6 +1282,11 @@ void CMenus::RenderPopupFullscreen(CUIRect Screen)
|
|||
pButtonText = m_aMessageButton;
|
||||
TopAlign = true;
|
||||
}
|
||||
else if(m_Popup == POPUP_SAVE_SKIN)
|
||||
{
|
||||
pTitle = Localize("Save skin");
|
||||
pExtraText = Localize("Are you sure you want to save your skin? If a skin with this name already exists, it will be replaced.");
|
||||
}
|
||||
|
||||
CUIRect Box, Part;
|
||||
Box = Screen;
|
||||
|
@ -1756,6 +1761,52 @@ void CMenus::RenderPopupFullscreen(CUIRect Screen)
|
|||
SetActive(false);
|
||||
}
|
||||
}
|
||||
else if(m_Popup == POPUP_SAVE_SKIN)
|
||||
{
|
||||
CUIRect Label, TextBox, Yes, No;
|
||||
|
||||
Box.HSplitBottom(20.f, &Box, &Part);
|
||||
Box.HSplitBottom(24.f, &Box, &Part);
|
||||
Part.VMargin(80.0f, &Part);
|
||||
|
||||
Part.VSplitMid(&No, &Yes);
|
||||
|
||||
Yes.VMargin(20.0f, &Yes);
|
||||
No.VMargin(20.0f, &No);
|
||||
|
||||
static CButtonContainer s_ButtonNo;
|
||||
if(DoButton_Menu(&s_ButtonNo, Localize("No"), 0, &No) || Ui()->ConsumeHotkey(CUi::HOTKEY_ESCAPE))
|
||||
m_Popup = POPUP_NONE;
|
||||
|
||||
static CButtonContainer s_ButtonYes;
|
||||
if(DoButton_Menu(&s_ButtonYes, Localize("Yes"), m_SkinNameInput.IsEmpty() ? 1 : 0, &Yes) || Ui()->ConsumeHotkey(CUi::HOTKEY_ENTER))
|
||||
{
|
||||
if(m_SkinNameInput.GetLength())
|
||||
{
|
||||
if(m_SkinNameInput.GetString()[0] != 'x' && m_SkinNameInput.GetString()[1] != '_')
|
||||
{
|
||||
if(m_pClient->m_Skins7.SaveSkinfile(m_SkinNameInput.GetString(), m_Dummy))
|
||||
{
|
||||
m_Popup = POPUP_NONE;
|
||||
m_SkinListNeedsUpdate = true;
|
||||
}
|
||||
else
|
||||
PopupMessage(Localize("Error"), Localize("Unable to save the skin"), Localize("Ok"), POPUP_SAVE_SKIN);
|
||||
}
|
||||
else
|
||||
PopupMessage(Localize("Error"), Localize("Unable to save the skin with a reserved name"), Localize("Ok"), POPUP_SAVE_SKIN);
|
||||
}
|
||||
}
|
||||
|
||||
Box.HSplitBottom(60.f, &Box, &Part);
|
||||
Box.HSplitBottom(24.f, &Box, &Part);
|
||||
|
||||
Part.VMargin(60.0f, &Label);
|
||||
Label.VSplitLeft(100.0f, &Label, &TextBox);
|
||||
TextBox.VSplitLeft(20.0f, nullptr, &TextBox);
|
||||
Ui()->DoLabel(&Label, Localize("Name"), 18.0f, TEXTALIGN_ML);
|
||||
Ui()->DoClearableEditBox(&m_SkinNameInput, &TextBox, 12.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Box.HSplitBottom(20.f, &Box, &Part);
|
||||
|
|
|
@ -768,6 +768,14 @@ public:
|
|||
bool HasFile() const { return m_aFilename[0]; }
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GHOST_SORT_NONE = -1,
|
||||
GHOST_SORT_NAME,
|
||||
GHOST_SORT_TIME,
|
||||
GHOST_SORT_DATE,
|
||||
};
|
||||
|
||||
std::vector<CGhostItem> m_vGhosts;
|
||||
|
||||
std::chrono::nanoseconds m_GhostPopulateStartTime{0};
|
||||
|
@ -776,6 +784,7 @@ public:
|
|||
CGhostItem *GetOwnGhost();
|
||||
void UpdateOwnGhost(CGhostItem Item);
|
||||
void DeleteGhostItem(int Index);
|
||||
void SortGhostlist();
|
||||
|
||||
bool CanDisplayWarning() const;
|
||||
|
||||
|
@ -802,6 +811,7 @@ public:
|
|||
POPUP_QUIT,
|
||||
POPUP_RESTART,
|
||||
POPUP_WARNING,
|
||||
POPUP_SAVE_SKIN,
|
||||
|
||||
// demo player states
|
||||
DEMOPLAYER_NONE = 0,
|
||||
|
|
|
@ -869,11 +869,14 @@ void CMenus::RenderServerbrowserDDNetFilter(CUIRect View,
|
|||
{
|
||||
if(Click == 1)
|
||||
{
|
||||
// Left click: when all are active, only activate one
|
||||
// Left click: when all are active, only activate one and none
|
||||
for(int j = 0; j < MaxItems; ++j)
|
||||
{
|
||||
if(j != ItemIndex)
|
||||
Filter.Add(GetItemName(j));
|
||||
if(const char *pItemName = GetItemName(j);
|
||||
j != ItemIndex &&
|
||||
!((&Filter == &ServerBrowser()->CountriesFilter() && str_comp(pItemName, IServerBrowser::COMMUNITY_COUNTRY_NONE) == 0) ||
|
||||
(&Filter == &ServerBrowser()->TypesFilter() && str_comp(pItemName, IServerBrowser::COMMUNITY_TYPE_NONE) == 0)))
|
||||
Filter.Add(pItemName);
|
||||
}
|
||||
}
|
||||
else if(Click == 2)
|
||||
|
@ -890,7 +893,10 @@ void CMenus::RenderServerbrowserDDNetFilter(CUIRect View,
|
|||
bool AllFilteredExceptUs = true;
|
||||
for(int j = 0; j < MaxItems; ++j)
|
||||
{
|
||||
if(j != ItemIndex && !Filter.Filtered(GetItemName(j)))
|
||||
if(const char *pItemName = GetItemName(j);
|
||||
j != ItemIndex && !Filter.Filtered(pItemName) &&
|
||||
!((&Filter == &ServerBrowser()->CountriesFilter() && str_comp(pItemName, IServerBrowser::COMMUNITY_COUNTRY_NONE) == 0) ||
|
||||
(&Filter == &ServerBrowser()->TypesFilter() && str_comp(pItemName, IServerBrowser::COMMUNITY_TYPE_NONE) == 0)))
|
||||
{
|
||||
AllFilteredExceptUs = false;
|
||||
break;
|
||||
|
@ -898,7 +904,7 @@ void CMenus::RenderServerbrowserDDNetFilter(CUIRect View,
|
|||
}
|
||||
// When last one is removed, re-enable all currently selectable items.
|
||||
// Don't use Clear, to avoid enabling also currently unselectable items.
|
||||
if(AllFilteredExceptUs)
|
||||
if(AllFilteredExceptUs && Active)
|
||||
{
|
||||
for(int j = 0; j < MaxItems; ++j)
|
||||
{
|
||||
|
|
|
@ -175,12 +175,12 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
|||
// increase/decrease speed
|
||||
if(!Input()->ModifierIsPressed() && !Input()->ShiftIsPressed() && !Input()->AltIsPressed())
|
||||
{
|
||||
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) || Input()->KeyPress(KEY_UP))
|
||||
if(Input()->KeyPress(KEY_UP) || (m_MenuActive && Input()->KeyPress(KEY_MOUSE_WHEEL_UP)))
|
||||
{
|
||||
DemoPlayer()->AdjustSpeedIndex(+1);
|
||||
UpdateLastSpeedChange();
|
||||
}
|
||||
else if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) || Input()->KeyPress(KEY_DOWN))
|
||||
else if(Input()->KeyPress(KEY_DOWN) || (m_MenuActive && Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN)))
|
||||
{
|
||||
DemoPlayer()->AdjustSpeedIndex(-1);
|
||||
UpdateLastSpeedChange();
|
||||
|
|
|
@ -76,7 +76,7 @@ void CMenus::RenderGame(CUIRect MainView)
|
|||
if(!Client()->DummyAllowed())
|
||||
{
|
||||
DoButton_Menu(&s_DummyButton, Localize("Connect Dummy"), 1, &Button);
|
||||
GameClient()->m_Tooltips.DoToolTip(&s_DummyButton, &Button, Localize("Dummy is not allowed on this server."));
|
||||
GameClient()->m_Tooltips.DoToolTip(&s_DummyButton, &Button, Localize("Dummy is not allowed on this server"));
|
||||
}
|
||||
else if(Client()->DummyConnectingDelayed())
|
||||
{
|
||||
|
@ -944,7 +944,7 @@ void CMenus::GhostlistPopulate()
|
|||
m_vGhosts.clear();
|
||||
m_GhostPopulateStartTime = time_get_nanoseconds();
|
||||
Storage()->ListDirectoryInfo(IStorage::TYPE_ALL, m_pClient->m_Ghost.GetGhostDir(), GhostlistFetchCallback, this);
|
||||
std::sort(m_vGhosts.begin(), m_vGhosts.end());
|
||||
SortGhostlist();
|
||||
|
||||
CGhostItem *pOwnGhost = 0;
|
||||
for(auto &Ghost : m_vGhosts)
|
||||
|
@ -1000,6 +1000,7 @@ void CMenus::UpdateOwnGhost(CGhostItem Item)
|
|||
Item.m_Date = std::time(0);
|
||||
Item.m_Failed = false;
|
||||
m_vGhosts.insert(std::lower_bound(m_vGhosts.begin(), m_vGhosts.end(), Item), Item);
|
||||
SortGhostlist();
|
||||
}
|
||||
|
||||
void CMenus::DeleteGhostItem(int Index)
|
||||
|
@ -1009,6 +1010,22 @@ void CMenus::DeleteGhostItem(int Index)
|
|||
m_vGhosts.erase(m_vGhosts.begin() + Index);
|
||||
}
|
||||
|
||||
void CMenus::SortGhostlist()
|
||||
{
|
||||
if(g_Config.m_GhSort == GHOST_SORT_NAME)
|
||||
std::stable_sort(m_vGhosts.begin(), m_vGhosts.end(), [](const CGhostItem &Left, const CGhostItem &Right) {
|
||||
return g_Config.m_GhSortOrder ? (str_comp(Left.m_aPlayer, Right.m_aPlayer) > 0) : (str_comp(Left.m_aPlayer, Right.m_aPlayer) < 0);
|
||||
});
|
||||
else if(g_Config.m_GhSort == GHOST_SORT_TIME)
|
||||
std::stable_sort(m_vGhosts.begin(), m_vGhosts.end(), [](const CGhostItem &Left, const CGhostItem &Right) {
|
||||
return g_Config.m_GhSortOrder ? (Left.m_Time > Right.m_Time) : (Left.m_Time < Right.m_Time);
|
||||
});
|
||||
else if(g_Config.m_GhSort == GHOST_SORT_DATE)
|
||||
std::stable_sort(m_vGhosts.begin(), m_vGhosts.end(), [](const CGhostItem &Left, const CGhostItem &Right) {
|
||||
return g_Config.m_GhSortOrder ? (Left.m_Date > Right.m_Date) : (Left.m_Date < Right.m_Date);
|
||||
});
|
||||
}
|
||||
|
||||
void CMenus::RenderGhost(CUIRect MainView)
|
||||
{
|
||||
// render background
|
||||
|
@ -1029,10 +1046,12 @@ void CMenus::RenderGhost(CUIRect MainView)
|
|||
Headers.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_T, 5.0f);
|
||||
Headers.VSplitRight(20.0f, &Headers, 0);
|
||||
|
||||
struct CColumn
|
||||
class CColumn
|
||||
{
|
||||
public:
|
||||
const char *m_pCaption;
|
||||
int m_Id;
|
||||
int m_Sort;
|
||||
float m_Width;
|
||||
CUIRect m_Rect;
|
||||
};
|
||||
|
@ -1046,11 +1065,11 @@ void CMenus::RenderGhost(CUIRect MainView)
|
|||
};
|
||||
|
||||
static CColumn s_aCols[] = {
|
||||
{"", -1, 2.0f, {0}},
|
||||
{"", COL_ACTIVE, 30.0f, {0}},
|
||||
{Localizable("Name"), COL_NAME, 200.0f, {0}},
|
||||
{Localizable("Time"), COL_TIME, 90.0f, {0}},
|
||||
{Localizable("Date"), COL_DATE, 150.0f, {0}},
|
||||
{"", -1, GHOST_SORT_NONE, 2.0f, {0}},
|
||||
{"", COL_ACTIVE, GHOST_SORT_NONE, 30.0f, {0}},
|
||||
{Localizable("Name"), COL_NAME, GHOST_SORT_NAME, 200.0f, {0}},
|
||||
{Localizable("Time"), COL_TIME, GHOST_SORT_TIME, 90.0f, {0}},
|
||||
{Localizable("Date"), COL_DATE, GHOST_SORT_DATE, 150.0f, {0}},
|
||||
};
|
||||
|
||||
int NumCols = std::size(s_aCols);
|
||||
|
@ -1065,8 +1084,22 @@ void CMenus::RenderGhost(CUIRect MainView)
|
|||
}
|
||||
|
||||
// do headers
|
||||
for(int i = 0; i < NumCols; i++)
|
||||
DoButton_GridHeader(&s_aCols[i].m_Id, Localize(s_aCols[i].m_pCaption), 0, &s_aCols[i].m_Rect);
|
||||
for(const auto &Col : s_aCols)
|
||||
{
|
||||
if(DoButton_GridHeader(&Col.m_Id, Localize(Col.m_pCaption), g_Config.m_GhSort == Col.m_Sort, &Col.m_Rect))
|
||||
{
|
||||
if(Col.m_Sort != GHOST_SORT_NONE)
|
||||
{
|
||||
if(g_Config.m_GhSort == Col.m_Sort)
|
||||
g_Config.m_GhSortOrder ^= 1;
|
||||
else
|
||||
g_Config.m_GhSortOrder = 0;
|
||||
g_Config.m_GhSort = Col.m_Sort;
|
||||
|
||||
SortGhostlist();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
View.Draw(ColorRGBA(0, 0, 0, 0.15f), 0, 0);
|
||||
|
||||
|
|
|
@ -3310,15 +3310,15 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
else if(State >= IUpdater::GETTING_MANIFEST && State < IUpdater::NEED_RESTART)
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Updating…"));
|
||||
str_copy(aBuf, Localize("Updating…"));
|
||||
else if(State == IUpdater::NEED_RESTART)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("DDNet Client updated!"));
|
||||
str_copy(aBuf, Localize("DDNet Client updated!"));
|
||||
m_NeedRestartUpdate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("No updates available"));
|
||||
str_copy(aBuf, Localize("No updates available"));
|
||||
UpdaterRect.VSplitLeft(TextRender()->TextWidth(14.0f, aBuf, -1, -1.0f) + 10.0f, &UpdaterRect, &Button);
|
||||
Button.VSplitLeft(100.0f, &Button, nullptr);
|
||||
static CButtonContainer s_ButtonUpdate;
|
||||
|
|
|
@ -52,10 +52,12 @@ void CMenus::RenderSettingsTee7(CUIRect MainView)
|
|||
MainView.HSplitBottom(40.0f, &MainView, &BottomView);
|
||||
BottomView.HSplitTop(20.f, 0, &BottomView);
|
||||
|
||||
CUIRect QuickSearch, Buttons;
|
||||
CUIRect QuickSearch, DirectoryButton, Buttons;
|
||||
CUIRect ButtonLeft, ButtonMiddle, ButtonRight;
|
||||
|
||||
BottomView.VSplitMid(&QuickSearch, &Buttons);
|
||||
BottomView.VSplitMid(&QuickSearch, &Buttons, 10.0f);
|
||||
QuickSearch.VSplitLeft(240.0f, &QuickSearch, &DirectoryButton);
|
||||
QuickSearch.VSplitRight(10.0f, &QuickSearch, nullptr);
|
||||
|
||||
const float ButtonSize = Buttons.w / 3;
|
||||
Buttons.VSplitLeft(ButtonSize, &ButtonLeft, &Buttons);
|
||||
|
@ -237,6 +239,14 @@ void CMenus::RenderSettingsTee7(CUIRect MainView)
|
|||
// bottom buttons
|
||||
if(s_CustomSkinMenu)
|
||||
{
|
||||
static CButtonContainer s_CustomSkinSaveButton;
|
||||
if(DoButton_Menu(&s_CustomSkinSaveButton, Localize("Save"), 0, &ButtonLeft))
|
||||
{
|
||||
m_Popup = POPUP_SAVE_SKIN;
|
||||
m_SkinNameInput.SelectAll();
|
||||
Ui()->SetActiveItem(&m_SkinNameInput);
|
||||
}
|
||||
|
||||
static CButtonContainer s_RandomizeSkinButton;
|
||||
if(DoButton_Menu(&s_RandomizeSkinButton, Localize("Randomize"), 0, &ButtonMiddle))
|
||||
{
|
||||
|
@ -251,7 +261,7 @@ void CMenus::RenderSettingsTee7(CUIRect MainView)
|
|||
if(DoButton_Menu(&s_CustomSkinDeleteButton, Localize("Delete"), 0, &ButtonMiddle) || Ui()->ConsumeHotkey(CUi::HOTKEY_DELETE))
|
||||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Are you sure that you want to delete the skin '%s'?"), m_pSelectedSkin->m_aName);
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Are you sure that you want to delete '%s'?"), m_pSelectedSkin->m_aName);
|
||||
PopupConfirm(Localize("Delete skin"), aBuf, Localize("Yes"), Localize("No"), &CMenus::PopupConfirmDeleteSkin7);
|
||||
}
|
||||
}
|
||||
|
@ -291,6 +301,16 @@ void CMenus::RenderSettingsTee7(CUIRect MainView)
|
|||
if(Ui()->DoClearableEditBox(&s_SkinFilterInput, &QuickSearch, 14.0f))
|
||||
m_SkinListNeedsUpdate = true;
|
||||
}
|
||||
|
||||
static CButtonContainer s_DirectoryButton;
|
||||
if(DoButton_Menu(&s_DirectoryButton, Localize("Skins directory"), 0, &DirectoryButton))
|
||||
{
|
||||
char aBuf[128 + IO_MAX_PATH_LENGTH];
|
||||
Storage()->GetCompletePath(IStorage::TYPE_SAVE, "skins7", aBuf, sizeof(aBuf));
|
||||
Storage()->CreateFolder("skins7", IStorage::TYPE_SAVE);
|
||||
Client()->ViewFile(aBuf);
|
||||
}
|
||||
GameClient()->m_Tooltips.DoToolTip(&s_DirectoryButton, &DirectoryButton, Localize("Open the directory to add custom skins"));
|
||||
}
|
||||
|
||||
void CMenus::PopupConfirmDeleteSkin7()
|
||||
|
@ -299,7 +319,7 @@ void CMenus::PopupConfirmDeleteSkin7()
|
|||
|
||||
if(!m_pClient->m_Skins7.RemoveSkin(m_pSelectedSkin))
|
||||
{
|
||||
PopupMessage(Localize("Error"), Localize("Unable to delete the skin"), Localize("Ok"));
|
||||
PopupMessage(Localize("Error"), Localize("Unable to delete skin"), Localize("Ok"));
|
||||
return;
|
||||
}
|
||||
m_pSelectedSkin = nullptr;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "menus.h"
|
||||
|
||||
using namespace FontIcons;
|
||||
|
||||
void CMenus::RenderStartMenu(CUIRect MainView)
|
||||
{
|
||||
GameClient()->m_MenuBackground.ChangePosition(CMenuBackground::POS_START);
|
||||
|
@ -39,14 +41,6 @@ void CMenus::RenderStartMenu(CUIRect MainView)
|
|||
MainView.VSplitLeft(30.0f, 0, &ExtMenu);
|
||||
ExtMenu.VSplitLeft(100.0f, &ExtMenu, 0);
|
||||
|
||||
ExtMenu.HSplitBottom(20.0f, &ExtMenu, &Button);
|
||||
ExtMenu.HSplitBottom(5.0f, &ExtMenu, nullptr);
|
||||
static CButtonContainer s_ConsoleButton;
|
||||
if(DoButton_Menu(&s_ConsoleButton, Localize("Console"), 0, &Button, nullptr, IGraphics::CORNER_ALL, 5.0f, 0.0f, ColorRGBA(0.0f, 0.0f, 0.0f, 0.25f)))
|
||||
{
|
||||
GameClient()->m_GameConsole.Toggle(CGameConsole::CONSOLETYPE_LOCAL);
|
||||
}
|
||||
|
||||
ExtMenu.HSplitBottom(20.0f, &ExtMenu, &Button);
|
||||
static CButtonContainer s_DiscordButton;
|
||||
if(DoButton_Menu(&s_DiscordButton, Localize("Discord"), 0, &Button, 0, IGraphics::CORNER_ALL, 5.0f, 0.0f, ColorRGBA(0.0f, 0.0f, 0.0f, 0.25f)))
|
||||
|
@ -194,13 +188,27 @@ void CMenus::RenderStartMenu(CUIRect MainView)
|
|||
}
|
||||
|
||||
// render version
|
||||
CUIRect VersionUpdate, CurVersion;
|
||||
MainView.HSplitBottom(20.0f, nullptr, &VersionUpdate);
|
||||
VersionUpdate.VSplitRight(50.0f, &CurVersion, nullptr);
|
||||
VersionUpdate.VMargin(VMargin, &VersionUpdate);
|
||||
|
||||
CUIRect CurVersion, ConsoleButton;
|
||||
MainView.HSplitBottom(45.0f, nullptr, &CurVersion);
|
||||
CurVersion.VSplitRight(40.0f, &CurVersion, nullptr);
|
||||
CurVersion.HSplitTop(20.0f, &ConsoleButton, &CurVersion);
|
||||
CurVersion.HSplitTop(5.0f, nullptr, &CurVersion);
|
||||
ConsoleButton.VSplitRight(40.0f, nullptr, &ConsoleButton);
|
||||
Ui()->DoLabel(&CurVersion, GAME_RELEASE_VERSION, 14.0f, TEXTALIGN_MR);
|
||||
|
||||
static CButtonContainer s_ConsoleButton;
|
||||
TextRender()->SetFontPreset(EFontPreset::ICON_FONT);
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
if(DoButton_Menu(&s_ConsoleButton, FONT_ICON_TERMINAL, 0, &ConsoleButton, nullptr, IGraphics::CORNER_ALL, 5.0f, 0.0f, ColorRGBA(0.0f, 0.0f, 0.0f, 0.1f)))
|
||||
{
|
||||
GameClient()->m_GameConsole.Toggle(CGameConsole::CONSOLETYPE_LOCAL);
|
||||
}
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
|
||||
CUIRect VersionUpdate;
|
||||
MainView.HSplitBottom(20.0f, nullptr, &VersionUpdate);
|
||||
VersionUpdate.VMargin(VMargin, &VersionUpdate);
|
||||
#if defined(CONF_AUTOUPDATE)
|
||||
CUIRect UpdateButton;
|
||||
VersionUpdate.VSplitRight(100.0f, &VersionUpdate, &UpdateButton);
|
||||
|
@ -248,12 +256,12 @@ void CMenus::RenderStartMenu(CUIRect MainView)
|
|||
}
|
||||
else if(State == IUpdater::FAIL)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Update failed! Check log…"));
|
||||
str_copy(aBuf, Localize("Update failed! Check log…"));
|
||||
TextRender()->TextColor(1.0f, 0.4f, 0.4f, 1.0f);
|
||||
}
|
||||
else if(State == IUpdater::NEED_RESTART)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("DDNet Client updated!"));
|
||||
str_copy(aBuf, Localize("DDNet Client updated!"));
|
||||
TextRender()->TextColor(1.0f, 0.4f, 0.4f, 1.0f);
|
||||
}
|
||||
Ui()->DoLabel(&VersionUpdate, aBuf, 14.0f, TEXTALIGN_ML);
|
||||
|
|
|
@ -349,240 +349,247 @@ void CScoreboard::RenderScoreboard(CUIRect Scoreboard, int Team, int CountStart,
|
|||
char aBuf[64];
|
||||
int MaxTeamSize = m_pClient->Config()->m_SvMaxTeamSize;
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
for(int RenderDead = 0; RenderDead < 2; RenderDead++)
|
||||
{
|
||||
// make sure that we render the correct team
|
||||
const CNetObj_PlayerInfo *pInfo = GameClient()->m_Snap.m_apInfoByDDTeamScore[i];
|
||||
if(!pInfo || pInfo->m_Team != Team)
|
||||
continue;
|
||||
|
||||
if(CountRendered++ < CountStart)
|
||||
continue;
|
||||
|
||||
int DDTeam = GameClient()->m_Teams.Team(pInfo->m_ClientId);
|
||||
int NextDDTeam = 0;
|
||||
bool RenderDead = Client()->m_TranslationContext.m_aClients[pInfo->m_ClientId].m_PlayerFlags7 & protocol7::PLAYERFLAG_DEAD;
|
||||
|
||||
ColorRGBA TextColor = TextRender()->DefaultTextColor();
|
||||
TextColor.a = RenderDead ? 0.5f : 1.0f;
|
||||
TextRender()->TextColor(TextColor);
|
||||
|
||||
for(int j = i + 1; j < MAX_CLIENTS; j++)
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
const CNetObj_PlayerInfo *pInfoNext = GameClient()->m_Snap.m_apInfoByDDTeamScore[j];
|
||||
if(!pInfoNext || pInfoNext->m_Team != Team)
|
||||
// make sure that we render the correct team
|
||||
const CNetObj_PlayerInfo *pInfo = GameClient()->m_Snap.m_apInfoByDDTeamScore[i];
|
||||
if(!pInfo || pInfo->m_Team != Team)
|
||||
continue;
|
||||
|
||||
NextDDTeam = GameClient()->m_Teams.Team(pInfoNext->m_ClientId);
|
||||
break;
|
||||
}
|
||||
if(CountRendered++ < CountStart)
|
||||
continue;
|
||||
|
||||
if(PrevDDTeam == -1)
|
||||
{
|
||||
for(int j = i - 1; j >= 0; j--)
|
||||
int DDTeam = GameClient()->m_Teams.Team(pInfo->m_ClientId);
|
||||
int NextDDTeam = 0;
|
||||
bool IsDead = Client()->m_TranslationContext.m_aClients[pInfo->m_ClientId].m_PlayerFlags7 & protocol7::PLAYERFLAG_DEAD;
|
||||
if(!RenderDead && IsDead)
|
||||
continue;
|
||||
if(RenderDead && !IsDead)
|
||||
continue;
|
||||
|
||||
ColorRGBA TextColor = TextRender()->DefaultTextColor();
|
||||
TextColor.a = RenderDead ? 0.5f : 1.0f;
|
||||
TextRender()->TextColor(TextColor);
|
||||
|
||||
for(int j = i + 1; j < MAX_CLIENTS; j++)
|
||||
{
|
||||
const CNetObj_PlayerInfo *pInfoPrev = GameClient()->m_Snap.m_apInfoByDDTeamScore[j];
|
||||
if(!pInfoPrev || pInfoPrev->m_Team != Team)
|
||||
const CNetObj_PlayerInfo *pInfoNext = GameClient()->m_Snap.m_apInfoByDDTeamScore[j];
|
||||
if(!pInfoNext || pInfoNext->m_Team != Team)
|
||||
continue;
|
||||
|
||||
PrevDDTeam = GameClient()->m_Teams.Team(pInfoPrev->m_ClientId);
|
||||
NextDDTeam = GameClient()->m_Teams.Team(pInfoNext->m_ClientId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CUIRect RowAndSpacing, Row;
|
||||
Scoreboard.HSplitTop(LineHeight + Spacing, &RowAndSpacing, &Scoreboard);
|
||||
RowAndSpacing.HSplitTop(LineHeight, &Row, nullptr);
|
||||
|
||||
// team background
|
||||
if(DDTeam != TEAM_FLOCK)
|
||||
{
|
||||
const ColorRGBA Color = GameClient()->GetDDTeamColor(DDTeam).WithAlpha(0.5f);
|
||||
int TeamRectCorners = 0;
|
||||
if(PrevDDTeam != DDTeam)
|
||||
if(PrevDDTeam == -1)
|
||||
{
|
||||
TeamRectCorners |= IGraphics::CORNER_T;
|
||||
State.m_TeamStartX = Row.x;
|
||||
State.m_TeamStartY = Row.y;
|
||||
}
|
||||
if(NextDDTeam != DDTeam)
|
||||
TeamRectCorners |= IGraphics::CORNER_B;
|
||||
RowAndSpacing.Draw(Color, TeamRectCorners, RoundRadius);
|
||||
|
||||
CurrentDDTeamSize++;
|
||||
|
||||
if(NextDDTeam != DDTeam)
|
||||
{
|
||||
const float TeamFontSize = FontSize / 1.5f;
|
||||
|
||||
if(NumPlayers > 8)
|
||||
for(int j = i - 1; j >= 0; j--)
|
||||
{
|
||||
if(DDTeam == TEAM_SUPER)
|
||||
str_copy(aBuf, Localize("Super"));
|
||||
else if(CurrentDDTeamSize <= 1)
|
||||
str_format(aBuf, sizeof(aBuf), "%d", DDTeam);
|
||||
const CNetObj_PlayerInfo *pInfoPrev = GameClient()->m_Snap.m_apInfoByDDTeamScore[j];
|
||||
if(!pInfoPrev || pInfoPrev->m_Team != Team)
|
||||
continue;
|
||||
|
||||
PrevDDTeam = GameClient()->m_Teams.Team(pInfoPrev->m_ClientId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CUIRect RowAndSpacing, Row;
|
||||
Scoreboard.HSplitTop(LineHeight + Spacing, &RowAndSpacing, &Scoreboard);
|
||||
RowAndSpacing.HSplitTop(LineHeight, &Row, nullptr);
|
||||
|
||||
// team background
|
||||
if(DDTeam != TEAM_FLOCK)
|
||||
{
|
||||
const ColorRGBA Color = GameClient()->GetDDTeamColor(DDTeam).WithAlpha(0.5f);
|
||||
int TeamRectCorners = 0;
|
||||
if(PrevDDTeam != DDTeam)
|
||||
{
|
||||
TeamRectCorners |= IGraphics::CORNER_T;
|
||||
State.m_TeamStartX = Row.x;
|
||||
State.m_TeamStartY = Row.y;
|
||||
}
|
||||
if(NextDDTeam != DDTeam)
|
||||
TeamRectCorners |= IGraphics::CORNER_B;
|
||||
RowAndSpacing.Draw(Color, TeamRectCorners, RoundRadius);
|
||||
|
||||
CurrentDDTeamSize++;
|
||||
|
||||
if(NextDDTeam != DDTeam)
|
||||
{
|
||||
const float TeamFontSize = FontSize / 1.5f;
|
||||
|
||||
if(NumPlayers > 8)
|
||||
{
|
||||
if(DDTeam == TEAM_SUPER)
|
||||
str_copy(aBuf, Localize("Super"));
|
||||
else if(CurrentDDTeamSize <= 1)
|
||||
str_format(aBuf, sizeof(aBuf), "%d", DDTeam);
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), Localize("%d\n(%d/%d)", "Team and size"), DDTeam, CurrentDDTeamSize, MaxTeamSize);
|
||||
TextRender()->Text(State.m_TeamStartX, maximum(State.m_TeamStartY + Row.h / 2.0f - TeamFontSize, State.m_TeamStartY + 3.0f /* padding top */), TeamFontSize, aBuf);
|
||||
}
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), Localize("%d\n(%d/%d)", "Team and size"), DDTeam, CurrentDDTeamSize, MaxTeamSize);
|
||||
TextRender()->Text(State.m_TeamStartX, maximum(State.m_TeamStartY + Row.h / 2.0f - TeamFontSize, State.m_TeamStartY + 3.0f /* padding top */), TeamFontSize, aBuf);
|
||||
{
|
||||
if(DDTeam == TEAM_SUPER)
|
||||
str_copy(aBuf, Localize("Super"));
|
||||
else if(CurrentDDTeamSize > 1)
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Team %d (%d/%d)"), DDTeam, CurrentDDTeamSize, MaxTeamSize);
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Team %d"), DDTeam);
|
||||
TextRender()->Text(Row.x + Row.w / 2.0f - TextRender()->TextWidth(TeamFontSize, aBuf) / 2.0f + 10.0f, Row.y + Row.h, TeamFontSize, aBuf);
|
||||
}
|
||||
|
||||
CurrentDDTeamSize = 0;
|
||||
}
|
||||
}
|
||||
PrevDDTeam = DDTeam;
|
||||
|
||||
// background so it's easy to find the local player or the followed one in spectator mode
|
||||
if((!GameClient()->m_Snap.m_SpecInfo.m_Active && pInfo->m_Local) ||
|
||||
(GameClient()->m_Snap.m_SpecInfo.m_SpectatorId == SPEC_FREEVIEW && pInfo->m_Local) ||
|
||||
(GameClient()->m_Snap.m_SpecInfo.m_Active && pInfo->m_ClientId == GameClient()->m_Snap.m_SpecInfo.m_SpectatorId))
|
||||
{
|
||||
Row.Draw(ColorRGBA(1.0f, 1.0f, 1.0f, 0.25f), IGraphics::CORNER_ALL, RoundRadius);
|
||||
}
|
||||
|
||||
// score
|
||||
if(Race7)
|
||||
{
|
||||
if(pInfo->m_Score == -1)
|
||||
{
|
||||
aBuf[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DDTeam == TEAM_SUPER)
|
||||
str_copy(aBuf, Localize("Super"));
|
||||
else if(CurrentDDTeamSize > 1)
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Team %d (%d/%d)"), DDTeam, CurrentDDTeamSize, MaxTeamSize);
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Team %d"), DDTeam);
|
||||
TextRender()->Text(Row.x + Row.w / 2.0f - TextRender()->TextWidth(TeamFontSize, aBuf) / 2.0f + 10.0f, Row.y + Row.h, TeamFontSize, aBuf);
|
||||
// 0.7 uses milliseconds and ddnets str_time wants centiseconds
|
||||
// 0.7 servers can also send the amount of precision the client should use
|
||||
// we ignore that and always show 3 digit precision
|
||||
str_time((int64_t)absolute(pInfo->m_Score / 10), TIME_MINS_CENTISECS, aBuf, sizeof(aBuf));
|
||||
}
|
||||
|
||||
CurrentDDTeamSize = 0;
|
||||
}
|
||||
}
|
||||
PrevDDTeam = DDTeam;
|
||||
|
||||
// background so it's easy to find the local player or the followed one in spectator mode
|
||||
if((!GameClient()->m_Snap.m_SpecInfo.m_Active && pInfo->m_Local) ||
|
||||
(GameClient()->m_Snap.m_SpecInfo.m_SpectatorId == SPEC_FREEVIEW && pInfo->m_Local) ||
|
||||
(GameClient()->m_Snap.m_SpecInfo.m_Active && pInfo->m_ClientId == GameClient()->m_Snap.m_SpecInfo.m_SpectatorId))
|
||||
{
|
||||
Row.Draw(ColorRGBA(1.0f, 1.0f, 1.0f, 0.25f), IGraphics::CORNER_ALL, RoundRadius);
|
||||
}
|
||||
|
||||
// score
|
||||
if(Race7)
|
||||
{
|
||||
if(pInfo->m_Score == -1)
|
||||
else if(TimeScore)
|
||||
{
|
||||
aBuf[0] = '\0';
|
||||
if(pInfo->m_Score == -9999)
|
||||
{
|
||||
aBuf[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
str_time((int64_t)absolute(pInfo->m_Score) * 100, TIME_HOURS, aBuf, sizeof(aBuf));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0.7 uses milliseconds and ddnets str_time wants centiseconds
|
||||
// 0.7 servers can also send the amount of precision the client should use
|
||||
// we ignore that and always show 3 digit precision
|
||||
str_time((int64_t)absolute(pInfo->m_Score / 10), TIME_MINS_CENTISECS, aBuf, sizeof(aBuf));
|
||||
str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Score, -999, 99999));
|
||||
}
|
||||
}
|
||||
else if(TimeScore)
|
||||
{
|
||||
if(pInfo->m_Score == -9999)
|
||||
TextRender()->Text(ScoreOffset + ScoreLength - TextRender()->TextWidth(FontSize, aBuf), Row.y + (Row.h - FontSize) / 2.0f, FontSize, aBuf);
|
||||
|
||||
// CTF flag
|
||||
if(pGameInfoObj && (pGameInfoObj->m_GameFlags & GAMEFLAG_FLAGS) &&
|
||||
pGameDataObj && (pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientId || pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientId))
|
||||
{
|
||||
aBuf[0] = '\0';
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->TextureSet(pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientId ? GameClient()->m_GameSkin.m_SpriteFlagBlue : GameClient()->m_GameSkin.m_SpriteFlagRed);
|
||||
Graphics()->QuadsBegin();
|
||||
Graphics()->QuadsSetSubset(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
IGraphics::CQuadItem QuadItem(TeeOffset, Row.y - 5.0f - Spacing / 2.0f, Row.h / 2.0f, Row.h);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
|
||||
const CGameClient::CClientData &ClientData = GameClient()->m_aClients[pInfo->m_ClientId];
|
||||
|
||||
// skin
|
||||
if(RenderDead)
|
||||
{
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->TextureSet(client_data7::g_pData->m_aImages[client_data7::IMAGE_DEADTEE].m_Id);
|
||||
Graphics()->QuadsBegin();
|
||||
if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS)
|
||||
{
|
||||
ColorRGBA Color = m_pClient->m_Skins7.GetTeamColor(true, 0, m_pClient->m_aClients[pInfo->m_ClientId].m_Team, protocol7::SKINPART_BODY);
|
||||
Graphics()->SetColor(Color.r, Color.g, Color.b, Color.a);
|
||||
}
|
||||
CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientId].m_RenderInfo;
|
||||
TeeInfo.m_Size *= TeeSizeMod;
|
||||
IGraphics::CQuadItem QuadItem(TeeOffset, Row.y, TeeInfo.m_Size, TeeInfo.m_Size);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
str_time((int64_t)absolute(pInfo->m_Score) * 100, TIME_HOURS, aBuf, sizeof(aBuf));
|
||||
CTeeRenderInfo TeeInfo = ClientData.m_RenderInfo;
|
||||
TeeInfo.m_Size *= TeeSizeMod;
|
||||
vec2 OffsetToMid;
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(CAnimState::GetIdle(), &TeeInfo, OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(TeeOffset + TeeLength / 2, Row.y + Row.h / 2.0f + OffsetToMid.y);
|
||||
RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), TeeRenderPos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Score, -999, 99999));
|
||||
}
|
||||
TextRender()->Text(ScoreOffset + ScoreLength - TextRender()->TextWidth(FontSize, aBuf), Row.y + (Row.h - FontSize) / 2.0f, FontSize, aBuf);
|
||||
|
||||
// CTF flag
|
||||
if(pGameInfoObj && (pGameInfoObj->m_GameFlags & GAMEFLAG_FLAGS) &&
|
||||
pGameDataObj && (pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientId || pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientId))
|
||||
{
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->TextureSet(pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientId ? GameClient()->m_GameSkin.m_SpriteFlagBlue : GameClient()->m_GameSkin.m_SpriteFlagRed);
|
||||
Graphics()->QuadsBegin();
|
||||
Graphics()->QuadsSetSubset(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
IGraphics::CQuadItem QuadItem(TeeOffset, Row.y - 5.0f - Spacing / 2.0f, Row.h / 2.0f, Row.h);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
|
||||
const CGameClient::CClientData &ClientData = GameClient()->m_aClients[pInfo->m_ClientId];
|
||||
|
||||
// skin
|
||||
if(RenderDead)
|
||||
{
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->TextureSet(client_data7::g_pData->m_aImages[client_data7::IMAGE_DEADTEE].m_Id);
|
||||
Graphics()->QuadsBegin();
|
||||
if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS)
|
||||
// name
|
||||
{
|
||||
ColorRGBA Color = m_pClient->m_Skins7.GetTeamColor(true, 0, m_pClient->m_aClients[pInfo->m_ClientId].m_Team, protocol7::SKINPART_BODY);
|
||||
Graphics()->SetColor(Color.r, Color.g, Color.b, Color.a);
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, NameOffset, Row.y + (Row.h - FontSize) / 2.0f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END);
|
||||
Cursor.m_LineWidth = NameLength;
|
||||
if(ClientData.m_AuthLevel)
|
||||
{
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClAuthedPlayerColor)));
|
||||
}
|
||||
if(g_Config.m_ClShowIds)
|
||||
{
|
||||
char aClientId[16];
|
||||
GameClient()->FormatClientId(pInfo->m_ClientId, aClientId, EClientIdFormat::INDENT_AUTO);
|
||||
TextRender()->TextEx(&Cursor, aClientId);
|
||||
}
|
||||
TextRender()->TextEx(&Cursor, ClientData.m_aName);
|
||||
|
||||
// ready / watching
|
||||
if(Client()->IsSixup() && Client()->m_TranslationContext.m_aClients[pInfo->m_ClientId].m_PlayerFlags7 & protocol7::PLAYERFLAG_READY)
|
||||
{
|
||||
TextRender()->TextColor(0.1f, 1.0f, 0.1f, TextColor.a);
|
||||
TextRender()->TextEx(&Cursor, "✓");
|
||||
}
|
||||
}
|
||||
CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientId].m_RenderInfo;
|
||||
TeeInfo.m_Size *= TeeSizeMod;
|
||||
IGraphics::CQuadItem QuadItem(TeeOffset, Row.y, TeeInfo.m_Size, TeeInfo.m_Size);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
CTeeRenderInfo TeeInfo = ClientData.m_RenderInfo;
|
||||
TeeInfo.m_Size *= TeeSizeMod;
|
||||
vec2 OffsetToMid;
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(CAnimState::GetIdle(), &TeeInfo, OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(TeeOffset + TeeLength / 2, Row.y + Row.h / 2.0f + OffsetToMid.y);
|
||||
RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), TeeRenderPos);
|
||||
}
|
||||
|
||||
// name
|
||||
{
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, NameOffset, Row.y + (Row.h - FontSize) / 2.0f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END);
|
||||
Cursor.m_LineWidth = NameLength;
|
||||
if(ClientData.m_AuthLevel)
|
||||
// clan
|
||||
{
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClAuthedPlayerColor)));
|
||||
if(str_comp(ClientData.m_aClan, GameClient()->m_aClients[GameClient()->m_aLocalIds[g_Config.m_ClDummy]].m_aClan) == 0)
|
||||
{
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClSameClanColor)));
|
||||
}
|
||||
else
|
||||
{
|
||||
TextRender()->TextColor(TextColor);
|
||||
}
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, ClanOffset + (ClanLength - minimum(TextRender()->TextWidth(FontSize, ClientData.m_aClan), ClanLength)) / 2.0f, Row.y + (Row.h - FontSize) / 2.0f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END);
|
||||
Cursor.m_LineWidth = ClanLength;
|
||||
TextRender()->TextEx(&Cursor, ClientData.m_aClan);
|
||||
}
|
||||
if(g_Config.m_ClShowIds)
|
||||
{
|
||||
char aClientId[16];
|
||||
GameClient()->FormatClientId(pInfo->m_ClientId, aClientId, EClientIdFormat::INDENT_AUTO);
|
||||
TextRender()->TextEx(&Cursor, aClientId);
|
||||
}
|
||||
TextRender()->TextEx(&Cursor, ClientData.m_aName);
|
||||
|
||||
// ready / watching
|
||||
if(Client()->IsSixup() && Client()->m_TranslationContext.m_aClients[pInfo->m_ClientId].m_PlayerFlags7 & protocol7::PLAYERFLAG_READY)
|
||||
{
|
||||
TextRender()->TextColor(0.1f, 1.0f, 0.1f, TextColor.a);
|
||||
TextRender()->TextEx(&Cursor, "✓");
|
||||
}
|
||||
}
|
||||
// country flag
|
||||
GameClient()->m_CountryFlags.Render(ClientData.m_Country, ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f),
|
||||
CountryOffset, Row.y + (Spacing + TeeSizeMod * 5.0f) / 2.0f, CountryLength, Row.h - Spacing - TeeSizeMod * 5.0f);
|
||||
|
||||
// clan
|
||||
{
|
||||
if(str_comp(ClientData.m_aClan, GameClient()->m_aClients[GameClient()->m_aLocalIds[g_Config.m_ClDummy]].m_aClan) == 0)
|
||||
// ping
|
||||
if(g_Config.m_ClEnablePingColor)
|
||||
{
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClSameClanColor)));
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA((300.0f - clamp(pInfo->m_Latency, 0, 300)) / 1000.0f, 1.0f, 0.5f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
TextRender()->TextColor(TextColor);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
}
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, ClanOffset + (ClanLength - minimum(TextRender()->TextWidth(FontSize, ClientData.m_aClan), ClanLength)) / 2.0f, Row.y + (Row.h - FontSize) / 2.0f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END);
|
||||
Cursor.m_LineWidth = ClanLength;
|
||||
TextRender()->TextEx(&Cursor, ClientData.m_aClan);
|
||||
}
|
||||
|
||||
// country flag
|
||||
GameClient()->m_CountryFlags.Render(ClientData.m_Country, ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f),
|
||||
CountryOffset, Row.y + (Spacing + TeeSizeMod * 5.0f) / 2.0f, CountryLength, Row.h - Spacing - TeeSizeMod * 5.0f);
|
||||
|
||||
// ping
|
||||
if(g_Config.m_ClEnablePingColor)
|
||||
{
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA((300.0f - clamp(pInfo->m_Latency, 0, 300)) / 1000.0f, 1.0f, 0.5f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Latency, 0, 999));
|
||||
TextRender()->Text(PingOffset + PingLength - TextRender()->TextWidth(FontSize, aBuf), Row.y + (Row.h - FontSize) / 2.0f, FontSize, aBuf);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
}
|
||||
str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Latency, 0, 999));
|
||||
TextRender()->Text(PingOffset + PingLength - TextRender()->TextWidth(FontSize, aBuf), Row.y + (Row.h - FontSize) / 2.0f, FontSize, aBuf);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
|
||||
if(CountRendered == CountEnd)
|
||||
break;
|
||||
if(CountRendered == CountEnd)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -790,15 +797,16 @@ bool CScoreboard::Active() const
|
|||
if(m_Active)
|
||||
return true;
|
||||
|
||||
const CNetObj_GameInfo *pGameInfoObj = GameClient()->m_Snap.m_pGameInfoObj;
|
||||
if(GameClient()->m_Snap.m_pLocalInfo && !GameClient()->m_Snap.m_SpecInfo.m_Active)
|
||||
{
|
||||
// we are not a spectator, check if we are dead
|
||||
if(!GameClient()->m_Snap.m_pLocalCharacter && g_Config.m_ClScoreboardOnDeath)
|
||||
// we are not a spectator, check if we are dead and the game isn't paused
|
||||
if(!GameClient()->m_Snap.m_pLocalCharacter && g_Config.m_ClScoreboardOnDeath &&
|
||||
!(pGameInfoObj && pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED))
|
||||
return true;
|
||||
}
|
||||
|
||||
// if the game is over
|
||||
const CNetObj_GameInfo *pGameInfoObj = GameClient()->m_Snap.m_pGameInfoObj;
|
||||
if(pGameInfoObj && pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_GAMEOVER)
|
||||
return true;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "menus.h"
|
||||
#include "skins7.h"
|
||||
|
||||
const char *const CSkins7::ms_apSkinPartNames[protocol7::NUM_SKINPARTS] = {"body", "marking", "decoration", "hands", "feet", "eyes"}; /* Localize("body","skins");Localize("marking","skins");Localize("decoration","skins");Localize("hands","skins");Localize("feet","skins");Localize("eyes","skins"); */
|
||||
const char *const CSkins7::ms_apSkinPartNames[protocol7::NUM_SKINPARTS] = {"body", "marking", "decoration", "hands", "feet", "eyes"};
|
||||
const char *const CSkins7::ms_apColorComponents[NUM_COLOR_COMPONENTS] = {"hue", "sat", "lgt", "alp"};
|
||||
|
||||
char *CSkins7::ms_apSkinVariables[NUM_DUMMIES][protocol7::NUM_SKINPARTS] = {{0}};
|
||||
|
@ -525,7 +525,7 @@ bool CSkins7::ValidateSkinParts(char *apPartNames[protocol7::NUM_SKINPARTS], int
|
|||
bool CSkins7::SaveSkinfile(const char *pSaveSkinName, int Dummy)
|
||||
{
|
||||
char aBuf[IO_MAX_PATH_LENGTH];
|
||||
str_format(aBuf, sizeof(aBuf), "skins/%s.json", pSaveSkinName);
|
||||
str_format(aBuf, sizeof(aBuf), SKINS_DIR "/%s.json", pSaveSkinName);
|
||||
IOHANDLE File = Storage()->OpenFile(aBuf, IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||
if(!File)
|
||||
return false;
|
||||
|
@ -547,7 +547,7 @@ bool CSkins7::SaveSkinfile(const char *pSaveSkinName, int Dummy)
|
|||
Writer.WriteAttribute("filename");
|
||||
Writer.WriteStrValue(ms_apSkinVariables[Dummy][PartIndex]);
|
||||
|
||||
const bool CustomColors = *ms_apUCCVariables[PartIndex];
|
||||
const bool CustomColors = *ms_apUCCVariables[Dummy][PartIndex];
|
||||
Writer.WriteAttribute("custom_colors");
|
||||
Writer.WriteBoolValue(CustomColors);
|
||||
|
||||
|
|
|
@ -191,6 +191,26 @@ void CGameClient::OnConsoleInit()
|
|||
Console()->Chain("player_color_feet", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player_skin", ConchainSpecialInfoupdate, this);
|
||||
|
||||
Console()->Chain("player7_skin", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_skin_body", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_skin_marking", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_skin_decoration", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_skin_hands", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_skin_feet", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_skin_eyes", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_color_body", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_color_marking", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_color_decoration", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_color_hands", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_color_feet", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_color_eyes", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_use_custom_color_body", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_use_custom_color_marking", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_use_custom_color_decoration", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_use_custom_color_hands", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_use_custom_color_feet", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("player7_use_custom_color_eyes", ConchainSpecialInfoupdate, this);
|
||||
|
||||
Console()->Chain("dummy_name", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy_clan", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy_country", ConchainSpecialDummyInfoupdate, this);
|
||||
|
@ -199,6 +219,26 @@ void CGameClient::OnConsoleInit()
|
|||
Console()->Chain("dummy_color_feet", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy_skin", ConchainSpecialDummyInfoupdate, this);
|
||||
|
||||
Console()->Chain("dummy7_skin", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_skin_body", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_skin_marking", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_skin_decoration", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_skin_hands", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_skin_feet", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_skin_eyes", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_color_body", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_color_marking", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_color_decoration", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_color_hands", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_color_feet", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_color_eyes", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_use_custom_color_body", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_use_custom_color_marking", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_use_custom_color_decoration", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_use_custom_color_hands", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_use_custom_color_feet", ConchainSpecialDummyInfoupdate, this);
|
||||
Console()->Chain("dummy7_use_custom_color_eyes", ConchainSpecialDummyInfoupdate, this);
|
||||
|
||||
Console()->Chain("cl_skin_download_url", ConchainRefreshSkins, this);
|
||||
Console()->Chain("cl_skin_community_download_url", ConchainRefreshSkins, this);
|
||||
Console()->Chain("cl_download_skins", ConchainRefreshSkins, this);
|
||||
|
@ -2460,7 +2500,7 @@ void CGameClient::SendSwitchTeam(int Team)
|
|||
void CGameClient::SendStartInfo7(bool Dummy) const
|
||||
{
|
||||
protocol7::CNetMsg_Cl_StartInfo Msg;
|
||||
Msg.m_pName = Dummy ? Client()->DummyName() : Config()->m_PlayerName;
|
||||
Msg.m_pName = Dummy ? Client()->DummyName() : Client()->PlayerName();
|
||||
Msg.m_pClan = Dummy ? Config()->m_ClDummyClan : Config()->m_PlayerClan;
|
||||
Msg.m_Country = Dummy ? Config()->m_ClDummyCountry : Config()->m_PlayerCountry;
|
||||
for(int p = 0; p < protocol7::NUM_SKINPARTS; p++)
|
||||
|
|
|
@ -49,10 +49,10 @@ struct CGameMsg7
|
|||
};
|
||||
|
||||
static CGameMsg7 gs_GameMsgList7[protocol7::NUM_GAMEMSGS] = {
|
||||
{/*GAMEMSG_TEAM_SWAP*/ DO_CHAT, PARA_NONE, "Teams were swapped"}, // Localize("Teams were swapped")
|
||||
{/*GAMEMSG_TEAM_SWAP*/ DO_CHAT, PARA_NONE, "Teams were swapped"},
|
||||
{/*GAMEMSG_SPEC_INVALIDID*/ DO_CHAT, PARA_NONE, "Invalid spectator id used"}, //!
|
||||
{/*GAMEMSG_TEAM_SHUFFLE*/ DO_CHAT, PARA_NONE, "Teams were shuffled"}, // Localize("Teams were shuffled")
|
||||
{/*GAMEMSG_TEAM_BALANCE*/ DO_CHAT, PARA_NONE, "Teams have been balanced"}, // Localize("Teams have been balanced")
|
||||
{/*GAMEMSG_TEAM_SHUFFLE*/ DO_CHAT, PARA_NONE, "Teams were shuffled"},
|
||||
{/*GAMEMSG_TEAM_BALANCE*/ DO_CHAT, PARA_NONE, "Teams have been balanced"},
|
||||
{/*GAMEMSG_CTF_DROP*/ DO_SPECIAL, PARA_NONE, ""}, // special - play ctf drop sound
|
||||
{/*GAMEMSG_CTF_RETURN*/ DO_SPECIAL, PARA_NONE, ""}, // special - play ctf return sound
|
||||
|
||||
|
@ -70,10 +70,10 @@ void CGameClient::DoTeamChangeMessage7(const char *pName, int ClientId, int Team
|
|||
char aBuf[128];
|
||||
switch(GetStrTeam7(Team, m_pClient->m_TranslationContext.m_GameFlags & protocol7::GAMEFLAG_TEAMS))
|
||||
{
|
||||
case STR_TEAM_GAME: str_format(aBuf, sizeof(aBuf), Localize("'%s' %sjoined the game"), pName, pPrefix); break;
|
||||
case STR_TEAM_RED: str_format(aBuf, sizeof(aBuf), Localize("'%s' %sjoined the red team"), pName, pPrefix); break;
|
||||
case STR_TEAM_BLUE: str_format(aBuf, sizeof(aBuf), Localize("'%s' %sjoined the blue team"), pName, pPrefix); break;
|
||||
case STR_TEAM_SPECTATORS: str_format(aBuf, sizeof(aBuf), Localize("'%s' %sjoined the spectators"), pName, pPrefix); break;
|
||||
case STR_TEAM_GAME: str_format(aBuf, sizeof(aBuf), "'%s' %sjoined the game", pName, pPrefix); break;
|
||||
case STR_TEAM_RED: str_format(aBuf, sizeof(aBuf), "'%s' %sjoined the red team", pName, pPrefix); break;
|
||||
case STR_TEAM_BLUE: str_format(aBuf, sizeof(aBuf), "'%s' %sjoined the blue team", pName, pPrefix); break;
|
||||
case STR_TEAM_SPECTATORS: str_format(aBuf, sizeof(aBuf), "'%s' %sjoined the spectators", pName, pPrefix); break;
|
||||
}
|
||||
m_Chat.AddLine(-1, 0, aBuf);
|
||||
}
|
||||
|
@ -233,9 +233,9 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
protocol7::CNetMsg_Sv_ServerSettings *pMsg = (protocol7::CNetMsg_Sv_ServerSettings *)pRawMsg;
|
||||
|
||||
if(!m_pClient->m_TranslationContext.m_ServerSettings.m_TeamLock && pMsg->m_TeamLock)
|
||||
m_Chat.AddLine(-1, 0, Localize("Teams were locked"));
|
||||
m_Chat.AddLine(-1, 0, "Teams were locked");
|
||||
else if(m_pClient->m_TranslationContext.m_ServerSettings.m_TeamLock && !pMsg->m_TeamLock)
|
||||
m_Chat.AddLine(-1, 0, Localize("Teams were unlocked"));
|
||||
m_Chat.AddLine(-1, 0, "Teams were unlocked");
|
||||
|
||||
m_pClient->m_TranslationContext.m_ServerSettings.m_KickVote = pMsg->m_KickVote;
|
||||
m_pClient->m_TranslationContext.m_ServerSettings.m_KickMin = pMsg->m_KickMin;
|
||||
|
@ -387,18 +387,18 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
switch(pMsg7->m_Type)
|
||||
{
|
||||
case protocol7::VOTE_START_OP:
|
||||
str_format(aBuf, sizeof(aBuf), Localize("'%s' called vote to change server option '%s' (%s)"), pName, pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
str_format(aBuf, sizeof(aBuf), "'%s' called vote to change server option '%s' (%s)", pName, pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
m_Chat.AddLine(-1, 0, aBuf);
|
||||
break;
|
||||
case protocol7::VOTE_START_KICK:
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("'%s' called for vote to kick '%s' (%s)"), pName, pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
str_format(aBuf, sizeof(aBuf), "'%s' called for vote to kick '%s' (%s)", pName, pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
m_Chat.AddLine(-1, 0, aBuf);
|
||||
break;
|
||||
}
|
||||
case protocol7::VOTE_START_SPEC:
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("'%s' called for vote to move '%s' to spectators (%s)"), pName, pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
str_format(aBuf, sizeof(aBuf), "'%s' called for vote to move '%s' to spectators (%s)", pName, pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
m_Chat.AddLine(-1, 0, aBuf);
|
||||
}
|
||||
}
|
||||
|
@ -409,24 +409,24 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
switch(pMsg7->m_Type)
|
||||
{
|
||||
case protocol7::VOTE_START_OP:
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Admin forced server option '%s' (%s)"), pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
str_format(aBuf, sizeof(aBuf), "Admin forced server option '%s' (%s)", pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
m_Chat.AddLine(-1, 0, aBuf);
|
||||
break;
|
||||
case protocol7::VOTE_START_SPEC:
|
||||
str_format(aBuf, sizeof(aBuf), Localize("Admin moved '%s' to spectator (%s)"), pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
str_format(aBuf, sizeof(aBuf), "Admin moved '%s' to spectator (%s)", pMsg7->m_pDescription, pMsg7->m_pReason);
|
||||
m_Chat.AddLine(-1, 0, aBuf);
|
||||
break;
|
||||
case protocol7::VOTE_END_ABORT:
|
||||
m_Voting.OnReset();
|
||||
m_Chat.AddLine(-1, 0, Localize("Vote aborted"));
|
||||
m_Chat.AddLine(-1, 0, "Vote aborted");
|
||||
break;
|
||||
case protocol7::VOTE_END_PASS:
|
||||
m_Voting.OnReset();
|
||||
m_Chat.AddLine(-1, 0, pMsg7->m_ClientId == -1 ? Localize("Admin forced vote yes") : Localize("Vote passed"));
|
||||
m_Chat.AddLine(-1, 0, pMsg7->m_ClientId == -1 ? "Admin forced vote yes" : "Vote passed");
|
||||
break;
|
||||
case protocol7::VOTE_END_FAIL:
|
||||
m_Voting.OnReset();
|
||||
m_Chat.AddLine(-1, 0, pMsg7->m_ClientId == -1 ? Localize("Admin forced vote no") : Localize("Vote failed"));
|
||||
m_Chat.AddLine(-1, 0, pMsg7->m_ClientId == -1 ? "Admin forced vote no" : "Vote failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,10 +630,10 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
const char *pMsg = "";
|
||||
switch(GetStrTeam7(aParaI[0], TeamPlay))
|
||||
{
|
||||
case STR_TEAM_GAME: pMsg = Localize("All players were moved to the game"); break;
|
||||
case STR_TEAM_RED: pMsg = Localize("All players were moved to the red team"); break;
|
||||
case STR_TEAM_BLUE: pMsg = Localize("All players were moved to the blue team"); break;
|
||||
case STR_TEAM_SPECTATORS: pMsg = Localize("All players were moved to the spectators"); break;
|
||||
case STR_TEAM_GAME: pMsg = "All players were moved to the game"; break;
|
||||
case STR_TEAM_RED: pMsg = "All players were moved to the red team"; break;
|
||||
case STR_TEAM_BLUE: pMsg = "All players were moved to the blue team"; break;
|
||||
case STR_TEAM_SPECTATORS: pMsg = "All players were moved to the spectators"; break;
|
||||
}
|
||||
m_Broadcast.DoBroadcast(pMsg); // client side broadcast
|
||||
}
|
||||
|
@ -643,8 +643,8 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
const char *pMsg = "";
|
||||
switch(GetStrTeam7(aParaI[0], TeamPlay))
|
||||
{
|
||||
case STR_TEAM_RED: pMsg = Localize("You were moved to the red team due to team balancing"); break;
|
||||
case STR_TEAM_BLUE: pMsg = Localize("You were moved to the blue team due to team balancing"); break;
|
||||
case STR_TEAM_RED: pMsg = "You were moved to the red team due to team balancing"; break;
|
||||
case STR_TEAM_BLUE: pMsg = "You were moved to the blue team due to team balancing"; break;
|
||||
}
|
||||
m_Broadcast.DoBroadcast(pMsg); // client side broadcast
|
||||
}
|
||||
|
@ -655,7 +655,7 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
case protocol7::GAMEMSG_GAME_PAUSED:
|
||||
{
|
||||
int ClientId = clamp(aParaI[0], 0, MAX_CLIENTS - 1);
|
||||
str_format(aBuf, sizeof(aBuf), Localize("'%s' initiated a pause"), m_aClients[ClientId].m_aName);
|
||||
str_format(aBuf, sizeof(aBuf), "'%s' initiated a pause", m_aClients[ClientId].m_aName);
|
||||
SendChat(aBuf);
|
||||
}
|
||||
break;
|
||||
|
@ -669,22 +669,22 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
{
|
||||
if(aParaI[0])
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("The blue flag was captured by '%s' (%.2f seconds)"), m_aClients[ClientId].m_aName, Time);
|
||||
str_format(aBuf, sizeof(aBuf), "The blue flag was captured by '%s' (%.2f seconds)", m_aClients[ClientId].m_aName, Time);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("The red flag was captured by '%s' (%.2f seconds)"), m_aClients[ClientId].m_aName, Time);
|
||||
str_format(aBuf, sizeof(aBuf), "The red flag was captured by '%s' (%.2f seconds)", m_aClients[ClientId].m_aName, Time);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(aParaI[0])
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("The blue flag was captured by '%s'"), m_aClients[ClientId].m_aName);
|
||||
str_format(aBuf, sizeof(aBuf), "The blue flag was captured by '%s'", m_aClients[ClientId].m_aName);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("The red flag was captured by '%s'"), m_aClients[ClientId].m_aName);
|
||||
str_format(aBuf, sizeof(aBuf), "The red flag was captured by '%s'", m_aClients[ClientId].m_aName);
|
||||
}
|
||||
}
|
||||
SendChat(aBuf);
|
||||
|
@ -696,7 +696,7 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
const char *pText = "";
|
||||
if(NumParaI == 0)
|
||||
{
|
||||
pText = Localize(gs_GameMsgList7[GameMsgId].m_pText);
|
||||
pText = gs_GameMsgList7[GameMsgId].m_pText;
|
||||
}
|
||||
|
||||
// handle message
|
||||
|
|
|
@ -1332,9 +1332,18 @@ float CUi::DoScrollbarH(const void *pId, const CUIRect *pRect, float Current, co
|
|||
Rail.VSplitLeft(pColorInner ? 8.0f : clamp(33.0f, Rail.h, Rail.w / 3.0f), &Handle, 0);
|
||||
Handle.x += (Rail.w - Handle.w) * Current;
|
||||
|
||||
CUIRect HandleArea = Handle;
|
||||
if(!pColorInner)
|
||||
{
|
||||
HandleArea.h = pRect->h * 0.9f;
|
||||
HandleArea.y = pRect->y + pRect->h * 0.05f;
|
||||
HandleArea.w += 6.0f;
|
||||
HandleArea.x -= 3.0f;
|
||||
}
|
||||
|
||||
// logic
|
||||
const bool InsideRail = MouseHovered(&Rail);
|
||||
const bool InsideHandle = MouseHovered(&Handle);
|
||||
const bool InsideHandle = MouseHovered(&HandleArea);
|
||||
bool Grabbed = false; // whether to apply the offset
|
||||
|
||||
if(CheckActiveItem(pId))
|
||||
|
@ -1366,6 +1375,12 @@ float CUi::DoScrollbarH(const void *pId, const CUIRect *pRect, float Current, co
|
|||
Grabbed = true;
|
||||
}
|
||||
|
||||
if(!pColorInner && (InsideHandle || Grabbed) && (CheckActiveItem(pId) || HotItem() == pId))
|
||||
{
|
||||
Handle.h += 3.0f;
|
||||
Handle.y -= 1.5f;
|
||||
}
|
||||
|
||||
if(InsideHandle && !MouseButton(0))
|
||||
{
|
||||
SetHotItem(pId);
|
||||
|
@ -1394,7 +1409,7 @@ float CUi::DoScrollbarH(const void *pId, const CUIRect *pRect, float Current, co
|
|||
else
|
||||
{
|
||||
Rail.Draw(ColorRGBA(1.0f, 1.0f, 1.0f, 0.25f), IGraphics::CORNER_ALL, Rail.h / 2.0f);
|
||||
Handle.Draw(HandleColor, IGraphics::CORNER_ALL, Handle.h / 2.0f);
|
||||
Handle.Draw(HandleColor, IGraphics::CORNER_ALL, Rail.h / 2.0f);
|
||||
}
|
||||
|
||||
return ReturnValue;
|
||||
|
|
|
@ -1074,11 +1074,9 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
|
|||
|
||||
// proof button
|
||||
TB_Top.VSplitLeft(40.0f, &Button, &TB_Top);
|
||||
static int s_ProofButton = 0;
|
||||
if(DoButton_Ex(&s_ProofButton, "Proof", MapView()->ProofMode()->IsEnabled(), &Button, 0, "[ctrl+p] Toggles proof borders. These borders represent the area that a player can see with default zoom.", IGraphics::CORNER_L) ||
|
||||
(m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_P) && ModPressed))
|
||||
if(DoButton_Ex(&m_QuickActionProof, m_QuickActionProof.Label(), m_QuickActionProof.Active(), &Button, 0, m_QuickActionProof.Description(), IGraphics::CORNER_L))
|
||||
{
|
||||
MapView()->ProofMode()->Toggle();
|
||||
m_QuickActionProof.Call();
|
||||
}
|
||||
|
||||
TB_Top.VSplitLeft(14.0f, &Button, &TB_Top);
|
||||
|
@ -1104,10 +1102,10 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
|
|||
// grid button
|
||||
TB_Top.VSplitLeft(25.0f, &Button, &TB_Top);
|
||||
static int s_GridButton = 0;
|
||||
if(DoButton_FontIcon(&s_GridButton, FONT_ICON_BORDER_ALL, MapView()->MapGrid()->IsEnabled(), &Button, 0, "[ctrl+g] Toggle Grid", IGraphics::CORNER_L) ||
|
||||
if(DoButton_FontIcon(&s_GridButton, FONT_ICON_BORDER_ALL, m_QuickActionToggleGrid.Active(), &Button, 0, m_QuickActionToggleGrid.Description(), IGraphics::CORNER_L) ||
|
||||
(m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_G) && ModPressed && !ShiftPressed))
|
||||
{
|
||||
MapView()->MapGrid()->Toggle();
|
||||
m_QuickActionToggleGrid.Call();
|
||||
}
|
||||
|
||||
// grid settings button
|
||||
|
@ -1123,23 +1121,23 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
|
|||
// zoom group
|
||||
TB_Top.VSplitLeft(20.0f, &Button, &TB_Top);
|
||||
static int s_ZoomOutButton = 0;
|
||||
if(DoButton_FontIcon(&s_ZoomOutButton, FONT_ICON_MINUS, 0, &Button, 0, "[NumPad-] Zoom out", IGraphics::CORNER_L))
|
||||
if(DoButton_FontIcon(&s_ZoomOutButton, FONT_ICON_MINUS, 0, &Button, 0, m_QuickActionZoomOut.Description(), IGraphics::CORNER_L))
|
||||
{
|
||||
MapView()->Zoom()->ChangeValue(50.0f);
|
||||
m_QuickActionZoomOut.Call();
|
||||
}
|
||||
|
||||
TB_Top.VSplitLeft(25.0f, &Button, &TB_Top);
|
||||
static int s_ZoomNormalButton = 0;
|
||||
if(DoButton_FontIcon(&s_ZoomNormalButton, FONT_ICON_MAGNIFYING_GLASS, 0, &Button, 0, "[NumPad*] Zoom to normal and remove editor offset", IGraphics::CORNER_NONE))
|
||||
if(DoButton_FontIcon(&s_ZoomNormalButton, FONT_ICON_MAGNIFYING_GLASS, 0, &Button, 0, m_QuickActionResetZoom.Description(), IGraphics::CORNER_NONE))
|
||||
{
|
||||
MapView()->ResetZoom();
|
||||
m_QuickActionResetZoom.Call();
|
||||
}
|
||||
|
||||
TB_Top.VSplitLeft(20.0f, &Button, &TB_Top);
|
||||
static int s_ZoomInButton = 0;
|
||||
if(DoButton_FontIcon(&s_ZoomInButton, FONT_ICON_PLUS, 0, &Button, 0, "[NumPad+] Zoom in", IGraphics::CORNER_R))
|
||||
if(DoButton_FontIcon(&s_ZoomInButton, FONT_ICON_PLUS, 0, &Button, 0, m_QuickActionZoomIn.Description(), IGraphics::CORNER_R))
|
||||
{
|
||||
MapView()->Zoom()->ChangeValue(-50.0f);
|
||||
m_QuickActionZoomIn.Call();
|
||||
}
|
||||
|
||||
TB_Top.VSplitLeft(5.0f, nullptr, &TB_Top);
|
||||
|
@ -1230,10 +1228,10 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
|
|||
static char s_PipetteButton;
|
||||
ColorPalette.VSplitLeft(PipetteButtonWidth, &Button, &ColorPalette);
|
||||
ColorPalette.VSplitLeft(Spacing, nullptr, &ColorPalette);
|
||||
if(DoButton_FontIcon(&s_PipetteButton, FONT_ICON_EYE_DROPPER, m_ColorPipetteActive ? 1 : 0, &Button, 0, "[Ctrl+Shift+C] Color pipette. Pick a color from the screen by clicking on it.", IGraphics::CORNER_ALL) ||
|
||||
if(DoButton_FontIcon(&s_PipetteButton, FONT_ICON_EYE_DROPPER, m_QuickActionPipette.Active(), &Button, 0, m_QuickActionPipette.Description(), IGraphics::CORNER_ALL) ||
|
||||
(CLineInput::GetActiveInput() == nullptr && ModPressed && ShiftPressed && Input()->KeyPress(KEY_C)))
|
||||
{
|
||||
m_ColorPipetteActive = !m_ColorPipetteActive;
|
||||
m_QuickActionPipette.Call();
|
||||
}
|
||||
|
||||
// Palette color pickers
|
||||
|
@ -1254,10 +1252,9 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
|
|||
// refocus button
|
||||
{
|
||||
TB_Bottom.VSplitLeft(50.0f, &Button, &TB_Bottom);
|
||||
static int s_RefocusButton = 0;
|
||||
int FocusButtonChecked = MapView()->IsFocused() ? -1 : 1;
|
||||
if(DoButton_Editor(&s_RefocusButton, "Refocus", FocusButtonChecked, &Button, 0, "[HOME] Restore map focus") || (m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_HOME)))
|
||||
MapView()->Focus();
|
||||
if(DoButton_Editor(&m_QuickActionRefocus, m_QuickActionRefocus.Label(), FocusButtonChecked, &Button, 0, m_QuickActionRefocus.Description()) || (m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_HOME)))
|
||||
m_QuickActionRefocus.Call();
|
||||
TB_Bottom.VSplitLeft(5.0f, nullptr, &TB_Bottom);
|
||||
}
|
||||
|
||||
|
@ -4302,12 +4299,9 @@ void CEditor::RenderLayers(CUIRect LayersBox)
|
|||
if(s_ScrollRegion.AddRect(AddGroupButton))
|
||||
{
|
||||
AddGroupButton.HSplitTop(RowHeight, &AddGroupButton, 0);
|
||||
static int s_AddGroupButton = 0;
|
||||
if(DoButton_Editor(&s_AddGroupButton, "Add group", 0, &AddGroupButton, IGraphics::CORNER_R, "Adds a new group"))
|
||||
if(DoButton_Editor(&m_QuickActionAddGroup, m_QuickActionAddGroup.Label(), 0, &AddGroupButton, IGraphics::CORNER_R, m_QuickActionAddGroup.Description()))
|
||||
{
|
||||
m_Map.NewGroup();
|
||||
m_SelectedGroup = m_Map.m_vpGroups.size() - 1;
|
||||
m_EditorHistory.RecordAction(std::make_shared<CEditorActionGroup>(this, m_SelectedGroup, false));
|
||||
m_QuickActionAddGroup.Call();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4806,8 +4800,8 @@ void CEditor::RenderImagesList(CUIRect ToolBox)
|
|||
{
|
||||
AddImageButton.HSplitTop(5.0f, nullptr, &AddImageButton);
|
||||
AddImageButton.HSplitTop(RowHeight, &AddImageButton, nullptr);
|
||||
if(DoButton_Editor(&s_AddImageButton, "Add", 0, &AddImageButton, 0, "Load a new image to use in the map"))
|
||||
InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Add Image", "Add", "mapres", false, AddImage, this);
|
||||
if(DoButton_Editor(&s_AddImageButton, m_QuickActionAddImage.Label(), 0, &AddImageButton, 0, m_QuickActionAddImage.Description()))
|
||||
m_QuickActionAddImage.Call();
|
||||
}
|
||||
s_ScrollRegion.End();
|
||||
}
|
||||
|
@ -5745,30 +5739,25 @@ void CEditor::RenderModebar(CUIRect View)
|
|||
|
||||
void CEditor::RenderStatusbar(CUIRect View, CUIRect *pTooltipRect)
|
||||
{
|
||||
const bool ButtonsDisabled = m_ShowPicker;
|
||||
|
||||
CUIRect Button;
|
||||
View.VSplitRight(100.0f, &View, &Button);
|
||||
static int s_EnvelopeButton = 0;
|
||||
if(DoButton_Editor(&s_EnvelopeButton, "Envelopes", ButtonsDisabled ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES, &Button, 0, "Toggles the envelope editor.") == 1)
|
||||
if(DoButton_Editor(&m_QuickActionEnvelopes, m_QuickActionEnvelopes.Label(), m_QuickActionEnvelopes.Color(), &Button, 0, m_QuickActionEnvelopes.Description()) == 1)
|
||||
{
|
||||
m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES ? EXTRAEDITOR_NONE : EXTRAEDITOR_ENVELOPES;
|
||||
m_QuickActionEnvelopes.Call();
|
||||
}
|
||||
|
||||
View.VSplitRight(10.0f, &View, nullptr);
|
||||
View.VSplitRight(100.0f, &View, &Button);
|
||||
static int s_SettingsButton = 0;
|
||||
if(DoButton_Editor(&s_SettingsButton, "Server settings", ButtonsDisabled ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_SERVER_SETTINGS, &Button, 0, "Toggles the server settings editor.") == 1)
|
||||
if(DoButton_Editor(&m_QuickActionServerSettings, m_QuickActionServerSettings.Label(), m_QuickActionServerSettings.Color(), &Button, 0, m_QuickActionServerSettings.Description()) == 1)
|
||||
{
|
||||
m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_SERVER_SETTINGS ? EXTRAEDITOR_NONE : EXTRAEDITOR_SERVER_SETTINGS;
|
||||
m_QuickActionServerSettings.Call();
|
||||
}
|
||||
|
||||
View.VSplitRight(10.0f, &View, nullptr);
|
||||
View.VSplitRight(100.0f, &View, &Button);
|
||||
static int s_HistoryButton = 0;
|
||||
if(DoButton_Editor(&s_HistoryButton, "History", ButtonsDisabled ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_HISTORY, &Button, 0, "Toggles the editor history view.") == 1)
|
||||
if(DoButton_Editor(&m_QuickActionHistory, m_QuickActionHistory.Label(), m_QuickActionHistory.Color(), &Button, 0, m_QuickActionHistory.Description()) == 1)
|
||||
{
|
||||
m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_HISTORY ? EXTRAEDITOR_NONE : EXTRAEDITOR_HISTORY;
|
||||
m_QuickActionHistory.Call();
|
||||
}
|
||||
|
||||
View.VSplitRight(10.0f, pTooltipRect, nullptr);
|
||||
|
@ -7702,7 +7691,7 @@ void CEditor::RenderMenubar(CUIRect MenuBar)
|
|||
if(DoButton_Ex(&s_SettingsButton, "Settings", 0, &SettingsButton, 0, nullptr, IGraphics::CORNER_T, EditorFontSizes::MENU, TEXTALIGN_ML))
|
||||
{
|
||||
static SPopupMenuId s_PopupMenuEntitiesId;
|
||||
Ui()->DoPopupMenu(&s_PopupMenuEntitiesId, SettingsButton.x, SettingsButton.y + SettingsButton.h - 1.0f, 200.0f, 92.0f, this, PopupMenuSettings, PopupProperties);
|
||||
Ui()->DoPopupMenu(&s_PopupMenuEntitiesId, SettingsButton.x, SettingsButton.y + SettingsButton.h - 1.0f, 200.0f, 106.0f, this, PopupMenuSettings, PopupProperties);
|
||||
}
|
||||
|
||||
CUIRect ChangedIndicator, Info, Help, Close;
|
||||
|
@ -7919,7 +7908,7 @@ void CEditor::Render()
|
|||
InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save", "maps", true, CallbackSaveCopyMap, this);
|
||||
// ctrl+shift+s to save as
|
||||
else if(Input()->KeyPress(KEY_S) && ModPressed && ShiftPressed)
|
||||
InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save", "maps", true, CallbackSaveMap, this);
|
||||
m_QuickActionSaveAs.Call();
|
||||
// ctrl+s to save
|
||||
else if(Input()->KeyPress(KEY_S) && ModPressed)
|
||||
{
|
||||
|
@ -8362,6 +8351,7 @@ void CEditor::Init()
|
|||
m_vComponents.emplace_back(m_MapView);
|
||||
m_vComponents.emplace_back(m_MapSettingsBackend);
|
||||
m_vComponents.emplace_back(m_LayerSelector);
|
||||
m_vComponents.emplace_back(m_Prompt);
|
||||
for(CEditorComponent &Component : m_vComponents)
|
||||
Component.OnInit(this);
|
||||
|
||||
|
@ -8602,21 +8592,29 @@ void CEditor::HandleWriterFinishJobs()
|
|||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "editor/save", aBuf);
|
||||
|
||||
// send rcon.. if we can
|
||||
if(Client()->RconAuthed())
|
||||
if(Client()->RconAuthed() && g_Config.m_EdAutoMapReload)
|
||||
{
|
||||
CServerInfo CurrentServerInfo;
|
||||
Client()->GetServerInfo(&CurrentServerInfo);
|
||||
NETADDR ServerAddr = Client()->ServerAddress();
|
||||
const unsigned char aIpv4Localhost[16] = {127, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
const unsigned char aIpv6Localhost[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
|
||||
|
||||
// and if we're on localhost
|
||||
if(!mem_comp(ServerAddr.ip, aIpv4Localhost, sizeof(aIpv4Localhost)) || !mem_comp(ServerAddr.ip, aIpv6Localhost, sizeof(aIpv6Localhost)))
|
||||
NETADDR pAddr = Client()->ServerAddress();
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(&Client()->ServerAddress(), aAddrStr, sizeof(aAddrStr), true);
|
||||
|
||||
// and if we're on a local address
|
||||
bool IsLocalAddress = false;
|
||||
if(pAddr.ip[0] == 127 || pAddr.ip[0] == 10 || (pAddr.ip[0] == 192 && pAddr.ip[1] == 168) || (pAddr.ip[0] == 172 && (pAddr.ip[1] >= 16 && pAddr.ip[1] <= 31)))
|
||||
IsLocalAddress = true;
|
||||
|
||||
if(str_startswith(aAddrStr, "[fe80:") || str_startswith(aAddrStr, "[::1"))
|
||||
IsLocalAddress = true;
|
||||
|
||||
if(IsLocalAddress)
|
||||
{
|
||||
char aMapName[128];
|
||||
IStorage::StripPathAndExtension(pJob->GetRealFileName(), aMapName, sizeof(aMapName));
|
||||
if(!str_comp(aMapName, CurrentServerInfo.m_aMap))
|
||||
Client()->Rcon("reload");
|
||||
Client()->Rcon("hot_reload");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <game/client/ui_listbox.h>
|
||||
#include <game/mapitems.h>
|
||||
|
||||
#include <game/editor/enums.h>
|
||||
#include <game/editor/mapitems/envelope.h>
|
||||
#include <game/editor/mapitems/layer.h>
|
||||
#include <game/editor/mapitems/layer_front.h>
|
||||
|
@ -38,6 +39,8 @@
|
|||
#include "layer_selector.h"
|
||||
#include "map_view.h"
|
||||
#include "smooth_value.h"
|
||||
#include <game/editor/prompt.h>
|
||||
#include <game/editor/quick_action.h>
|
||||
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
|
@ -60,7 +63,8 @@ enum
|
|||
|
||||
DIALOG_NONE = 0,
|
||||
DIALOG_FILE,
|
||||
DIALOG_MAPSETTINGS_ERROR
|
||||
DIALOG_MAPSETTINGS_ERROR,
|
||||
DIALOG_QUICK_PROMPT,
|
||||
};
|
||||
|
||||
class CEditorImage;
|
||||
|
@ -278,6 +282,7 @@ class CEditor : public IEditor
|
|||
std::vector<std::reference_wrapper<CEditorComponent>> m_vComponents;
|
||||
CMapView m_MapView;
|
||||
CLayerSelector m_LayerSelector;
|
||||
CPrompt m_Prompt;
|
||||
|
||||
bool m_EditorWasUsedBefore = false;
|
||||
|
||||
|
@ -319,7 +324,20 @@ public:
|
|||
const CMapView *MapView() const { return &m_MapView; }
|
||||
CLayerSelector *LayerSelector() { return &m_LayerSelector; }
|
||||
|
||||
void FillGameTiles(EGameTileOp FillTile) const;
|
||||
bool CanFillGameTiles() const;
|
||||
void AddGroup();
|
||||
void AddTileLayer();
|
||||
void LayerSelectImage();
|
||||
bool IsNonGameTileLayerSelected() const;
|
||||
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) CQuickAction m_QuickAction##name;
|
||||
#include <game/editor/quick_actions.h>
|
||||
#undef REGISTER_QUICK_ACTION
|
||||
|
||||
CEditor() :
|
||||
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) m_QuickAction##name(text, description, callback, disabled, active, button_color),
|
||||
#include <game/editor/quick_actions.h>
|
||||
#undef REGISTER_QUICK_ACTION
|
||||
m_ZoomEnvelopeX(1.0f, 0.1f, 600.0f),
|
||||
m_ZoomEnvelopeY(640.0f, 0.1f, 32000.0f),
|
||||
m_MapSettingsCommandContext(m_MapSettingsBackend.NewContext(&m_SettingsCommandInput))
|
||||
|
|
|
@ -320,7 +320,7 @@ void CEditorActionDeleteQuad::Redo()
|
|||
CEditorActionEditQuadPoint::CEditorActionEditQuadPoint(CEditor *pEditor, int GroupIndex, int LayerIndex, int QuadIndex, std::vector<CPoint> const &vPreviousPoints, std::vector<CPoint> const &vCurrentPoints) :
|
||||
CEditorActionLayerBase(pEditor, GroupIndex, LayerIndex), m_QuadIndex(QuadIndex), m_vPreviousPoints(vPreviousPoints), m_vCurrentPoints(vCurrentPoints)
|
||||
{
|
||||
str_format(m_aDisplayText, sizeof(m_aDisplayText), "Edit quad points");
|
||||
str_copy(m_aDisplayText, "Edit quad points");
|
||||
}
|
||||
|
||||
void CEditorActionEditQuadPoint::Undo()
|
||||
|
@ -628,7 +628,7 @@ CEditorActionGroup::CEditorActionGroup(CEditor *pEditor, int GroupIndex, bool De
|
|||
if(m_Delete)
|
||||
str_format(m_aDisplayText, sizeof(m_aDisplayText), "Delete group %d", m_GroupIndex);
|
||||
else
|
||||
str_format(m_aDisplayText, sizeof(m_aDisplayText), "New group");
|
||||
str_copy(m_aDisplayText, "New group", sizeof(m_aDisplayText));
|
||||
}
|
||||
|
||||
void CEditorActionGroup::Undo()
|
||||
|
@ -1198,7 +1198,7 @@ CEditorActionTileArt::CEditorActionTileArt(CEditor *pEditor, int PreviousImageCo
|
|||
IEditorAction(pEditor), m_PreviousImageCount(PreviousImageCount), m_vImageIndexMap(vImageIndexMap)
|
||||
{
|
||||
str_copy(m_aTileArtFile, pTileArtFile);
|
||||
str_format(m_aDisplayText, sizeof(m_aDisplayText), "Tile art");
|
||||
str_copy(m_aDisplayText, "Tile art");
|
||||
}
|
||||
|
||||
void CEditorActionTileArt::Undo()
|
||||
|
@ -1266,7 +1266,7 @@ CEditorCommandAction::CEditorCommandAction(CEditor *pEditor, EType Type, int *pS
|
|||
switch(m_Type)
|
||||
{
|
||||
case EType::ADD:
|
||||
str_format(m_aDisplayText, sizeof(m_aDisplayText), "Add command");
|
||||
str_copy(m_aDisplayText, "Add command");
|
||||
break;
|
||||
case EType::EDIT:
|
||||
str_format(m_aDisplayText, sizeof(m_aDisplayText), "Edit command %d", m_CommandIndex);
|
||||
|
|
36
src/game/editor/enums.h
Normal file
36
src/game/editor/enums.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef GAME_EDITOR_ENUMS_H
|
||||
#define GAME_EDITOR_ENUMS_H
|
||||
|
||||
constexpr const char *g_apGametileOpNames[] = {
|
||||
"Air",
|
||||
"Hookable",
|
||||
"Death",
|
||||
"Unhookable",
|
||||
"Hookthrough",
|
||||
"Freeze",
|
||||
"Unfreeze",
|
||||
"Deep Freeze",
|
||||
"Deep Unfreeze",
|
||||
"Blue Check-Tele",
|
||||
"Red Check-Tele",
|
||||
"Live Freeze",
|
||||
"Live Unfreeze",
|
||||
};
|
||||
enum class EGameTileOp
|
||||
{
|
||||
AIR,
|
||||
HOOKABLE,
|
||||
DEATH,
|
||||
UNHOOKABLE,
|
||||
HOOKTHROUGH,
|
||||
FREEZE,
|
||||
UNFREEZE,
|
||||
DEEP_FREEZE,
|
||||
DEEP_UNFREEZE,
|
||||
BLUE_CHECK_TELE,
|
||||
RED_CHECK_TELE,
|
||||
LIVE_FREEZE,
|
||||
LIVE_UNFREEZE,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -6,6 +6,7 @@
|
|||
#include <engine/shared/map.h>
|
||||
#include <game/editor/editor.h>
|
||||
#include <game/editor/editor_actions.h>
|
||||
#include <game/editor/enums.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
|
@ -693,93 +694,126 @@ void CLayerTiles::ShowInfo()
|
|||
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
||||
}
|
||||
|
||||
CUi::EPopupMenuFunctionResult CLayerTiles::RenderProperties(CUIRect *pToolBox)
|
||||
void CLayerTiles::FillGameTiles(EGameTileOp Fill)
|
||||
{
|
||||
CUIRect Button;
|
||||
|
||||
const bool EntitiesLayer = IsEntitiesLayer();
|
||||
if(!CanFillGameTiles())
|
||||
return;
|
||||
|
||||
std::shared_ptr<CLayerGroup> pGroup = m_pEditor->m_Map.m_vpGroups[m_pEditor->m_SelectedGroup];
|
||||
|
||||
// Game tiles can only be constructed if the layer is relative to the game layer
|
||||
if(!EntitiesLayer && !(pGroup->m_OffsetX % 32) && !(pGroup->m_OffsetY % 32) && pGroup->m_ParallaxX == 100 && pGroup->m_ParallaxY == 100)
|
||||
int Result = (int)Fill;
|
||||
switch(Fill)
|
||||
{
|
||||
pToolBox->HSplitBottom(12.0f, pToolBox, &Button);
|
||||
static int s_GameTilesButton = 0;
|
||||
if(m_pEditor->DoButton_Editor(&s_GameTilesButton, "Game tiles", 0, &Button, 0, "Constructs game tiles from this layer"))
|
||||
m_pEditor->PopupSelectGametileOpInvoke(m_pEditor->Ui()->MouseX(), m_pEditor->Ui()->MouseY());
|
||||
const int Selected = m_pEditor->PopupSelectGameTileOpResult();
|
||||
int Result = Selected;
|
||||
switch(Selected)
|
||||
case EGameTileOp::HOOKTHROUGH:
|
||||
Result = TILE_THROUGH_CUT;
|
||||
break;
|
||||
case EGameTileOp::FREEZE:
|
||||
Result = TILE_FREEZE;
|
||||
break;
|
||||
case EGameTileOp::UNFREEZE:
|
||||
Result = TILE_UNFREEZE;
|
||||
break;
|
||||
case EGameTileOp::DEEP_FREEZE:
|
||||
Result = TILE_DFREEZE;
|
||||
break;
|
||||
case EGameTileOp::DEEP_UNFREEZE:
|
||||
Result = TILE_DUNFREEZE;
|
||||
break;
|
||||
case EGameTileOp::BLUE_CHECK_TELE:
|
||||
Result = TILE_TELECHECKIN;
|
||||
break;
|
||||
case EGameTileOp::RED_CHECK_TELE:
|
||||
Result = TILE_TELECHECKINEVIL;
|
||||
break;
|
||||
case EGameTileOp::LIVE_FREEZE:
|
||||
Result = TILE_LFREEZE;
|
||||
break;
|
||||
case EGameTileOp::LIVE_UNFREEZE:
|
||||
Result = TILE_LUNFREEZE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(Result > -1)
|
||||
{
|
||||
const int OffsetX = -pGroup->m_OffsetX / 32;
|
||||
const int OffsetY = -pGroup->m_OffsetY / 32;
|
||||
|
||||
std::vector<std::shared_ptr<IEditorAction>> vpActions;
|
||||
std::shared_ptr<CLayerTiles> pGLayer = m_pEditor->m_Map.m_pGameLayer;
|
||||
int GameLayerIndex = std::find(m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin(), m_pEditor->m_Map.m_pGameGroup->m_vpLayers.end(), pGLayer) - m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin();
|
||||
|
||||
if(Result != TILE_TELECHECKIN && Result != TILE_TELECHECKINEVIL)
|
||||
{
|
||||
case 4:
|
||||
Result = TILE_THROUGH_CUT;
|
||||
break;
|
||||
case 5:
|
||||
Result = TILE_FREEZE;
|
||||
break;
|
||||
case 6:
|
||||
Result = TILE_UNFREEZE;
|
||||
break;
|
||||
case 7:
|
||||
Result = TILE_DFREEZE;
|
||||
break;
|
||||
case 8:
|
||||
Result = TILE_DUNFREEZE;
|
||||
break;
|
||||
case 9:
|
||||
Result = TILE_TELECHECKIN;
|
||||
break;
|
||||
case 10:
|
||||
Result = TILE_TELECHECKINEVIL;
|
||||
break;
|
||||
case 11:
|
||||
Result = TILE_LFREEZE;
|
||||
break;
|
||||
case 12:
|
||||
Result = TILE_LUNFREEZE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(Result > -1)
|
||||
{
|
||||
const int OffsetX = -pGroup->m_OffsetX / 32;
|
||||
const int OffsetY = -pGroup->m_OffsetY / 32;
|
||||
|
||||
static const char *s_apGametileOpNames[] = {
|
||||
"Air",
|
||||
"Hookable",
|
||||
"Death",
|
||||
"Unhookable",
|
||||
"Hookthrough",
|
||||
"Freeze",
|
||||
"Unfreeze",
|
||||
"Deep Freeze",
|
||||
"Deep Unfreeze",
|
||||
"Blue Check-Tele",
|
||||
"Red Check-Tele",
|
||||
"Live Freeze",
|
||||
"Live Unfreeze",
|
||||
};
|
||||
|
||||
std::vector<std::shared_ptr<IEditorAction>> vpActions;
|
||||
std::shared_ptr<CLayerTiles> pGLayer = m_pEditor->m_Map.m_pGameLayer;
|
||||
int GameLayerIndex = std::find(m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin(), m_pEditor->m_Map.m_pGameGroup->m_vpLayers.end(), pGLayer) - m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin();
|
||||
|
||||
if(Result != TILE_TELECHECKIN && Result != TILE_TELECHECKINEVIL)
|
||||
if(pGLayer->m_Width < m_Width + OffsetX || pGLayer->m_Height < m_Height + OffsetY)
|
||||
{
|
||||
if(pGLayer->m_Width < m_Width + OffsetX || pGLayer->m_Height < m_Height + OffsetY)
|
||||
std::map<int, std::shared_ptr<CLayer>> savedLayers;
|
||||
savedLayers[LAYERTYPE_TILES] = pGLayer->Duplicate();
|
||||
savedLayers[LAYERTYPE_GAME] = savedLayers[LAYERTYPE_TILES];
|
||||
|
||||
int PrevW = pGLayer->m_Width;
|
||||
int PrevH = pGLayer->m_Height;
|
||||
const int NewW = pGLayer->m_Width < m_Width + OffsetX ? m_Width + OffsetX : pGLayer->m_Width;
|
||||
const int NewH = pGLayer->m_Height < m_Height + OffsetY ? m_Height + OffsetY : pGLayer->m_Height;
|
||||
pGLayer->Resize(NewW, NewH);
|
||||
vpActions.push_back(std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, GameLayerIndex, ETilesProp::PROP_WIDTH, PrevW, NewW));
|
||||
const std::shared_ptr<CEditorActionEditLayerTilesProp> &Action1 = std::static_pointer_cast<CEditorActionEditLayerTilesProp>(vpActions[vpActions.size() - 1]);
|
||||
vpActions.push_back(std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, GameLayerIndex, ETilesProp::PROP_HEIGHT, PrevH, NewH));
|
||||
const std::shared_ptr<CEditorActionEditLayerTilesProp> &Action2 = std::static_pointer_cast<CEditorActionEditLayerTilesProp>(vpActions[vpActions.size() - 1]);
|
||||
|
||||
Action1->SetSavedLayers(savedLayers);
|
||||
Action2->SetSavedLayers(savedLayers);
|
||||
}
|
||||
|
||||
int Changes = 0;
|
||||
for(int y = OffsetY < 0 ? -OffsetY : 0; y < m_Height; y++)
|
||||
{
|
||||
for(int x = OffsetX < 0 ? -OffsetX : 0; x < m_Width; x++)
|
||||
{
|
||||
if(GetTile(x, y).m_Index)
|
||||
{
|
||||
const CTile ResultTile = {(unsigned char)Result};
|
||||
pGLayer->SetTile(x + OffsetX, y + OffsetY, ResultTile);
|
||||
Changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vpActions.push_back(std::make_shared<CEditorBrushDrawAction>(m_pEditor, m_pEditor->m_SelectedGroup));
|
||||
char aDisplay[256];
|
||||
str_format(aDisplay, sizeof(aDisplay), "Construct '%s' game tiles (x%d)", g_apGametileOpNames[(int)Fill], Changes);
|
||||
m_pEditor->m_EditorHistory.RecordAction(std::make_shared<CEditorActionBulk>(m_pEditor, vpActions, aDisplay, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!m_pEditor->m_Map.m_pTeleLayer)
|
||||
{
|
||||
std::shared_ptr<CLayerTele> pLayer = std::make_shared<CLayerTele>(m_pEditor, m_Width, m_Height);
|
||||
m_pEditor->m_Map.MakeTeleLayer(pLayer);
|
||||
m_pEditor->m_Map.m_pGameGroup->AddLayer(pLayer);
|
||||
|
||||
vpActions.push_back(std::make_shared<CEditorActionAddLayer>(m_pEditor, m_pEditor->m_SelectedGroup, m_pEditor->m_Map.m_pGameGroup->m_vpLayers.size() - 1));
|
||||
|
||||
if(m_Width != pGLayer->m_Width || m_Height > pGLayer->m_Height)
|
||||
{
|
||||
std::map<int, std::shared_ptr<CLayer>> savedLayers;
|
||||
savedLayers[LAYERTYPE_TILES] = pGLayer->Duplicate();
|
||||
savedLayers[LAYERTYPE_GAME] = savedLayers[LAYERTYPE_TILES];
|
||||
|
||||
int NewW = pGLayer->m_Width;
|
||||
int NewH = pGLayer->m_Height;
|
||||
if(m_Width > pGLayer->m_Width)
|
||||
{
|
||||
NewW = m_Width;
|
||||
}
|
||||
if(m_Height > pGLayer->m_Height)
|
||||
{
|
||||
NewH = m_Height;
|
||||
}
|
||||
|
||||
int PrevW = pGLayer->m_Width;
|
||||
int PrevH = pGLayer->m_Height;
|
||||
const int NewW = pGLayer->m_Width < m_Width + OffsetX ? m_Width + OffsetX : pGLayer->m_Width;
|
||||
const int NewH = pGLayer->m_Height < m_Height + OffsetY ? m_Height + OffsetY : pGLayer->m_Height;
|
||||
pGLayer->Resize(NewW, NewH);
|
||||
pLayer->Resize(NewW, NewH);
|
||||
vpActions.push_back(std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, GameLayerIndex, ETilesProp::PROP_WIDTH, PrevW, NewW));
|
||||
const std::shared_ptr<CEditorActionEditLayerTilesProp> &Action1 = std::static_pointer_cast<CEditorActionEditLayerTilesProp>(vpActions[vpActions.size() - 1]);
|
||||
vpActions.push_back(std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, GameLayerIndex, ETilesProp::PROP_HEIGHT, PrevH, NewH));
|
||||
|
@ -788,124 +822,94 @@ CUi::EPopupMenuFunctionResult CLayerTiles::RenderProperties(CUIRect *pToolBox)
|
|||
Action1->SetSavedLayers(savedLayers);
|
||||
Action2->SetSavedLayers(savedLayers);
|
||||
}
|
||||
|
||||
int Changes = 0;
|
||||
for(int y = OffsetY < 0 ? -OffsetY : 0; y < m_Height; y++)
|
||||
{
|
||||
for(int x = OffsetX < 0 ? -OffsetX : 0; x < m_Width; x++)
|
||||
{
|
||||
if(GetTile(x, y).m_Index)
|
||||
{
|
||||
const CTile ResultTile = {(unsigned char)Result};
|
||||
pGLayer->SetTile(x + OffsetX, y + OffsetY, ResultTile);
|
||||
Changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vpActions.push_back(std::make_shared<CEditorBrushDrawAction>(m_pEditor, m_pEditor->m_SelectedGroup));
|
||||
char aDisplay[256];
|
||||
str_format(aDisplay, sizeof(aDisplay), "Construct '%s' game tiles (x%d)", s_apGametileOpNames[Selected], Changes);
|
||||
m_pEditor->m_EditorHistory.RecordAction(std::make_shared<CEditorActionBulk>(m_pEditor, vpActions, aDisplay, true));
|
||||
}
|
||||
else
|
||||
|
||||
std::shared_ptr<CLayerTele> pTLayer = m_pEditor->m_Map.m_pTeleLayer;
|
||||
int TeleLayerIndex = std::find(m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin(), m_pEditor->m_Map.m_pGameGroup->m_vpLayers.end(), pTLayer) - m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin();
|
||||
|
||||
if(pTLayer->m_Width < m_Width + OffsetX || pTLayer->m_Height < m_Height + OffsetY)
|
||||
{
|
||||
if(!m_pEditor->m_Map.m_pTeleLayer)
|
||||
{
|
||||
std::shared_ptr<CLayerTele> pLayer = std::make_shared<CLayerTele>(m_pEditor, m_Width, m_Height);
|
||||
m_pEditor->m_Map.MakeTeleLayer(pLayer);
|
||||
m_pEditor->m_Map.m_pGameGroup->AddLayer(pLayer);
|
||||
std::map<int, std::shared_ptr<CLayer>> savedLayers;
|
||||
savedLayers[LAYERTYPE_TILES] = pTLayer->Duplicate();
|
||||
savedLayers[LAYERTYPE_TELE] = savedLayers[LAYERTYPE_TILES];
|
||||
|
||||
vpActions.push_back(std::make_shared<CEditorActionAddLayer>(m_pEditor, m_pEditor->m_SelectedGroup, m_pEditor->m_Map.m_pGameGroup->m_vpLayers.size() - 1));
|
||||
int PrevW = pTLayer->m_Width;
|
||||
int PrevH = pTLayer->m_Height;
|
||||
int NewW = pTLayer->m_Width < m_Width + OffsetX ? m_Width + OffsetX : pTLayer->m_Width;
|
||||
int NewH = pTLayer->m_Height < m_Height + OffsetY ? m_Height + OffsetY : pTLayer->m_Height;
|
||||
pTLayer->Resize(NewW, NewH);
|
||||
std::shared_ptr<CEditorActionEditLayerTilesProp> Action1, Action2;
|
||||
vpActions.push_back(Action1 = std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, TeleLayerIndex, ETilesProp::PROP_WIDTH, PrevW, NewW));
|
||||
vpActions.push_back(Action2 = std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, TeleLayerIndex, ETilesProp::PROP_HEIGHT, PrevH, NewH));
|
||||
|
||||
if(m_Width != pGLayer->m_Width || m_Height > pGLayer->m_Height)
|
||||
{
|
||||
std::map<int, std::shared_ptr<CLayer>> savedLayers;
|
||||
savedLayers[LAYERTYPE_TILES] = pGLayer->Duplicate();
|
||||
savedLayers[LAYERTYPE_GAME] = savedLayers[LAYERTYPE_TILES];
|
||||
|
||||
int NewW = pGLayer->m_Width;
|
||||
int NewH = pGLayer->m_Height;
|
||||
if(m_Width > pGLayer->m_Width)
|
||||
{
|
||||
NewW = m_Width;
|
||||
}
|
||||
if(m_Height > pGLayer->m_Height)
|
||||
{
|
||||
NewH = m_Height;
|
||||
}
|
||||
|
||||
int PrevW = pGLayer->m_Width;
|
||||
int PrevH = pGLayer->m_Height;
|
||||
pLayer->Resize(NewW, NewH);
|
||||
vpActions.push_back(std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, GameLayerIndex, ETilesProp::PROP_WIDTH, PrevW, NewW));
|
||||
const std::shared_ptr<CEditorActionEditLayerTilesProp> &Action1 = std::static_pointer_cast<CEditorActionEditLayerTilesProp>(vpActions[vpActions.size() - 1]);
|
||||
vpActions.push_back(std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, GameLayerIndex, ETilesProp::PROP_HEIGHT, PrevH, NewH));
|
||||
const std::shared_ptr<CEditorActionEditLayerTilesProp> &Action2 = std::static_pointer_cast<CEditorActionEditLayerTilesProp>(vpActions[vpActions.size() - 1]);
|
||||
|
||||
Action1->SetSavedLayers(savedLayers);
|
||||
Action2->SetSavedLayers(savedLayers);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<CLayerTele> pTLayer = m_pEditor->m_Map.m_pTeleLayer;
|
||||
int TeleLayerIndex = std::find(m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin(), m_pEditor->m_Map.m_pGameGroup->m_vpLayers.end(), pTLayer) - m_pEditor->m_Map.m_pGameGroup->m_vpLayers.begin();
|
||||
|
||||
if(pTLayer->m_Width < m_Width + OffsetX || pTLayer->m_Height < m_Height + OffsetY)
|
||||
{
|
||||
std::map<int, std::shared_ptr<CLayer>> savedLayers;
|
||||
savedLayers[LAYERTYPE_TILES] = pTLayer->Duplicate();
|
||||
savedLayers[LAYERTYPE_TELE] = savedLayers[LAYERTYPE_TILES];
|
||||
|
||||
int PrevW = pTLayer->m_Width;
|
||||
int PrevH = pTLayer->m_Height;
|
||||
int NewW = pTLayer->m_Width < m_Width + OffsetX ? m_Width + OffsetX : pTLayer->m_Width;
|
||||
int NewH = pTLayer->m_Height < m_Height + OffsetY ? m_Height + OffsetY : pTLayer->m_Height;
|
||||
pTLayer->Resize(NewW, NewH);
|
||||
std::shared_ptr<CEditorActionEditLayerTilesProp> Action1, Action2;
|
||||
vpActions.push_back(Action1 = std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, TeleLayerIndex, ETilesProp::PROP_WIDTH, PrevW, NewW));
|
||||
vpActions.push_back(Action2 = std::make_shared<CEditorActionEditLayerTilesProp>(m_pEditor, m_pEditor->m_SelectedGroup, TeleLayerIndex, ETilesProp::PROP_HEIGHT, PrevH, NewH));
|
||||
|
||||
Action1->SetSavedLayers(savedLayers);
|
||||
Action2->SetSavedLayers(savedLayers);
|
||||
}
|
||||
|
||||
int Changes = 0;
|
||||
for(int y = OffsetY < 0 ? -OffsetY : 0; y < m_Height; y++)
|
||||
{
|
||||
for(int x = OffsetX < 0 ? -OffsetX : 0; x < m_Width; x++)
|
||||
{
|
||||
if(GetTile(x, y).m_Index)
|
||||
{
|
||||
auto TileIndex = (y + OffsetY) * pTLayer->m_Width + x + OffsetX;
|
||||
Changes++;
|
||||
|
||||
STeleTileStateChange::SData Previous{
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Number,
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Type,
|
||||
pTLayer->m_pTiles[TileIndex].m_Index};
|
||||
|
||||
pTLayer->m_pTiles[TileIndex].m_Index = TILE_AIR + Result;
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Number = 1;
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Type = TILE_AIR + Result;
|
||||
|
||||
STeleTileStateChange::SData Current{
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Number,
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Type,
|
||||
pTLayer->m_pTiles[TileIndex].m_Index};
|
||||
|
||||
pTLayer->RecordStateChange(x, y, Previous, Current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vpActions.push_back(std::make_shared<CEditorBrushDrawAction>(m_pEditor, m_pEditor->m_SelectedGroup));
|
||||
char aDisplay[256];
|
||||
str_format(aDisplay, sizeof(aDisplay), "Construct 'tele' game tiles (x%d)", Changes);
|
||||
m_pEditor->m_EditorHistory.RecordAction(std::make_shared<CEditorActionBulk>(m_pEditor, vpActions, aDisplay, true));
|
||||
Action1->SetSavedLayers(savedLayers);
|
||||
Action2->SetSavedLayers(savedLayers);
|
||||
}
|
||||
|
||||
int Changes = 0;
|
||||
for(int y = OffsetY < 0 ? -OffsetY : 0; y < m_Height; y++)
|
||||
{
|
||||
for(int x = OffsetX < 0 ? -OffsetX : 0; x < m_Width; x++)
|
||||
{
|
||||
if(GetTile(x, y).m_Index)
|
||||
{
|
||||
auto TileIndex = (y + OffsetY) * pTLayer->m_Width + x + OffsetX;
|
||||
Changes++;
|
||||
|
||||
STeleTileStateChange::SData Previous{
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Number,
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Type,
|
||||
pTLayer->m_pTiles[TileIndex].m_Index};
|
||||
|
||||
pTLayer->m_pTiles[TileIndex].m_Index = TILE_AIR + Result;
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Number = 1;
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Type = TILE_AIR + Result;
|
||||
|
||||
STeleTileStateChange::SData Current{
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Number,
|
||||
pTLayer->m_pTeleTile[TileIndex].m_Type,
|
||||
pTLayer->m_pTiles[TileIndex].m_Index};
|
||||
|
||||
pTLayer->RecordStateChange(x, y, Previous, Current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vpActions.push_back(std::make_shared<CEditorBrushDrawAction>(m_pEditor, m_pEditor->m_SelectedGroup));
|
||||
char aDisplay[256];
|
||||
str_format(aDisplay, sizeof(aDisplay), "Construct 'tele' game tiles (x%d)", Changes);
|
||||
m_pEditor->m_EditorHistory.RecordAction(std::make_shared<CEditorActionBulk>(m_pEditor, vpActions, aDisplay, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CLayerTiles::CanFillGameTiles() const
|
||||
{
|
||||
const bool EntitiesLayer = IsEntitiesLayer();
|
||||
if(EntitiesLayer)
|
||||
return false;
|
||||
|
||||
std::shared_ptr<CLayerGroup> pGroup = m_pEditor->m_Map.m_vpGroups[m_pEditor->m_SelectedGroup];
|
||||
|
||||
// Game tiles can only be constructed if the layer is relative to the game layer
|
||||
return !(pGroup->m_OffsetX % 32) && !(pGroup->m_OffsetY % 32) && pGroup->m_ParallaxX == 100 && pGroup->m_ParallaxY == 100;
|
||||
}
|
||||
|
||||
CUi::EPopupMenuFunctionResult CLayerTiles::RenderProperties(CUIRect *pToolBox)
|
||||
{
|
||||
CUIRect Button;
|
||||
|
||||
const bool EntitiesLayer = IsEntitiesLayer();
|
||||
|
||||
if(CanFillGameTiles())
|
||||
{
|
||||
pToolBox->HSplitBottom(12.0f, pToolBox, &Button);
|
||||
static int s_GameTilesButton = 0;
|
||||
if(m_pEditor->DoButton_Editor(&s_GameTilesButton, "Game tiles", 0, &Button, 0, "Constructs game tiles from this layer"))
|
||||
m_pEditor->PopupSelectGametileOpInvoke(m_pEditor->Ui()->MouseX(), m_pEditor->Ui()->MouseY());
|
||||
const int Selected = m_pEditor->PopupSelectGameTileOpResult();
|
||||
FillGameTiles((EGameTileOp)Selected);
|
||||
}
|
||||
|
||||
if(m_pEditor->m_Map.m_pGameLayer.get() != this)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define GAME_EDITOR_MAPITEMS_LAYER_TILES_H
|
||||
|
||||
#include <game/editor/editor_trackers.h>
|
||||
#include <game/editor/enums.h>
|
||||
#include <map>
|
||||
|
||||
#include "layer.h"
|
||||
|
@ -122,6 +123,8 @@ public:
|
|||
void BrushSelecting(CUIRect Rect) override;
|
||||
int BrushGrab(std::shared_ptr<CLayerGroup> pBrush, CUIRect Rect) override;
|
||||
void FillSelection(bool Empty, std::shared_ptr<CLayer> pBrush, CUIRect Rect) override;
|
||||
void FillGameTiles(EGameTileOp Fill);
|
||||
bool CanFillGameTiles() const;
|
||||
void BrushDraw(std::shared_ptr<CLayer> pBrush, float wx, float wy) override;
|
||||
void BrushFlipX() override;
|
||||
void BrushFlipY() override;
|
||||
|
|
|
@ -68,17 +68,9 @@ CUi::EPopupMenuFunctionResult CEditor::PopupMenuFile(void *pContext, CUIRect Vie
|
|||
|
||||
View.HSplitTop(2.0f, nullptr, &View);
|
||||
View.HSplitTop(12.0f, &Slot, &View);
|
||||
if(pEditor->DoButton_MenuItem(&s_OpenCurrentMapButton, "Load Current Map", 0, &Slot, 0, "Opens the current in game map for editing (ctrl+alt+l)"))
|
||||
if(pEditor->DoButton_MenuItem(&s_OpenCurrentMapButton, pEditor->m_QuickActionLoadCurrentMap.Label(), 0, &Slot, 0, pEditor->m_QuickActionLoadCurrentMap.Description()))
|
||||
{
|
||||
if(pEditor->HasUnsavedData())
|
||||
{
|
||||
pEditor->m_PopupEventType = POPEVENT_LOADCURRENT;
|
||||
pEditor->m_PopupEventActivated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEditor->LoadCurrentMap();
|
||||
}
|
||||
pEditor->m_QuickActionLoadCurrentMap.Call();
|
||||
return CUi::POPUP_CLOSE_CURRENT;
|
||||
}
|
||||
|
||||
|
@ -107,9 +99,9 @@ CUi::EPopupMenuFunctionResult CEditor::PopupMenuFile(void *pContext, CUIRect Vie
|
|||
|
||||
View.HSplitTop(2.0f, nullptr, &View);
|
||||
View.HSplitTop(12.0f, &Slot, &View);
|
||||
if(pEditor->DoButton_MenuItem(&s_SaveAsButton, "Save As", 0, &Slot, 0, "Saves the current map under a new name (ctrl+shift+s)"))
|
||||
if(pEditor->DoButton_MenuItem(&s_SaveAsButton, pEditor->m_QuickActionSaveAs.Label(), 0, &Slot, 0, pEditor->m_QuickActionSaveAs.Description()))
|
||||
{
|
||||
pEditor->InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save", "maps", true, CEditor::CallbackSaveMap, pEditor);
|
||||
pEditor->m_QuickActionSaveAs.Call();
|
||||
return CUi::POPUP_CLOSE_CURRENT;
|
||||
}
|
||||
|
||||
|
@ -314,20 +306,20 @@ CUi::EPopupMenuFunctionResult CEditor::PopupMenuSettings(void *pContext, CUIRect
|
|||
static int s_ButtonOff = 0;
|
||||
static int s_ButtonDec = 0;
|
||||
static int s_ButtonHex = 0;
|
||||
if(pEditor->DoButton_Ex(&s_ButtonOff, "Off", pEditor->m_ShowTileInfo == SHOW_TILE_OFF, &Off, 0, "Do not show tile information", IGraphics::CORNER_L))
|
||||
CQuickAction *pAction = &pEditor->m_QuickActionShowInfoOff;
|
||||
if(pEditor->DoButton_Ex(&s_ButtonOff, pAction->LabelShort(), pAction->Active(), &Off, 0, pAction->Description(), IGraphics::CORNER_L))
|
||||
{
|
||||
pEditor->m_ShowTileInfo = SHOW_TILE_OFF;
|
||||
pEditor->m_ShowEnvelopePreview = SHOWENV_NONE;
|
||||
pAction->Call();
|
||||
}
|
||||
if(pEditor->DoButton_Ex(&s_ButtonDec, "Dec", pEditor->m_ShowTileInfo == SHOW_TILE_DECIMAL, &Dec, 0, "[ctrl+i] Show tile information", IGraphics::CORNER_NONE))
|
||||
pAction = &pEditor->m_QuickActionShowInfoDec;
|
||||
if(pEditor->DoButton_Ex(&s_ButtonDec, pAction->LabelShort(), pAction->Active(), &Dec, 0, pAction->Description(), IGraphics::CORNER_NONE))
|
||||
{
|
||||
pEditor->m_ShowTileInfo = SHOW_TILE_DECIMAL;
|
||||
pEditor->m_ShowEnvelopePreview = SHOWENV_NONE;
|
||||
pAction->Call();
|
||||
}
|
||||
if(pEditor->DoButton_Ex(&s_ButtonHex, "Hex", pEditor->m_ShowTileInfo == SHOW_TILE_HEXADECIMAL, &Hex, 0, "[ctrl+shift+i] Show tile information in hexadecimal", IGraphics::CORNER_R))
|
||||
pAction = &pEditor->m_QuickActionShowInfoHex;
|
||||
if(pEditor->DoButton_Ex(&s_ButtonHex, pAction->LabelShort(), pAction->Active(), &Hex, 0, pAction->Description(), IGraphics::CORNER_R))
|
||||
{
|
||||
pEditor->m_ShowTileInfo = SHOW_TILE_HEXADECIMAL;
|
||||
pEditor->m_ShowEnvelopePreview = SHOWENV_NONE;
|
||||
pAction->Call();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,6 +371,30 @@ CUi::EPopupMenuFunctionResult CEditor::PopupMenuSettings(void *pContext, CUIRect
|
|||
}
|
||||
}
|
||||
|
||||
View.HSplitTop(2.0f, nullptr, &View);
|
||||
View.HSplitTop(12.0f, &Slot, &View);
|
||||
{
|
||||
Slot.VMargin(5.0f, &Slot);
|
||||
|
||||
CUIRect Label, Selector;
|
||||
Slot.VSplitMid(&Label, &Selector);
|
||||
CUIRect No, Yes;
|
||||
Selector.VSplitMid(&No, &Yes);
|
||||
|
||||
pEditor->Ui()->DoLabel(&Label, "Auto map reload", 10.0f, TEXTALIGN_ML);
|
||||
|
||||
static int s_ButtonNo = 0;
|
||||
static int s_ButtonYes = 0;
|
||||
if(pEditor->DoButton_Ex(&s_ButtonNo, "No", !g_Config.m_EdAutoMapReload, &No, 0, "Do not run 'hot_reload' on the local server while rcon authed on map save", IGraphics::CORNER_L))
|
||||
{
|
||||
g_Config.m_EdAutoMapReload = false;
|
||||
}
|
||||
if(pEditor->DoButton_Ex(&s_ButtonYes, "Yes", g_Config.m_EdAutoMapReload, &Yes, 0, "Run 'hot_reload' on the local server while rcon authed on map save", IGraphics::CORNER_R))
|
||||
{
|
||||
g_Config.m_EdAutoMapReload = true;
|
||||
}
|
||||
}
|
||||
|
||||
return CUi::POPUP_KEEP_OPEN;
|
||||
}
|
||||
|
||||
|
@ -578,16 +594,9 @@ CUi::EPopupMenuFunctionResult CEditor::PopupGroup(void *pContext, CUIRect View,
|
|||
// new tile layer
|
||||
View.HSplitBottom(5.0f, &View, nullptr);
|
||||
View.HSplitBottom(12.0f, &View, &Button);
|
||||
static int s_NewTileLayerButton = 0;
|
||||
if(pEditor->DoButton_Editor(&s_NewTileLayerButton, "Add tile layer", 0, &Button, 0, "Creates a new tile layer"))
|
||||
if(pEditor->DoButton_Editor(&pEditor->m_QuickActionAddTileLayer, pEditor->m_QuickActionAddTileLayer.Label(), 0, &Button, 0, pEditor->m_QuickActionAddTileLayer.Description()))
|
||||
{
|
||||
std::shared_ptr<CLayer> pTileLayer = std::make_shared<CLayerTiles>(pEditor, pEditor->m_Map.m_pGameLayer->m_Width, pEditor->m_Map.m_pGameLayer->m_Height);
|
||||
pTileLayer->m_pEditor = pEditor;
|
||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->AddLayer(pTileLayer);
|
||||
int LayerIndex = pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_vpLayers.size() - 1;
|
||||
pEditor->SelectLayer(LayerIndex);
|
||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_Collapse = false;
|
||||
pEditor->m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(pEditor, pEditor->m_SelectedGroup, LayerIndex));
|
||||
pEditor->m_QuickActionAddTileLayer.Call();
|
||||
return CUi::POPUP_CLOSE_CURRENT;
|
||||
}
|
||||
|
||||
|
|
172
src/game/editor/prompt.cpp
Normal file
172
src/game/editor/prompt.cpp
Normal file
|
@ -0,0 +1,172 @@
|
|||
#include <engine/keys.h>
|
||||
#include <game/client/ui_listbox.h>
|
||||
#include <game/editor/quick_action.h>
|
||||
|
||||
#include "editor.h"
|
||||
|
||||
#include "prompt.h"
|
||||
|
||||
bool FuzzyMatch(const char *pHaystack, const char *pNeedle)
|
||||
{
|
||||
if(!pNeedle || !pNeedle[0])
|
||||
return false;
|
||||
char aBuf[2] = {0};
|
||||
const char *pHit = pHaystack;
|
||||
int NeedleLen = str_length(pNeedle);
|
||||
for(int i = 0; i < NeedleLen; i++)
|
||||
{
|
||||
if(!pHit)
|
||||
return false;
|
||||
aBuf[0] = pNeedle[i];
|
||||
pHit = str_find_nocase(pHit, aBuf);
|
||||
if(pHit)
|
||||
pHit++;
|
||||
}
|
||||
return pHit;
|
||||
}
|
||||
|
||||
bool CPrompt::IsActive()
|
||||
{
|
||||
return CEditorComponent::IsActive() || Editor()->m_Dialog == DIALOG_QUICK_PROMPT;
|
||||
}
|
||||
|
||||
void CPrompt::SetActive()
|
||||
{
|
||||
Editor()->m_Dialog = DIALOG_QUICK_PROMPT;
|
||||
CEditorComponent::SetActive();
|
||||
|
||||
Ui()->SetActiveItem(&m_PromptInput);
|
||||
}
|
||||
|
||||
void CPrompt::SetInactive()
|
||||
{
|
||||
m_ResetFilterResults = true;
|
||||
m_PromptInput.Clear();
|
||||
if(Editor()->m_Dialog == DIALOG_QUICK_PROMPT)
|
||||
Editor()->m_Dialog = DIALOG_NONE;
|
||||
CEditorComponent::SetInactive();
|
||||
}
|
||||
|
||||
bool CPrompt::OnInput(const IInput::CEvent &Event)
|
||||
{
|
||||
if(Input()->ModifierIsPressed() && Input()->KeyIsPressed(KEY_P))
|
||||
{
|
||||
SetActive();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPrompt::OnInit(CEditor *pEditor)
|
||||
{
|
||||
CEditorComponent::OnInit(pEditor);
|
||||
|
||||
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) m_vQuickActions.emplace_back(&Editor()->m_QuickAction##name);
|
||||
#include <game/editor/quick_actions.h>
|
||||
#undef REGISTER_QUICK_ACTION
|
||||
}
|
||||
|
||||
void CPrompt::OnRender(CUIRect _)
|
||||
{
|
||||
if(!IsActive())
|
||||
return;
|
||||
|
||||
if(Ui()->ConsumeHotkey(CUi::HOTKEY_ESCAPE))
|
||||
{
|
||||
SetInactive();
|
||||
return;
|
||||
}
|
||||
|
||||
static CListBox s_ListBox;
|
||||
CUIRect Prompt, PromptBox;
|
||||
CUIRect Suggestions;
|
||||
|
||||
Ui()->MapScreen();
|
||||
CUIRect Overlay = *Ui()->Screen();
|
||||
|
||||
Overlay.Draw(ColorRGBA(0, 0, 0, 0.33f), IGraphics::CORNER_NONE, 0.0f);
|
||||
CUIRect Background;
|
||||
Overlay.VMargin(150.0f, &Background);
|
||||
Background.HMargin(50.0f, &Background);
|
||||
Background.Draw(ColorRGBA(0, 0, 0, 0.80f), IGraphics::CORNER_ALL, 5.0f);
|
||||
|
||||
Background.Margin(10.0f, &Prompt);
|
||||
|
||||
Prompt.VSplitMid(nullptr, &PromptBox);
|
||||
|
||||
Prompt.HSplitTop(16.0f, &PromptBox, &Suggestions);
|
||||
PromptBox.Draw(ColorRGBA(0, 0, 0, 0.75f), IGraphics::CORNER_ALL, 2.0f);
|
||||
Suggestions.y += 6.0f;
|
||||
|
||||
if(Ui()->DoClearableEditBox(&m_PromptInput, &PromptBox, 10.0f) || m_ResetFilterResults)
|
||||
{
|
||||
m_PromptSelectedIndex = 0;
|
||||
m_vpFilteredPromptList.clear();
|
||||
if(m_ResetFilterResults && m_pLastAction && !m_pLastAction->Disabled())
|
||||
{
|
||||
m_vpFilteredPromptList.push_back(m_pLastAction);
|
||||
}
|
||||
for(auto *pQuickAction : m_vQuickActions)
|
||||
{
|
||||
if(pQuickAction->Disabled())
|
||||
continue;
|
||||
|
||||
if(m_PromptInput.IsEmpty() || FuzzyMatch(pQuickAction->Label(), m_PromptInput.GetString()))
|
||||
{
|
||||
bool Skip = false;
|
||||
if(m_ResetFilterResults)
|
||||
if(pQuickAction == m_pLastAction)
|
||||
Skip = true;
|
||||
if(!Skip)
|
||||
m_vpFilteredPromptList.push_back(pQuickAction);
|
||||
}
|
||||
}
|
||||
m_ResetFilterResults = false;
|
||||
}
|
||||
|
||||
s_ListBox.SetActive(!Ui()->IsPopupOpen());
|
||||
s_ListBox.DoStart(15.0f, m_vpFilteredPromptList.size(), 1, 5, m_PromptSelectedIndex, &Suggestions, false);
|
||||
|
||||
float LabelWidth = Overlay.w > 855.0f ? 200.0f : 100.0f;
|
||||
|
||||
for(size_t i = 0; i < m_vpFilteredPromptList.size(); i++)
|
||||
{
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(m_vpFilteredPromptList[i], m_PromptSelectedIndex >= 0 && (size_t)m_PromptSelectedIndex == i);
|
||||
if(!Item.m_Visible)
|
||||
continue;
|
||||
|
||||
CUIRect LabelColumn, DescColumn;
|
||||
float Margin = 5.0f;
|
||||
Item.m_Rect.VSplitLeft(Margin, nullptr, &LabelColumn);
|
||||
LabelColumn.VSplitLeft(LabelWidth, &LabelColumn, &DescColumn);
|
||||
DescColumn.VSplitRight(Margin, &DescColumn, nullptr);
|
||||
|
||||
SLabelProperties Props;
|
||||
Props.m_MaxWidth = LabelColumn.w;
|
||||
Props.m_EllipsisAtEnd = true;
|
||||
Ui()->DoLabel(&LabelColumn, m_vpFilteredPromptList[i]->Label(), 10.0f, TEXTALIGN_ML, Props);
|
||||
|
||||
Props.m_MaxWidth = DescColumn.w;
|
||||
ColorRGBA DescColor = TextRender()->DefaultTextColor();
|
||||
DescColor.a = Item.m_Selected ? 1.0f : 0.8f;
|
||||
TextRender()->TextColor(DescColor);
|
||||
Ui()->DoLabel(&DescColumn, m_vpFilteredPromptList[i]->Description(), 10.0f, TEXTALIGN_MR, Props);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
}
|
||||
|
||||
const int NewSelected = s_ListBox.DoEnd();
|
||||
if(m_PromptSelectedIndex != NewSelected)
|
||||
{
|
||||
m_PromptSelectedIndex = NewSelected;
|
||||
}
|
||||
|
||||
if(s_ListBox.WasItemActivated())
|
||||
{
|
||||
if(m_PromptSelectedIndex >= 0)
|
||||
{
|
||||
CQuickAction *pBtn = m_vpFilteredPromptList[m_PromptSelectedIndex];
|
||||
SetInactive();
|
||||
pBtn->Call();
|
||||
m_pLastAction = pBtn;
|
||||
}
|
||||
}
|
||||
}
|
29
src/game/editor/prompt.h
Normal file
29
src/game/editor/prompt.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef GAME_EDITOR_PROMPT_H
|
||||
#define GAME_EDITOR_PROMPT_H
|
||||
|
||||
#include <game/client/lineinput.h>
|
||||
#include <game/client/ui_rect.h>
|
||||
#include <game/editor/quick_action.h>
|
||||
|
||||
#include "component.h"
|
||||
|
||||
class CPrompt : public CEditorComponent
|
||||
{
|
||||
bool m_ResetFilterResults = true;
|
||||
CQuickAction *m_pLastAction = nullptr;
|
||||
int m_PromptSelectedIndex = -1;
|
||||
|
||||
std::vector<CQuickAction *> m_vpFilteredPromptList;
|
||||
std::vector<CQuickAction *> m_vQuickActions;
|
||||
CLineInputBuffered<512> m_PromptInput;
|
||||
|
||||
public:
|
||||
void OnInit(CEditor *pEditor) override;
|
||||
bool OnInput(const IInput::CEvent &Event) override;
|
||||
void OnRender(CUIRect _) override;
|
||||
bool IsActive();
|
||||
void SetActive();
|
||||
void SetInactive();
|
||||
};
|
||||
|
||||
#endif
|
69
src/game/editor/quick_action.h
Normal file
69
src/game/editor/quick_action.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef GAME_EDITOR_QUICK_ACTION_H
|
||||
#define GAME_EDITOR_QUICK_ACTION_H
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
typedef std::function<void()> FButtonClickCallback;
|
||||
typedef std::function<bool()> FButtonDisabledCallback;
|
||||
typedef std::function<bool()> FButtonActiveCallback;
|
||||
typedef std::function<int()> FButtonColorCallback;
|
||||
|
||||
class CQuickAction
|
||||
{
|
||||
private:
|
||||
const char *m_pLabel;
|
||||
const char *m_pDescription;
|
||||
|
||||
FButtonClickCallback m_pfnCallback;
|
||||
FButtonDisabledCallback m_pfnDisabledCallback;
|
||||
FButtonActiveCallback m_pfnActiveCallback;
|
||||
FButtonColorCallback m_pfnColorCallback;
|
||||
|
||||
public:
|
||||
CQuickAction(
|
||||
const char *pLabel,
|
||||
const char *pDescription,
|
||||
FButtonClickCallback pfnCallback,
|
||||
FButtonDisabledCallback pfnDisabledCallback,
|
||||
FButtonActiveCallback pfnActiveCallback,
|
||||
FButtonColorCallback pfnColorCallback) :
|
||||
m_pLabel(pLabel),
|
||||
m_pDescription(pDescription),
|
||||
m_pfnCallback(std::move(pfnCallback)),
|
||||
m_pfnDisabledCallback(std::move(pfnDisabledCallback)),
|
||||
m_pfnActiveCallback(std::move(pfnActiveCallback)),
|
||||
m_pfnColorCallback(std::move(pfnColorCallback))
|
||||
{
|
||||
}
|
||||
|
||||
// code to run when the action is triggered
|
||||
void Call() const { m_pfnCallback(); }
|
||||
|
||||
// bool that indicates if the action can be performed not or not
|
||||
bool Disabled() { return m_pfnDisabledCallback(); }
|
||||
|
||||
// bool that indicates if the action is currently running
|
||||
// only applies to actions that can be turned on or off like proof borders
|
||||
bool Active() { return m_pfnActiveCallback(); }
|
||||
|
||||
// color "enum" that represents the state of the quick actions button
|
||||
// used as Checked argument for DoButton_Editor()
|
||||
int Color() { return m_pfnColorCallback(); }
|
||||
|
||||
const char *Label() const { return m_pLabel; }
|
||||
|
||||
// skips to the part of the label after the first colon
|
||||
// useful for buttons that only show the state
|
||||
const char *LabelShort() const
|
||||
{
|
||||
const char *pShort = str_find(m_pLabel, ": ");
|
||||
if(!pShort)
|
||||
return m_pLabel;
|
||||
return pShort + 2;
|
||||
}
|
||||
|
||||
const char *Description() const { return m_pDescription; }
|
||||
};
|
||||
|
||||
#endif
|
71
src/game/editor/quick_actions.cpp
Normal file
71
src/game/editor/quick_actions.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include <game/mapitems.h>
|
||||
|
||||
#include "editor.h"
|
||||
|
||||
#include "editor_actions.h"
|
||||
|
||||
void CEditor::FillGameTiles(EGameTileOp FillTile) const
|
||||
{
|
||||
std::shared_ptr<CLayerTiles> pTileLayer = std::static_pointer_cast<CLayerTiles>(GetSelectedLayerType(0, LAYERTYPE_TILES));
|
||||
if(pTileLayer)
|
||||
pTileLayer->FillGameTiles(FillTile);
|
||||
}
|
||||
|
||||
bool CEditor::CanFillGameTiles() const
|
||||
{
|
||||
std::shared_ptr<CLayerTiles> pTileLayer = std::static_pointer_cast<CLayerTiles>(GetSelectedLayerType(0, LAYERTYPE_TILES));
|
||||
if(pTileLayer)
|
||||
return pTileLayer->CanFillGameTiles();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CEditor::AddGroup()
|
||||
{
|
||||
m_Map.NewGroup();
|
||||
m_SelectedGroup = m_Map.m_vpGroups.size() - 1;
|
||||
m_EditorHistory.RecordAction(std::make_shared<CEditorActionGroup>(this, m_SelectedGroup, false));
|
||||
}
|
||||
|
||||
void CEditor::AddTileLayer()
|
||||
{
|
||||
std::shared_ptr<CLayer> pTileLayer = std::make_shared<CLayerTiles>(this, m_Map.m_pGameLayer->m_Width, m_Map.m_pGameLayer->m_Height);
|
||||
pTileLayer->m_pEditor = this;
|
||||
m_Map.m_vpGroups[m_SelectedGroup]->AddLayer(pTileLayer);
|
||||
int LayerIndex = m_Map.m_vpGroups[m_SelectedGroup]->m_vpLayers.size() - 1;
|
||||
SelectLayer(LayerIndex);
|
||||
m_Map.m_vpGroups[m_SelectedGroup]->m_Collapse = false;
|
||||
m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(this, m_SelectedGroup, LayerIndex));
|
||||
}
|
||||
|
||||
bool CEditor::IsNonGameTileLayerSelected() const
|
||||
{
|
||||
std::shared_ptr<CLayer> pLayer = GetSelectedLayer(0);
|
||||
if(!pLayer)
|
||||
return false;
|
||||
if(pLayer->m_Type != LAYERTYPE_TILES)
|
||||
return false;
|
||||
if(
|
||||
pLayer == m_Map.m_pGameLayer ||
|
||||
pLayer == m_Map.m_pFrontLayer ||
|
||||
pLayer == m_Map.m_pSwitchLayer ||
|
||||
pLayer == m_Map.m_pTeleLayer ||
|
||||
pLayer == m_Map.m_pSpeedupLayer ||
|
||||
pLayer == m_Map.m_pTuneLayer)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CEditor::LayerSelectImage()
|
||||
{
|
||||
if(!IsNonGameTileLayerSelected())
|
||||
return;
|
||||
|
||||
std::shared_ptr<CLayer> pLayer = GetSelectedLayer(0);
|
||||
std::shared_ptr<CLayerTiles> pTiles = std::static_pointer_cast<CLayerTiles>(pLayer);
|
||||
|
||||
static SLayerPopupContext s_LayerPopupContext = {};
|
||||
s_LayerPopupContext.m_pEditor = this;
|
||||
Ui()->DoPopupMenu(&s_LayerPopupContext, Ui()->MouseX(), Ui()->MouseY(), 120, 270, &s_LayerPopupContext, PopupLayer);
|
||||
PopupSelectImageInvoke(pTiles->m_Image, Ui()->MouseX(), Ui()->MouseY());
|
||||
}
|
281
src/game/editor/quick_actions.h
Normal file
281
src/game/editor/quick_actions.h
Normal file
|
@ -0,0 +1,281 @@
|
|||
// This file can be included several times.
|
||||
|
||||
#ifndef REGISTER_QUICK_ACTION
|
||||
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description)
|
||||
#endif
|
||||
|
||||
#define ALWAYS_FALSE []() -> bool { return false; }
|
||||
#define DEFAULT_BTN []() -> int { return -1; }
|
||||
|
||||
REGISTER_QUICK_ACTION(
|
||||
ToggleGrid,
|
||||
"Toggle Grid",
|
||||
[&]() { MapView()->MapGrid()->Toggle(); },
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> bool { return MapView()->MapGrid()->IsEnabled(); },
|
||||
DEFAULT_BTN,
|
||||
"[Ctrl+G] Toggle Grid.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesAir,
|
||||
"Game tiles: Air",
|
||||
[&]() { FillGameTiles(EGameTileOp::AIR); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesHookable,
|
||||
"Game tiles: Hookable",
|
||||
[&]() { FillGameTiles(EGameTileOp::HOOKABLE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesDeath,
|
||||
"Game tiles: Death",
|
||||
[&]() { FillGameTiles(EGameTileOp::DEATH); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesUnhookable,
|
||||
"Game tiles: Unhookable",
|
||||
[&]() { FillGameTiles(EGameTileOp::UNHOOKABLE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesHookthrough,
|
||||
"Game tiles: Hookthrough",
|
||||
[&]() { FillGameTiles(EGameTileOp::HOOKTHROUGH); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesFreeze,
|
||||
"Game tiles: Freeze",
|
||||
[&]() { FillGameTiles(EGameTileOp::FREEZE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesUnfreeze,
|
||||
"Game tiles: Unfreeze",
|
||||
[&]() { FillGameTiles(EGameTileOp::UNFREEZE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesDeepFreeze,
|
||||
"Game tiles: Deep Freeze",
|
||||
[&]() { FillGameTiles(EGameTileOp::DEEP_FREEZE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesDeepUnfreeze,
|
||||
"Game tiles: Deep Unfreeze",
|
||||
[&]() { FillGameTiles(EGameTileOp::DEEP_UNFREEZE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesBlueCheckTele,
|
||||
"Game tiles: Blue Check Tele",
|
||||
[&]() { FillGameTiles(EGameTileOp::BLUE_CHECK_TELE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesRedCheckTele,
|
||||
"Game tiles: Red Check Tele",
|
||||
[&]() { FillGameTiles(EGameTileOp::RED_CHECK_TELE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesLiveFreeze,
|
||||
"Game tiles: Live Freeze",
|
||||
[&]() { FillGameTiles(EGameTileOp::LIVE_FREEZE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
GameTilesLiveUnfreeze,
|
||||
"Game tiles: Live Unfreeze",
|
||||
[&]() { FillGameTiles(EGameTileOp::LIVE_UNFREEZE); },
|
||||
[&]() -> bool { return !CanFillGameTiles(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Constructs game tiles from this layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
AddGroup,
|
||||
"Add group",
|
||||
[&]() { AddGroup(); },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Adds a new group.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
ResetZoom,
|
||||
"Reset Zoom",
|
||||
[&]() { MapView()->ResetZoom(); },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"[Numpad*] Zoom to normal and remove editor offset.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
ZoomOut,
|
||||
"Zoom Out",
|
||||
[&]() { MapView()->Zoom()->ChangeValue(50.0f); },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"[Numpad-] Zoom out.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
ZoomIn,
|
||||
"Zoom In",
|
||||
[&]() { MapView()->Zoom()->ChangeValue(-50.0f); },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"[Numpad+] Zoom in.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
Refocus,
|
||||
"Refocus",
|
||||
[&]() { MapView()->Focus(); },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"[Home] Restore map focus.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
Proof,
|
||||
"Proof",
|
||||
[&]() { MapView()->ProofMode()->Toggle(); },
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> bool { return MapView()->ProofMode()->IsEnabled(); },
|
||||
DEFAULT_BTN,
|
||||
"Toggles proof borders. These borders represent the area that a player can see with default zoom.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
AddTileLayer, "Add tile layer", [&]() { AddTileLayer(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Creates a new tile layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
SaveAs,
|
||||
"Save As",
|
||||
[&]() { InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save As", "maps", true, CEditor::CallbackSaveMap, this); },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"[Ctrl+Shift+S] Saves the current map under a new name.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
LoadCurrentMap,
|
||||
"Load Current Map",
|
||||
[&]() {
|
||||
if(HasUnsavedData())
|
||||
{
|
||||
m_PopupEventType = POPEVENT_LOADCURRENT;
|
||||
m_PopupEventActivated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadCurrentMap();
|
||||
}
|
||||
},
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"[Ctrl+Alt+L] Opens the current in game map for editing.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
Envelopes,
|
||||
"Envelopes",
|
||||
[&]() { m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES ? EXTRAEDITOR_NONE : EXTRAEDITOR_ENVELOPES; },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> int { return m_ShowPicker ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES; },
|
||||
"Toggles the envelope editor.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
ServerSettings,
|
||||
"Server settings",
|
||||
[&]() { m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_SERVER_SETTINGS ? EXTRAEDITOR_NONE : EXTRAEDITOR_SERVER_SETTINGS; },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> int { return m_ShowPicker ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_SERVER_SETTINGS; },
|
||||
"Toggles the server settings editor.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
History,
|
||||
"History",
|
||||
[&]() { m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_HISTORY ? EXTRAEDITOR_NONE : EXTRAEDITOR_HISTORY; },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> int { return m_ShowPicker ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_HISTORY; },
|
||||
"Toggles the editor history view.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
AddImage,
|
||||
"Add Image",
|
||||
[&]() { InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Add Image", "Add", "mapres", false, AddImage, this); },
|
||||
ALWAYS_FALSE,
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Load a new image to use in the map.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
LayerPropAddImage,
|
||||
"Layer: Add Image",
|
||||
[&]() { LayerSelectImage(); },
|
||||
[&]() -> bool { return !IsNonGameTileLayerSelected(); },
|
||||
ALWAYS_FALSE,
|
||||
DEFAULT_BTN,
|
||||
"Pick mapres image for currently selected layer.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
ShowInfoOff,
|
||||
"Show Info: Off",
|
||||
[&]() {
|
||||
m_ShowTileInfo = SHOW_TILE_OFF;
|
||||
m_ShowEnvelopePreview = SHOWENV_NONE;
|
||||
},
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> bool { return m_ShowTileInfo == SHOW_TILE_OFF; },
|
||||
DEFAULT_BTN,
|
||||
"Do not show tile information.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
ShowInfoDec,
|
||||
"Show Info: Dec",
|
||||
[&]() {
|
||||
m_ShowTileInfo = SHOW_TILE_DECIMAL;
|
||||
m_ShowEnvelopePreview = SHOWENV_NONE;
|
||||
},
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> bool { return m_ShowTileInfo == SHOW_TILE_DECIMAL; },
|
||||
DEFAULT_BTN,
|
||||
"[Ctrl+I] Show tile information.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
ShowInfoHex,
|
||||
"Show Info: Hex",
|
||||
[&]() {
|
||||
m_ShowTileInfo = SHOW_TILE_HEXADECIMAL;
|
||||
m_ShowEnvelopePreview = SHOWENV_NONE;
|
||||
},
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> bool { return m_ShowTileInfo == SHOW_TILE_HEXADECIMAL; },
|
||||
DEFAULT_BTN,
|
||||
"[Ctrl+Shift+I] Show tile information in hexadecimal.")
|
||||
REGISTER_QUICK_ACTION(
|
||||
Pipette,
|
||||
"Pipette",
|
||||
[&]() { m_ColorPipetteActive = !m_ColorPipetteActive; },
|
||||
ALWAYS_FALSE,
|
||||
[&]() -> bool { return m_ColorPipetteActive; },
|
||||
DEFAULT_BTN,
|
||||
"[Ctrl+Shift+C] Color pipette. Pick a color from the screen by clicking on it.")
|
||||
|
||||
#undef ALWAYS_FALSE
|
||||
#undef DEFAULT_BTN
|
|
@ -565,7 +565,7 @@ void CGameContext::ConMapInfo(IConsole::IResult *pResult, void *pUserData)
|
|||
if(pResult->NumArguments() > 0)
|
||||
pSelf->Score()->MapInfo(pResult->m_ClientId, pResult->GetString(0));
|
||||
else
|
||||
pSelf->Score()->MapInfo(pResult->m_ClientId, g_Config.m_SvMap);
|
||||
pSelf->Score()->MapInfo(pResult->m_ClientId, pSelf->Server()->GetMapName());
|
||||
}
|
||||
|
||||
void CGameContext::ConTimeout(IConsole::IResult *pResult, void *pUserData)
|
||||
|
|
|
@ -103,6 +103,35 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
|
|||
TrySetRescue(RESCUEMODE_MANUAL);
|
||||
Server()->StartRecord(m_pPlayer->GetCid());
|
||||
|
||||
int Team = GameServer()->m_aTeamMapping[m_pPlayer->GetCid()];
|
||||
|
||||
if(Team != -1)
|
||||
{
|
||||
GameServer()->m_pController->Teams().SetForceCharacterTeam(m_pPlayer->GetCid(), Team);
|
||||
GameServer()->m_aTeamMapping[m_pPlayer->GetCid()] = -1;
|
||||
|
||||
if(GameServer()->m_apSavedTeams[Team])
|
||||
{
|
||||
GameServer()->m_apSavedTeams[Team]->Load(GameServer(), Team, true, true);
|
||||
delete GameServer()->m_apSavedTeams[Team];
|
||||
GameServer()->m_apSavedTeams[Team] = nullptr;
|
||||
}
|
||||
|
||||
if(GameServer()->m_apSavedTees[m_pPlayer->GetCid()])
|
||||
{
|
||||
GameServer()->m_apSavedTees[m_pPlayer->GetCid()]->Load(m_pPlayer->GetCharacter(), Team);
|
||||
delete GameServer()->m_apSavedTees[m_pPlayer->GetCid()];
|
||||
GameServer()->m_apSavedTees[m_pPlayer->GetCid()] = nullptr;
|
||||
}
|
||||
|
||||
if(GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()])
|
||||
{
|
||||
m_pPlayer->m_LastTeleTee = *GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()];
|
||||
delete GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()];
|
||||
GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -212,11 +241,7 @@ void CCharacter::HandleJetpack()
|
|||
{
|
||||
if(m_Core.m_Jetpack)
|
||||
{
|
||||
float Strength;
|
||||
if(!m_TuneZone)
|
||||
Strength = Tuning()->m_JetpackStrength;
|
||||
else
|
||||
Strength = TuningList()[m_TuneZone].m_JetpackStrength;
|
||||
float Strength = GetTuning(m_TuneZone)->m_JetpackStrength;
|
||||
TakeDamage(Direction * -1.0f * (Strength / 100.0f / 6.11f), 0, m_pPlayer->GetCid(), m_Core.m_ActiveWeapon);
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +267,7 @@ void CCharacter::HandleNinja()
|
|||
GameServer()->CreateDamageInd(m_Pos, 0, NinjaTime / Server()->TickSpeed(), TeamMask() & GameServer()->ClientsMaskExcludeClientVersionAndHigher(VERSION_DDNET_NEW_HUD));
|
||||
}
|
||||
|
||||
m_Armor = clamp(10 - (NinjaTime / 15), 0, 10);
|
||||
GameServer()->m_pController->SetArmorProgress(this, NinjaTime);
|
||||
|
||||
// force ninja Weapon
|
||||
SetWeapon(WEAPON_NINJA);
|
||||
|
@ -260,12 +285,9 @@ void CCharacter::HandleNinja()
|
|||
// Set velocity
|
||||
m_Core.m_Vel = m_Core.m_Ninja.m_ActivationDir * g_pData->m_Weapons.m_Ninja.m_Velocity;
|
||||
vec2 OldPos = m_Pos;
|
||||
vec2 GroundElasticity;
|
||||
|
||||
if(!m_TuneZone)
|
||||
GroundElasticity = vec2(Tuning()->m_GroundElasticityX, Tuning()->m_GroundElasticityY);
|
||||
else
|
||||
GroundElasticity = vec2(TuningList()[m_TuneZone].m_GroundElasticityX, TuningList()[m_TuneZone].m_GroundElasticityY);
|
||||
vec2 GroundElasticity = vec2(
|
||||
GetTuning(m_TuneZone)->m_GroundElasticityX,
|
||||
GetTuning(m_TuneZone)->m_GroundElasticityY);
|
||||
|
||||
Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(GetProximityRadius(), GetProximityRadius()), GroundElasticity);
|
||||
|
||||
|
@ -427,7 +449,7 @@ void CCharacter::FireWeapon()
|
|||
if(m_PainSoundTimer <= 0 && !(m_LatestPrevInput.m_Fire & 1))
|
||||
{
|
||||
m_PainSoundTimer = 1 * Server()->TickSpeed();
|
||||
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG, TeamMask());
|
||||
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -444,7 +466,7 @@ void CCharacter::FireWeapon()
|
|||
{
|
||||
// reset objects Hit
|
||||
m_NumObjectsHit = 0;
|
||||
GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE, TeamMask());
|
||||
GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
|
||||
Antibot()->OnHammerFire(m_pPlayer->GetCid());
|
||||
|
||||
|
@ -476,11 +498,7 @@ void CCharacter::FireWeapon()
|
|||
else
|
||||
Dir = vec2(0.f, -1.f);
|
||||
|
||||
float Strength;
|
||||
if(!m_TuneZone)
|
||||
Strength = Tuning()->m_HammerStrength;
|
||||
else
|
||||
Strength = TuningList()[m_TuneZone].m_HammerStrength;
|
||||
float Strength = GetTuning(m_TuneZone)->m_HammerStrength;
|
||||
|
||||
vec2 Temp = pTarget->m_Core.m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f;
|
||||
Temp = ClampVel(pTarget->m_MoveRestrictions, Temp);
|
||||
|
@ -500,11 +518,7 @@ void CCharacter::FireWeapon()
|
|||
// if we Hit anything, we have to wait for the reload
|
||||
if(Hits)
|
||||
{
|
||||
float FireDelay;
|
||||
if(!m_TuneZone)
|
||||
FireDelay = Tuning()->m_HammerHitFireDelay;
|
||||
else
|
||||
FireDelay = TuningList()[m_TuneZone].m_HammerHitFireDelay;
|
||||
float FireDelay = GetTuning(m_TuneZone)->m_HammerHitFireDelay;
|
||||
m_ReloadTimer = FireDelay * Server()->TickSpeed() / 1000;
|
||||
}
|
||||
}
|
||||
|
@ -514,11 +528,7 @@ void CCharacter::FireWeapon()
|
|||
{
|
||||
if(!m_Core.m_Jetpack || !m_pPlayer->m_NinjaJetpack || m_Core.m_HasTelegunGun)
|
||||
{
|
||||
int Lifetime;
|
||||
if(!m_TuneZone)
|
||||
Lifetime = (int)(Server()->TickSpeed() * Tuning()->m_GunLifetime);
|
||||
else
|
||||
Lifetime = (int)(Server()->TickSpeed() * TuningList()[m_TuneZone].m_GunLifetime);
|
||||
int Lifetime = (int)(Server()->TickSpeed() * GetTuning(m_TuneZone)->m_GunLifetime);
|
||||
|
||||
new CProjectile(
|
||||
GameWorld(),
|
||||
|
@ -540,11 +550,7 @@ void CCharacter::FireWeapon()
|
|||
|
||||
case WEAPON_SHOTGUN:
|
||||
{
|
||||
float LaserReach;
|
||||
if(!m_TuneZone)
|
||||
LaserReach = Tuning()->m_LaserReach;
|
||||
else
|
||||
LaserReach = TuningList()[m_TuneZone].m_LaserReach;
|
||||
float LaserReach = GetTuning(m_TuneZone)->m_LaserReach;
|
||||
|
||||
new CLaser(&GameServer()->m_World, m_Pos, Direction, LaserReach, m_pPlayer->GetCid(), WEAPON_SHOTGUN);
|
||||
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
|
@ -553,11 +559,7 @@ void CCharacter::FireWeapon()
|
|||
|
||||
case WEAPON_GRENADE:
|
||||
{
|
||||
int Lifetime;
|
||||
if(!m_TuneZone)
|
||||
Lifetime = (int)(Server()->TickSpeed() * Tuning()->m_GrenadeLifetime);
|
||||
else
|
||||
Lifetime = (int)(Server()->TickSpeed() * TuningList()[m_TuneZone].m_GrenadeLifetime);
|
||||
int Lifetime = (int)(Server()->TickSpeed() * GetTuning(m_TuneZone)->m_GrenadeLifetime);
|
||||
|
||||
new CProjectile(
|
||||
GameWorld(),
|
||||
|
@ -572,17 +574,13 @@ void CCharacter::FireWeapon()
|
|||
MouseTarget // MouseTarget
|
||||
);
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE, TeamMask());
|
||||
GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
}
|
||||
break;
|
||||
|
||||
case WEAPON_LASER:
|
||||
{
|
||||
float LaserReach;
|
||||
if(!m_TuneZone)
|
||||
LaserReach = Tuning()->m_LaserReach;
|
||||
else
|
||||
LaserReach = TuningList()[m_TuneZone].m_LaserReach;
|
||||
float LaserReach = GetTuning(m_TuneZone)->m_LaserReach;
|
||||
|
||||
new CLaser(GameWorld(), m_Pos, Direction, LaserReach, m_pPlayer->GetCid(), WEAPON_LASER);
|
||||
GameServer()->CreateSound(m_Pos, SOUND_LASER_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
|
@ -598,7 +596,7 @@ void CCharacter::FireWeapon()
|
|||
m_Core.m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
|
||||
m_Core.m_Ninja.m_OldVelAmount = length(m_Core.m_Vel);
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE, TeamMask());
|
||||
GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -608,10 +606,7 @@ void CCharacter::FireWeapon()
|
|||
if(!m_ReloadTimer)
|
||||
{
|
||||
float FireDelay;
|
||||
if(!m_TuneZone)
|
||||
Tuning()->Get(38 + m_Core.m_ActiveWeapon, &FireDelay);
|
||||
else
|
||||
TuningList()[m_TuneZone].Get(38 + m_Core.m_ActiveWeapon, &FireDelay);
|
||||
GetTuning(m_TuneZone)->Get(38 + m_Core.m_ActiveWeapon, &FireDelay);
|
||||
m_ReloadTimer = FireDelay * Server()->TickSpeed() / 1000;
|
||||
}
|
||||
}
|
||||
|
@ -2067,7 +2062,7 @@ void CCharacter::ForceSetRescue(int RescueMode)
|
|||
void CCharacter::DDRaceTick()
|
||||
{
|
||||
mem_copy(&m_Input, &m_SavedInput, sizeof(m_Input));
|
||||
m_Armor = clamp(10 - (m_FreezeTime / 15), 0, 10);
|
||||
GameServer()->m_pController->SetArmorProgress(this, m_FreezeTime);
|
||||
if(m_Input.m_Direction != 0 || m_Input.m_Jump != 0)
|
||||
m_LastMove = Server()->Tick();
|
||||
|
||||
|
|
|
@ -263,6 +263,7 @@ public:
|
|||
bool IsSuper() const { return m_Core.m_Super; }
|
||||
|
||||
CSaveTee &GetLastRescueTeeRef(int Mode = RESCUEMODE_AUTO) { return m_RescueTee[Mode]; }
|
||||
CTuningParams *GetTuning(int Zone) { return Zone ? &TuningList()[Zone] : Tuning(); }
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -94,6 +94,7 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
|
|||
{
|
||||
pHit->UnFreeze();
|
||||
}
|
||||
pHit->TakeDamage(vec2(0, 0), 0, m_Owner, m_Type);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,8 @@ void CProjectile::Tick()
|
|||
pChr->Freeze();
|
||||
}
|
||||
}
|
||||
else if(pTargetChr)
|
||||
pTargetChr->TakeDamage(vec2(0, 0), 0, m_Owner, m_Type);
|
||||
|
||||
if(pOwnerChar && !GameLayerClipped(ColPos) &&
|
||||
((m_Type == WEAPON_GRENADE && pOwnerChar->HasTelegunGrenade()) || (m_Type == WEAPON_GUN && pOwnerChar->HasTelegunGun())))
|
||||
|
|
|
@ -105,6 +105,17 @@ void CGameContext::Construct(int Resetting)
|
|||
|
||||
if(Resetting == NO_RESET)
|
||||
{
|
||||
for(auto &pSavedTee : m_apSavedTees)
|
||||
pSavedTee = nullptr;
|
||||
|
||||
for(auto &pSavedTeleTee : m_apSavedTeleTees)
|
||||
pSavedTeleTee = nullptr;
|
||||
|
||||
for(auto &pSavedTeam : m_apSavedTeams)
|
||||
pSavedTeam = nullptr;
|
||||
|
||||
std::fill(std::begin(m_aTeamMapping), std::end(m_aTeamMapping), -1);
|
||||
|
||||
m_NonEmptySince = 0;
|
||||
m_pVoteOptionHeap = new CHeap();
|
||||
}
|
||||
|
@ -119,7 +130,18 @@ void CGameContext::Destruct(int Resetting)
|
|||
delete pPlayer;
|
||||
|
||||
if(Resetting == NO_RESET)
|
||||
{
|
||||
for(auto &pSavedTee : m_apSavedTees)
|
||||
delete pSavedTee;
|
||||
|
||||
for(auto &pSavedTeleTee : m_apSavedTeleTees)
|
||||
delete pSavedTeleTee;
|
||||
|
||||
for(auto &pSavedTeam : m_apSavedTeams)
|
||||
delete pSavedTeam;
|
||||
|
||||
delete m_pVoteOptionHeap;
|
||||
}
|
||||
|
||||
if(m_pScore)
|
||||
{
|
||||
|
@ -757,7 +779,6 @@ void CGameContext::StartVote(const char *pDesc, const char *pCommand, const char
|
|||
{
|
||||
// reset votes
|
||||
m_VoteEnforce = VOTE_ENFORCE_UNKNOWN;
|
||||
m_VoteEnforcer = -1;
|
||||
for(auto &pPlayer : m_apPlayers)
|
||||
{
|
||||
if(pPlayer)
|
||||
|
@ -1188,7 +1209,7 @@ void CGameContext::OnTick()
|
|||
}
|
||||
else if(m_VoteEnforce == VOTE_ENFORCE_YES_ADMIN)
|
||||
{
|
||||
Console()->ExecuteLine(m_aVoteCommand, m_VoteEnforcer);
|
||||
Console()->ExecuteLine(m_aVoteCommand, m_VoteCreator);
|
||||
SendChat(-1, TEAM_ALL, "Vote passed enforced by authorized player", -1, FLAG_SIX);
|
||||
EndVote();
|
||||
}
|
||||
|
@ -1261,7 +1282,7 @@ void CGameContext::OnTick()
|
|||
if(m_SqlRandomMapResult->m_Success)
|
||||
{
|
||||
if(PlayerExists(m_SqlRandomMapResult->m_ClientId) && m_SqlRandomMapResult->m_aMessage[0] != '\0')
|
||||
SendChatTarget(m_SqlRandomMapResult->m_ClientId, m_SqlRandomMapResult->m_aMessage);
|
||||
SendChat(-1, TEAM_ALL, m_SqlRandomMapResult->m_aMessage);
|
||||
if(m_SqlRandomMapResult->m_aMap[0] != '\0')
|
||||
Server()->ChangeMap(m_SqlRandomMapResult->m_aMap);
|
||||
else
|
||||
|
@ -1467,26 +1488,6 @@ void CGameContext::OnClientEnter(int ClientId)
|
|||
}
|
||||
m_pController->OnPlayerConnect(m_apPlayers[ClientId]);
|
||||
|
||||
if(Server()->IsSixup(ClientId))
|
||||
{
|
||||
{
|
||||
protocol7::CNetMsg_Sv_GameInfo Msg;
|
||||
Msg.m_GameFlags = protocol7::GAMEFLAG_RACE;
|
||||
Msg.m_MatchCurrent = 1;
|
||||
Msg.m_MatchNum = 0;
|
||||
Msg.m_ScoreLimit = 0;
|
||||
Msg.m_TimeLimit = 0;
|
||||
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_NORECORD, ClientId);
|
||||
}
|
||||
|
||||
// /team is essential
|
||||
{
|
||||
protocol7::CNetMsg_Sv_CommandInfoRemove Msg;
|
||||
Msg.m_pName = "team";
|
||||
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_NORECORD, ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CNetMsg_Sv_CommandInfoGroupStart Msg;
|
||||
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_NORECORD, ClientId);
|
||||
|
@ -1710,6 +1711,17 @@ void CGameContext::OnClientDrop(int ClientId, const char *pReason)
|
|||
delete m_apPlayers[ClientId];
|
||||
m_apPlayers[ClientId] = 0;
|
||||
|
||||
delete m_apSavedTeams[ClientId];
|
||||
m_apSavedTeams[ClientId] = nullptr;
|
||||
|
||||
delete m_apSavedTees[ClientId];
|
||||
m_apSavedTees[ClientId] = nullptr;
|
||||
|
||||
delete m_apSavedTeleTees[ClientId];
|
||||
m_apSavedTeleTees[ClientId] = nullptr;
|
||||
|
||||
m_aTeamMapping[ClientId] = -1;
|
||||
|
||||
m_VoteUpdate = true;
|
||||
|
||||
// update spectator modes
|
||||
|
@ -3116,6 +3128,8 @@ void CGameContext::ConRandomUnfinishedMap(IConsole::IResult *pResult, void *pUse
|
|||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
||||
int Stars = pResult->NumArguments() ? pResult->GetInteger(0) : -1;
|
||||
if(pResult->m_ClientId != -1)
|
||||
pSelf->m_VoteCreator = pResult->m_ClientId;
|
||||
|
||||
pSelf->m_pScore->RandomUnfinishedMap(pSelf->m_VoteCreator, Stars);
|
||||
}
|
||||
|
@ -3194,6 +3208,37 @@ void CGameContext::ConSetTeamAll(IConsole::IResult *pResult, void *pUserData)
|
|||
pSelf->m_pController->DoTeamChange(pPlayer, Team, false);
|
||||
}
|
||||
|
||||
void CGameContext::ConHotReload(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(!pSelf->GetPlayerChar(i))
|
||||
continue;
|
||||
|
||||
CCharacter *pChar = pSelf->GetPlayerChar(i);
|
||||
|
||||
// Save the tee individually
|
||||
pSelf->m_apSavedTees[i] = new CSaveTee();
|
||||
pSelf->m_apSavedTees[i]->Save(pChar, false);
|
||||
|
||||
if(pSelf->m_apPlayers[i])
|
||||
pSelf->m_apSavedTeleTees[i] = new CSaveTee(pSelf->m_apPlayers[i]->m_LastTeleTee);
|
||||
|
||||
// Save the team state
|
||||
pSelf->m_aTeamMapping[i] = pSelf->GetDDRaceTeam(i);
|
||||
if(pSelf->m_aTeamMapping[i] == TEAM_SUPER)
|
||||
pSelf->m_aTeamMapping[i] = pChar->m_TeamBeforeSuper;
|
||||
|
||||
if(pSelf->m_apSavedTeams[pSelf->m_aTeamMapping[i]])
|
||||
continue;
|
||||
|
||||
pSelf->m_apSavedTeams[pSelf->m_aTeamMapping[i]] = new CSaveTeam();
|
||||
pSelf->m_apSavedTeams[pSelf->m_aTeamMapping[i]]->Save(pSelf, pSelf->m_aTeamMapping[i], true, true);
|
||||
}
|
||||
pSelf->Server()->ReloadMap();
|
||||
}
|
||||
|
||||
void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
@ -3346,6 +3391,7 @@ void CGameContext::ConForceVote(IConsole::IResult *pResult, void *pUserData)
|
|||
{
|
||||
str_format(aBuf, sizeof(aBuf), "authorized player forced server option '%s' (%s)", pValue, pReason);
|
||||
pSelf->SendChatTarget(-1, aBuf, FLAG_SIX);
|
||||
pSelf->m_VoteCreator = pResult->m_ClientId;
|
||||
pSelf->Console()->ExecuteLine(pOption->m_aCommand);
|
||||
break;
|
||||
}
|
||||
|
@ -3420,8 +3466,18 @@ void CGameContext::ConClearVotes(IConsole::IResult *pResult, void *pUserData)
|
|||
struct CMapNameItem
|
||||
{
|
||||
char m_aName[IO_MAX_PATH_LENGTH - 4];
|
||||
bool m_IsDirectory;
|
||||
|
||||
bool operator<(const CMapNameItem &Other) const { return str_comp_nocase(m_aName, Other.m_aName) < 0; }
|
||||
static bool CompareFilenameAscending(const CMapNameItem Lhs, const CMapNameItem Rhs)
|
||||
{
|
||||
if(str_comp(Lhs.m_aName, "..") == 0)
|
||||
return true;
|
||||
if(str_comp(Rhs.m_aName, "..") == 0)
|
||||
return false;
|
||||
if(Lhs.m_IsDirectory != Rhs.m_IsDirectory)
|
||||
return Lhs.m_IsDirectory;
|
||||
return str_comp_filenames(Lhs.m_aName, Rhs.m_aName) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
void CGameContext::ConAddMapVotes(IConsole::IResult *pResult, void *pUserData)
|
||||
|
@ -3429,19 +3485,48 @@ void CGameContext::ConAddMapVotes(IConsole::IResult *pResult, void *pUserData)
|
|||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
||||
std::vector<CMapNameItem> vMapList;
|
||||
pSelf->Storage()->ListDirectory(IStorage::TYPE_ALL, "maps", MapScan, &vMapList);
|
||||
std::sort(vMapList.begin(), vMapList.end());
|
||||
const char *pDirectory = pResult->GetString(0);
|
||||
|
||||
// Don't allow moving to parent directories
|
||||
if(str_find_nocase(pDirectory, ".."))
|
||||
return;
|
||||
|
||||
char aPath[IO_MAX_PATH_LENGTH] = "maps/";
|
||||
str_append(aPath, pDirectory, sizeof(aPath));
|
||||
pSelf->Storage()->ListDirectory(IStorage::TYPE_ALL, aPath, MapScan, &vMapList);
|
||||
std::sort(vMapList.begin(), vMapList.end(), CMapNameItem::CompareFilenameAscending);
|
||||
|
||||
for(auto &Item : vMapList)
|
||||
{
|
||||
char aDescription[64];
|
||||
str_format(aDescription, sizeof(aDescription), "Map: %s", Item.m_aName);
|
||||
if(!str_comp(Item.m_aName, "..") && (!str_comp(aPath, "maps/")))
|
||||
continue;
|
||||
|
||||
char aCommand[IO_MAX_PATH_LENGTH * 2 + 10];
|
||||
char aMapEscaped[IO_MAX_PATH_LENGTH * 2];
|
||||
char *pDst = aMapEscaped;
|
||||
str_escape(&pDst, Item.m_aName, aMapEscaped + sizeof(aMapEscaped));
|
||||
str_format(aCommand, sizeof(aCommand), "change_map \"%s\"", aMapEscaped);
|
||||
char aDescription[VOTE_DESC_LENGTH];
|
||||
str_format(aDescription, sizeof(aDescription), "%s: %s%s", Item.m_IsDirectory ? "Directory" : "Map", Item.m_aName, Item.m_IsDirectory ? "/" : "");
|
||||
|
||||
char aCommand[VOTE_CMD_LENGTH];
|
||||
char aOptionEscaped[IO_MAX_PATH_LENGTH * 2];
|
||||
char *pDst = aOptionEscaped;
|
||||
str_escape(&pDst, Item.m_aName, aOptionEscaped + sizeof(aOptionEscaped));
|
||||
|
||||
char aDirectory[IO_MAX_PATH_LENGTH] = "";
|
||||
if(pResult->NumArguments())
|
||||
str_copy(aDirectory, pDirectory);
|
||||
|
||||
if(!str_comp(Item.m_aName, ".."))
|
||||
{
|
||||
fs_parent_dir(aDirectory);
|
||||
str_format(aCommand, sizeof(aCommand), "clear_votes; add_map_votes \"%s\"", aDirectory);
|
||||
}
|
||||
else if(Item.m_IsDirectory)
|
||||
{
|
||||
str_append(aDirectory, "/", sizeof(aDirectory));
|
||||
str_append(aDirectory, aOptionEscaped, sizeof(aDirectory));
|
||||
|
||||
str_format(aCommand, sizeof(aCommand), "clear_votes; add_map_votes \"%s\"", aDirectory);
|
||||
}
|
||||
else
|
||||
str_format(aCommand, sizeof(aCommand), "change_map \"%s/%s\"", pDirectory, aOptionEscaped);
|
||||
|
||||
pSelf->AddVote(aDescription, aCommand);
|
||||
}
|
||||
|
@ -3451,11 +3536,15 @@ void CGameContext::ConAddMapVotes(IConsole::IResult *pResult, void *pUserData)
|
|||
|
||||
int CGameContext::MapScan(const char *pName, int IsDir, int DirType, void *pUserData)
|
||||
{
|
||||
if(IsDir || !str_endswith(pName, ".map"))
|
||||
if((!IsDir && !str_endswith(pName, ".map")) || !str_comp(pName, "."))
|
||||
return 0;
|
||||
|
||||
CMapNameItem Item;
|
||||
str_truncate(Item.m_aName, sizeof(Item.m_aName), pName, str_length(pName) - str_length(".map"));
|
||||
Item.m_IsDirectory = IsDir;
|
||||
if(!IsDir)
|
||||
str_truncate(Item.m_aName, sizeof(Item.m_aName), pName, str_length(pName) - str_length(".map"));
|
||||
else
|
||||
str_copy(Item.m_aName, pName);
|
||||
static_cast<std::vector<CMapNameItem> *>(pUserData)->push_back(Item);
|
||||
|
||||
return 0;
|
||||
|
@ -3552,12 +3641,13 @@ void CGameContext::OnConsoleInit()
|
|||
Console()->Register("say", "r[message]", CFGFLAG_SERVER, ConSay, this, "Say in chat");
|
||||
Console()->Register("set_team", "i[id] i[team-id] ?i[delay in minutes]", CFGFLAG_SERVER, ConSetTeam, this, "Set team of player to team");
|
||||
Console()->Register("set_team_all", "i[team-id]", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team");
|
||||
Console()->Register("hot_reload", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConHotReload, this, "Reload the map while preserving the state of tees and teams");
|
||||
|
||||
Console()->Register("add_vote", "s[name] r[command]", CFGFLAG_SERVER, ConAddVote, this, "Add a voting option");
|
||||
Console()->Register("remove_vote", "r[name]", CFGFLAG_SERVER, ConRemoveVote, this, "remove a voting option");
|
||||
Console()->Register("force_vote", "s[name] s[command] ?r[reason]", CFGFLAG_SERVER, ConForceVote, this, "Force a voting option");
|
||||
Console()->Register("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, "Clears the voting options");
|
||||
Console()->Register("add_map_votes", "", CFGFLAG_SERVER, ConAddMapVotes, this, "Automatically adds voting options for all maps");
|
||||
Console()->Register("add_map_votes", "?s[directory]", CFGFLAG_SERVER, ConAddMapVotes, this, "Automatically adds voting options for all maps");
|
||||
Console()->Register("vote", "r['yes'|'no']", CFGFLAG_SERVER, ConVote, this, "Force a vote to yes/no");
|
||||
Console()->Register("votes", "?i[page]", CFGFLAG_SERVER, ConVotes, this, "Show all votes (page 0 by default, 20 entries per page)");
|
||||
Console()->Register("dump_antibot", "", CFGFLAG_SERVER, ConDumpAntibot, this, "Dumps the antibot status");
|
||||
|
@ -3703,7 +3793,7 @@ void CGameContext::RegisterChatCommands()
|
|||
Console()->Register("rescuemode", "?r['auto'|'manual']", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConRescueMode, this, "Sets one of the two rescue modes (auto or manual). Prints current mode if no arguments provided");
|
||||
Console()->Register("tp", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleTo, this, "Depending on the number of supplied arguments, teleport yourself to; (0.) where you are spectating or aiming; (1.) the specified player name");
|
||||
Console()->Register("teleport", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleTo, this, "Depending on the number of supplied arguments, teleport yourself to; (0.) where you are spectating or aiming; (1.) the specified player name");
|
||||
Console()->Register("tpxy", "f[x] f[y]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleXY, this, "Teleport yourself to the specified coordinates. A tilde (~) can be used to denote your current position, e.g. '/tpxy ~1 ~' to teleport one tile to the right");
|
||||
Console()->Register("tpxy", "s[x] s[y]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleXY, this, "Teleport yourself to the specified coordinates. A tilde (~) can be used to denote your current position, e.g. '/tpxy ~1 ~' to teleport one tile to the right");
|
||||
Console()->Register("lasttp", "", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConLastTele, this, "Teleport yourself to the last location you teleported to");
|
||||
Console()->Register("tc", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleCursor, this, "Teleport yourself to player or to where you are spectating/or looking if no player name is given");
|
||||
Console()->Register("telecursor", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleCursor, this, "Teleport yourself to player or to where you are spectating/or looking if no player name is given");
|
||||
|
@ -4745,7 +4835,6 @@ void CGameContext::ForceVote(int EnforcerId, bool Success)
|
|||
return;
|
||||
|
||||
m_VoteEnforce = Success ? CGameContext::VOTE_ENFORCE_YES_ADMIN : CGameContext::VOTE_ENFORCE_NO_ADMIN;
|
||||
m_VoteEnforcer = EnforcerId;
|
||||
|
||||
char aBuf[256];
|
||||
const char *pOption = Success ? "yes" : "no";
|
||||
|
|
|
@ -124,6 +124,7 @@ class CGameContext : public IGameServer
|
|||
static void ConSay(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConHotReload(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConAddVote(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConRemoveVote(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConForceVote(IConsole::IResult *pResult, void *pUserData);
|
||||
|
@ -180,6 +181,10 @@ public:
|
|||
// keep last input to always apply when none is sent
|
||||
CNetObj_PlayerInput m_aLastPlayerInput[MAX_CLIENTS];
|
||||
bool m_aPlayerHasInput[MAX_CLIENTS];
|
||||
CSaveTeam *m_apSavedTeams[MAX_CLIENTS];
|
||||
CSaveTee *m_apSavedTees[MAX_CLIENTS];
|
||||
CSaveTee *m_apSavedTeleTees[MAX_CLIENTS];
|
||||
int m_aTeamMapping[MAX_CLIENTS];
|
||||
|
||||
// returns last input if available otherwise nulled PlayerInput object
|
||||
// ClientId has to be valid
|
||||
|
@ -571,7 +576,6 @@ public:
|
|||
VOTE_TYPE_SPECTATE,
|
||||
};
|
||||
int m_VoteVictim;
|
||||
int m_VoteEnforcer;
|
||||
|
||||
inline bool IsOptionVote() const { return m_VoteType == VOTE_TYPE_OPTION; }
|
||||
inline bool IsKickVote() const { return m_VoteType == VOTE_TYPE_KICK; }
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue